Do-Something | Set-Variable Foo
Especially for stuff that generates a lot of output, I’ve learned to pipe commands to Set-Variable. It’s no different than starting the command with “$foo =”, such as $foo = Do-Something, However, I like ‘building’ a command pipeline on the command line, adding a new Where-Object here, a Foreach-Object there, and throttling the output with Select-Object –First 1 while I’m testing. When it’s good to go, I can hit [Home] and add the variable assignment, but I often find that I will keep with my “add a piped cmdlet” mindset and change the Select-Object –First 1 to Set-Variable foo.
As such, my shell is often littered with $foo, $bar, $baz, etc. That’s great while I’m working, but it doesn’t give me an idea of what generated the command should I come back to this shell after a time, such as a meeting or a meal.
Here’s a function (and alias) that can save a lot of typing and brainpower:
function Save-ToVariable
{
param ( [string]$Name = $null );
$line = $MyInvocation.Line -replace '^\s*';
if (!$Name)
{
$name = $line -replace '[\s\|].*' -replace '\W';
if (!$name) { $name = $line -replace '\s' -replace '\W.*'; }
if (!$name) { $name = "commandID_$((Get-History -Count 1).Id + 1 )_output"; }
$name = "__$name";
} # if (!$Name)
$input |
% {
$_;
} |
Set-Variable -Name $Name -Scope Global;
Write-Host -ForegroundColor Green -BackgroundColor Black "`$$Name populated with output '$line'"
} # function Save-ToVariable
New-Alias -Name svt -Value Save-ToVariable -Description 'Save STDIN to variable' -Scope Global -Force;
This allows me to simply append “|svt”, and it will auto-generate the variable name based on the first command in the pipeline, if I didn’t specify one with the –Name parameter. If it can't generate the name, it will create one based on the command history's ID number.