Views: 2,233
			
This post will demo how to run remote PowerShell to an Azure vm. It’s either can from Azure Automation Portal or from a vm that running in Azure. This includes set up the connection to an Azure VM as well as call a command inside of an Azure API.
Before you get started, you need to make sure to install two modules from Azure Runbook Gallery (Thanks to the System Center Automation Team)
One is Connect-AzureVM, the other is Invoke-PSCommandSample.
Install and publish those two modules, and then run a command like below:
| 12
 3
 4
 5
 6
 |     Invoke-PSCommandSample -AzureSubscriptionName "Visual Studio Premium with MSDN" `-ServiceName "DEMO" `
 -VMName "DC01" `
 -VMCredentialName "VMDomainCred" `
 -PSCommand "Get-WindowsFeature" `
 -AzureOrgIdCredential $Cred
 
 | 
 
If you cannot find the module, please use the following:
Connect-AzureVM:
|  12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 | <#.SYNOPSIS
 Sets up the connection to an Azure VM
 
 .DESCRIPTION
 This runbook sets up a connection to an Azure virtual machine. It requires the Azure virtual machine to
 have the Windows Remote Management service enabled, which is the default. It sets up a connection to the Azure
 subscription and then imports the certificate used for the Azure VM so remote PowerShell calls can be made to it.
 
 .PARAMETER AzureSubscriptionName
 Name of the Azure subscription to connect to
 
 .PARAMETER AzureOrgIdCredential
 A credential containing an Org Id username / password with access to this Azure subscription.
 
 If invoking this runbook inline from within another runbook, pass a PSCredential for this parameter.
 
 If starting this runbook using Start-AzureAutomationRunbook, or via the Azure portal UI, pass as a string the
 name of an Azure Automation PSCredential asset instead. Azure Automation will automatically grab the asset with
 that name and pass it into the runbook.
 
 .PARAMETER ServiceName
 Name of the cloud service where the VM is located.
 
 .PARAMETER VMName
 Name of the virtual machine that you want to connect to
 
 .EXAMPLE
 Connect-AzureVM -AzureSubscriptionName "Visual Studio Ultimate with MSDN" -ServiceName "Finance" -VMName "WebServer01" -AzureOrgIdCredential $cred
 
 .NOTES
 AUTHOR: System Center Automation Team
 LASTEDIT: Dec 18, 2014
 #>
 workflow Connect-AzureVM
 {
 [OutputType([System.Uri])]
 
 Param
 (
 [parameter(Mandatory=$true)]
 [String]
 $AzureSubscriptionName,
 
 [parameter(Mandatory=$true)]
 [PSCredential]
 $AzureOrgIdCredential,
 
 [parameter(Mandatory=$true)]
 [String]
 $ServiceName,
 
 [parameter(Mandatory=$true)]
 [String]
 $VMName
 )
 
 Add-AzureAccount -Credential $AzureOrgIdCredential | Write-Verbose
 
 # Select the Azure subscription we will be working against
 Select-AzureSubscription -SubscriptionName $AzureSubscriptionName | Write-Verbose
 
 InlineScript {
 # Get the Azure certificate for remoting into this VM
 $winRMCert = (Get-AzureVM -ServiceName $Using:ServiceName -Name $Using:VMName | select -ExpandProperty vm).DefaultWinRMCertificateThumbprint
 $AzureX509cert = Get-AzureCertificate -ServiceName $Using:ServiceName -Thumbprint $winRMCert -ThumbprintAlgorithm sha1
 
 # Add the VM certificate into the LocalMachine
 if ((Test-Path Cert:LocalMachineRoot$winRMCert) -eq $false)
 {
 Write-Progress "VM certificate is not in local machine certificate store - adding it"
 $certByteArray = [System.Convert]::fromBase64String($AzureX509cert.Data)
 $CertToImport = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 -ArgumentList (,$certByteArray)
 $store = New-Object System.Security.Cryptography.X509Certificates.X509Store "Root", "LocalMachine"
 $store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
 $store.Add($CertToImport)
 $store.Close()
 }
 
 # Return the WinRM Uri so that it can be used to connect to this VM
 Get-AzureWinRMUri -ServiceName $Using:ServiceName -Name $Using:VMName
 }
 }
 
 | 
 
Invoke-PSCommandSample:
|  12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 | <#.SYNOPSIS
 This runbook calls a command inside of an Azure VM
 
 .DESCRIPTION
 This runbook connects into an Azure virtual machine and runs the PowerShell command passed in.
 It has a dependency on the Connect-AzureVM runbook to set up the connection to the virtual machine
 before the command can be run.
 
 .PARAMETER AzureSubscriptionName
 Name of the Azure subscription to connect to
 
 .PARAMETER AzureOrgIdCredential
 A credential containing an Org Id username / password with access to this Azure subscription.
 
 If invoking this runbook inline from within another runbook, pass a PSCredential for this parameter.
 
 If starting this runbook using Start-AzureAutomationRunbook, or via the Azure portal UI, pass as a string the
 name of an Azure Automation PSCredential asset instead. Azure Automation will automatically grab the asset with
 that name and pass it into the runbook.
 
 .PARAMETER ServiceName
 Name of the cloud service where the VM is located.
 
 .PARAMETER VMName
 Name of the virtual machine that you want to connect to
 
 .PARAMETER VMCredentialName
 Name of a PowerShell credential asset that is stored in the Automation service.
 This credential should have access to the virtual machine.
 
 .PARAMETER PSCommand
 PowerShell command that you want to run inside the Azure virtual machine.
 
 .EXAMPLE
 Invoke-PSCommandSample -AzureSubscriptionName "Visual Studio Ultimate with MSDN" -ServiceName "Finance" -VMName "WebServer01" -VMCredentialName "FinanceCredentials" -PSCommand "ipconfig /all" -AzureOrgIdCredential $cred
 
 .NOTES
 AUTHOR: System Center Automation Team
 LASTEDIT: Aug 14, 2014
 #>
 Workflow Invoke-PSCommandSample
 {
 Param
 (
 [parameter(Mandatory=$true)]
 [String]
 $AzureSubscriptionName,
 
 [parameter(Mandatory=$true)]
 [PSCredential]
 $AzureOrgIdCredential,
 
 [parameter(Mandatory=$true)]
 [String]
 $ServiceName,
 
 [parameter(Mandatory=$true)]
 [String]
 $VMName,
 
 [parameter(Mandatory=$true)]
 [String]
 $VMCredentialName,
 
 [parameter(Mandatory=$true)]
 [String]
 $PSCommand
 )
 
 # Get credentials to Azure VM
 $Credential = Get-AutomationPSCredential -Name $VMCredentialName
 if ($Credential -eq $null)
 {
 throw "Could not retrieve '$VMCredentialName' credential asset. Check that you created this asset in the Automation service."
 }
 
 # Set up Azure connection by calling the Connect-Azure runbook. You should call this runbook after
 # every CheckPoint-WorkFlow to ensure that the management certificate is available if this runbook
 # gets interrupted and starts from the last checkpoint
 $Uri = Connect-AzureVM -AzureSubscriptionName $AzureSubscriptionName -AzureOrgIdCredential $AzureOrgIdCredential -ServiceName $ServiceName -VMName $VMName
 
 # Run a command on the Azure VM
 $PSCommandResult = InlineScript {
 Invoke-command -ConnectionUri $Using:Uri -credential $Using:Credential -ScriptBlock {
 Invoke-Expression $Args[0]
 } -Args $Using:PSCommand
 
 }
 
 $PSCommandResult
 }
 
 |