Getting Started with Windows PowerShell  



A couple years ago one of the Scripting Children got his driver’s permit; that same day, the Scripting Dad took his son out for his first driving lesson. As you might expect, the Scripting Son was pretty excited and couldn’t wait to get to the parking lot where the lesson would take place. After parking the car, the Scripting Dad and the Scripting Son changed places. The Scripting Son started the car, dutifully checked his mirrors, released the parking brake, and shifted the car into Drive. And then, for a moment or two, he paused before finally stepping on the gas and driving a car for the first time.


Why the pause? That’s easy: it’s one thing to want to drive a car, but it’s a whole ‘nother thing to actually drivea car. You can’t blame the Scripting Son for hesitating a bit; after all, for years he’d been riding a bike, and he was able to get pretty much any place he needed to get to. Why change now? Why discard a tried-and-true mode of transportation for something new, something that he might not like, something that might be too hard? Admittedly, cars have some advantages over bikes. But at what cost?


The same thing is true when it comes to new technologies designed for system administration. By now most of you have heard of Windows PowerShell, Microsoft’s new command console and scripting language; many of you have even downloaded and installed PowerShell. (If you haven’t, see our Downloading Windows PowerShell page for more information.) Like the Scripting Son, however, you might have gotten that far and then paused: after all, it’s one thing to want a new command console and scripting language, but it’s a whole ‘nother thing to actually start usingthat command console and scripting language. You’ve been using the GUI, Cmd.exe, and VBScript for years, and you’ve pretty much been able to carry out any system administration task you needed to carry out. Why change now? Why discard a tried-and-true mode of system management for something new, something that you might not like, something that might be too hard?


Those are all good questions and all valid concerns. And, to be honest, we can’t really address them all in this introductory article. However, we willsay this: just because you get a driver’s license that doesn’t mean that you can never ride a bike again. Transportation is not a “zero-sum” proposition: having a driver’s license doesn’t mean you can’t also ride a bike, a bus, or a motorcycle. (Or even – gasp! – walk.) Would you rather ride a bike than drive a car? That’s fine; ride a bike when you want to ride a bike, and drive a car when you want to drive a car. If it turns out that you’re happier riding a bike, well, good for you: ride your bike, and drive a car only when you really need to.


You should think of Windows PowerShell in the same light. If you learn Windows PowerShell, does that mean you have to stop using the GUI and you have to throw out all your VBScript scripts? Of course not. Many people believe that Windows PowerShell is a replacement for VBScript and other management technologies. That’s not really true; if anything, PowerShell is a complementto VBScript and other management technologies. Over time, some people will decide, “Wow, I really like PowerShell; I think I’m going to use PowerShell for everything.” That’s fine; have fun and let the Scripting Guys know how we can help. Other people are going to think, “I don’t know. I like some of the things PowerShell has to offer, but I’ve got a pretty big investment in VBScript scripts. I’d rather stick with VBScript.” Well, guess what? That’s also fine. As the saying goes, if it ain’t broke, don’t fix it. If VBScript works for you then keep using VBScript.


So then why even bother with Windows PowerShell? There are several reasons. For one, it’s like having a driver’s license: you might never need it, but it’s good to have, just in case. It’s true that, at the moment, PowerShell might not seem like that big of a deal: for the average system administrator pretty much everything you can do with Windows PowerShell you can already do with VBScript. On the other hand, however, there areexceptions: if you want to automate the management of Microsoft Exchange Server 2007 you’ll need to use PowerShell. As time marches on these “exceptions” are likely to become the rule: PowerShell will continue to be enhanced and improved upon (version 2.0 is in development right now) while VBScript won’t. Admittedly, you might not need PowerShell right now; however that could change in the very near future. So why not go ahead and learn it now, when you can take your time and learn at your pace?


