Use the PowerShell Passthru Parameter and Get Back Objects

Summary: Learn how to use the passthru parameter in Windows PowerShell to return objects from commands and allow more management tools.


Hey, Scripting Guy! QuestionHey, 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?



Hey, Scripting Guy! AnswerHello 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.

Image of command and associated object

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 | Stop-Process

The commands and associated output are shown in the following figure.

Image of commands and associated output

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.

Image of command and associated output

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 | Remove-Item

The commands and associated output are shown in the following figure.

Image of commands and associated output

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.

Image of commands and associated output


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, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.


Ed Wilson, Microsoft Scripting Guy



Comments (7)

  1. Klaus Schulte says:

    Hi Ed,

    this is quite interesting!

    I rarely used the -passthrough parameter and in fact I might have even forgotten about it if you hadn't reminded me by now 🙂

    Getting hold of a handle to objects created by some cmldlets is a nice feature that let's us control the object effortlessly!

    There are a lot of situations where you have to get control over already existing objects which maybe a pain or even impossible in certain situations. In general it is always a good idea to keep a handle to an object created by us unless we definitely know, that this is not needed during the lifetime of the object.


  2. JV says:

    Consider the following:

    if(Import-Module ace){'true'}else{'false'}

    if(Import-Module ace -passthru){'true'}else{'false'}

  3. Raj Kumar says:

    This is quite good.

  4. David Nogue says:

    Good night Ed,

    Thank you very mucho for this amazing explanation, it’s all really clear.


  5. Tesfaye Hiwot says:

    Awesome, cleared that up for me real quick! Looking forward to my week of PowerShell training starting on Monday.

  6. Mikel V. says:

    Hi Ed,
    gcm -CommandType 8 | ? {$_.definition -match ‘passthru’} doesn’t show all the cmdlets, at least i miss one of them: out-gridview

  7. A. Kantchev says:

    Hi Ed,
    searching for a one-liner for renaming a host I stuck on this post. Thanks to the mentioned and explained Where-Object ( ~= ?) – which I totally forgot how to use – I got myself the command I was looking for:

    >> Get-WmiObject -Class Win32_ComputerSystem | ? { $_.rename("new-hostname") }