WinRM + Powershell Remote Execution for Windows

A while back, I posted about using WinRM for automating tasks on remote Windows machines.
WinRM (Windows Remote Management) is Microsoft’s implementation of WS-Management, a SOAP based protocol for management of devices and servers. Among other things, it can be used to connect to remote Windows servers and run commands on them, similar to SSH in the Linux world.
In this post, I am going to show an actual example of using WinRM to execute commands on a remote machine using Powershell.


 

Beyond simple automation – Windows orchestration made easy. Test drive Cloudify.     Go

 


We’ll need two Windows hosts for this example, which we will start on the Amazon cloud.
Environment Setup
Let’s set up all of the resources we’ll need. I’ll use the EC2 CLI to set everything up. Of-course, if you already have two windows machine to use, you can skip this part.

  • Set up the security group

We will need to open two ports – 3389 for Remote Desktop access to the client machine, and 5985 for WinRM access to the server machine.

ec2-create-group -d “WinRM Group” WinRM-Group
ec2-authorize -P TCP -p 3389 -s 0.0.0.0/0 WinRM-Group
ec2-authorize -P TCP -p 5985 -s 0.0.0.0/0 WinRM-Group

  • Create the keypair for our test


ec2-create-keypair “WinRM-kp”

And save the created private key in a file named WinRM-kp.pem

  • Now let’s start the instances


ec2-run-instances ami-678c4c10 -n 2 -g “WinRM-Group” -k “WinRM-kp” -t “m1.medium”
INSTANCE i-37973874 ami-678c4c10 pending WinRM-kp 0 m1.medium 2014-06-24T07:44:51+0000 eu-west-1a windows monitoring-disabled ebs hvm xen sg-871a25f0 default false
INSTANCE i-36973875 ami-678c4c10 pending WinRM-kp 1 m1.medium 2014-06-24T07:44:51+0000 eu-west-1a windows monitoring-disabled ebs hvm xen sg-871a25f0 default false

Note the instance IDs, highlighted above. We’ll need them later.
For this example I have chosen to use Windows 2008 R2. The AMI ID is ami-678c4c10 at the time of writing this post, but may of-course change in the future.
I recommend adding the Name tag to the instances to make the API results and web console more readable:

ec2-create-tags i-37973874 -t Name=Client
ec2-create-tags i-36973875 -t Name=Server

Make sure to note the public DNS names of the new machines:

~$ec2-describe-instances i-37973874
INSTANCE i-37973874 ami-678c4c10 ec2-54-73-137-146.eu-west-1.compute.amazonaws.com
TAG instance i-37973874 Name Client
~$ ec2-describe-instances i-36973875
RESERVATION r-dde5109e 535075449278 WinRM-Group
INSTANCE i-36973875 ami-678c4c10 ec2-54-74-118-124.eu-west-1.compute.amazonaws.com
TAG instance i-36973875 Name Server

  • Now we wait until the Windows passwords become available. This can take a few minutes:


ec2-get-password -k WinRM-kp.pem i-37973874
XXXXXXXX
ec2-get-password -k WinRM-kp.pem i-36973875
YYYYYYYY

WinRM in Action
OK, our environment is set up. First, lets RDPs (Remote Desktop) to the client machine.
Once on the client machine, we need to set up the client environment.
First, open a Powershell window.

  • Enable WinRM access to the remote machine

We need to tell Windows which remote hosts can be connected to.

Set-Item WSMan:localhostClientTrustedHosts -Value ec2-54-74-118-124.eu-west-1.compute.amazonaws.com -Force

Note that you can just allow access to any host with:

Set-Item WSMan:localhostClientTrustedHosts -Value * -Force

  • Enable script execution on the client:


Set-ExecutionPolicy -Force unrestricted

  • Create the Powershell credentials

You can create the credentials interactively, or with a script.
The interactive version brings up a windows pop-up where you enter your username and password:

$cred = Get-Credential

To skip the interactive bits and run everything automatically:

$securePassword = ConvertTo-SecureString -AsPlainText -Force ‘YYYYYYYY’
$cred = New-Object System.Management.Automation.PSCredential ‘Administrator’, $securePassword

  • And start you remote Powershell session


Enter-PSSession -ComputerName ec2-54-74-118-124.eu-west-1.compute.amazonaws.com -Credential $cred

That’s it. You now have a running remote session. Any command you run in this shell is in fact running on the remote machine.
Note that we did not make any changes to the server – you can just bring up a plain vanilla instance on EC2 and start working on it immediately.
Some Additional Useful Commands

  • Create a reusable session


New-PSSession -ComputerName ec2-54-74-118-124.eu-west-1.compute.amazonaws.com -Credential $cred
Id Name ComputerName State ConfigurationName Availability
— —- ———— —– —————– ————
2 Session2 ec2-54-74-11… Opened Microsoft.PowerShell Available
Enter-PSSession 2

Creating a session like this lets you open multiple sessions and go back and forth among them without having to open a new session each time.

  • List Open sessions


Get-PSSession

  • Close a Session


Remove-PSSession 2

  • Remote execute a command


Invoke-Command -ComputerName ec2-54-74-118-124.eu-west-1.compute.amazonaws.com -Credential $cred -ScriptBlock {dir}

Really useful for executing that one-line command on the server.

  • Remote execute a script file


Invoke-Command -ComputerName ec2-54-74-118-124.eu-west-1.compute.amazonaws.com -Credential $cred .pathtoscript.ps1

Environment Cleanup

  • Undo client side changes

If you are keeping the client machine, you may want to remove the server from the Trusted Hosts list:

Set-Item WSMan:localhostClientTrustedHosts “”

  • EC2 Cleanup

Let’s clean up all of the resources:

ec2-terminate-instances i-37973874 i-36973875
ec2-delete-group WinRM-Group
ec2-delete-keypair WinRM-kp

Not using EC2?
Your windows server just needs to have WinRM installed and enabled. WinRM is usually available on any reasonably up to date Windows server. To enable WinRM you need to run one command:

Enable-PSRemoting -Force

Make sure port 5985 is allowed on whatever firewall system you are using.


This was originally posted at Barak’s blog Head in the Clouds, find it here.

 

comments

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    Back to top