That, of course, is the reason for the Windows PowerShell Owner’s Manual: this is intended to be a gentle and relaxed introduction to Windows PowerShell. Like most owner’s manuals, we’ll tell you how to put the pedal to the metal and “drive” your new command console and scripting language; over time, we’ll also explain how to care for and maintain your new command console and scripting language. And don’t worry: in addition to standard equipment we’ll cover accessories and customization as well. We know that some of you installed Windows PowerShell and, ever since, have been sitting around thinking, “Well, now what?” If that’s you, well, you can stop fretting: you’ve come to the right place.


Note. For better or worse, this particular article can only provide a somewhat-cursory introduction to Windows PowerShell. As time goes by, we’ll drill down deeper and deeper into PowerShell and what you can do with it; if you can’t wait till then you might want to take a look at the Scripting Guys’ five Windows PowerShell webcasts .


Starting Windows PowerShell


When you install Windows PowerShell the setup program should also install a Start Menu shortcut for you; in Windows XP and Windows Server 2003 that shortcut can be found by clicking Start, pointing to All Programs, pointing to Windows PowerShell 1.0, and then clicking Windows PowerShell. What if you didn’tget a Start Menu shortcut? Well, PowerShell installs, by default, in %windir%\System32\WindowsPowerShell\v1.0 (e.g., C:\Windows\System32\WindowsPowerShell\v1.0). Open that folder, double-click PowerShell.exeand have at it.


When you dostart Windows PowerShell you’ll see something similar to this:



If you’re thinking, “Hmmm, that looks a lot like a good old MS-DOS command window,” well, there’s a reason for that: PowerShell actually leverages the good old MS-DOS command shell. And there’s at least one advantage to that. Because you’ve probably used the old MS-DOS command shell a million times you already have a pretty good idea of how to use PowerShell: you just type in commands and press ENTER. For example, do you need to know your IP address? Then type ipconfigand press ENTER:


PS C:\Scripts> ipconfig

Windows IP Configuration

Ethernet adapter Local Area Connection:

        Media State . . . . . . . . . . . : Media disconnected

Ethernet adapter Wireless Network Connection:

        Connection-specific DNS Suffix  . :
        IP Address. . . . . . . . . . . . :
        Subnet Mask . . . . . . . . . . . :
        Default Gateway . . . . . . . . . :


As the preceding example implies, you can run all your command-line executables from within the PowerShell console; you can even run VBScript scripts and batch files from within the PowerShell console. Want to run the script C:\Scripts\Test.vbs from within Windows PowerShell? Okey-doke:


PS C:\Scripts> test.vbs

Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

This message was generated by Test.vbs.


Note. Interested in learning more about the console itself? Then take a look at the Owner’s Manualsections on customizing the PowerShell console and on Windows PowerShell shortcut keys .


Oh, and don’t forget our article on tab expansion . (As if anyone couldforget our article on tab expansion!)


In addition, a lot of the console commands you’ve grown to love – like cdand cls, or even Unix commands like ls  – have Windows PowerShell equivalents. Although there are some minor exceptions, these commands work exactly the way you would expect them to work. Want to change from the C:\Scripts folder to the C:\Windows folder? Then just use the cd command:


PS C:\scripts> cd c:\windows

Or, if you prefer:

PS C:\scripts> chdir c:\windows


In general, these console commands are “aliases” to Windows PowerShell cmdlets. If you’d like to see a complete list of available aliases just type the following from the PowerShell command prompt and press ENTER:




In case you’re wondering, PowerShell commands are typically case-insensitive. You could also type thisfrom the command prompt:




Or even this:




Whoa, Whoa, Wait a Second: What Are Cmdlets?


Oh, right; good question. Cmdlets are Windows PowerShell commands, and are roughly equivalent to command-line tools. (Although, in this case, cmdlets are PowerShell-specific; you can’t run a PowerShell cmdlet unless you are running Windows PowerShell). Without command-line tools Cmd.exe wouldn’t be of much use. Although the console has a few built-in commands (such as cd and cls) most of the “heavy lifting” (and most of the useful tasks) are carried out by command-line tools such as Ipconfig.exe and Ping.exe. Windows PowerShell works in a similar way: although the shell has a few built-in commands, most of the heavy lifting is performed by cmdlets.


In fact, even PowerShell commands like cd are aliases to cmdlets, an alias being nothing more than a “nickname” for a cmdlet. In this case, for example, cd is just another way to reference the Set-Locationcmdlet. Want to switch to the C:\Windows folder? Instead of using the cd alias you could call the Set-Location cmdlet:


PS C:\scripts> Set-Location C:\Windows


Of course, Windows PowerShell includes cmdlets that do things far more interesting than simply switch you from one folder to another. For example, try typing this command and seeing what you get back:


PS C:\WINDOWS> Get-Process


You shouldget back information similar to this, information about all the processes currently running on your computer:


Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    103       5     1296       3676    32     0.05   2964 alg
    264       7     4872      10244    70     0.84    920 asghost
    101       4     3080       4692    38     1.77   2124 atiptaxx
    168       7     5584       6968    54     0.30   2896 BTStackServer
    143       5     3712       6640    52     0.30   2776 BTTray
    752      13    11048      20256    77     2.81    452 CcmExec
    672       7     2796       6864    68    18.80   1184 csrss
    139       6     1204       4544    38     0.70   2760 ctfmon


Pretty slick, huh? Maybe you’d like to list all the files and folders in C:\Scripts, including anything which happens to live in a subfolder of C:\Scripts. Well, all you had to do was ask:


Get-ChildItem C:\Scripts -recurse


All we’re doing here is calling the Get-ChildItemcmdlet. You might have noticed that we also passed Get-ChildItem a pair of parameters: C:\Scriptsand –recurse. As you probably figured out, C:\Scripts is the name of the folder we want to work with. You might notice, as well, that we didn’t enclose the folder path in double quote marks. That’s pretty much always going to be true in PowerShell: there’s no need to enclose parameters in quote marks … unless that parameter includes blank spaces. For example, suppose you want to list the files and folders found in C:\Documents and Settings\Ken Myer. Because that path includes blank spaces you need to enclose the path name in double quote marks:


Get-ChildItem "C:\Documents and Settings\Ken Myer"


The second parameter in our original command, -recurse, tells the Get-ChildItem to recursively retrieve information from the parent folder; that’s just a fancy way of telling Get-ChildItem to retrieve information from all the subfolders of C:\Scripts (as well as sub-subfolders of those subfolders, and so on). Windows PowerShell version 1.0 ships with 129 cmdlets, cmdlets that let you work with files and folders, read from and write to text files, manage event logs, and even instantiate COM and .NET Framework objects.


Now that’s all well and good, but the Scripting Son didn’t really learn how to drive until he got behind the wheel and started driving: reading about something is no substitute for actually doingsomething. Windows PowerShell is no different: you can read about cmdlets all you want, but you won’t get a good feeling for cmdlets and what they can do until you get behind the wheel and actually start using Windows PowerShell. And while the Scripting Guys can’t sit in the passenger’s seat and offer useful advice (like, “Slow down! Watch out for the curb! Don’t you everslam on the brakes like that!) we cando the next best thing: we can provide step-by-step guidance that walks you through a typical system administration scenario using Windows PowerShell. If that sounds like fun (and why wouldn’t it be?), take a look at our Windows PowerShell virtual lab .


Bonus Tip


Here’s a little time-saving tip for you. When using parameters in conjunction with a cmdlet, you only have to type as much of the parameter name as needed to make that parameter distinct. What does that mean? Well, Get-ChildItem has only one parameter (recurse) that starts with the letter r. That means we can specify the –recurse parameter by using this command:


Get-ChildItem C:\Scripts -r


Pretend, for a moment, that Get-ChildItem has another parameter that starts with the letter r; let’s call this hypothetical parameter –readonly. In that case we can specify the –recurse parameter by using thiscommand:


Get-ChildItem C:\Scripts -rec


Why did we have to type –rec? That’s easy: we had to type three letters before we could differentiate –recurse and –readonly:


·          -re curse

·          -re adonly


Still too much typing for you? Well, if you use the gcialias (which, needless to say, is the alias for Get-ChildItem) you can retrieve a recursive list of all the files and folders in C:\Scripts by doing no more typing than this:


gci C:\Scripts -r




I Have a Couple Questions For You


Yes, we know: you’d like to know what other cmdlets are available to you andyou’d like to know what you can do with all those cmdlets. To tell you the truth, we won’t be able to answer those questions in this article. However, we canpoint you to readily-available resources that will help you answer these questions for yourself.


To begin with, Windows PowerShell is a pretty chatty and out-going technology: all you have to do is ask and PowerShell will be happy to tell you all about itself. For example, remember the Get-Alias cmdlet, which returned a list of all the PowerShell aliases available to you? Well, there’s a similar cmdlet – Get-Command– that returns a list of all the PowerShell cmdlets available to you. Here’s a partial look at what happens when you run Get-Command:


PS C:\scripts> Get-Command

CommandType     Name                                                Definition
-----------     ----                                                ----------
Cmdlet          Add-Content                                         Add-Content [-Path] <String[]> [-Value] <Object[...
Cmdlet          Add-History                                         Add-History [[-InputObject] <PSObject[]>] [-Pass...
Cmdlet          Add-Member                                          Add-Member [-MemberType] <PSMemberTypes> [-Name]...
Cmdlet          Add-PSSnapin                                        Add-PSSnapin [-Name] <String[]> [-PassThru] [-Ve...
Cmdlet          Clear-Content                                       Clear-Content [-Path] <String[]> [-Filter <Strin...
Cmdlet          Clear-Item                                          Clear-Item [-Path] <String[]> [-Force] [-Filter ...
Cmdlet          Clear-ItemProperty                                  Clear-ItemProperty [-Path] <String[]> [-Name] <S...


A Quick Detour


What do the three dots (…) at the end of each line mean? They mean that there is additional information about each cmdlet; however, that information wouldn’t all fit on the screen. Is there a way to makeit all fit on the screen? Sure; all you have to do is display the information in list view rather than table view:


PS C:\scripts> Get-Command | Format-List


In turn, you’ll get back complete information for each cmdlet:


Name             : Add-Content
CommandType      : Cmdlet
Definition       : Add-Content [-Path] <String[]> [-Value] <Object[]> [-PassThru] [-Filter <String>] [-Include <String[
                   ]>] [-Exclude <String[]>] [-Force] [-Credential <PSCredential>] [-Verbose] [-Debug] [-ErrorAction <A
                   ctionPreference>] [-ErrorVariable <String>] [-OutVariable <String>] [-OutBuffer <Int32>] [-WhatIf] [
                   -Confirm] [-Encoding <FileSystemCmdletProviderEncoding>]
                   Add-Content [-LiteralPath] <String[]> [-Value] <Object[]> [-PassThru] [-Filter <String>] [-Include <
                   String[]>] [-Exclude <String[]>] [-Force] [-Credential <PSCredential>] [-Verbose] [-Debug] [-ErrorAc
                   tion <ActionPreference>] [-ErrorVariable <String>] [-OutVariable <String>] [-OutBuffer <Int32>] [-Wh
                   atIf] [-Confirm] [-Encoding <FileSystemCmdletProviderEncoding>]

Path             :
AssemblyInfo     :
DLL              : C:\WINDOWS\assembly\GAC_MSIL\Microsoft.PowerShell.Commands.Management\\Micr
HelpFile         : Microsoft.PowerShell.Commands.Management.dll-Help.xml
ParameterSets    : {Path, LiteralPath}
ImplementingType : Microsoft.PowerShell.Commands.AddContentCommand
Verb             : Add
Noun             : Content


How did we manage to do that? Well, as it turns out, Format-Listis a cmdlet that takes information passed to it and then outputs that information in list view (that is, property values are displayed on separate lines rather than as columns in a table). But what’s that weird symbol – | – in the middle of the command? Well, that weird symbol is the pipe separator, and it indicates that we want to “pipe” the information returned by Get-Command and hand it over to Format-List for additional processing. You say that makes no sense to you whatsoever? That’s all right; that’s why this manual includes a chapter on pipelines and piping .


Now, Back to Our Regularly-Scheduled Article


Get-Command is pretty useful: after all, it gives you a definitive list of the cmdlets that are available to you. However, it doesn’t tell you how to usethose cmdlets. For that, you need to access PowerShell’s built-in help system.


PowerShell is Here to Help


One of the really nice features of Windows PowerShell is the fact that it includes a very extensive help system, which just happens to be incorporated right into the shell itself. Once you know the name of a cmdlet, you can get additional information on that cmdlet (and how to use it) by calling the Get-Helpcmdlet:


Get-Help Format-List


Wait, wait: don’t type that in yet. Like we said, PowerShell has a very extensive help system; however, it also has a somewhat complicatedhelp system. Typing Get-Help Format-Listwill, indeed, show you additional information about the Format-List cmdlet; however, that information will consist largely of a syntax diagram and a brief description of the cmdlet. For more extension information, including example commands and a detailed description of allowed parameters, you need to tack on the –fullparameter, like so:


Get-Help Format-List -full


Or, if you’re interested only in the example, tack on the –examplesparameter:


Get-Help Format-List -examples


Wait, wait: don’t type those commands in yet, either. The actual help topics found in PowerShell are very, very good; however, PowerShell’s help engine leaves a little something to be desired. For example, when you open a help topic using Get-Help, PowerShell displays the entire topic and then leaves the cursor at the very end of the topic. To actually read the information from start to finish you have to scroll up and find the first line. You can work around that problem (sort of) by piping the results of Get-Help to the morecommand, which enables you to display information one page (screen) at a time:


Get-Help Format-List –full | more


That helps, although you can only page your way forward; you can’t go backwards. (Try it and you’ll see what we mean.)


The other issue is a little harder to work around: for better or worse (mostly for worse) PowerShell’s help engine doesn’t do a very good job of respecting word breaks at the end of a line. For example:


    The Get-Process cmdlet retrieves a process object for each process. Without parameters, "Get-Process" gets all of t
    he processes on the computer, as though you typed "Get-Process *". You can also identify a particular process by pr
    ocess name or process ID (PID), or pass a process object through the pipeline to Get-Process. For Get-Process, the
    default method is by process name. For Stop-Process, the default method is by process ID.


Take a look at the first line under Detailed Description. As you can see, the word thedoesn’t quite fit on the line. However, instead moving the entire word to the next line, PowerShell went ahead and printed the tat the end of line 1, then printed the rest of the word ( he) at the beginning of line 2. Does that make the help a little hard to read? You might say that.


So is there a workaround for this word-wrap issue? Not as far as we know. Which is why the Scripting Guys put together the Windows PowerShell graphical help file. This is the same help you get in Windows PowerShell (plus, just for the heck of it, a copy of our VBScript to Windows PowerShell Conversion Guide). However, we’ve taken that help and wrapped it up in a regular old .chm file; that makes it a little easier to read, and gives you full-text search capability as well. And if you follow the instructions in the Readmefile, you can even access this help from the command prompt, simply by typing in a command similar to this:


Get-GUIHelp Format-List


And no need for parameters like –full or –examples. With the graphical help file you always get allthe information available for a topic.


But you know what? You’re right. Help is incredibly useful, provided that you already know what it is you want to do. (For example, you know you want to use Get-ChildItem to list all the files and folders found in C:\Scripts, you just can’t remember which parameter enables you to recursively search for these files.) But what if you have no idea what you can even dowith Windows PowerShell in the first place? Are you just supposed to read the help file from start to finish?


Well, you can if you want to. Alternatively, you might want to take a look at the Script Center ’s Task-Based Introduction to Windows PowerShell. Here you’ll find scores of task-based articles, with titles like Save Data to a Text File and Copy Files or Folders . One thing you might want to do is browse through those articles and thenlook in the help file for more detailed information on the cmdlets used to carry out those tasks.


Note. And yes, the graphical help file includes links to corresponding articles in the Task-Based Introduction. For example, if you’re viewing information about the Set-Content cmdlet in the graphical help file you’ll see a link to the article Save Data to a Text File.


Hey, What About Scripts?


You don’t think we’d forget about scripts and scripting, do you? (They don’t call us the ScriptingGuys for nothing.) Windows PowerShell provides a very cool and very powerful environment for writing and running scripts; however, actually getting scripts to run under PowerShell can be a little tricky, at least at first. Therefore, this Owner’s Manual includes a separate article on running scripts in Windows PowerShell.


We’ll leave most of the scripting-related information to that article; we’ll also recommend you take a look at our PowerShell scripting webcast if you’re eager to try your hand at writing Windows PowerShell scripts. In this article we’ll simply note that PowerShell scripts can be written using any text editor; Notepad, for example, has everything you need in order to write a Windows PowerShell script. Just make sure you save the file as a plain text file and that you give the thing a .ps1file extension; that’s all you have to do.


Note. OK, there might be a littlemore: you actually have to write some script code. Yet another reason to take a look at the PowerShell scripting webcast .


Here’s another cool thing about PowerShell. Throughout this article we’ve referred to PowerShell as being a command console and scripting language. There’s a good reason for that: you can run PowerShell commands from the command prompt oryou can save those commands as .ps1 files and run them as scripts. Even cooler, these commands can be (and usually are) identical: the commands you type at the command prompt can be used as-is in scripts, and vice-versa.


For example, consider this simple two-line PowerShell script:


$a = Get-ChildItem C:\Scripts


In the first line, this script uses Get-ChildItem to retrieve a collection of all the files and folders stored in C:\Scripts; that collection is stored in the variable $a. In the second line, the script simply displays the value of $a.


Not all that exciting, is it? That’s hard to argue with. However, what isexciting is this: you can either save these two commands as a .ps1 file and then run those commands as a script, or you can type the commands at the command prompt, one after another. What happens if you type the commands at the command prompt? You got: the first command retrieves a collection of all the files and folders stored in C:\Scripts and stores that information in a variable named $a; the second command echoes back the value of $a. Work from the command prompt or write a script? In a certain sense, it doesn’t really matter.


Needless to say, we’ll have more – much more – about scripts and script writing in future updates to the Owner’s Manual.


So Where Do I Go From Here?


We’d suggest two things. First, take a look at the PowerShell Week webcasts , five presentations introducing Windows PowerShell. Those webcasts include:


·          And Now for Something Completely Different: Introducing Windows PowerShell

·          One Cmdlet, Two Cmdlet, Three Cmdlet, Four: An Introduction to Windows PowerShell Commands

·          Object, Objects Everywhere: Working with Objects in Windows PowerShell

·          New Kid on the Scriptblock: Writing Scripts with Windows PowerShell

·          Amazing But True: Thing You Never Dreamt You Could Do with Windows PowerShell


Second, kick the metaphorical PowerShell tires by trying out the virtual lab . It’s always better to try something hands-on rather than read about it. (Which, you might have noticed, we didn’t bother to tell you until you’d finished reading this big, long article.)


And keep visiting the Script Center ’s PowerShell section . We’ll be adding more and more content to this section, including more installments to the Owner’s Manual.