You’re writing a series of PowerShell functions that are to be used in a pipeline (pseudo code):
$Output = Get-Data | Where-Data
and you want to grab the output of each command but not interfere with the pipeline throughput? Say you want to see what Get-Data
is getting and passing into Where-Data
Well, we’re going to look at implementing something close to the built in ErrorVariable
and WarningVariable
I’ve written about before https://stuart-moore.com/powershell-using-errorvariable-and-warningvariable/. We’ll start with this pipeline:
$output = Get-Data -Path 'C:\dbatools\standby' | Where-Object {$_.Name -like 'Restore-DbaDatabase.ps1'}
where we’ll have the following Get-Data
function:
function Get-Data{ [CmdletBinding()] param( [string]$Path ) Process { Get-ChildItem -Path $Path } }
So nothing too fancy, really just a wrapper around Get-ChildItem
, but it gets me a decent data set that I can then filter. Now if this function was also doing some filtering of the data and we weren’t seeing the output we wanted in $ouput
then it would be nice to grab the data before it’s passed on. To do this we’ll take a variable name as a parameter and then assign than within the function using Set-Variable
:
function Get-Data{ [CmdletBinding()] param( [string]$Path, [string]$ReturnVar ) Process { $Data = Get-ChildItem -Path $Path if ($ReturnVar){ Set-Variable -Name $ReturnVar -Value $Data -Scope Global } $Data } } $output = Get-Data -Path 'C:\dbatools\standby' -ReturnVar ReturnVar | Where-Object {$_.Name -eq 'PointInTime20170707182205.bak'} $output $ReturnVar
Things to note in the function:
we use Set-Variable
as this copes better if the variable already exists. Be careful of this as you will clobber the existing variable
Wrap Set-Variable
in an if
block, or it’ll throw when passed an empty variable name (if you wanted to be really solid, you’d want to put some validation around the parameter to make sure you only take in legal variable names.
We set the scope of the variable to Global
to make sure we can see it outside of our command or module.
If you have a large function with lots of points where you’d like the option to return data from various points for future debugging, then you can always have multiple return variable parameters and populate them as you need them.