Is it possible to use the -WhatIf argument when executing external commands? I want to be able to run a script with -WhatIf and have it print out a full list of all the external commands and arguments it's going to run without actually running them.
I've tried doing stuff like the following:
Function Invoke-Checked
{
param([ScriptBlock]$s)
if ($PSCmdlet.ShouldProcess($s.ToString(), "Execute"))
{
Invoke-Command $s
}
}
But that won't expand any variables that are present in the scriptblock - doing something like:
$s = { & dir $test }
Invoke-Checked $s
just prints
Performing the operation "Execute" on target " & dir $test ".
not particularly helpful.
Is there any way to do what I want?
First of all - you need to make sure that your 'wrapper' function supports WhatIf.
Another thing: you can expand the scriptBlock, but I'm not really convinced that is smart thing to do: e.g. if $test = 'Some path with spaces'
, it would stop working after expansion.
That being said: here are two options that work for me: using GetNewClosure()
method on scriptBlock, and expanding whole thing:
function Invoke-ExpandedChecked {
[CmdletBinding(
SupportsShouldProcess = $true,
ConfirmImpact = 'Medium'
)]
param([ScriptBlock]$ScriptBlock)
$expanded = $ExecutionContext.InvokeCommand.ExpandString($ScriptBlock)
$script = [scriptblock]::Create($expanded)
if ($PSCmdlet.ShouldProcess($script.ToString(), "Execute"))
{
& $script
}
}
function Invoke-Checked {
[CmdletBinding(
SupportsShouldProcess = $true,
ConfirmImpact = 'Medium'
)]
param([ScriptBlock]$ScriptBlock)
$newClosure = $ScriptBlock.GetNewClosure()
if ($PSCmdlet.ShouldProcess($newClosure.ToString(), "Execute"))
{
& $newClosure
}
}
$test = '.\DSCDemo.ps_'
$s = { cmd /c dir $test}
Invoke-Checked $s -WhatIf
Invoke-Checked $s
Invoke-ExpandedChecked $s -WhatIf
Invoke-ExpandedChecked $s
And an example of results for path with spaces:
$test = 'C:\Program Files'
Invoke-Checked $s
Invoke-ExpandedChecked $s
Works fine for one with new enclosure. With expanded:
cmd : File Not Found
At line:1 char:2
+ cmd /c dir C:\Program Files