WinBoss
WinBoss

Reputation: 923

Double hopping credentials from VSTS through Azure PowerShell script to PowerShell script on target VM

I need to automate execution of scripts on target VMs as a domain administrator. The problem is, VMs don't have public. I also should not rewrite the script as it has been written by a team member and I'd rather provide my team with a solution that works for them and is automatable, instead of rewriting their scripts every time. The current process looks like thi

  1. VSTS initiates a build process with Azure PowerShell script command1.ps1
  2. Command1.ps1 installs Azure Custom Script Extension on the target VM
  3. Custom script extension downloads and executes command2.ps1 that runs command3.ps1 as a domain administrator

The problem I'm having is I'm unable to pass credentials from VSTS to command2.ps1 Please, recommend me how I should do that properly. The options I found:

  1. Not sure if it is possible with VSTS https://blogs.technet.microsoft.com/ashleymcglone/2016/08/30/powershell-remoting-kerberos-double-hop-solved-securely/

  2. Add IP public address to the target VM, configure WinRM, execute command2.ps1, delete public IP address

I'm sure there is a better way of doing this. command1.ps1:

    param
(
    [Parameter(Mandatory)]
    [String]$resourceGroupName,

    [Parameter(Mandatory)]
    [String]$targetVMname,

    [Parameter(Mandatory)]
    [String]$vmLocation,

    [Parameter(Mandatory)]
    [String]$FileUri,

    [Parameter(Mandatory)]
    [String]$nameOfTheScriptToRun,

    [Parameter(Mandatory)]
    [String]$customScriptExtensionName,

    [Parameter(Mandatory)]
    [String]$domainAdminName,

    [Parameter(Mandatory)]
    [String]$domainAdminPassword

)

$domainAdminPasswordSecureString = ConvertTo-SecureString -String $domainAdminPassword -AsPlainText -Force
$DomainCredentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $domainAdminName, $domainAdminPasswordSecureString

Set-AzureRmVMCustomScriptExtension -Argument "-DomainCredentials $DomainCredentials" `
    -ResourceGroupName $resourceGroupName `
    -VMName $targetVMname `
    -Location $vmLocation `
    -FileUri $FileUri `
    -Run $nameOfTheScriptToRun `
    -Name $customScriptExtensionName

Remove-AzureRmVMCustomScriptExtension -Force `
    -ResourceGroupName $resourceGroupName `
    -VMName $targetVMname `
    -Name $customScriptExtensionName

command2.ps1:

    param
(
    [Parameter(Mandatory)]
    [System.Management.Automation.PSCredential]$DomainCredentials
)

$url = "https://raw.githubusercontent.com/x/command2.ps1"
$output = "C:\command2.ps1"

Invoke-WebRequest -Uri $url -OutFile $output
Start-Process -FilePath powershell.exe -ArgumentList $output -Credential $DomainCredentials

Upvotes: 1

Views: 401

Answers (1)

4c74356b41
4c74356b41

Reputation: 72171

You don't actually have the double hop problem, because you are not executing the command on the node, you are launching the extension, which downloads the script and executes it.

So what you need to do is this:

Set-AzureRMVMCustomScriptExtension ... -Argument "-domainAdminName admin -domainAdminPassword passw0rD" -VM $Vm
$vm | Update-AzureVM

and in your script (which is invoked INSIDE the machine, so command2.ps1) do:

$domainAdminPasswordSecureString = ConvertTo-SecureString -String $domainAdminPassword -AsPlainText -Force
$DomainCredentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $domainAdminName, $domainAdminPasswordSecureString

and paste the appropriate params into the second script (so it accepts those)

Also, you don't need the intermediate script, you can just download "https://raw.githubusercontent.com/x/command2.ps1" and execute it with arguments

Upvotes: 3

Related Questions