Skip to main content

Windows

View the Errors Generated by a Command

Problem

You want to view the errors generated in the current session.

Solution

To access the list of errors generated so far, use the $error variable, as shown by Example 131.

Example 131. Viewing errors contained in the $error variable

PS >1/0 Attempted to divide by zero. At line:1 char:3

+ 1/0 PS >$error[0] | FormatList Force

ErrorRecord
: Attempted to divide by zero.

StackTrace
:
at System.Management.Automation.Parser.ExpressionNode.A

(...)

Message
: Attempted to divide by zero.

Data
: {}

InnerException : System.DivideByZeroException: Attempted to divide by zero. at System.Management.Automation.ParserOps.polyDiv(Execu val, Object rval) TargetSite : System.Collections.ObjectModel.Collection`1[System.Managem

ctions.IEnumerable) HelpLink : Source : System.Management.Automation

Discussion

The PowerShell $error variable always holds the list of errors generated so far in the current shell session. This list includes both terminating and nonterminating errors.

By default, PowerShell displays error records in a customized view. If you want to view an error in a table or list (through the FormatTable or FormatList cmdlets), you must also specify the –Force option to override this customized view.

If you want to display errors in a more compact manner, PowerShell supports an additional view called CategoryView that you set through the $errorView preference variable:

PS >GetChildItem IDoNotExist GetChildItem : Cannot find path 'C:\IDoNotExist' because it does not exist. At line:1 char:4

+ GetChildItem IDoNotExist PS >$errorView = "CategoryView" PS >GetChildItem IDoNotExist ObjectNotFound: (C:\IDoNotExist:String) [GetChildItem], ItemNotFoundExcep tion

To clear the list of errors, call the Clear() method on the $error list:

PS >$error.Count 2 PS >$error.Clear() PS >$error.Count 0

Compare the Output of Two Commands

Problem

You want to compare the output of two commands.

Solution

To compare the output of two commands, store the output of each command in variables, and then use the CompareObject cmdlet to compare those variables:

PS >notepad PS >$processes = GetProcess PS >StopProcess ProcessName Notepad PS >$newProcesses = GetProcess PS >CompareObject $processes $newProcesses

InputObject SideIndicator

System.Diagnostics.Process (notepad) =

Discussion

The solution shows how to determine which processes have exited between the two calls to GetProcess. The SideIndicator of = tells us that the process was present in the left collection ($processes) but not in the right ($newProcesses).

For more information about the CompareObject cmdlet, type GetHelp CompareObject.

Add Information to the End of a File in Windows PowerShell

Problem

You want to redirect the output of a pipeline into a file but add the information to the end of that file.

Solution

To redirect the output of a command into a file, use either the Append parameter of the OutFile cmdlet, or one of the appending redirection operators. Both support options to append text to the end of a file.

OutFile:

GetChildItem | OutFile Append files.txt

Redirection operators:

GetChildItem >> files.txt

Discussion

The OutFile cmdlet and redirection operators share a lot in common—and for the most part, you can use either.

Find Items in an Array That Match a Value

Problem

You have an array and want to find all elements that match a given item or term— either exactly, by pattern, or by regular expression.

Solution

To find all elements that match an item, use the –eq, like, and –match comparison operators:

PS >$array = "Item 1","Item 2","Item 3","Item 1","Item 12" PS >$array eq "Item 1" Item 1 Item 1 PS >$array like "*1*" Item 1 Item 1 Item 12 PS >$array match "Item .." Item 12

Discussion

The eq, like, and match operators are useful ways to find elements in a collection that match your given term. The –eq operator returns all elements that are equal to your term, the –like operator returns all elements that match the wildcard given in your pattern, and the –match operator returns all elements that match the regular expression given in your pattern.

Navigate the Registry

Problem

You want to navigate and explore the Windows Registry.

Solution

Use the SetLocation just as you would navigate the filesystem to navigate the registry:

PS >SetLocation HKCU: PS >SetLocation \Software\Microsoft\Windows\CurrentVersion\Run PS >GetLocation

Path

HKCU:\Software\Microsoft\Windows\CurrentVersion\Run

Discussion

PowerShell lets you navigate the Windows Registry in exactly the same way that you navigate the filesystem, certificate drives, and other navigationbased providers. Like these other providers, the registry provider supports the SetLocation cmdlet (with the standard aliases of sl, cd, and chdir), PushLocation (with the standard alias pushd), PopLocation (with the standard alias popd), and more.

Automate Wizard-Guided Tasks

Problem

You want to automate tasks you normally complete through one of the wizards in the Exchange Management Console.

Solution

To automate a wizardguided task, complete the wizard in the Exchange Management Shell, and then save the script it displays for future reference.

Discussion

Since the Exchange Management Console user interface uses PowerShell cmdlets to accomplish all its actions, every wizard displays the PowerShell script that you could run to accomplish the same task.

Launch the Exchange Management Console, and then click Recipient Configuration

➝ Mailbox. In the Actions pane, click New Mailbox. Select User Mailbox ➝ Existing User ➝ Preeda Ola. Type preeda as an alias, and then complete the wizard. The final step provides the PowerShell command that you can use next time.

Windows PowerShell

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.

These help topics introduces PowerShell from the perspective of its interactive shell.

Write a Script in PowerShell

Problem

You want to store your commands in a script, so that you can share them or reuse them later.

Solution

To write a PowerShell script, create a plaintext file with your editor of choice. Add your PowerShell commands to that script (the same PowerShell commands you use from the interactive shell) and then save it with a .ps1 extension.

Discussion

One of the most important things to remember about PowerShell is that running scripts and working at the command line are essentially equivalent operations. If you see it in a script, you can type it or paste it at the command line. If you typed it on the command line, you can paste it into a text file and call it a script.

Once you write your script, PowerShell lets you call it in the same way that you call other programs and existing tools. Running a script does the same thing as running all the commands in that script.

PowerShell introduces a few features related to running scripts and tools that may at first confuse you if you aren’t aware of them. For more information about how to call scripts and existing tools.

The first time you try to run a script in PowerShell, PowerShell provides the error message:

File c:\tools\myFirstScript.ps1 cannot be loaded because the execution of scri pts is disabled on this system. Please see "gethelp about_signing" for more d etails. At line:1 char:12

+ myFirstScript

Since relatively few computer users write scripts, PowerShell’s default security policies prevent scripts from running. Once you begin writing scripts, though, you should configure this policy to something less restrictive.

When it comes to the filename of your script, picking a descriptive name is the best way to guarantee that you will always remember what that script does—or at least have a good idea. This is an issue that PowerShell tackles elegantly, by naming every cmdlet in the VerbNoun pattern: a command that performs an action (verb)onan item (noun). As an example of the usefulness of this philosophy, consider the names of typical Windows commands given in Example 101:

Example 101. The names of some standard Windows commands

PS >dir $env:WINDIR\System32\*.exe | SelectObject Name

Name

accwiz.exe actmovie.exe ahui.exe alg.exe append.exe arp.exe asr_fmt.exe asr_ldm.exe asr_pfu.exe at.exe atmadm.exe attrib.exe (...)

Compare this to the names of some standard Windows PowerShell cmdlets given in Example 102.

Example 102. The names of some standard Windows PowerShell cmdlets

PS >GetCommand | SelectObject Name

Name

AddContent AddHistory AddMember AddPSSnapin ClearContent ClearItem ClearItemProperty ClearVariable CompareObject ConvertFromSecureString ConvertPath ConvertToHtml (...)

As an additional way to improve discovery, PowerShell takes this even further with the philosophy (and explicit goal) that “you can manage 80 percent of your system with less than 50 verbs.As you learn the standard verbs for a concept (such as Get as the standard verb of Read, Open, and so on), you can often guess the verb of a command as the first step in discovering it.

When you name your script (especially if you intend to share it), make every effort to pick a name that follows these conventions.

Find Files That Match a Pattern in PowerShell

Problem

You want to get a list of files that match a specific pattern.

Solution

Use the GetChildItem cmdlet for both simple and advanced wildcard support:

    • To find all items in the current directory that match a PowerShell wildcard, sup
    • ply that wildcard to the GetChildItem cmdlet: GetChildItem *.txt
    • To find all items in the current directory that match a providerspecific filter, sup
    • ply that filter to the –Filter parameter: GetChildItem –Filter *~2*
    • To find all items in the current directory that do not match a PowerShell wild
    • card, supply that wildcard to the –Exclude parameter: GetChildItem Exclude *.txt
  • To find all items in subdirectories that match a PowerShell wildcard, use

the –Include and –Recurse parameters: GetChildItem –Include *.txt –Recurse

• To find all items in subdirectories that match a providerspecific filter, use the

–Filter and –Recurse parameters: GetChildItem –Filter *.txt –Recurse

• To find all items in subdirectories that do not match a PowerShell wildcard, use the –Exclude and –Recurse parameters:

GetChildItem –Exclude *.txt –Recurse Use the WhereObject cmdlet for advanced regular expression support:

    • To find all items with a filename that matches a regular expression, use the
    • WhereObject cmdlet to compare the Name property to the regular expression: GetChildItem | WhereObject { $_.Name match '^KB[09]+\.log$' }
  • To find all items with a directory name that matches a regular expression, use the WhereObject cmdlet to compare the DirectoryName property to the regular expression:

GetChildItem –Recurse | WhereObject { $_.DirectoryName match 'Release' }

• To find all items with a directory name or filename that matches a regular expression, use the WhereObject cmdlet to compare the FullName property to the regular expression:

GetChildItem –Recurse | WhereObject { $_.FullName match 'temp' }

Discussion

The GetChildItem cmdlet supports wildcarding through three parameters:

Path The Path parameter is the first (and default) parameter. While you can enter simple paths such as ., C:\ or D:\Documents, you can also supply paths that include wildcards—such as *, *.txt, [az]???.log, or even C:\win*\*.N[af]?\ F*\v2*\csc.exe.

Include/Exclude The –Include and –Exclude parameters act as a filter on wildcarding that happens on the Path parameter. If you specify the –Recurse parameter, the –Include and –Exclude wildcards apply to all items returned.

The most common mistake with the –Include parameter comes when you use it against a path with no wildcards. For example, this doesn’t seem to produce the expected results:

GetChildItem $env:WINDIR Include *.log

That command produces no results, as you have not supplied an item wildcard to the path. Instead, the correct command is:

GetChildItem $env:WINDIR\* Include *.log

Filter The –Filter parameter lets you filter results based on the providerspecific filtering language of the provider from which you retrieve items. Since PowerShell’s wildcarding support closely mimics filesystem wildcards, and most people use the –Filter parameter only on the filesystem, this seems like a redundant (and equivalent) parameter. ASQL provider, however, would use SQL syntax in its –Filter parameter. Likewise, an Active Directory provider would use LDAP paths in its –Filter parameter.

Although it may not be obvious, the filesystem provider’s filtering language is not exactly the same as the PowerShell wildcard syntax. For example, the Filter parameter matches against the short filenames, too:

PS >GetChildItem | SelectObject Name

Name

A Long File Name With Spaces Also.txt A Long File Name With Spaces.txt

PS >GetChildItem *1* | SelectObject Name PS >GetChildItem Filter *1* | SelectObject Name

Name

A Long File Name With Spaces.txt

On the other hand, PowerShell’s wildcard syntax supports far more than the filesystem’s native filtering language. For more information about the PowerShell’s wildcard syntax, type GetHelp About_WildCard.

When you want to perform filtering even more advanced than what PowerShell’s wildcarding syntax offers, the WhereObject cmdlet provides infinite possibilities. For example, to exclude certain directories from a search:

GetChildItem Rec | WhereObject { $_.DirectoryName notmatch "Debug" }

or, to list all directories:

GetChildItem | WhereObject { $_.PsIsContainer }

Since the syntax of the WhereObject cmdlet can sometimes be burdensome for simple queries, the CompareProperty script provides an attractive alternative:

GetChildItem Rec | CompareProperty DirectoryName notmatch Debug For a filter that is difficult (or impossible) to specify programmatically, the SelectFilteredObject script lets you interactively filter the output.

Because of PowerShell’s pipeline model, an advanced file set generated by GetChildItem automatically turns into an advanced file set for other cmdlets to operate on:

PS >GetChildItem Rec | WhereObject { $_.Length gt 20mb } | >> SortObject Descending Length | SelectFilteredObject | >> RemoveItem WhatIf >> What if: Performing operation "Remove File" on Target "C:\temp\backup092300 .zip". What if: Performing operation "Remove File" on Target "C:\temp\sptricking_ iT2.zip". What if: Performing operation "Remove File" on Target "C:\temp\slime.mov". What if: Performing operation "Remove File" on Target "C:\temp\helloworld. mov".

For more information about the GetChildItem cmdlet, type GetHelp GetChildItem. For more information about the WhereObject cmdlet, type GetHelp WhereObject.

Enable or Disable the Windows Firewall

Problem

You want to enable or disable the Windows Firewall.

Solution

To manage the Windows Firewall, use the LocalPolicy.CurrentProfile. FirewallEnabled property of the HNetCfg.FwMgr COM object:

PS >$firewall = NewObject com HNetCfg.FwMgr PS >$firewall.LocalPolicy.CurrentProfile.FirewallEnabled = $true PS >$firewall.LocalPolicy.CurrentProfile.FirewallEnabled True

Discussion

The HNetCfg.FwMgr COM object provides programmatic access to the Windows Firewall in Windows XP SP2 and later. The LocalPolicy.CurrentProfile property provides the majority of its functionality.

For more information about managing the Windows Firewall through its COM API, visit http://msdn.microsoft.com and search for “Using Windows Firewall API.” The documentation provides examples in VBScript but gives a useful overview of the functionality available.

If you are unfamiliar with the VBScriptspecific portions of the documentation, the Microsoft Script Center provides a useful guide to help you convert from VBScript to PowerShell. You can find that document at: http://www.microsoft.com/technet/ scriptcenter/topics/winpsh/convert/default.mspx.