tan and grey spiral stairs looks similar to a shell

Getting Started with PowerShell

Don't be afraid to jump in

You're doubtless aware that Windows PowerShell exists, and that it's somehow a big deal in the Microsoft world. But perhaps you've been too busy to really dig into PowerShell, or maybe you aren't sure why you should care about it. Let's clear up some misconceptions and answer that question in the process.

Why PowerShell?

First, we need to bust two major PowerShell myths.

PowerShell is a scripting language. Not true. PowerShell contains a scripting language: a very tiny one, with only about two dozen keywords. But PowerShell is actually a command-line shell, much like cmd.exe or UNIX Bash shell. You run commands—such as Ipconfig, Ping, and other commands that you've undoubtedly run in the past—in this shell. True, at some point you might want to combine multiple commands into a batch file, and you're welcome to call that scripting if you want to. But it isn't really programming such as you'd perform in Microsoft Visual Studio.

Part of this myth comes from the fact that PowerShell allows itself to be used as a kind of lightweight programming language by folks that have those skills. But it doesn't require you to have those skills to be effective.

Microsoft wants to push people away from the GUI. Also not true. Microsoft is trying to de-emphasize running GUI consoles on the server; servers aren't well-equipped to deliver a good GUI experience without compromising server-lever performance. But running GUIs on the client, even one that connects to a server to do its work, is very much alive.

PowerShell merely represents an alternative for administrators. GUIs can be built to run PowerShell commands in the background, so PowerShell can both provide the functional guts to a GUI and be available for direct use by administrators.

That said, Microsoft is definitely engaging in triage over what its GUI consoles can do, typically focusing on day-to-day tasks. Unusual or less frequent tasks might eventually be available only via the command line. Be upset about that if you want, but also understand that failing to add PowerShell to your skills repertoire could damage your career in the long term.

Running Commands

Using PowerShell doesn't need to be complicated. For example, suppose you want to add a new user to Active Directory (AD). That task is fairly easy:

New-ADUser -Name DonJ -samAccountName DonJ -Title CTO -City "Las Vegas" -Department IT

As you can see, the New-ADUser command accepts several command-line parameters. Those parameters (e.g., -Name, -Title, -City) correspond to the same fields that you'd see when using Active Directory Users and Computers to add a user. So why use the command line instead of the GUI? Because the command line makes it easier to do many things in bulk.

For example, suppose you've been given a Microsoft Excel spreadsheet of new users that need accounts. The first row of the spreadsheet contains column headers: City, Title, Department, Name, and samAccountName—the attributes of those users. Simply save the Excel file as a comma-separated value (CSV) file, perhaps naming it NewUsers.csv. From there, you can easily use PowerShell to create the new users:

Import-CSV NewUsers.csv | New-ADUser

As you can imagine, this approach is much faster than manually creating the users in the GUI. PowerShell takes just a few seconds to create 100 user accounts, whereas creating that many accounts in the GUI can take a few hours. By the way, New-ADUser is a command from the Microsoft ActiveDirectory module, which you'll find in the Remote Server Administration Tools for Windows 7 and on Windows Server 2008 R2 (and later) domain controllers (DCs). You need to run

Import-Module ActiveDirectory

to load the module into memory after installing it on your system.

Learning the Syntax

The most difficult thing about any command-line interface (CLI) is learning the command syntax. Which parameters are available? What does each one do, and which values will it accept? Administrators often spend hours on a search engine looking for syntax examples. But with PowerShell, you can get started much more easily. Need to do something with services?

Help *service*

Run that command in the shell and you'll get a listing of commands that deal with services. Suppose you find a promising-looking one in Set-Service. You can quickly learn how to use that command by running another command:

Help Set-Service -full

The -full parameter is important. This parameter provides a lot of extra information, including details on each and every parameter's usage as well as practical examples. No need to hop on Bing to find examples; they're already in the product.

Note that some folks use the formal Get-Help command rather than just Help. I prefer the latter, which automatically pauses the display after each screen of text. There's no need to pipe the file to More when you use Help.

A Few Gotchas

Like any technology, PowerShell includes a few gotchas that can trip up newcomers. For example, you need to know that all PowerShell commands run in something called a pipeline. Basically, each time you press Enter, all the commands you just typed are put into a pipeline and run. Most commands accept input and produce output that way. Here's an example:

Get-Process | Sort -Property VM -Descending | Select -First 10

Whatever the last command in that pipeline outputs is what appears on the screen. If the last command outputs nothing, you get nothing on the screen. Try this instead:

