可以使用 -WhatIf 和调用运算符 (&) 吗?
Possible to use -WhatIf and the invocation operator (&)?
是否可以在执行外部命令时使用-WhatIf参数?我希望能够 运行 带有 -WhatIf 的脚本,并让它打印出所有外部命令和参数的完整列表 运行 而实际上 运行 宁他们。
我尝试过如下操作:
Function Invoke-Checked
{
param([ScriptBlock]$s)
if ($PSCmdlet.ShouldProcess($s.ToString(), "Execute"))
{
Invoke-Command $s
}
}
但这不会扩展脚本块中存在的任何变量 - 执行如下操作:
$s = { & dir $test }
Invoke-Checked $s
只是打印
Performing the operation "Execute" on target " & dir $test ".
不是特别有用。
有什么方法可以做我想做的事吗?
首先 - 您需要确保您的 'wrapper' 函数支持 WhatIf。
另一件事:您可以扩展 scriptBlock,但我不太相信这样做是明智的:例如如果$test = 'Some path with spaces'
,展开后会停止工作
话虽这么说:这里有两个对我有用的选项:在 scriptBlock 上使用 GetNewClosure()
方法,并扩展整个东西:
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
以及带空格的路径的结果示例:
$test = 'C:\Program Files'
Invoke-Checked $s
Invoke-ExpandedChecked $s
对于带有新外壳的人来说效果很好。随着展开:
cmd : File Not Found
At line:1 char:2
+ cmd /c dir C:\Program Files
我将把这个问题解释为“我如何将 -whatif 与 运行 外部命令一起使用?”,因为这就是我发现这个问题的方式。
# myscript.ps1
[cmdletbinding(SupportsShouldProcess=$True)]
Param($path) # put Param() if no parameters
if ($pscmdlet.ShouldProcess($Path, 'creating folder')) { # not -whatif
cmd /c mkdir $path
}
.\myscript foo -whatif
What if: Performing the operation "creating folder" on target "foo".
是否可以在执行外部命令时使用-WhatIf参数?我希望能够 运行 带有 -WhatIf 的脚本,并让它打印出所有外部命令和参数的完整列表 运行 而实际上 运行 宁他们。
我尝试过如下操作:
Function Invoke-Checked
{
param([ScriptBlock]$s)
if ($PSCmdlet.ShouldProcess($s.ToString(), "Execute"))
{
Invoke-Command $s
}
}
但这不会扩展脚本块中存在的任何变量 - 执行如下操作:
$s = { & dir $test }
Invoke-Checked $s
只是打印
Performing the operation "Execute" on target " & dir $test ".
不是特别有用。
有什么方法可以做我想做的事吗?
首先 - 您需要确保您的 'wrapper' 函数支持 WhatIf。
另一件事:您可以扩展 scriptBlock,但我不太相信这样做是明智的:例如如果$test = 'Some path with spaces'
,展开后会停止工作
话虽这么说:这里有两个对我有用的选项:在 scriptBlock 上使用 GetNewClosure()
方法,并扩展整个东西:
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
以及带空格的路径的结果示例:
$test = 'C:\Program Files'
Invoke-Checked $s
Invoke-ExpandedChecked $s
对于带有新外壳的人来说效果很好。随着展开:
cmd : File Not Found
At line:1 char:2
+ cmd /c dir C:\Program Files
我将把这个问题解释为“我如何将 -whatif 与 运行 外部命令一起使用?”,因为这就是我发现这个问题的方式。
# myscript.ps1
[cmdletbinding(SupportsShouldProcess=$True)]
Param($path) # put Param() if no parameters
if ($pscmdlet.ShouldProcess($Path, 'creating folder')) { # not -whatif
cmd /c mkdir $path
}
.\myscript foo -whatif
What if: Performing the operation "creating folder" on target "foo".