BUY THIS BOOK
Add to Cart

Print Book $49.99


Add to Cart

PDF $39.99

Safari Books Online

What is this?

Add to UK Cart

Print Book £30.99

What is this?

Looking to Reprint or License this content?


Windows PowerShell Cookbook
Windows PowerShell Cookbook for Windows, Exchange 2007, and MOM V3

By Lee Holmes
Book Price: $49.99 USD
£30.99 GBP
PDF Price: $39.99

Cover | Table of Contents | Colophon


Table of Contents

Chapter 1: The Windows PowerShell Interactive Shell
Above all else, the design of Windows PowerShell places priority on its use as an efficient and powerful interactive shell. Even its scripting language plays a critical role in this effort, as it too heavily favors interactive use.
What surprises most people when they first launch PowerShell is its similarity to the command prompt that has long existed as part of Windows. Familiar tools continue to run. Familiar commands continue to run. Even familiar hotkeys are the same. Supporting this familiar user interface, though, is a powerful engine that lets you accomplish once cumbersome administrative and scripting tasks with ease.
This chapter introduces PowerShell from the perspective of its interactive shell.
You rely on a lot of effort invested in your current tools. You have traditional executables, Perl scripts, VBScript, and of course, a legacy build system that has organically grown into a tangled mess of batch files. You want to use PowerShell, but don't want to give up everything you already have.
To run a program, script, batch file, or other executable command in the system's path, enter its filename. For these executable types, the extension is optional:
	Program.exe arguments
	ScriptName.ps1 arguments
	BatchFile.cmd arguments