Get-Process | Sort -Property VM -Descending | Select -First 10 |
Export-CSV procs.csv

Because Export-CSV doesn't produce output, nothing appears on the screen. You do, however, get a CSV file on disk, which is cool.

Also, be aware that when something does appear on the screen, the output's appearance is governed by PowerShell's formatting defaults. You can manipulate those:

Get-Process | Sort -Property VM -Descending | Select -First 10 |
Format-Table -Property ID,VM,PM,Name -autoSize

However, the four Format cmdlets—Format-List, Format-Table, Format-Wide, and Format-Custom—don't produce traditional output. They produce instructions that are designed to construct an onscreen display. Therefore, a command such as the following won't work as you might expect:

Get-Process | Sort -Property VM -Descending | Select -First 10 |
Format-Table -Property ID,VM,PM,Name -autoSize |
ConvertTo-HTML | Out-File procs.html 

The input to ConvertTo-HTML is screen-layout instructions, so you'll get an HTML file with those instructions. It's pretty much just all hexadecimal codes and garbage, as far as we human beings are concerned. There's an easy way to avoid this gotcha: Don't put any command after a Format cmdlet, unless that command is Out-Printer or Out-File, both of which are specially designed to understand screen-layout instructions.

Extending the Shell

Like the Microsoft Management Console (MMC), PowerShell is designed to be extended so that it can manage different technologies. As Table 1 shows, there are two ways to extend the shell, depending on whether you're using PowerShell version 1 (v1) or version 2 (v2). Both methods offer a means of discovering which extensions you have installed locally.


PowerShell v2 Only

PowerShell v1 and v2

Table 1: Extending PowerShell

Find what's available

Get-Module -ListAvailable

Get-PSSnapin -Registered

Load an extension

Import-Module name

Add-PSSnapin name

See which commands were added

Get-Command -Module name

Get-Command -PSSnapin name

Learn to use a command

Help command-name

Help command-name

Note that the PowerShell v2 method of finding what's available lists only modules that are installed in specific locations; some product extensions don't put their modules in the right place. However, those products typically create a Start menu shortcut that will tell you where the module is installed.

Some folks get a bit hung up on the idea that there are product-specific versions of PowerShell, such as the Exchange Management Shell or the SharePoint Management Shell. The fact is that there's no such thing as product-specific versions of PowerShell although Microsoft named features in a way that implies otherwise. The Exchange Management Shell is nothing more than a Start menu shortcut. Look at its properties: You'll see that it runs good old PowerShell.exe. The shortcut simply simultaneously runs PowerShell and auto-runs a particular script, or loads a particular module. You can manually load that module: Just look at the properties of the Start menu shortcut to see the module location, and then run

Get-Module path-to-module

That way, you can load whichever modules you like into the shell.


There's a lot of talk about objects in PowerShell, which freaks out some people. They immediately think, "This is starting to sound like development, and I didn't sign up for programming. Count me out!"

Chill. "Object" is just a word that means "a data structure." Imagine an Excel spreadsheet or even a Microsoft Access database table. Each row in the table or sheet is an object; each column is a property. It's that simple. The command


produces an onscreen table display, with each row representing one service object, and each column representing an object property. This isn't programming; it's just a different terminology. With that terminology in mind, you can do some pretty amazing things.

Remove objects you don't want to look at. Use the Where-Object cmdlet to filter things out of the pipeline. Take this command, for example:

Get-Service | Where { $_.Status -eq 'Running' } 

This command displays only running services. The syntax is crazy, but decipherable. Within the curly brackets (which specify the criteria for objects that you want to see), you use $_ to refer to whatever the previous command produced. I didn't want to look at an entire service object, I just wanted to work with a portion of it. How do you specify a portion, or fraction, in math? With a decimal point, as in "3.147," right? So I followed $_ with a decimal point, and then specified the fraction with which I wanted to work: Status. I know from previous runs of Get-Service that the Status column contains "Running" for running services, so I said I only wanted to keep the services in which the Status column equals (that's the -eq comparison operator) "Running." Run

Help about_comparison_operators

to read more on comparison operators.

Choose which properties to display. You can easily choose columns other than the defaults:

Get-Service | Select -Property Name,Status

Change the sort order. The default sort order is always ascending. You can reverse that if you want to:

Get-Service | Sort -Property Name -Descending

Combine. You can pipe the output of many commands to the input of another:

Get-Service | Sort -Property Status |
Select -Property Name,Status

Don't Let the Internet Stress You Out

