December 7, 2013

Day 7 - Managing Windows with PowerShell

Written By: Steven Murawski (@stevenmurawski)
Edited By: Adam Compton (@comptona)

Thanks for stopping in today. I've got the honor of sharing a bit about a management technology I use to wrangle my Windows Server environment into compliance. Windows Server has long appeared unfriendly to command line and scripted management. This is no longer the case (and hasn't been for a few years now). PowerShell is a game-changer for Windows management and management at scale and is a true force multiplier.

The History

PowerShell quietly stole onto the scene back in 2006. PowerShell offered the Windows administrator and power user a better shell experience (and it was not hard to beat cmd.exe). PowerShell touted direct access to all the richness of the .NET Framework, simplified access and discoverability for WMI (Windows Management Instrumentation), and wrappers for working with COM objects (to make access to traditional Windows APIs more accessible). VMWare quickly recognized the effectiveness of the PowerShell platform and was one of the first third parties to embrace and offer PowerShell cmdlets outside of the Windows OS.

PowerShell Version 2 was released in 2009. V2 introduced a number of great enhancements, the biggest of which was PowerShell Remoting. Over time PowerShell's ecosystem grew. Exchange Server was the first Microsoft server product to fully buy in to PowerShell's philosophy of building management functionality and layering a GUI on top of that. Exchange Server went a step further and used the GUI to teach the command line (in a sad turn, the most recent version of Exchange stepped back and no longer teaches the PowerShell commands used). More OS roles and features began to support PowerShell, as did more Microsoft server focused products. Third parties continued to embrace PowerShell as well, especially in the storage and virtualization space.

PowerShell Version 3 came to fruition in 2012. PowerShell V3 brought enhancements to remoting, durable workflows, and most importantly an easy way for wrapping WMI or CIM (Common Information Model - the standard that WMI is based on) APIs with a XML mapping file to generate PowerShell cmdlets. This advance allowed PowerShell cmdlet (the basic unit of operation in PowerShell) coverage to explode. With PowerShell V3 (and Server 2012), Windows Server and its various roles and features became much more automation friendly.

PowerShell Version 4 has followed closely afterwards. Microsoft appears to be accelerating their release cycle and so V4 surfaced only a year after V3. Version 4 brings Desired State Configuration, a configuration management agent (and a DSL for creating configuration descriptions) to Windows Server 2012 R2 (and downlevel to Server 2012 and Server 2008 R2).

The Shell

PowerShell is an object-based shell. This means that the output of native PowerShell commands (cmdlets) are objects. Why is this important you may ask? Well, the Windows management paradigm is better represented in objects. But, the functional purpose for admins is that we get pre-parsed output. This also lets PowerShell supply some standard mechanisms for grouping, sorting, output formatting, and a variety of other common tasks. The PowerShell runtime provides standards for parameter parsing, argument transformation and validation, pipeline input, and support for the Verbose, Debug, Warning, Error, and Output streams. The runtime also provides to all cmdlets and advanced functions (PowerShell scripts that offer similar functionality to cmdlets) common parameters to enable switches to turn on Verbose and Debug output, change error handling behavior, and collect output. In addition, the runtime makes it trivial to offer WhatIf and Confirm behavior for commands with potential destructive or irreversable change.

Remote Server Management

One of the big wins in leveraging PowerShell for your Windows Server management options is the remoting infrastructure. PowerShell supports several scenarios for remote execution - one to one, fan in, and fan out.

One to one remoting offers two scenarios: one that you'd expect, and one that's a little different. The expected scenario is where you can use Enter-PSSession to connect directly to a management session on a remote machine. This is loosely the equivalent to "ssh'ing" to a remote box. The second scenario supported in one to one style remoting is implicit remoting. In this case, you've established a connection to a remote machine and instead of working directly at the remote console you can tell PowerShell to create proxies for the commands on the remote machine and add those to your current PowerShell session (or export them to disk for more permanent use). The proxies created handle connecting to the remote server if a connection is not already present. Your input to the proxies is marshalled across the remoting connection and the commands are executed on the remote server. This type of remoting can be very powerful, but it is one of the least used and least tested (for support by third party or Windows server role and feature commands).

The second variant for remoting is fan in. In this method, you configure an endpoint to offer up commands to users based on roles (or any criteria you want to evaluate). This scenario supports hosted services or where you need to delegate different capabilities to different parties. This scenario is leveraged by administrators connecting in a one to one or fan out scenario.

The third remoting scenario is fan out. This is one of the most powerful variants on how remoting can be leveraged. Invoke-Command offers the ability to reach out to one or more computers and execute a script or arbitrary block of code and return the results to the calling computer. There are options to throttle execution across x number of hosts, to have all the results return in the background (as a background job), and to marshal input to the script or arbitrary code executing remotely. This lets you, from one command, execute the same instructions across tens, hundreds, or thousands of machines at the same time, and have the results streamed back to you for review at your convenience.

Remoting does offer one major hurdle (and several minor ones). A remoting session is much lower overhead than an interactive remote desktop session, because the connection is actually hosted in the Windows Remote Management (WinRM) service. Since the connection is being made to a service, commands are executed in the context of that service (with your credentials). However, by default services are constrained from passing your credentials outside of their own processes (so the service cannot just impersonate you at the service author's whim). This can cause a number of commands to fail due to permissions issues (WinRM runs as Network Service). This means many commands for things like Failover Clustering will require additional rights. There are two ways to work around this, either with Kerberos delegation or by enabling CredSSP; both options have security considerations that should be evaluated before you enable them.

Other Tasty Tidbits

In addition to remoting, PowerShell offers several capabilities to make your management scenarios easier. Version 2 introduced background jobs, where long running tasks can be done in another session and the results retrieved later. PowerShell (since V2) ships with a built-in script editor, the PowerShell ISE, which while not great is "good enough" to get work done and enhance your scripting experience (there are also some nice third party editors, including PowerGUI, PowerShellPlus, and PowerShell Studio.

Each version of PowerShell offers a significantly better experience, so I would encourage you to run the highest version your environment will support. Going from V1 to V2 enables background jobs, remoting, and some other great scenarios. Going from V2 to V3 will offer a tremendous boost in performance. Adding V4 will give you access to Desired State Configuration (my personal favorite).

Regardless of the version of PowerShell you are on, there are a number of features which can help you use PowerShell to learn PowerShell. There is a built in help system (Get-Help or aliased to man). PowerShell includes the ability to set breakpoints in scripts for debugging purposes or step through scripts as they execute. If you really want to go low level, PowerShell offers a window into the engine operations through Trace-Command where you can view tracing messages as commands execute and route that to the console or debugger of your choice.

Come Explore

I hope I've whetted your appetite for PowerShell as a management surface for the Windows Server environment. If you want to learn more, hop on over to for forums, blogs, free e-books, and a welcoming community ready to help. If IRC is your thing, #powershell on Freenode remains a great resource for interactive help and learning. Finally, the bedrock of the PowerShell Community remains the PowerScripting Podcast, which has been shining lights into all areas of PowerShell use since PowerShell was released. Now, I'm going to go back to reading some of the other great SysAdvent articles!

1 comment :

Adam Bertram said...

I've been using Powershell for 3 years now and love it. If you're a sys admin, you MUST learn Powershell or you're going to be left behind. Just wanted to put a plug into my blog in case anyone would like to read more stuff about Powershell. I post nearly every day some of the scripts I use and how I use them.

- Adam