To run a command that contains a space in its name, enclose its filename in single-quotes (') and precede the command with an ampersand (&), known in PowerShell as the Invoke operator:
	& 'C:\Program Files\Program\Program.exe' arguments
To run a command in the current directory, place .\ in front of its filename:
	.\Program.exe arguments
To run a command with spaces in its name from the current directory, precede it with both an ampersand and .\:
	& '.\Program With Spaces.exe' arguments
In this case, the solution is mainly to use your current tools as you always have. The only difference is that you run them in the PowerShell interactive shell, rather than cmd.exe.
The final three tips in the solution merit special attention. They are the features of PowerShell that many new users stumble on when it comes to running programs. The first is running commands that contain spaces. 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!
Introduction
Above all else, the design of Windows PowerShell places priority on its use as an efficient and powerful interactive shell. Even its scripting language plays a critical role in this effort, as it too heavily favors interactive use.
What surprises most people when they first launch PowerShell is its similarity to the command prompt that has long existed as part of Windows. Familiar tools continue to run. Familiar commands continue to run. Even familiar hotkeys are the same. Supporting this familiar user interface, though, is a powerful engine that lets you accomplish once cumbersome administrative and scripting tasks with ease.
This chapter introduces PowerShell from the perspective of its interactive shell.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Run Programs, Scripts, and Existing Tools
You rely on a lot of effort invested in your current tools. You have traditional executables, Perl scripts, VBScript, and of course, a legacy build system that has organically grown into a tangled mess of batch files. You want to use PowerShell, but don't want to give up everything you already have.
To run a program, script, batch file, or other executable command in the system's path, enter its filename. For these executable types, the extension is optional:
	Program.exe arguments
	ScriptName.ps1 arguments
	BatchFile.cmd arguments
To run a command that contains a space in its name, enclose its filename in single-quotes (') and precede the command with an ampersand (&), known in PowerShell as the Invoke operator:
	& 'C:\Program Files\Program\Program.exe' arguments
To run a command in the current directory, place .\ in front of its filename:
	.\Program.exe arguments
To run a command with spaces in its name from the current directory, precede it with both an ampersand and .\:
	& '.\Program With Spaces.exe' arguments
In this case, the solution is mainly to use your current tools as you always have. The only difference is that you run them in the PowerShell interactive shell, rather than cmd.exe.
The final three tips in the solution merit special attention. They are the features of PowerShell that many new users stumble on when it comes to running programs. The first is running commands that contain spaces. In cmd.exe, the way to run a command that contains spaces is to surround it with quotes:
	"C:\Program Files\Program\Program.exe"
In PowerShell, though, placing text inside quotes is part of a feature that lets you evaluate complex expressions at the prompt, as shown in .
Example 1-1. Evaluating expressions at the PowerShell prompt
PS >1 + 1
2
PS >26 * 1.15
29.9
PS >"Hello" + " World"
Hello World
PS >"Hello World"
Hello World
PS >"C:\Program Files\Program\Program.exe"
C:\Program Files\Program\Program.exe
PS >
So, a program name in quotes is no different from any other string in quotes. It's just an expression. As shown previously, the way to run a command in a string is to precede that string with 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!
Run a PowerShell Command
You want to run a PowerShell command.
To run a PowerShell command, type its name at the command prompt. For example:
	PS >Get-Process

	Handles  NPM(K)    PM(K)    WS(K)   VM(M)  CPU(s)    Id ProcessName
	-------  ------    -----    -----   -----  ------    -- ----------- 
 	    133       5    11760     7668      46          1112 audiodg
  	    184       5    33248      508      93          1692 avgamsvr
	    143       7    31852      984      97          1788 avgemc
The Get-Process command is an example of a native PowerShell command, called a cmdlet. As compared to traditional commands, cmdlets provide significant benefits to both administrators and developers:
  • They share a common and regular command-line syntax.
  • They support rich pipeline scenarios (using the output of one command as the input of another).
  • They produce easily manageable object-based output, rather than error-prone plain text output.
Because the Get-Process cmdlet generates rich object-based output, you can use its output for many process-related tasks.
The Get-Process cmdlet is just one of the many that PowerShell supports. See , "Find a Command to Accomplish a Task" to learn techniques for finding additional commands that PowerShell supports.
For more information about working with classes from the .NET Framework, see , "Work with .NET Objects."
  • , "Find a Command to Accomplish a Task"
  • , "Work with .NET 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!
Customize Your Shell, Profile, and Prompt
You want to customize PowerShell's interactive experience with a personalized prompt, aliases, and more.
When you want to customize aspects of PowerShell, place those customizations in your personal profile script. PowerShell provides easy access to this profile script by storing its location in the $profile variable.
By default, PowerShell's security policies prevent scripts (including your profile) from running. Once you begin writing scripts, though, you should configure this policy to something less restrictive. For information on how to configure your execution policy, see , "Enable Scripting Through an Execution Policy."
To create a new profile (and overwrite one if it already exists):
	New-Item -type file -force $profile
To edit your profile:
	notepad $profile
To see your profile file:
	Get-ChildItem $profile
Once you create a profile script, you can add a function called Prompt that returns a string. PowerShell displays the output of this function as your command-line prompt.
	function Prompt
	{
	    "PS [$env:COMPUTERNAME] >"
	}
This example prompt displays your computer name, and look like: PS [LEE-DESK]>
You may also find it helpful to add aliases to your profile. Aliases let you to refer to common commands by a name that you choose. Personal profile scripts let you automatically define aliases, functions, variables, or any other customizations that you might set interactively from the PowerShell prompt. Aliases are among the most common customizations, as they let you refer to PowerShell commands (and your own scripts) by a name that is easier to type.
If you want to define an alias for a command but also need to modify the parameters to that command, then define a function instead.
For example:
	Set-Alias new New-Object
	Set-Alias iexplore 'C:\Program Files\Internet Explorer\iexplore.exe'
Your changes will become effective once you save your profile and restart Power-Shell. To reload your profile immediately, run the command:
	. $profile
Functions are also very common customizations, with the most popular of those being the Prompt function.
Although the Prompt
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Find a Command to Accomplish a Task
You want to accomplish a task in PowerShell but don't know the command or cmdlet to accomplish that task.
Use the Get-Command cmdlet to search for and investigate commands.
To get the summary information about a specific command, specify the command name as an argument:
	Get-Command CommandName
To get the detailed information about a specific command, pipe the output of Get-Command to the Format-List cmdlet:
	Get-Command CommandName | Format-List
To search for all commands with a name that contains text, surround the text with asterisk characters:
	Get-Command *text*
To search for all commands that use the Get verb, supply Get to the -Verb parameter:
	Get-Command -Verb Get
To search for all commands that act on a service, supply Service to the -Noun parameter:
	Get-Command -Noun Service
One of the benefits that PowerShell provides administrators is the consistency of its command names. All PowerShell commands (called cmdlets) follow a regular Verb-Noun pattern. For example: Get-Process, Get-EventLog, and Set-Location. The verbs come from a relatively small set of standard verbs (as listed in , Standard PowerShell Verbs), and describe what action the cmdlet takes. The nouns are specific to the cmdlet and describe what the cmdlet acts on.
Knowing this philosophy, you can easily learn to work with groups of cmdlets. If you want to start a service on the local machine, the standard verb for that is Start.A good guess would be to first try Start-Service (which in this case would be correct), but typing Get-Command -Verb Start would also be an effective way to see what things you can start. Going the other way, you can see what actions are supported on services by typing Get-Command -Noun Service.
See , "Get Help on a Command" for a way to list all commands along with a brief description of what they do.
The Get-Command cmdlet is one of the three commands you will use most commonly as you explore Windows PowerShell. The other two commands are Get-Help and Get-Member.
There is one important point when it comes to looking for a PowerShell command to accomplish a task. Many times, that PowerShell command does not exist, because the task is best accomplished the same way it always was—
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Get Help on a Command
You want to learn about how a specific command works and how to use it.
The command that provides help and usage information about a command is called Get-Help. It supports several different views of the help information, depending on your needs.
To get the summary of help information for a specific command, provide the command's name as an argument to the Get-Help cmdlet. This primarily includes its synopsis, syntax, and detailed description:
	Get-Help CommandName
or
	CommandName -?
To get the detailed help information for a specific command, supply the–Detailed flag to the Get-Help cmdlet. In addition to the summary view, this also includes its parameter descriptions and examples:
	Get-Help CommandName -Detailed
To get the full help information for a specific command, supply the–Full flag to the Get-Help cmdlet. In addition to the detailed view, this also includes its full parameter descriptions and additional notes:
	Get-Help CommandName -Full
To get only the examples for a specific command, supply the–Examples flag to the Get-Help cmdlet:
	Get-Help CommandName -Examples
The Get-Help cmdlet is the primary way to interact with the help system in PowerShell. Like the Get-Command cmdlet, the Get-Help cmdlet supports wildcards. If you want to list all commands that match a certain pattern (for example, *process*), you can simply type Get-Help *process*.
To generate a list of all cmdlets along with a brief synopsis, run the following command:
	Get-Help * | Select-Object Name,Synopsis | Format-Table -Auto
If the pattern matches only a single command, PowerShell displays the help for that command. Although wildcarding is a helpful way to search PowerShell help, see , "Program: Search Help for Text" for a script that lets you search the help content for a specified pattern.
The Get-Help cmdlet is one of the three commands you will use most commonly as you explore Windows PowerShell. The other two commands are Get-Command and Get-Member.
For more information about the Get-Help cmdlet, type Get-Help Get-Help.
  • , "Program: Search Help for Text"
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Program: Search Help for Text
Both the Get-Command and Get-Help cmdlets let you search for command names that match a given pattern. However, when you don't know exactly what portions of a command name you are looking for, you will more often have success searching through the help content for an answer. On Unix systems, this command is called Apropos. Similar functionality does not exist as part of the PowerShell's help facilities, however.
That doesn't need to stop us, though, as we can write the functionality ourselves.
To run this program, supply a search string to the Search-Help script (given in ). The search string can be either simple text or a regular expression. The script then displays the name and synopsis of all help topics that match. To see the help content for that topic, use the Get-Help cmdlet.
Example 1-3. Search-Help.ps1
##############################################################################
##
## Search-Help.ps1
##
## Search the PowerShell help documentation for a given keyword or regular
## expression.
##
## Example:
##  Search-Help hashtable
##  Search-Help "(datetime|ticks)"
##############################################################################

param($pattern = $(throw "Please specify content to search for"))

$helpNames = $(Get-Help * | Where-Object { $_.Category -ne "Alias" })

foreach($helpTopic in $helpNames)
{
   $content = Get-Help -Full $helpTopic.Name | Out-String
   if($content -match $pattern)
   {
      $helpTopic | Select-Object Name,Synopsis
   }
}
For more information about running scripts, see , "Run Programs, Scripts, and Existing Tools."
  • , "Run Programs, Scripts, and Existing Tools"
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Invoke a PowerShell Script From Outside PowerShell
You want to invoke a PowerShell script from a batch file, a logon script, scheduled task, or any other non-PowerShell application.
Launch PowerShell.exe in the following way:
	PowerShell "& 'full path to script' arguments"
For example,
	PowerShell "& 'c:\shared scripts\Get-Report.ps1' Hello World"
Supplying a single string argument to PowerShell.exe invokes PowerShell, runs the command as though you had typed it in the interactive shell, and then exits. Since the path to a script often contains spaces, you invoke the script by placing its name between single quotes, and after the & character. If the script name does not contain spaces, you can omit the single quotes and & character. This technique lets you invoke a PowerShell script as the target of a logon script, advanced file association, scheduled task and more.
If you are the author of the program that needs to run PowerShell scripts or commands, PowerShell lets you call these scripts and commands much more easily than calling its command-line interface. For more information about this approach, see , "Add PowerShell Scripting to Your Own Program."
If the command becomes much more complex than a simple script call, special characters in the application calling PowerShell (such as cmd.exe) might interfere with the command you want to send to PowerShell. For this situation, PowerShell supports an EncodedCommand parameter: a Base64 encoded representation of the Unicode string you want to run. demonstrates how to convert a string containing PowerShell commands to a Base64 encoded form.
Example 1-4. Converting PowerShell commands into a Base64 encoded form
$commands = '1..10 | % { "PowerShell Rocks" }'
$bytes = [System.Text.Encoding]::Unicode.GetBytes($commands)
$encodedString = [Convert]::ToBase64String($bytes)
Once you have the encoded string, you can use it as the value of the EncodedCommand parameter, as shown in .
Example 1-5. Launching PowerShell with an encoded command from cmd.exe
Microsoft Windows [Version 6.0.6000]
Copyright (c) 2006 Microsoft Corporation. All rights reserved.

C:\Users\Lee>PowerShell -EncodedCommand MQAuAC4AMQAwACAAfAAgACUAIAB7ACAAIgBQAG8A↵
dwBlAHIAUwBoAGUAbABsACAAUgBvAGMAawBzACIAIAB9AA==
PowerShell Rocks
PowerShell Rocks
PowerShell Rocks
PowerShell Rocks
PowerShell Rocks
PowerShell Rocks
PowerShell Rocks
PowerShell Rocks
PowerShell Rocks
PowerShell Rocks
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Program: Retain Changes to Environment Variables Set by a Batch File
When a batch file modifies an environment variable, cmd.exe retains this change even after the script exits. This often causes problems, as one batch file can accidentally pollute the environment of another. That said, batch file authors sometimes intentionally change the global environment to customize the path and other aspects of the environment to suit a specific task.
However, environment variables are private details of a process and disappear when that process exits. This makes the environment customization scripts mentioned above stop working when you run them from PowerShell—just as they fail to work when you run them from another cmd.exe (for example, cmd.exe /c MyScript.cmd).
The script in lets you run batch files that modify the environment and retain their changes even after cmd.exe exits. It accomplishes this by storing the environment variables in a text file once the batch file completes, and then setting all those environment variables again in your PowerShell session.
To run this script, type Invoke-CmdScript Scriptname.cmd or Invoke-CmdScript Scriptname.bat—whichever extension the batch files uses.
If this is the first time you've run a script in PowerShell, you will need to configure your Execution Policy. For more information about selecting an execution policy, see , "Enable Scripting Through an Execution Policy."
Notice that this script uses the full names for cmdlets: Get-Content, Foreach-Object, Set-Content, and Remove-Item. This makes the script readable and is ideal for scripts that somebody else will read. It is by no means required, though. For quick scripts and interactive use, shorter aliases (such as gc, %, sc, and ri) can make you more productive.
Example 1-6. Invoke-CmdScript.ps1
##############################################################################
##
## Invoke-CmdScript.ps1
##
## Invoke the specified batch file (and parameters), but also propagate any
## environment variable changes back to the PowerShell environment that
## called it.
##
## i.e., for an already existing 'foo-that-sets-the-FOO-env-variable.cmd': 
##
## PS > type foo-that-sets-the-FOO-env-variable.cmd
## @set FOO=%*
## echo FOO set to %FOO%.
##
## PS > $env:FOO
##
## PS > Invoke-CmdScript "foo-that-sets-the-FOO-env-variable.cmd" Test 
##
## C:\Temp>echo FOO set to Test. 
## FOO set to Test.
##
## PS > $env:FOO 
## Test 
##
##############################################################################

param([string] $script, [string] $parameters)

$tempFile = [IO.Path]::GetTempFileName()

## Store the output of cmd.exe. We also ask cmd.exe to output
## the environment table after the batch file completes 
cmd /c " '"$script'" $parameters && set > '"$tempFile'" "

## Go through the environment variables in the temp file.
## For each of them, set the variable in our local environment.
Get-Content $tempFile | Foreach-Object {
    if($_ -match "^(.*?)=(.*)$")
    {
        Set-Content "env:\$($matches[1])" $matches[2]
    }
}

Remove-Item $tempFile
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Get the System Date and Time
You want to get the system date.
To get the system date, run the command Get-Date.
The Get-Date command generates rich object-based output, so you can use its result for many date-related tasks. For example, to determine the current day of the week:
	PS >$date = Get-Date
	PS >$date.DayOfWeek
	Sunday
For more information about the Get-Date cmdlet, type Get-Help Get-Date.
For more information about working with classes from the .NET Framework, see , "Work with .NET Objects."
  • , "Work with .NET 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!
Determine the Status of the Last Command
You want to get status information about the last command you executed, such as whether it succeeded.
Use one of the two variables PowerShell provides to determine the status of the last command you executed: the $lastExitCode variable and the $? variable.
$lastExitCode
A number that represents the exit code/error level of the last script or application that exited
$? (pronounced "dollar hook")
A Boolean value that represents the success or failure of the last command
The $lastExitCode PowerShell variable is similar to the %errorlevel% variable in DOS. It holds the exit code of the last application to exit. This lets you continue to interact with traditional executables (such as ping, findstr, and choice) that use exit codes as a primary communication mechanism. PowerShell also extends the meaning of this variable to include the exit codes of scripts, which can set their status using the exit statement. demonstrates this interaction.
Example 1-7. Interacting with the $lastExitCode and $? variables
PS >ping localhost

Pinging MyComputer [127.0.0.1] with 32 bytes of data:

Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128

Ping statistics for 127.0.0.1:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milliseconds:
    Minimum = 0ms, Maximum = 0ms, Average = 0ms
PS >$?
True
PS >$lastExitCode

0
PS >ping missing-host
Ping request could not find host missing-host. Please check the name and try again.
PS >$?
False
PS >$lastExitCode
1
The $? variable describes the exit status of the last application in a more general manner. PowerShell sets this variable to False on error conditions such as when:
  • An application exits with a non-zero exit code.
  • A cmdlet or script writes anything to its error stream.
  • A cmdlet or script encounters a terminating error or exception.
For commands that do not indicate an error condition, PowerShell sets the $? variable to 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!
Measure the Duration of a Command
You want to know how long a command takes to execute.
To measure the duration of a command, use the Measure-Command cmdlet:
	PS >Measure-Command { Start-Sleep -Milliseconds 337 }

	Days              : 0
	Hours             : 0
	Minutes           : 0
	Seconds           : 0
	Milliseconds      : 339
	Ticks             : 3392297
	TotalDays         : 3.92626967592593E-06
	TotalHours        : 9.42304722222222E-05
	TotalMinutes      : 0.00565382833333333
	TotalSeconds      : 0.3392297
	TotalMilliseconds : 339.2297
In interactive use, it is common to want to measure the duration of a command. An example of this might be running a performance benchmark on an application you've developed. The Measure-Command cmdlet makes this easy to do. Because the command generates rich object-based output, you can use its output for many date-related tasks. See , "Work with .NET Objects," for more information.
For more information about the Measure-Command cmdlet, type Get-Help Measure-Command.
  • , "Work with .NET 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!
Customize the Shell to Improve Your Productivity
You want to use the PowerShell console more efficiently for copying, pasting, history management, and scrolling.
Run the commands shown in to permanently customize your Power-Shell console windows and make many tasks easier.
Example 1-8. Set-ConsoleProperties.ps1
Push-Location
Set-Location HKCU:\Console
New-Item '.\%SystemRoot%_system32_WindowsPowerShell_v1.0_powershell.exe'
Set-Location '.\%SystemRoot%_system32_WindowsPowerShell_v1.0_powershell.exe'

New-ItemProperty . ColorTable00 -type DWORD -value 0x00562401
New-ItemProperty . ColorTable07 -type DWORD -value 0x00f0edee
New-ItemProperty . FaceName -type STRING -value "Lucida Console"
New-ItemProperty . FontFamily -type DWORD -value 0x00000036
New-ItemProperty . FontSize -type DWORD -value 0x000c0000
New-ItemProperty . FontWeight -type DWORD -value 0x00000190
New-ItemProperty . HistoryNoDup -type DWORD -value 0x00000000
New-ItemProperty . QuickEdit -type DWORD -value 0x00000001
New-ItemProperty . ScreenBufferSize -type DWORD -value 0x0bb80078
New-ItemProperty . WindowSize -type DWORD -value 0x00320078
Pop-Location
These commands customize the console color, font, history storage properties, QuickEdit mode, buffer size, and window size.
With these changes in place, you can also improve your productivity by learning some of the hotkeys for common tasks, as listed in . PowerShell uses the same input facilities as cmd.exe, and so brings with it all the input features that you are already familiar with—and some that you aren't!
Table : Partial list of Windows PowerShell hotkeys
Hotkey
Meaning
Up arrow
Scan backward through your command history.
Down arrow
Scan forward through your command history.
PgUp
Display the first command in your command history.
PgDown
Display the last command in your command history.
Left arrow
Move cursor one character to the left on your command line.
Right arrow
Move cursor one character to the right on your command line.
Home
Move the cursor to the beginning of the command line.
End
Move the cursor to the end of the command line.
Control + Left arrow
Move the cursor one word to the left on your command line.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Program: Learn Aliases for Common Commands
In interactive use, full cmdlet names (such as Get-ChildItem) are cumbersome and slow to type. Although aliases are much more efficient, it takes awhile to discover them. To learn aliases more easily, you can modify your prompt to remind you of the shorter version of any aliased commands that you use.
This involves two steps:
  1. Add the program,Get-AliasSuggestion.ps1, shown in , to your tools directory or other directory.
    Example 1-9. Get-AliasSuggestion.ps1
    ##############################################################################
    ##
    ## Get-AliasSuggestion.ps1
    ##
    ## Get an alias suggestion from the full text of the last command
    ##
    ## ie:
    ##
    ## PS > Get-AliasSuggestion Remove-ItemProperty
    ## Suggestion: An alias for Remove-ItemProperty is rp
    ##
    ############################################################################## 
    
    param($lastCommand)
    
    $helpMatches = @()
    
    ## Get the alias suggestions
    foreach($alias in Get-Alias)
    {
        if($lastCommand -match ("\b" +
            [System.Text.RegularExpressions.Regex]::Escape($alias.Definition) + "\b"))
        {
            $helpMatches += "Suggestion: An alias for $($alias.Definition) is $($alias.Name)" 
        }
    }
    
    $helpMatches
    
  2. Add the text from to the Prompt function in your profile. If you do not yet have a Prompt function, see , "Customize Your Shell, Profile, and Prompt" to learn how to add one. If you already have a prompt function, you only need to add the content from inside the prompt function of .
    Example 1-10. A useful prompt to teach you aliases for common commands
        function Prompt
        {
        ## Get the last item from the history
        $historyItem = Get-History -Count 1
    
        ## If there were any history items
        if($historyItem)
        {
            ## Get the training suggestion for that item
            $suggestions = @(Get-AliasSuggestion $historyItem.CommandLine)
            ## If there were any suggestions
            if($suggestions)
            {
                ## For each suggestion, write it to the screen
                foreach($aliasSuggestion in $suggestions)
                {
                    Write-Host "$aliasSuggestion"
                }
                Write-Host "" 
    
            }
        }
    
        ## Rest of prompt goes here
        "PS [$env:COMPUTERNAME] >"
    }
    
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Access and Manage Your Console History
After working in the shell for a while, you want to invoke commands from your history, view your command history, and save your command history.
The shortcuts given in , "Customize the Shell to Improve Your Productivity" let you manage your history, but PowerShell offers several features to help you work with your console in even more detail.
To get the most recent commands from your session, use the Get-History cmdlet:
	Get-History
To rerun a specific command from your session history, provide its Id to the Invoke-History cmdlet:
	Invoke-History Id
To increase (or limit) the number of commands stored in your session history, assign a new value to the $MaximumHistoryCount variable:
	$MaximumHistoryCount = Count
To save your command history to a file, pipe the output of Get-History to the Export-CliXml cmdlet:
	Get-History | Export-CliXml Filename
To add a previously saved command history to your current session history, call the Import-CliXml cmdlet and then pipe that output to the Add-History cmdlet:
	Import-CliXml Filename | Add-History
Unlike the console history hotkeys discussed in , "Customize the Shell to Improve Your Productivity" the Get-History cmdlet produces rich objects that represent information about items in your history. Each object contains that item's ID, command line, start of execution time, and end of execution time.
Once you know the ID of a history item(as shown in the output of Get-History), you can pass it to Invoke-History to execute that command again. The example prompt function shown in , "Customize Your Shell, Profile, and Prompt" makes working with prior history items easy—as the prompt for each command includes the history ID that will represent it.
The IDs provided by the Get-History cmdlet differ from the IDs given by the Windows console common history hotkeys (such as F7), because their history management techniques differ.
By default, PowerShell stores only the last 64 entries of your command history. If you want to raise or lower this amount, set the $MaximumHistoryCount variable to the size you desire. To make this change permanent, set the variable in your PowerShell profile script. To clear your history, either restart the shell, or temporarily set 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!
Store the Output of a Command into a File
You want to redirect the output of a pipeline into a file.
To redirect the output of a command into a file, use either the Out-File cmdlet or one of the redirection operators.
Out-File:
	
	Get-ChildItem | Out-File unicodeFile.txt
	Get-Content filename.cs | Out-File -Encoding ASCII file.txt
	Get-ChildItem | Out-File-Width 120 unicodeFile.cs
Redirection operators:
	Get-ChildItem > files.txt
	Get-ChildItem 2> errors.txt
The Out-File cmdlet and redirection operators share a lot in common—and for the most part, you can use either. The redirection operators are unique because they give the greatest amount of control over redirecting individual streams. The Out-File cmdlet is unique primarily because it lets you easily configure the formatting width and encoding.
The default formatting width and the default output encoding are two aspects of output redirection that can sometimes cause difficulty.
The default formatting width sometimes causes problems because redirecting PowerShell-formatted output into a file is designed to mimic what you see on the screen. If your screen is 80 characters wide, the file will be 80 characters wide as well. Examples of PowerShell-formatted output include directory listings (that are implicitly for-matted as a table) as well as any commands that you explicitly format using one of the Format-*set of cmdlets. If this causes problems, you can customize the width of the file with the—Width parameter on the Out-File cmdlet.
The default output encoding sometimes causes unexpected results because PowerShell creates all files using the UTF-16 Unicode encoding by default. This allows PowerShell to fully support the entire range of international characters, cmdlets, and output. Although this is a great improvement to traditional shells, it may cause an unwanted surprise when running large search and replace operations on ASCII source code files, for example. To force PowerShell to send its output to a file in the ASCII encoding, use the—Encoding parameter on the Out-File cmdlet.
For more information about the Out-File cmdlet, type Get-Help Out-File. For a full list of supported redirection operators, see "Capturing Output" 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!
Add Information to the End of a File
You want to redirect the output of a pipeline into a file but add the information to the end of that file.
To redirect the output of a command into a file, use either the -Append parameter of the Out-File cmdlet, or one of the appending redirection operators as described in "Capturing Output" in . Both support options to append text to the end of a file.
Out-File:
	Get-ChildItem | Out-File -Append files.txt
Redirection operators:
	Get-ChildItem >> files.txt
The Out-File cmdlet and redirection operators share a lot in common—and for the most part, you can use either. See the discussion in , "Store the Output of a Command into a File" for a more detailed comparison of the two approaches, including reasons that you would pick one over the other.
  • , "Store the Output of a Command into a File"
  • "Capturing Output" 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!
Record a Transcript of Your Shell Session
You want to record a log or transcript of your shell session.
To record a transcript of your shell session, run the command Start-Transcript Path. Path is optional and defaults to a filename based on the current system time. By default, PowerShell places this file in the My Documents directory. To stop recording the transcript of your shell system, run the command Stop-Transcript.
Although the Get-History cmdlet is helpful, it does not record the output produced during your PowerShell session. To accomplish that, use the Start-Transcript cmdlet. In addition to the Path parameter described previously, the Start-Transcript cmdlet also supports parameters that let you control how PowerShell interacts with the output file.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Display the Properties of an Item As a List
You have an item (for example, an error record, directory item, or .NET object), and you want to display detailed information about that object in a list format.
To display detailed information about an item, pass that item to the Format-List cmdlet. For example, to display an error in list format, type the commands:
	$currentError = $error[0]
	$currentError | Format-List -Force
The Format-List cmdlet is one of the three PowerShell formatting cmdlets. These cmdlets include Format-Table, Format-List, and Format-Wide. The Format-List cmdlet takes input and displays information about that input as a list. By default, PowerShell takes the list of properties to display from the *.format.ps1xml files in PowerShell's installation directory. To display all properties of the item, type Format-List *. Sometimes, you might type Format-List * but still not get a list of the item's properties. This happens when the item is defined in the *.format.ps1xml files, but does not define anything to be displayed for the list command. In that case, type Format-List-Force.
For more information about the Format-List cmdlet, type Get-Help Format-List.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Display the Properties of an Item As a Table
You have a set of items (for example, error records, directory items, or .NET objects), and you want to display summary information about them in a table format.
To display summary information about a set of items, pass those items to the Format-Table cmdlet. This is the default type of formatting for sets of items in PowerShell and provides several useful features.
To use PowerShell's default formatting, pipe the output of a cmdlet (such as the Get-Process cmdlet) to the Format-Table cmdlet:
	Get-Process | Format-Table
To display specific properties (such as Name and WorkingSet,) in the table formatting, supply those property names as parameters to the Format-Table cmdlet:
	Get-Process | Format-Table Name,WS
To instruct PowerShell to format the table in the most readable manner, supply the–Auto flag to the Format-Table cmdlet. PowerShell defines "WS" as an alias of the WorkingSet for processes:
	Get-Process | Format-Table Name,WS -Auto
To define a custom column definition (such as a process's Working Setin mega-bytes), supply a custom formatting expression to the Format-Table cmdlet:
	$fields = "Name",@{Label = "WS (MB)"; Expression = {$_.WS / 1mb}; Align = "Right"} 
	Get-Process | Format-Table $fields -Auto
The Format-Table cmdlet is one of the three PowerShell formatting cmdlets. These cmdlets include Format-Table, Format-List, and Format-Wide. The Format-Table cmdlet takes input and displays information about that input as a table. By default, PowerShell takes the list of properties to display from the *.format.ps1xml files in PowerShell's installation directory. You can display all properties of the items if you type Format-Table *, although this is rarely a useful view.
The -Auto parameter to Format-Table is a helpful way to automatically format the table to use screen space as efficiently as possible. It does come at a cost, however. To figure out the best table layout, PowerShell needs to examine each item in the incoming set of items. For small sets of items, this doesn't make much difference, but for large sets (such as a recursive directory listing) it does. Without 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!
Manage the Error Output of Commands
You want to display detailed information about errors that come from commands.
To list all errors (up to $MaximumErrorCount) that have occurred in this session, access the $error array:
	$error
To list the last error that occurred in this session, access the first element in the $error array:
	$error[0]
To list detailed information about an error, pipe the error into the Format-List cmdlet with the -Force parameter:
	$currentError = $error[0]
	$currentError | Format-List -Force
To list detailed information about the command that caused an error, access its InvocationInfo property:
	$currentError = $error[0]
	$currentError.InvocationInfo
To display errors in a more succinct category-based view, change the $errorView variable to "CategoryView":
	$errorView = "CategoryView"
To clear the list of errors collected by PowerShell so far, call the Clear() method on the $error variable:
	$error.Clear()
Errors are a simple fact of life in the administrative world. Not all errors mean disaster, though. Because of this, PowerShell separates errors into two categories: nonterminating and terminating.
Nonterminating errors are the most common type of error. They indicate that the cmdlet, script, function, or pipeline encountered an error that it was able to recover from or was able to continue past. An example of a nonterminating error comes from the Copy-Item cmdlet. If it fails to copy a file from one location to another, it can still proceed with the rest of the files specified.
A terminating error, on the other hand, indicates a deeper, more fundamental error in the operation. An example of this can again come from the Copy-Item cmdlet when you specify invalid command-line parameters.
For more information on how to handle both nonterminating and terminating errors, see , Tracing and Error Management.
, Tracing and Error Management
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Configure Debug, Verbose, and Progress Output
You want to manage the detailed debug, verbose, and progress output generated by cmdlets and scripts.
To enable debug output for scripts and cmdlets that generate it:
	
	$debugPreference = "Continue"
	Start-DebugCommand
To enable verbose mode for a cmdlet that checks for the -Verbose parameter:
	Copy-Item c:\temp\*.txt c:\temp\backup\ -Verbose
To disable progress output from a script or cmdlet that generates it:
	$progressPreference = "SilentlyContinue"
	Get-Progress.ps1
In addition to error output (as described in , "Manage the Error Output of Commands"), many scripts and cmdlets generate several other types of output. This includes:
Debug output
Helps you diagnose problems that may arise and can provide a view into the inner workings of a command. You can use the Write-Debug cmdlet to produce this type of output in a script or the WriteDebug() method to produce this type of output in a cmdlet. PowerShell displays this output in yellow, unless you customize it through the $host.PrivateData.Debug* color configuration variables.
Verbose output
Helps you monitor the actions of commands at a finer level than the default. You can use the Write-Verbose cmdlet to produce this type of output in a script or the WriteVerbose() method to produce this type of output in a cmdlet. PowerShell displays this output in yellow, unless you customize it through the $host.PrivateData.Verbose* color configuration variables.
Progress output
Helps you monitor the status of long-running commands. You can use the Write-Progress cmdlet to produce this type of output in a script or the WriteProgress() method to produce this type of output in a cmdlet. PowerShell displays this output in yellow, unless you customize it through the $host.PrivateData.Progress* color configuration variables.
Some cmdlets generate verbose and debug output only if you specify the -Verbose and -Debug parameters, respectively.
To configure the debug, verbose, and progress output of a script or cmdlet, modify the $debugPreference, $verbosePreference, and $progressPreference shell variables. These variables can accept the following values:
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Extend Your Shell with Additional Snapins
You want to use PowerShell cmdlets and providers written by a third party.
In PowerShell, extensions that contain additional cmdlets and providers are called snapins. The author might distribute them with an automated installer but can also distribute them as a standalone PowerShell assembly. PowerShell identifies each snapin by the filename of its assembly and by the snapin name that its author provides.
To use a snapin:
  1. Obtain the snapin assembly.
  2. Copy it to a secure location on your computer. Since snapins are equivalent to executable programs, pick a location (such as the Program Files directory) that provides users read access but not write access.
  3. Register the snapin. From the directory that contains the snapin assembly, run InstallUtil SnapinFilename.dll. This command lets all users on the computer load and run commands defined by the snapin. You can find the InstallUtil utility in the .NET Framework's installation directory—commonly C:\WINDOWS\ Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe.
  4. Add the snapin. At a PowerShell prompt (or in your profile file), run the command Add-PsSnapin SnapinIdentifier. To see all available snapin identifiers, review the names listed in the output of the command:
    	Get-PsSnapin -Registered
    
  5. Use the cmdlets and providers contained in that snapin.
To remove the snapin registration from your system, type InstallUtil /u SnapinFilename.dll. Once uninstalled, you may delete the files associated with the snapin.
For interactive use (or in a profile), the Add-PsSnapin cmdlet is the most common way to load an individual snapin. To load a preconfigured list of snapins, though, the following section , "Use Console Files to Load and Save Sets of Snapins" offers another option.
One popular source of additional snapins is the PowerShell Community Extensions project, located at http://www.codeplex.com/PowerShellCX.
  • , "Use Console Files to Load and Save Sets of Snapins"
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get th