There are times when you do not need to display data in the PowerShell console, but it still wants to show up anyways. A good case is when you are trying to add items to a collection, such as an arraylist.
$list = New-Object System.Collections.ArrayList $list.Add('Something') $list.Add('Else')
If you are writing some code that sends data to another command or to a file, you do not want this to pollute the pipeline. The approach is to send this data to a NULL destination and in PowerShell, there are a few different approaches that I commonly see.
- Out-Null
- Typically used via the pipeline to send data to a NULL destination; but it does have the –InputObject parameter to use as well.
- $Null = <code>
- $Null is an automatic variable that when used to save output, actually gets rid of the output
- ‘Stuff’ > $Null
- Same as doing $Null=
- [void]
- Common .Net type used in C# that specifies a return value type for a method that does not return a value.
Here is a quick demonstration of each of these in action.
$list = New-Object System.Collections.ArrayList $list.Add('Something') | Out-Null Out-Null -InputObject $list.Add('Else') $Null = $list.Add('New') [void]$list.Add('Here') $list.Add('Today') > $Null
Here we see that all of the return values that normally would be showing up has in fact been sent to NULL and is no longer showing up on the console (and in turn will not pollute the pipeline).
So with these options, which is actually the fastest approach to all of this? Well, lets find out!
$Time = (1..1E4 | ForEach { (Measure-Command {Get-Date | out-null}).TotalMilliseconds } | Measure-Object -Average).Average [pscustomobject]@{ Type = '| Out-Null' TimeMs = [math]::Round($Time,2) } $Time = (1..1E4 | ForEach { (Measure-Command {out-null -InputObject Get-Date}).TotalMilliseconds } | Measure-Object -Average).Average [pscustomobject]@{ Type = 'Out-Null -InputObject' TimeMs = [math]::Round($Time,2) } $Time = (1..1E4 | ForEach { (Measure-Command {Get-Date > $Null}).TotalMilliseconds } | Measure-Object -Average).Average [pscustomobject]@{ Type = '> $Null' TimeMs = [math]::Round($Time,2) } $Time = (1..1E4 | ForEach { (Measure-Command {$Null = Get-Date}).TotalMilliseconds } | Measure-Object -Average).Average [pscustomobject]@{ Type = '$Null=' TimeMs = [math]::Round($Time,2) } $Time = (1..1E4 | ForEach { (Measure-Command {[void](Get-Date)}).TotalMilliseconds } | Measure-Object -Average).Average [pscustomobject]@{ Type = '[void]' TimeMs = [math]::Round($Time,2) }
The winner by a nose is [void]. Using $Null (both approaches) is pretty close as well and in fact these two could be interchanged without much notice. The use of Out-Null with the pipeline is the slowest and its InputObject parameter is 3rd.
So with that, we have a few ways to redirect unneeded output without sending data down the pipeline that is not needed.
Pingback: out-null | My Blog on Powershell
Hi,
I really like this type of post ! Thank you !
I tried your script and in two different computer, I do not have exactly the same results :
In the first (Core i5-4570 3.2GHz – 16Go RAM) :
Type TimeMs
—- ——
| Out-Null 0,07
Out-Null -InputObject 0,04
In the second (VM 2 core of Xeon E5504 2GHz – 12Go RAM) :
Type TimeMs
—- ——
| Out-Null 0,23
Out-Null -InputObject 0,13
Pingback: Quick Hits: Adding Items to an Array and a Look at Performance | Learn Powershell | Achieve More
I really like this style of post. Comparing the various ways to do a thing is so practical and helpful.
I concur. These … ‘Optimization’ articles are quite nice. Keep it up 🙂
Don’t forget: foo > $null
Nice! Completely forgot about that one. I’ll be sure to add it tonight or tomorrow.