Summary: Guest blogger, Jason Hofferle, talks about the basics of Windows PowerShell remoting.
Microsoft Scripting Guy, Ed Wilson, is here. This week I am in Seattle, Washington presenting at Microsoft TechReady 15. I have been talking to Jason for some time, and I thought that now would be a great chance to share some of his insights with us. This is the first in a series of five blogs by Jason.
Jason Hofferle has been an IT professional since 1997. His experience includes enterprise desktop engineering for a Fortune 500 financial institution and Active Directory design for local governments and law enforcement. Jason currently works for the Defense Contract Management Agency, where he implements new technology such as virtual desktop infrastructure. He recently has been speaking about Windows PowerShell at SQL Saturday and IT Pro Camp events in Florida, and he frequently attends the Tampa PowerShell User Group.
Blog: Force Multiplication through IT Automation
Twitter: @jhofferle
As Windows PowerShell enthusiasts go, I might be considered a late adopter. I’ve kept tabs on Windows PowerShell since it was called Monad, but it wasn’t until it was included with the Windows 7 operating system that I really started using it on a consistent basis. When version 2 was released, it included some game-changing features that convinced me Windows PowerShell was the future. One of these features is PowerShell Remoting, which allows me to run commands on a remote system as if I was sitting in front of it. It provides a consistent framework for managing computers across a network.
When I start explaining PowerShell Remoting to others, sometimes the initial reaction is, “Big deal,” because there are already many techniques available for working with remote computers. We have Windows Management Instrumentation (WMI), which is commonly used with VBScript. We have executables from resource kits or non-Microsoft tools that allow remote management, for example, the Sysinternals PSExec tools. Even many of the Windows PowerShell cmdlets have a ComputerName parameter to specify remote computers. So how does PowerShell Remoting differ from the capabilities we already have? Why should someone go through the trouble of enabling this feature when so many tools are available that don’t have a dependency on PowerShell Remoting?
Many of these methods have their downsides. First of all, there’s no consistency between utilities. One command may require parameters with a slash, the next wants a slash with a colon, and many handle quotation marks differently than others. The knowledge gained from learning one tool doesn’t transfer to another, so when I need to perform a different administrative task, I need to read through documentation and deal with the quirks of a new utility.
Another issue is that many use distributed COM (DCOM) or remote procedure call (RPC) to connect to remote systems. This may work well on a single internal network, but it causes problems when these tools need to traverse firewalls or play nice with intrusion prevention or other security systems. I don’t know too many firewall administrators who want to open up RPC ports. Finally, existing tools sometimes work differently depending on if a command is being run locally or remotely. I’ve had several occasions using WMI with VBScript where something is working perfectly on my local system, but it fails miserably when I try it on a remote computer because that particular application programming interface (API) can only be used locally. Wouldn’t it be nice if we could have consistent management commands that worked no matter where they were being run?
PowerShell Remoting is a solution to some of the security and consistency issues that IT professionals currently work around. It’s built on Microsoft’s implementation of the Web Services for Management (WSMan) protocol, and it uses the Windows Remote Management (WinRM) service to manage communication and authentication. This framework was designed to be a secure and reliable method for managing computers that’s built on well-known standards like Simple Object Access Protocol (SOAP) and Hypertext Transfer Protocol (HTTP).
Unlike utilities that use various programming interfaces to talk to a remote computer, PowerShell Remoting connects my local Windows PowerShell session with another session running on the remote system. The commands that I enter are sent to the remote computer, executed locally, and then the results are sent back. Because all commands run locally, I don’t have to worry about an individual cmdlet lacking the plumbing to work across my network. Everything runs on the same framework, so I only need to learn the Windows PowerShell way of executing remote commands.
A major advantage over other methods of remote management is that a single port is used for every application that uses WSMan. Instead of poking different holes in a firewall for every application, only the port used by WSMan needs to be configured, and the WinRM service will make sure the traffic gets routed to the correct application.
There are several authentication methods, including Kerberos protocol and Windows Challenge/Response. The communication between two computers is encrypted at the protocol layer, except when basic access authentication is used, which is intended for use with Hypertext Transfer Protocol Secure (HTTPS) sessions.
Besides the simplicity of PowerShell Remoting (after it’s configured, there is very little to worry about), there are some massive performance benefits when using one-to-many or fan-out remoting. These performance benefits convinced me to start converting some of my VBScript scripts into Windows PowerShell because it saved so much time. With fan-out remoting, I provide Windows PowerShell a list of computers along with the command I want them to run. Windows PowerShell “fans-out” and sends the command to the remote computers in parallel. Each remote system runs the command locally and sends the results back. This is different from the common VBScript technique of using a foreach loop to perform operations against a list of computers, one at a time.
When talking about PowerShell Remoting at a conference or similar event, it’s difficult to demonstrate the benefits because fan-out doesn’t really reach its potential until I throw hundreds or thousands of computers at it. It sounds powerful on paper, but I needed some real-world numbers to help communicate the effectiveness. I also needed some data to convince my own organization, so I performed some tests that would help articulate how powerful this feature can be.
A scenario where I commonly use PowerShell Remoting is when I need to query a large number of computers for a specific event. For my performance testing, I decided to search the security event log for the last twenty log-on events. To get baseline data without using PowerShell Remoting, I stored a list of computer names in a $Computers variable and piped it to a loop.
$Computers | foreach { Get-WinEvent –FilterHashTable @{logname=”security”;id=4624} –MaxEvents 20 –ComputerName $_ }
For the comparison, I used the same Get-WinEvent cmdlet, but in conjunction with Invoke-Command, which is a PoweShell Remoting command. Invoke-Command takes my list of computer names and tells them to run the command specified in the script block. The ThrottleLimit parameter is telling Windows PowerShell to connect to 50 computers simultaneously.
Invoke-Command –ComputerName $Computers –ScriptBlock { Get-WinEvent –FilterHashTable @{logname=”security”;id=4624} –MaxEvents 20 } –ThrottleLimit 50
By using a foreach loop, similar to how it might be done with VBscript or without PowerShell Remoting, it took over six hours to complete the operation against 100 computers. By using PowerShell Remoting, it took 15 seconds. This is a real-world situation on a production network against Windows 7 computers that were multiple wide area network (WAN) hops away in many cases. By using this same command, I increased the number of computers to see how well it scaled.
With PowerShell Remoting, I can retrieve the last twenty log-on events from the local security log on 1000 workstations in a little over two minutes.
PowerShell Remoting is the killer feature in Windows PowerShell. When it’s configured in an environment, it provides a transparent and efficient framework for managing computers. It has saved me countless hours and simplified many daily tasks. No matter what type of environment you have, PowerShell Remoting is worth checking out.
~Jason
Thank you, Jason, for an excellent blog. We look forward to Part Two tomorrow.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy