可以使用-WhatIf和调用运算符(&)?

时间:2015-01-09 17:01:29

标签: powershell invoke

执行外部命令时是否可以使用-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 ".

不是特别有帮助。

有没有办法做我想做的事?

2 个答案:

答案 0 :(得分:2)

首先 - 你需要确保你的包装'函数支持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

答案 1 :(得分:0)

我将把这个问题解释为“我如何在运行外部命令时使用 -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".