Summary: Learn how to use the passthru parameter in Windows PowerShell to return objects from commands and allow more management tools.
Hey, Scripting Guy! I have got a rather curious question that I have not been able to find anything about. What is up with the passthru parameter? I mean, I see it on some commands, and not on other commands. Also, I have no idea what it really does, but when I see it, it seems to do cool stuff. But when I try to use it, all I do is get errors. Is this some secret Microsoft trick?
—ML
Hello ML,
Microsoft Scripting Guy Ed Wilson here. This is an exciting day! Yesterday, I announced that Pittsburgh will have its first PowerShell Users Group meeting on December 13, 2011. Today, I get to announce that Charlotte, North Carolina, has also formed a PowerShell Users Group. They will have their first meeting in January.
ML, you are right, the passthru parameter seems to be mysterious. Perhaps a few examples will show how it works. First of all, passthru is not one of the common parameters, and it does not exist everywhere. The common parameters are:
- -Verbose
- -Debug
- -WarningAction
- -WarningVariable
- -ErrorAction
- -ErrorVariable
- -OutVariable
- -OutBuffer
There are also two parameters that are available when a command will change system state (such as Start-Process, Stop-Process). The two risk mitigation parameters are:
- -WhatIf
- -Confirm
To find all of the Windows PowerShell cmdlets that have a passthru parameter, I use the Get-Command cmdlet. I then pipe the resulting cmdletInfo object to the Where-Object and look for matches on passthru. The resulting command is shown here (in the following command, gcm is an alias for the Get-Command cmdlet; a commandtype of 8 is a cmdlet; I use the ? as an alias for the Where-Object cmdlet):
gcm -CommandType 8 | ? {$_.definition -match 'passthru'}
When I pipe the results from this command on Windows PowerShell 2.0 with no added modules or snap-ins, it returns 44. This means that, by default, there are 44 cmdlets that use a passthru parameter.
So, what does passthru do for me? For example, there are many Windows PowerShell cmdelts that simply work, and they do not return any data. An example is the Start-Process cmdlet. Here is an example of using the Start-Process cmdlet to start Notepad. Notice, that the line following the command is empty; this is because nothing is returned from the command:
PS C:\> Start-Process notepad
PS C:\>
If I add the passthru switched parameter to the end of the command, a Process object returns to the Windows PowerShell console. The nice thing about this is that I can use this Process object to track and work with the newly created instance of Notepad. The command to start the Notepad process and to return a Process object to the Windows PowerShell console is shown here:
Start-Process notepad –PassThru
The command and associated object is shown in the following figure.
If I store the returned Process object in a variable, I can then use it to obtain additional information about the process. In the following code, I store the returned Process object in a variable named $notepad. I then examine the start time of the process, and finally I stop the process by piping the Process object to the Stop-Process cmdlet:
$notepad = Start-Process notepad –PassThru
$notepad.StartTime
$notepad | Stop-Process
The commands and associated output are shown in the following figure.
Another cmdlet that contains a passthru parameter is the Copy-Item cmdlet. When I use the cmdlet to copy a file from one location to another location, nothing returns to the Windows PowerShell console. In the following command, I copy the a.txt file from the c:\fso folder to the C:\fso31 folder. Nothing is returned to the Windows PowerShell console:
Copy-Item -path C:\fso\a.txt -Destination C:\fso31
If I would like to see information about the copied file, I use the passthru switched parameter. The revised syntax is shown here:
Copy-Item -path C:\fso\a.txt -Destination C:\fso31 –PassThru
The command and associated output are shown in the following figure.
The returned object is an instance of a FileInfo object. To work with the file, I store the returned FileInfo object in a variable named $text. I can now directly access any of the properties of the FileInfo object. My favorite property is the FullName property that points to the complete file name as well as the path to the file. Once I am finished working with the file, I can easily remote it by piping the FileInfo object stored in the $Text variable. These commands are shown here:
$Text = Copy-Item -path C:\fso\a.txt -Destination C:\fso31 -PassThru
$text.GetType()
$text.FullName
$text | Remove-Item
The commands and associated output are shown in the following figure.
By default, when using the Import-Module cmdlet to import a module into the current Windows PowerShell session, nothing is returned. In the following example, I import my Unit Conversion Module; nothing appears on the Windows PowerShell console line:
PS C:\> Import-Module conv*
PS C:\>
Now, I will remove the unit conversion module, and try it again. This time, I will use the passthru parameter. The revised command results in a PSModuleInfo object returned to the Windows PowerShell console. This is useful because it tells the name of the module imported, and it lists the commands exported via the module. The commands and associated output are shown in the following figure.
Well, ML, as you can see, using the passthru parameter forces Windows PowerShell to go ahead and pass newly created or modified objects instead of hiding them. By knowing when to use and not to use the parameter, great flexibility is gained.
That is all there is to using the passthru parameter. Join me tomorrow for more cool stuff about Windows PowerShell.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy