PowerShell Windows remote management of virtual machines in Azure

Working remotely on virtual machines in Windows Azure using PowerShell is something I do quite often. The first thing I do after I created a new virtual machine is in fact to enable Windows Remote Management (WinRM). Enabling WinRM makes it possible to connect from you local PowerShell to a PowerShell session on the target machine, just like an SSH session in the Linux world. You also can register PowerShell script blocks, stored in external files, and get them executed on the target machine. Because WinRM in the Windows Azure world demands an SSL/TLS connection the communication is secured.

Adding a virtual machine endpoint for PS remoting

If it’s not created already you need to create en endpoint for the virtual machine to allow PowerShell remoting. PS remoting uses the TCP port 5986, so the definition for the Azure endpoint that allows HTTPS secured PowerShell remote sessions might look like this:

get-azurevm $mySvc $vmName | Add-AzureEndpoint -Name PS-HTTPS -Protocol TCP -LocalPort 5986 -PublicPort 5986 | Update-AzureVM

Enabling PowerShell remoting on the target machine

If you are dealing with a virtual machine that has an older versions of Windows 2012 R2 installed you need to run the following command:

This command starts the windows service, sets the startup type to automatic and assigns a (HTTP) listener endpoint to all addresses the vm is providing.
Microsoft made it much more easy for us with Windows 2012 R2, because since then the WinRM service is running by default.

Adding an HTTPS listener to WinRM

By default WinRM installs an HTTP listener, what is less secure. In Windows Azure we need to secure the communication using SSL/TLS. To enable that it’s necessary to add the appropriate listener on the target machine. This HTTPS listener needs to be bound to a server certificate, what can be self signed or assigned by the usual authorities on the internet.
If you have the certificate installed you can run following command to add the listener in a standard command shell on the target machine:
winrm create winrm/config/Listener?Address=*+Transport=HTTPS @{Hostname="HOSTNAME.cloudapp.net";CertificateThumbprint="THUMBRPINT"}
You need to replace the HOSTNAME by the host name of the target machine and the THUMBPRINT by the thumbprint value of the server certificate.
Now the virtual machine is ready to accept PowerShell remoting.

Open a Powershell Remote session using SSL and a credentials object

To open a remote session on the target machine in PowerShell we need to create a credentials object based on a username and password pair of the remote machine. We use a secure string object in PowerShell to handle the password securely.
$password = ConvertTo-SecureString $myPwd -AsPlainText -Force
$cred= New-Object System.Management.Automation.PSCredential ($username, $password)
Enter-PSSession -ComputerName HOSTNAME.cloudapp.net -Credential $cred -UseSSL
First we declare two variables for the password and username. Then we convert the plain text password into a secure string representation. Based on the secure password and the username we create a PowerShell credential object.
Finally, the Enter-PSSession command connects the remote machine and switches the context of the your PowerShell to the remote session just like SSH does on a Linux system.

Running a remote script using SSL and a credentials object

Running a script on a remote machine needs the same setup. We also need to provide a credentials object. The command can be a single line of code or a whole PowerShell script stored in a external file.
$password = ConvertTo-SecureString $myPwd -AsPlainText -Force
$cred= New-Object System.Management.Automation.PSCredential ($username, $password )
$computername= "HOSTNAME"
$cmdAutoAdmin = { New-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon' -Name AutoAdminLogon -Value "1" }
invoke-command -ComputerName $computername -Credential $cred -UseSSL -ScriptBlock $cmdAutoAdmin

This example uses the invoke-command to patch the a registry value on the remote machine. First, the command is stored in the cmdAutoAmdin value and then invoked on the remote machine.


About Oliver Dehne
Father of two little boys, good boys. Sometimes I like coding, trying to be a good developer.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: