BUY THIS BOOK
Add to Cart

Print Book $12.99


Add to Cart

PDF $10.99

Safari Books Online

What is this?

Add to UK Cart

Print Book £7.99

What is this?

Looking to Reprint or License this content?


Windows PowerShell Pocket Reference
Windows PowerShell Pocket Reference Pocket Reference

By Lee Holmes
Book Price: $12.99 USD
£7.99 GBP
PDF Price: $10.99

Cover | Table of Contents


Table of Contents

Chapter 1: A Whirlwind Tour of Windows PowerShell
When learning a new technology, it is natural to feel bewildered at first by all the unfamiliar features and functionality. This perhaps rings especially true for users new to Windows PowerShell, because it may be their first experience with a fully featured command-line shell. Or worse, they've heard stories of PowerShell's fantastic integrated scripting capabilities and fear being forced into a world of programming that they've actively avoided until now.
Fortunately, these fears are entirely misguided: PowerShell is a shell that both grows with you and grows on you. Let's take a tour to see what it is capable of:
  • PowerShell works with standard Windows commands and applications. You don't have to throw away what you already know and use.
  • PowerShell introduces a powerful new type of command. PowerShell commands (called cmdlets) share a common Verb-Noun syntax and offer many usability improvements over standard commands.
  • PowerShell understands objects. Working directly with richly structured objects makes working with (and combining) PowerShell commands immensely easier than working in the plain-text world of traditional shells.
  • PowerShell caters to administrators. Even with all its advances, PowerShell focuses strongly on its use as an interactive shell, and the experience of entering commands in a running PowerShell application.
  • PowerShell supports discovery. Using three simple commands, you can learn and discover almost anything PowerShell has to offer.
  • PowerShell enables ubiquitous scripting. With a fully fledged scripting language that works directly from the command line, PowerShell lets you automate tasks with ease.
  • PowerShell bridges many technologies. By letting you work with .NET, COM, WMI, XML, and Active Directory, PowerShell makes working with these previously isolated technologies easier than ever before.
  • PowerShell simplifies management of data stores. Through its provider model, PowerShell lets you manage data stores using the same techniques you already use to manage files and folders.
We'll explore each of these attributes in this introductory tour of PowerShell.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Introduction
When learning a new technology, it is natural to feel bewildered at first by all the unfamiliar features and functionality. This perhaps rings especially true for users new to Windows PowerShell, because it may be their first experience with a fully featured command-line shell. Or worse, they've heard stories of PowerShell's fantastic integrated scripting capabilities and fear being forced into a world of programming that they've actively avoided until now.
Fortunately, these fears are entirely misguided: PowerShell is a shell that both grows with you and grows on you. Let's take a tour to see what it is capable of:
  • PowerShell works with standard Windows commands and applications. You don't have to throw away what you already know and use.
  • PowerShell introduces a powerful new type of command. PowerShell commands (called cmdlets) share a common Verb-Noun syntax and offer many usability improvements over standard commands.
  • PowerShell understands objects. Working directly with richly structured objects makes working with (and combining) PowerShell commands immensely easier than working in the plain-text world of traditional shells.
  • PowerShell caters to administrators. Even with all its advances, PowerShell focuses strongly on its use as an interactive shell, and the experience of entering commands in a running PowerShell application.
  • PowerShell supports discovery. Using three simple commands, you can learn and discover almost anything PowerShell has to offer.
  • PowerShell enables ubiquitous scripting. With a fully fledged scripting language that works directly from the command line, PowerShell lets you automate tasks with ease.
  • PowerShell bridges many technologies. By letting you work with .NET, COM, WMI, XML, and Active Directory, PowerShell makes working with these previously isolated technologies easier than ever before.
  • PowerShell simplifies management of data stores. Through its provider model, PowerShell lets you manage data stores using the same techniques you already use to manage files and folders.
We'll explore each of these attributes in this introductory tour of PowerShell.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
An Interactive Shell
At its core, PowerShell is first and foremost an interactive shell. While it supports scripting and other powerful features, its focus as a shell underpins everything.
Getting started in PowerShell is a simple matter of launching PowerShell.exe rather than cmd.exe—the shells begin to diverge as you explore the intermediate and advanced functionality, but you can be productive in PowerShell immediately.
To launch Windows PowerShell, click:
Start → All Programs → Windows PowerShell 1.0 → Windows PowerShell
Or alternatively, click:
Start → Run
and then type:
PowerShell
A PowerShell prompt window opens that's nearly identical to the traditional command prompt window of Windows XP, Windows Server 2003, and their many ancestors. The PS> prompt indicates that PowerShell is ready for input, as shown in .
Figure : Windows PowerShell, ready for input
Once you've launched your PowerShell prompt, you can enter DOS-style and Unix-style commands for navigating around the filesystem, just as you would with any Windows or Unix command prompt—as in the interactive session shown in .
Example . Entering standard DOS-style file manipulation commands in response to the PowerShell prompt produces the same results you get when you use them with any other Windows shell
PS C:\Documents and Settings\Lee> function Prompt { "PS >" }
PS >pushd .
PS >cd \
PS >dir

    Directory: Microsoft.PowerShell.Core\FileSystem::C:\

Mode           LastWriteTime   Length  Name
----           -------------   ------  ----
d----    11/2/2006   4:36 AM           $WINDOWS.~BT
d----     5/8/2007   8:37 PM           Blurpark
d----   11/29/2006   2:47 PM           Boot
d----   11/28/2006   2:10 PM           DECCHECK
d----   10/7/2006    4:30 PM           Documents and Settings
d----   5/21/2007    6:02 PM           F&SC-demo
d----    4/2/2007    7:21 PM           Inetpub
d----   5/20/2007    4:59 PM           Program Files
d----   5/21/2007    7:26 PM           temp
d----   5/21/2007    8:55 PM           Windows
-a---    1/7/2006   10:37 PM        0  autoexec.bat
-ar-s   11/29/2006   1:39 PM     8192  BOOTSECT.BAK
-a---     1/7/2006  10:37 PM        0  config.sys
-a---     5/1/2007   8:43 PM    33057  RUU.log
-a---     4/2/2007   7:46 PM     2487  secedit.INTEG.RAW

PS >popd
PS >pwd

Path
----
C:\Documents and Settings\Lee
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Structured Commands (Cmdlets)
In addition to supporting traditional Windows executables, PowerShell introduces a powerful new type of command called a cmdlet (pronounced command-let.) All cmdlets are named in a Verb-Noun pattern, such as Get-Process, Get-Content, and Stop-Process.
PS >Get-Process -Name lsass

Handles NPM(K) PM(K)  WS(K)  VM(M) CPU(s)  Id  ProcessName
------- ------ -----  -----  ----- ------  --  -----------
    668     13  6228  1660      46        932  lsass
In this example, you provide a value to the ProcessName parameter to get a specific process by name.
Once you know the handful of common verbs in PowerShell, learning how to work with new nouns becomes much easier. While you may never have worked with a certain object before (such as a Service), the standard Get, Set, Start, and Stop actions still apply. For a list of these common verbs, see .
You don't always have to type these full cmdlet names, however. PowerShell lets you use the Tab key to auto-complete cmdlet names and parameter names:
PS >Get-Pr<Tab> -N<Tab> lsass
For quick interactive use, even that may be too much typing. For improved efficiency, PowerShell defines aliases for all common commands and lets you define your own. In addition to alias names, PowerShell only requires that you type enough of the parameter name to disambiguate it from the other parameters in that cmdlet. PowerShell is also case-insensitive. Using the built-in gps alias that represents the Get-Process cmdlet (along with parameter shortening), you can instead type:
PS >gps -n lsass
Going even further, PowerShell supports positional parameters on cmdlets. Positional parameters let you provide parameter values in a certain position on the command line, rather than having to specify them by name. The Get-Process cmdlet takes a process name as its first positional parameter. This parameter even supports wildcards:
PS >gps l*s
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Deep Integration of Objects
PowerShell begins to flex more of its muscle as you explore the way it handles structured data and richly functional objects. For example, the following command generates a simple text string. Since nothing captures that output, PowerShell displays it to you:
PS >"Hello World"
Hello World
The string you just generated is, in fact, a fully functional object from the .NET Framework. For example, you can access its Length property, which tells you how many characters are in the string. To access a property, you place a dot between the object and its property name:
PS >"Hello World".Length
11
All PowerShell commands that produce output generate that output as objects as well. For example, the Get-Process cmdlet generates a System.Diagnostics.Process object, which you can store in a variable. In PowerShell, variable names start with a $ character. If you have an instance of Notepad running, the following command stores a reference to it:
$process = Get-Process notepad
Since this is a fully functional Process object from the .NET Framework, you can call methods on that object to perform actions on it. This command calls the Kill() method, which stops a process. To access a method, you place a dot between the object and its method name:
$process.Kill()
PowerShell supports this functionality more directly through the Stop-Process cmdlet, but this example demonstrates an important point about your ability to interact with these rich objects.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Administrators As First-Class Users
While PowerShell's support for objects from the .NET Framework quickens the pulse of most users, PowerShell continues to focus strongly on administrative tasks. For example, PowerShell supports MB (for megabyte) and GB (for gigabyte) as some of the standard administrative constants. For example, how many disks will it take to back up a 40 GB hard drive to CD-ROM?
PS >40GB / 650MB
63.0153846153846
Just because PowerShell is an administrator-focused shell doesn't mean you can't still use the .NET Framework for administrative tasks, though! In fact, PowerShell makes a great calendar. For example, is 2008 a leap year? PowerShell can tell you:
PS >[DateTime]::IsLeapYear(2008)
True
Going further, how might you determine how much time remains until summer? The following command converts "06/21/2008" (the start of summer) to a date, and then subtracts the current date from that. It stores the result in the $result variable, and then accesses the TotalDays property.
PS >$result = [DateTime] "06/21/2008" - [DateTime]::Now
PS >$result.TotalDays
283.0549285662616
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Composable Commands
Whenever a command generates output, you can use a pipeline character (|) to pass that output directly to another command. If the second command understands the objects produced by the first command, it can operate on the results.
You can chain together many commands this way, creating powerful compositions out of a few simple operations. For example, the following command gets all items in the Path1 directory and moves them to the Path2 directory:
Get-Item Path1\* | Move-Item -Destination Path2
You can create even more complex commands by adding additional cmdlets to the pipeline. In , the first command gets all processes running on the system. It passes those to the Where-Object cmdlet, which runs a comparison against each incoming item. In this case, the comparison is $_.Handles -ge 500, which checks whether the Handles property of the current object (represented by the $_ variable) is greater than or equal to 500. For each object in which this comparison holds true, you pass the results to the Sort-Object cmdlet, asking it to sort items by their Handles property. Finally, you pass the objects to the Format-Table cmdlet to generate a table that contains the Handles, Name, and Description of the process.
Example . You can build more complex PowerShell commands by using pipelines to link cmdlets, as shown in this example with Get-Process, Where-Object, Sort Object, and Format-Table
PS >Get-Process |
>>     Where-Object { $_.Handles -ge 500 } |
>>     Sort-Object Handles |
>>     Format-Table Handles,Name,Description -Auto
>>

Handles Name     Description
------- ----     -----------
    588 winlogon
    592 svchost
    667 lsass
    725 csrss
    742 System
    964 WINWORD  Microsoft Office Word
   1112 OUTLOOK  Microsoft Office Outlook
   2063 svchost
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Techniques to Protect You from Yourself
While aliases, wildcards, and composable pipelines are powerful, their use in commands that modify system information can easily be nerve-wracking. After all, what does this command do? Think about it, but don't try it just yet:
PS >gps [b-t]*[c-r] | Stop-Process
It appears to stop all processes that begin with the letters b through t and end with the letters c through r. How can you be sure? Let PowerShell tell you. For commands that modify data, PowerShell supports -WhatIf and -Confirm parameters that let you see what a command would do:
PS >gps [b-t]*[c-r] | Stop-Process -whatif
What if: Performing operation "Stop-Process" on Target
   "ctfmon (812)".
What if: Performing operation "Stop-Process" on Target
   "Ditto (1916)".
What if: Performing operation "Stop-Process" on Target
   "dsamain (316)".
What if: Performing operation "Stop-Process" on Target
   "ehrecvr (1832)".
What if: Performing operation "Stop-Process" on Target
   "ehSched (1852)".
What if: Performing operation "Stop-Process" on Target
   "EXCEL (2092)".
What if: Performing operation "Stop-Process" on Target
   "explorer (1900)".
(...)
In this interaction, using the -WhatIf parameter with the Stop-Process pipelined command lets you preview which processes on your system will be stopped before you actually carry out the operation.
Note that this example is not a dare! In the words of one reviewer:
Not only did it stop everything, but on Vista, it forced a shutdown with only one minute warning!
It was very funny though…. At least I had enough time to save everything first!
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Common Discovery Commands
While reading through a guided tour is helpful, I find that most learning happens in an ad-hoc fashion. To find all commands that match a given wildcard, use the Get-Command cmdlet. For example, by entering the following, you can find out which PowerShell commands (and Windows applications) contain the word process.
PS >Get-Command *process*

