Users can define the length of a pipeline (that is, the number of commands in a single pipeline is unlimited). Here’s an example for a more complex pipeline:
Get-ChildItem h:\Documents –r -filter *.doc
| Where-Object { $_.Length -gt 40000 }
| Select-Object Name, Length
| Sort-Object Length
| Format-List
Get-ChildItem identifies all Microsoft Word files in the directory h:\Documents and its children. The second commandlet (Where-Object) reduces the result to those objects where the property Lengthis greater than 40000. Select-Object cuts all properties from Name and Length. The fourth commandlet in the pipeline sorts the expression according to the property Length. Finally, the last commandlet creates a list format.
The sequence of the single commands, however, is not optional. You cannot, for example, put sorting after formatting in the preceding com-mand; even though there is an object after the formatting, this object rep-resents a text stream. Where-Object and Sort-Object could be exchanged; for reasons of resource use, however, it is wiser to limit the out-put first and sort the limited list after this.
Commandlet #1
Output Pipeline Input Pipeline Output Pipeline Input Pipeline
UpstreamCommandlet DownstreamCommandlet
get-service | Where-Object {$_.status -eq "running"} | out-file
. NET Objects of Type
System ServiceProcess.. ServiceController
Selection
Storing
You can access all properties and methods of .NET objects that have been placed by an earlier commandlet in the pipeline. Members of the objects can be used either via parameters of the commandlets (for exam-ple, in Sort-Object Length) or by an explicit reference to the recent pipeline object ($_) in a loop or condition (for example, Where-Object {
$_.Length -gt 40000 }).
NOTE Not all sequences of commandlets make sense. Some sequences aren’t even valid. A commandlet may expect certain kinds of input objects. Therefore, you should use commandlets that can process any kind of entry object.
Output
A regular commandlet should not create its own screen output, but should put a number of objects in the pipeline. Only certain commandlets are pre-defined to create an output, including the following:
■ Out-Default Standard output according to WPS configuration (DotNetTypes.Format.ps1xml).
■ Out-Host Same as Out-Default with additional option for pagewise output.
■ Out-Null Pipeline objects are not transferred.
■ Format-Wide Two-column list (see Figure 3.3)
■ Format-List Detailed list (see Figure 3.4)
■ Format-Table Table (see Figure 3.5)
NOTE Unfortunately, after the beta versions, Microsoft removed some com-mandlets that offered an output on a higher abstraction level. Therefore, the fol-lowing commandlets are not available in WPS 1.0:
■ Windows Forms data grid (Out-Grid)
■ Excel chart (Out-Excel)
■ E-mail (Out-Email)
■ Column diagram (Out-Chart)
However, Microsoft has announced that at least a commandlet named Out-GridViewwill be available in WPS 2.0.
Output 49
3.PIPELINING
Figure 3.3 Format-Wideoutput
Figure 3.4 Format-Listoutput
Output 51
3.PIPELINING
Figure 3.5 Format-Tableoutput
Standard Output
When you do not name a format function at the end of a pipeline, WPS automatically uses the commandlet Out-Default. Out-Default uses a predefined output standard that is stored in DotNetTypes.Format.
ps1xml in the installation directory of WPS. There, you can get the infor-mation that, for example, type System.Diagnostics.Processproduces an output in an eight-column table (see Figure 3.6).
Pagewise Output
Often, output is too long to be presented on one screen page. Some out-put is even longer than the standard buffer of the WPS window (for exam-ple,Get-Command | Get-Help). You enforce the pagewise output with the parameter –p in the Out-Host commandlet. In this case, Out-Host has to be written as follows:
Get-Command | Get-Help | Out-Host -p
Figure 3.6 Clipping from the description of the standard output for type System.Diagnostics.Processin DotNetTypes.Format.ps1xml
Restricting the Output
The output commands allow specifications of object properties to be pre-sented. For example
Get-Process | Format-Table -p id,processname,workingset
creates a table of processes with process ID, name of processes, and use of space. Names of properties can also be abbreviated with placeholder
*, as follows:
Get-Process | Format-Table -p id,processn*,working*
NOTE You can get the same output when you use Select-Object: Get-Process | Select-Object id, processname,
➥workingset | Format-Table
Output of Single Values
To display specific text or the content of a variable, you just have to write this on the console (see Figure 3.7). Alternatively, you can use the com-mandletsWrite-Host, Write-Warn, and Write-Error. The command-letsWrite-WarnandWrite-Errorcreate highlighted output.
With Write-Host, you can specify colors:
Write-Host "Hello Holger" -foregroundcolor red -backgroundcolor
➥white
Output 53
3.PIPELINING
Figure 3.7 Output of constants and variables
To mix literals and variables in an output, you must either link them with +
$a + " can be reached at " + $b + ".
➥This information is dated: " + $c + "."
or integrate the variables directly in the string. In contrast to other lan-guages, WPS evaluates the string and searches for he dollar sign ($) (vari-able resolution):
"$a can be reached at $b. This information is dated: $c."
You can also use placeholders and format markers common in .NET (for example, d = date in the long version). In addition, include the param-eter –fafter the string. Based on the format possibilities, this option is the most powerful:
"{0} can be reached at {1}.
➥This information is dated: {2:d}." -f $a, $b, $c
The following list summarizes the three equivalent possibilities:
$a = "Holger Schwichtenberg"
$b = "[email protected]"
$c = get-Date
# possibility 1
$a + " can be reached at " + $b + ".
➥This information is dated: " + $c + "."
# possibility 2
"$a can be reached at $b. This information is dated: $c."
# possibility 3
"{0} can be reached at {1}.
➥This information is dated: {2:D}." -f $a, $b, $c
Listing 3.1 Formatted Output (of the preceding script)
Holger Schwichtenberg can be reached at [email protected].
➥This information is dated: 14.09.2007 16:53:13.
Holger Schwichtenberg can be reached at [email protected].
➥This information is dated: 14.09.2007 16:53:13.
Holger Schwichtenberg can be reached at [email protected].
➥This information is dated: Thursday, 14. September 2007.
Suppressing the Output
Because the standard output is in place, all return values of commandlet pipelines also display. This is not always desired.
You have three alternatives to suppress the output:
1. At the end of the pipeline, use Out-Null:
Commandlet | Commandlet | Out-Null
2. Transfer the result of the pipeline to a variable:
$a = Commandlet | Commandlet
3. Convert the result of the pipeline to type [void]:
[void] (Commandlet | Commandlet)
Other Output Functions
The following list shows further output possibilities in WPS 1.0:
■ With the commandlet Out-Printer, send the output to the printer.
■ With Out file, you can write the content to a file.
■ Output the process list to the standard printer:
Get-Process | Out-Printer
■ Output the process list to a specific printer:
Get-Process | Out-Printer "HP LaserJet PCL6 on E02"
■ Output the process list in a text file (overwriting existing content):
Get-Process | Out file "c:\temp\processlist.txt"
Output 55
3.PIPELINING
■ Output the process list in a text file (adding to existing content):
Get-Process | Out file "c:\temp\processlist.txt"
-Append