One problem with the Internet is that it gives everyone a voice. PowerShell is designed to be approachable and usable by many audiences. But just because you've found some 900-line sample script doesn't mean that kind of programmer-style approach is the only way to use PowerShell; it's just how one person chooses to use it, probably because that's the approach that person understands the best.

On ShellHub.com,  I've collected a short list of PowerShell resources that tend to favor a more administrator, type-a-command-and-press-Enter approach, rather than the programmer-style approach favored by some enthusiasts. When you're more comfortable with the shell, you'll likely start modifying your own approach, getting ever-more complex. That's fine. But you can start simple and still do great stuff. For example, in my book Windows PowerShell Scripting and Toolmaking, I start with a simple command that you can type in to get immediate results. I gradually build on that command, adding parameters, adding help, and so forth, until 100 pages later it looks and feels like a native PowerShell cmdlet. You don't need to tackle all PowerShell's complexity at once. Start small and work your way up.

You Don't Need to Start Over

I'll often ask a trick question of my students when I teach a PowerShell class: "How do you map a network drive in PowerShell?" Many will search through Help, struggling to find something. They'll often run across New-PSDrive, which isn't the right answer; its drives aren't visible outside of PowerShell. Eventually I'll give them the answer: Net Use.

Everyone smacks their foreheads. It's a good lesson: Microsoft isn't asking you to discard everything you already know. (Weird, right?!) All the command-line techniques you already know—Net Use, Icacls, DsAcls, NSLookup, Ping, Ipconfig, Pathping—still work, so continue to use them. You can mix and match those pretty freely with PowerShell's native cmdlets, too. So if you already know how to do something, don't bang your head against a wall trying to figure out the PowerShell way to do it. Just do what you know.

Why Is PowerShell Scary to Some Admins?

I'll tell you a little secret. Many administrators got into Windows administration, as opposed to UNIX or something else, specifically because Windows is easy, at least on the surface. Run through a few wizards, click a few buttons, and your job is done. Many of those administrators (and I'm sure you've met a few) actually have very little understanding of what's going on underneath those buttons and wizards. That's why PowerShell frightens them. It isn't that they're afraid of learning the syntax, or even that they think typing is so tedious. It's that PowerShell strips away much of the hand-holding that the GUI has been doing.

Being able to use PowerShell well requires a firm understanding of what's happening in the technology you're administering. PowerShell expertise is a symptom of an excellent, knowledgeable administrator. Unfortunately, years of having the details hidden by a GUI has left many of our colleagues less knowledgeable than they ought to be. I've spoken with administrators who've never run Ping, who couldn't troubleshoot AD replication without a GUI tool, and who know little about how email messages are queued and delivered on Exchange. Those admins have a tough time using PowerShell.

Here's a question for you: Can you, or can you not, create an AD user account that has a blank logon name? The answer is, you can—once. The user won't be able to log on, of course, but AD's only requirement for a logon name is that it be unique. "Blank" is unique the first time you use it; it's only when you try to create a second blank user that the operation will fail. Of course, if you've interacted with AD only through the GUI console, you won't know this because the GUI console won't let you create a blank logon name at all. But if you really know what AD is doing under the hood, then the answer is obvious.

PowerShell demands this kind of in-depth skill and knowledge. The good news is that having that in-depth skill and knowledge also makes things such as troubleshooting, architecture, planning, and so on, much easier. Getting yourself to the point where you can use PowerShell effectively will make you a better administrator, not because of PowerShell, but because of the greater technical knowledge it requires. So dig in.

Use It or Lose It

I have a little saying that's become something of a proverb: "Learn PowerShell or learn to say, 'Would you like fries with that?'" I'm already seeing organizations discriminate on PowerShell. If PowerShell expertise is a sign of a better, more knowledgeable admin, why not choose to keep and promote those folks over less knowledgeable people? PowerShell expertise is a more reliable indicator of true expertise than any certification exam that Microsoft could create. If you think certifications were a key to you getting and maintaining your job, then make no mistake: PowerShell is even more crucial. Ignore it at your peril.

Here's another way to think about it: If your sole value to your company is your ability to click "Next, Next, Finish" without understanding what's happening under the hood and without being able to automate that task to make it faster and more efficient . . . well, you're what I call a "button monkey." In other words, you're easily replaced. Me, I'd rather be the one with the "arcane" knowledge of how to automate things so that I don't have to spend my time doing boring, repetitive tasks—and so that I'm much harder to get rid of.

Hide comments


  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.