CommandType    Name          Definition
-----------    ----          ----------
Cmdlet         Get-Process   Get-Process [[-Name] <Str...
Application    qprocess.exe  c:\windows\system32\qproc...
Cmdlet         Stop-Process  Stop-Process [-Id] <Int32...
To see what a command such as Get-Process does, use the Get-Help cmdlet, like this:
PS >Get-Help Get-Process
Since PowerShell lets you work with objects from the .NET Framework, it provides the Get-Member cmdlet to retrieve information about the properties and methods that an object, such as a .NET System.String, supports. Piping a string to the Get-Member command displays its type name and its members:
PS >"Hello World" | Get-Member

   TypeName: System.String

Name       MemberType  Definition
----       ----------  ----------
(...)
PadLeft    Method      System.String PadLeft(Int32 tota...
PadRight   Method      System.String PadRight(Int32 tot...
Remove     Method      System.String Remove(Int32 start...
Replace    Method      System.String Replace(Char oldCh...
Split      Method      System.String[] Split(Params Cha...
StartsWith Method      System.Boolean StartsWith(String...
Substring  Method      System.String Substring(Int32 st...

ToChar-                System.Char[] ToCharArray(), Sys...
ArrayMethod
ToLower    Method      System.String ToLower(), System....
ToLower-   Method      System.String ToLowerInvariant()
Invariant
ToString   Method      System.String ToString(), System...
ToUpper    Method      System.String ToUpper(), System....
ToUpper-   Method      System.String ToUpperInvariant()
Invariant
Trim       Method      System.String Trim(Params Char[]...
TrimEnd    Method      System.String TrimEnd(Params Cha...
TrimStart  Method      System.String TrimStart(Params C...
Chars      Parameter-  System.Char Chars(Int32 index) {...
           izedProperty
Length     Property    System.Int32 Length {get;}
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Ubiquitous Scripting
PowerShell makes no distinction between the commands you type at the command line and the commands you write in a script. This means that your favorite cmdlets work in scripts and that your favorite scripting techniques (such as the foreach statement) work directly on the command line.
For example, to add up the handle count for all running processes:
PS >$handleCount = 0
PS >foreach($process in Get-Process) { $handleCount +=
    $process.Handles }
PS >$handleCount
19403
While PowerShell provides a command (Measure-Object) to measure statistics about collections, this short example shows how PowerShell lets you apply techniques that normally require a separate scripting or programming language.
In addition to using PowerShell scripting keywords, you can also create and work directly with objects from the .NET Framework. PowerShell becomes almost like the C# immediate mode in Visual Studio. In , you see how PowerShell lets you easily interact with the .NET Framework.
Example . Using objects from the .NET Framework to retrieve a web page and process its content
PS >$webClient = New-Object System.Net.WebClient
PS >$content = $webClient.DownloadString("http://blogs.msdn.com/
PowerShell/rss.aspx")
PS >$content.Substring(0,1000)
<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/
utility/FeedStylesheets/rss.xsl" media="screen"?>
<rss version="2.0"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel>
<title>Windo
(...)
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Ad-Hoc Development
By blurring the lines between interactive administration and writing scripts, the history buffer of PowerShell sessions quickly becomes the basis for ad-hoc script development. In this example, you call the Get-History cmdlet to retrieve the history of your session. For each of those items, you get its CommandLine property (the thing you typed) and send the output to a new script file.
PS >Get-History | Foreach-Object { $_.CommandLine } >
    c:\temp\script.ps1
PS >notepad c:\temp\script.ps1
(save the content you want to keep)
PS >c:\temp\script.ps1
If this is the first time you've run a script in PowerShell, you will need to configure your Execution Policy. For more information, type 'help about_signing'.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Bridging Technologies
We've seen how PowerShell lets you fully leverage the .NET Framework in your tasks, but its support for common technologies stretches even further. As shows, PowerShell supports XML.
Example . Working with XML content in PowerShell
PS >$xmlContent = [xml] $content
PS >$xmlContent

xml                      xml-stylesheet           rss
---                      --------------           ---
                                                  rss

PS >$xmlContent.rss

version : 2.0
dc      : http://purl.org/dc/elements/1.1/
slash   : http://purl.org/rss/1.0/modules/slash/
wfw     : http://wellformedweb.org/CommentAPI/
channel : channel

PS >$xmlContent.rss.channel.item | select Title

title
---
CMD.exe compatibility
Time Stamping Log Files
Microsoft Compute Cluster now has a PowerShell Provider and
Cmdlets
The Virtuous Cycle: .NET Developers using PowerShell
(...)
And Windows Management Instrumentation (WMI):
PS >Get-WmiObject Win32_Bios

SMBIOSBIOSVersion : ASUS A7N8X Deluxe ACPI BIOS Rev 1009
Manufacturer      : Phoenix Technologies, LTD
Name              : Phoenix - AwardBIOS v6.00PG
SerialNumber      : xxxxxxxxxxx
Version           : Nvidia - 42302e31
Or, as shows, Active Directory Service Interfaces (ADSI).
Example . Working with Active Directory in PowerShell
PS >[ADSI] "WinNT://./Administrator" | Format-List *

UserFlags                  : {66113}
MaxStorage                 : {-1}
PasswordAge                : {19550795}
PasswordExpired            : {0}
LoginHours                 : {255 255 255 255 255 255 255 255
                             255 255 255 255 255 255 255 255
                             255 255 255 255 255}
FullName                   : {}
Description                : {Built-in account for
                             administering the computer/
                             domain}
BadPasswordAttempts        : {0}
LastLogin                  : {5/21/2007 3:00:00 AM}
HomeDirectory              : {}
LoginScript                : {}
Profile                    : {}
HomeDirDrive               : {}
Parameters                 : {}
PrimaryGroupID             : {513}
Name                       : {Administrator}

MinPasswordLength          : {0}
MaxPasswordAge             : {3710851}
MinPasswordAge             : {0}
PasswordHistoryLength      : {0}
AutoUnlockInterval         : {1800}
LockoutObservationInterval : {1800}
MaxBadPasswordsAllowed     : {0}
RasPermissions             : {1}
objectSid                  : {1 5 0 0 0 0 0 5 21 0 0 0 121 227
                             252 83 122 130 50 34 67 23 10 50
                             244 1 0 0}
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Namespace Navigation Through Providers
Another avenue PowerShell provides for working with the system is a providers. PowerShell providers let you navigate and manage data stores using the same techniques you already use to work with the filesystem, as illustrated in .
This also works on the registry, as shown in .
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Much, Much More
As exciting as this guided tour was, it barely scratches the surface of how you can use PowerShell to improve your productivity and systems management skills. For more information about getting started in PowerShell, see the "Getting Started" and "User Guide" files included in the Windows PowerShell section of your Start menu. For a cookbook-style guide to PowerShell (and hard-won solutions to its most common problems), you may be interested in the source of the material in this pocket reference: my book Windows PowerShell Cookbook (O'Reilly).
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 2: PowerShell Language and Environment
PowerShell breaks any line that you enter into its individual units (tokens), and then interprets each token in one of two ways: as a command or as an expression. The difference is subtle: expressions support logic and flow control statements (such as if, foreach, and throw) while commands do not. You will often want to control the way that Windows PowerShell interprets your statements, so lists the available options.
Table : Windows PowerShell evaluation controls
Statement
Example
Explanation
Precedence control:()
PS >5 * (1 + 2)
15
PS >(dir).Count
2276
Forces the evaluation of a command or expression, similar to how parentheses force the order of evaluation in a math expression.
Expression subparse: $()
PS >"The answer is
(2+2)"
The answer is (2+2)

PS >"The answer is
$(2+2)"
The answer is 4

PS >$value = 10
PS >$result = $(
>>   if($value -gt 0)
{ $true }
      else { $false }
>> )
>>
PS >$result
True
Forces the evaluation of a command or expression, similar to how parentheses force the order of evaluation in a mathematical expression. However, a subparse is as powerful as a subprogram, and is required only when it contains logic or flow control statements. This statement is also used to expand dynamic information inside a string.
List evaluation:@()
PS >"Hello".Length
5
PS >@("Hello").Length
1
PS >(Get-ChildItem).
     Count
12
PS >(Get-ChildItem
     *.txt).Count
PS >@(Get-ChildItem
     *.txt).Count
1
Forces an expression to be evaluated as a list. If it is already a list, it will remain a list. If it is not, PowerShell temporarily treats it as one.
To create single-line comments, begin a line with the # character. Windows PowerShell does not support multiline comments, but you can deactivate larger regions of your script by placing them in a here string:
# This is a regular comment

# Start of the here string
$null = @"
function MyTest
{
    "This should not be considered a function"
}

$myVariable = 10;
"@
# End of the here string

# This is regular script again
See "Strings" to learn more about here strings.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Commands and Expressions
PowerShell breaks any line that you enter into its individual units (tokens), and then interprets each token in one of two ways: as a command or as an expression. The difference is subtle: expressions support logic and flow control statements (such as if, foreach, and throw) while commands do not. You will often want to control the way that Windows PowerShell interprets your statements, so lists the available options.
Table : Windows PowerShell evaluation controls
Statement
Example
Explanation
Precedence control:()
PS >5 * (1 + 2)
15
PS >(dir).Count
2276
Forces the evaluation of a command or expression, similar to how parentheses force the order of evaluation in a math expression.
Expression subparse: $()
PS >"The answer is
(2+2)"
The answer is (2+2)

PS >"The answer is
$(2+2)"
The answer is 4

PS >$value = 10
PS >$result = $(
>>   if($value -gt 0)
{ $true }
      else { $false }
>> )
>>
PS >$result
True
Forces the evaluation of a command or expression, similar to how parentheses force the order of evaluation in a mathematical expression. However, a subparse is as powerful as a subprogram, and is required only when it contains logic or flow control statements. This statement is also used to expand dynamic information inside a string.
List evaluation:@()
PS >"Hello".Length
5
PS >@("Hello").Length
1
PS >(Get-ChildItem).
     Count
12
PS >(Get-ChildItem
     *.txt).Count
PS >@(Get-ChildItem
     *.txt).Count
1
Forces an expression to be evaluated as a list. If it is already a list, it will remain a list. If it is not, PowerShell temporarily treats it as one.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Comments
To create single-line comments, begin a line with the # character. Windows PowerShell does not support multiline comments, but you can deactivate larger regions of your script by placing them in a here string:
# This is a regular comment

# Start of the here string
$null = @"
function MyTest
{
    "This should not be considered a function"
}

$myVariable = 10;
"@
# End of the here string

# This is regular script again
See "Strings" to learn more about here strings.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Variables
Windows PowerShell provides several ways to define and access variables, as summarized in .
Table : Windows PowerShell variable syntaxes
Syntax
Meaning
$simpleVariable = "Value"
A simple variable name. The variable name must consist of alphanumeric characters. Variable names are not case sensitive.
${arbitrary!@#@#`{var`}iable} = "Value"
An arbitrary variable name. The variable name must be surrounded by curly braces, but may contain any characters. Curly braces in the variable name must be escaped with a backtick (`).
${c:\filename.extension}
Variable "Get and Set Content" syntax. This is similar to the arbitrary variable name syntax. If the name corresponds to a valid PowerShell path, you can get and set the content of the item at that location by reading and writing to the variable.
[datatype] $variable = "Value"
Strongly typed variable. Ensures that the variable may contain only data of the type you declare. PowerShell throws an error if it cannot coerce the data to this type when you assign it.
$SCOPE:variable
Gets or sets the variable at that specific scope. Valid scope names are global (to make a variable available to the entire shell), script (to make a variable available only to the current script), local (to make a variable available only to the current scope and subscopes), and private (to make a variable available only to the current scope). The default scope is the current scope: global when defined interactively in the shell, script when defined outside any functions or script blocks in a script, and local elsewhere.
New-Item Variable:\variable–Value value
Creates a new variable using the Variable Provider.
Get-Item Variable:\variableGet-Variable variable
Gets the variable using the Variable Provider or Get-Variable cmdlet. This lets you access extra information about the variable, such as its options and description.
New-Variable variable-Option option-Value value
Creates a variable using the New-Variable cmdlet. This lets you provide extra information about the variable, such as its options and description.
Unlike some languages, PowerShell rounds (not truncates) numbers when it converts them to the
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Booleans
Boolean (true or false) variables are most commonly initialized to their literal values of $true and $false. When it evaluates variables as part of a Boolean expression (for example, an if statement), though, PowerShell maps them to a suitable Boolean representation, as listed in .
Table : Windows PowerShell Boolean interpretations
Result
Boolean representation
$true
True
$false
False
$null
False
Nonzero number
True
Zero
False
Nonempty string
True
Empty string
False
Nonempty array
True
Empty array
False
Hashtable (either empty or not)
True
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Strings
Windows PowerShell offers several facilities for working with plain-text data.
To define a literal string (one in which no variable or escape expansion occurs), enclose it in single quotes:
$myString = 'hello 't $ENV:SystemRoot'
$myString gets the actual value of hello 't $ENV:SystemRoot.
To define an expanding string (one in which variable and escape expansion occurs), enclose it in double quotes:
$myString = "hello 't $ENV:SystemRoot"
$myString gets a value similar to hello C:\WINDOWS.
To include a single quote in a single-quoted string or a double quote in a double-quoted string, you may include two of the quote characters in a row:
PS >"Hello ""There""!"
Hello "There"!
PS >'Hello ''There''!'
Hello 'There'!
To include a complex expression inside an expanding string, use a subexpression. For example:
$prompt = "$(Get-Location) >"
$prompt gets a value similar to c:\temp >.
Accessing the properties of an object requires a subexpression:
$output = "Current script name is:
    $($myInvocation.MyCommand.Path)"
$output gets a value similar to Current script name is c:\Test-Script.ps1.
To define a here string (one that may span multiple lines), place the two characters @" at the beginning, and the two characters "@ on their own line at the end.
For example:
$myHereString = @"
This text may span multiple lines, and may
contain "quotes".
"@
Here strings may be of either the literal (single-quoted) or expanding (double quoted) variety.
Windows PowerShell supports escape sequences inside strings, as listed in .
Table : Windows PowerShell escape sequences
Sequence
Meaning
`0
The null character. Often used as a record separator.
`a
The alarm character. Generates a beep when displayed on the console.
`b
The backspace character. The previous character remains in the string but is overwritten when displayed on the console.
`f
A form feed. Creates a page break when printed on most printers.
`n
A newline.
`r
A carriage return. Newlines in PowerShell are indicated entirely by the `n character, so this is rarely required.
`t
A tab.
`v
A vertical tab.
''(Two single quotes)
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Numbers
PowerShell offers several options for interacting with numbers and numeric data.
To define a variable that holds numeric data, simply assign it as you would other variables. PowerShell automatically stores your data in a format that is sufficient to accurately hold it.
$myInt = 10
$myInt gets the value of 10, as a (32-bit) integer.
$myDouble = 3.14
$myDouble gets the value of 3.14, as a (53-bit, 9 bits of precision) double.
To explicitly assign a number as a long (64-bit) integer or decimal (96-bit, 96 bits of precision), use the long and decimal suffixes:
$myLong = 2147483648L
$myLong gets the value of 2147483648, as a long integer.
$myDecimal = 0.999D
$myDecimal gets the value of 0.999.
PowerShell also supports scientific notation:
$myPi = 3141592653e-9
$myPi gets the value of 3.141592653.
The data types in PowerShell (integer, long integer, double, and decimal) are built on the .NET data types of the same name.
Since computer administrators rarely get the chance to work with numbers in even powers of ten, PowerShell offers the numeric constants of gb, mb, and kb to represent gigabytes, megabytes, and kilobytes, respectively:
PS >$downloadTime = (1gb + 250mb) / 120kb
PS >$downloadTime
10871.4666666667
To directly enter a hexadecimal number, use the hexadecimal prefix 0x:
$myErrorCode = 0xFE4A
$myErrorCode gets the integer value 65098.
The PowerShell scripting language does not natively support other number bases, but its support for interaction with the .NET Framework enables conversion to and from binary, octal, decimal, and hexadecimal:
$myBinary = [Convert]::ToInt32("101101010101", 2)
$myBinary gets the integer value of 2901.
$myOctal = [Convert]::ToInt32("1234567", 8)
$myOctal gets the integer value of 342391.
$myHexString = [Convert]::ToString(65098, 16)
$myHexString gets the string value of fe4a.
$myBinaryString = [Convert]::ToString(12345, 2)
$myBinaryString gets the string value of 11000000111001.
See "Working with the .NET Framework," later in this chapter, to learn more about using PowerShell to interact with the .NET Framework.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Arrays and Lists
PowerShell arrays hold lists of data. The @() (array cast) syntax tells PowerShell to treat the contents between the parentheses as an array. To create an empty array, type:
$myArray = @()
To define a nonempty array, use a comma to separate its elements:
$mySimpleArray = 1,"Two",3.14
Arrays may optionally be only a single element long:
$myList = ,"Hello"
Or, alternatively (using the array cast syntax):
$myList = @("Hello")
Elements of an array do not need to be all of the same data type, unless you declare it as a strongly typed array. In the following example, the outer square brackets define a strongly typed variable (as mentioned in "Variables," earlier in this chapter), and int[] represents an array of integers:
[int[]] $myArray = 1,2,3.14
In this mode, PowerShell throws an error if it cannot convert any of the elements in your list to the required data type. In this case, it rounds 3.14 to the integer value of 3.
PS >$myArray[2]
3
To ensure that PowerShell treats collections of uncertain length (such as history lists or directory listings) as a list, use the list evaluation syntax @(…) described in "Commands and Expressions," earlier in this chapter.
Arrays can also be multidimensional "jagged" arrays—arrays within arrays:
$multiDimensional = @(
      (1,2,3,4),
      (5,6,7,8)
   )
$multiDimensional[0][1] returns 2, coming from row 0, column 1.
$multiDimensional[1][3] returns 8, coming from row 1, column 3.
To define a multidimensional array that is not jagged, create a multidimensional instance of the .NET type. For integers, that would be an array of System.Int32:
$multidimensional = New-Object "Int32[,]" 2,4
$multidimensional[0,1] = 2
$multidimensional[1,3] = 8
To access a specific element in an array, use the [] operator. PowerShell numbers your array elements starting at 0. Using $myArray = 1,2,3,4,5,6 as an example:
$myArray[0]
Returns 1, the first element in the array.
$myArray[2]
Returns 3, the third element in the array.
$myArray[-1]
Returns 6, the last element in the array.
$myArray[-2]
Returns 5, the second-to-last element in the array.
You can also access ranges of elements in your array:
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Hashtables (Associative Arrays)
PowerShell hashtables (or associative arrays) let you associate keys with values. To define a hashtable, use the syntax:
$myHashtable = @{}
You can initialize a hashtable with its key/value pairs when you create it. PowerShell assumes that the keys are strings, but the values may be any data type.
$myHashtable = @{ Key1 = "Value1";
"Key 2" = 1,2,3; 3.14 = "Pi" }
To access or modify a specific element in an associative array, you may use either the array-access or property-access syntax:
$myHashtable["Key1"]
Returns "Value1".
$myHashtable."Key 2"
Returns the array 1,2,3.
$myHashtable["New Item"] = 5
Adds "New Item" to the hashtable.
$myHashtable."New Item" = 5
Also adds "New Item" to the hashtable.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
XML
PowerShell supports XML as a native data type. To create an XML variable, cast a string to the [xml] type:
$myXml = [xml] @"
<AddressBook>
   <Person contactType="Personal">
      <Name>Lee</Name>
      <Phone type="home">555-1212</Phone>
      <Phone type="work">555-1213</Phone>
   </Person>
   <Person contactType="Business">
      <Name>Ariel</Name>
      <Phone>555-1234</Phone>
   </Person>
</AddressBook>
"@
PowerShell exposes all child nodes and attributes as properties. When it does this, PowerShell automatically groups children that share the same node type:
$myXml.AddressBook
Returns an object that contains a Person property.
$myXml.AddressBook.Person
Returns a list of Person nodes. Each Person node exposes contactType, Name, and Phone as properties.
$myXml.AddressBook.Person[0]
Returns the first Person node.
$myXml.AddressBook.Person[0].ContactType
Returns Personal as the contact type of the first Person node.
The XML data type wraps the .NET XmlDocument and XmlElement classes. Unlike most PowerShell .NET wrappers, this wrapper does not expose the properties from the underlying class because they may conflict with the dynamic properties that PowerShell adds for node names.
To access properties of the underlying class, use the PsBase property. For example:
$myXml.PsBase.InnerXml
See "Working with the .NET Framework," later in this chapter, to learn more about using PowerShell to interact with the .NET Framework.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Simple Operators
Once you've defined your data, the next step is to work with it.
The arithmetic operators let you perform mathematical operations on your data, as shown in .
Table : Windows PowerShell arithmetic operators
Operator
Meaning
+
The addition operator:
$leftValue + $rightValue
When used with numbers, returns their sum.
When used with strings, returns a new string created by appending the second string to the first.
When used with arrays, returns a new array created by appending the second array to the first.
When used with hashtables, returns a new hashtable created by merging the two hashtables. Since hashtable keys must be unique, PowerShell returns an error if the second hashtable includes any keys already defined in the first hashtable.
When used with any other type, PowerShell uses that type's additio