我通常在我的PowerShell函数中使用SupportsShouldProcess
以及$PSCmdlet.ShouldProcess()
,因此我可以理智地检查脚本将要执行的操作。通常,我只围绕将改变环境的行为来实现这一点,例如: 添加,新功能,设置 cmdlet等。在某些情况下,我还想绕过获取 - 使用-WhatIf
开关运行脚本时的cmdlet。例如:
我有一个脚本,在对每个文件执行某些操作之前使用Get-FileHash
指纹文件夹中的所有文件。在此示例中,有10k +文件,平均大小为100MB或更多,我不想花时间在我使用-WhatIf
时对文件进行指纹识别。我无法包装整个操作只是一个$PSCmdlet.ShouldProcess("All Files","Get-FileHash")
块。
对循环中的每个项目运行$PSCmdlet.ShouldProcess()
的效果是我转储了数千行"如果:"文字回到控制台。
问题:有没有办法使用$PSCmdlet.ShouldProcess()
,所以不写入控制台?如果没有,人们可以使用哪些变通办法?
示例代码
虽然我觉得这个问题只是抽象意义上的,但这是一个非常实用的论坛,所以这里是我上面提到的任务的简单例子:
$Files = Get-ChildItem -Path <ReallyBigFolder>
foreach($File in $Files){
$Action = Get-MyAction -Filename -$File.Fullname
# Take hash of file
$Hash = Get-FileHash -Path -$File.Fullname
# Keep audit happy
Write-Audit -Action $Action -Hash $Hash
switch($Action){
"Retain" {
# do nothing
break
}
"Remove" {
if($PSCmdlet.ShouldProcess($File.Fullname,"Remove-Item")){
Remove-Item $File.Fullname
}
break
}
default { # barf }
}
}
假设将保留95%的文件,因此在此示例中我们仅使用&#34;在屏幕上获取500行的WhatIf输出,但花时间散列文件并编写审计日志(假设后者调用REST API或其他在多次迭代中缓慢的事情)。
如果我将Get-FileHash
和Write-Audit
cmdlet放在ShouldProcess()
块中,那么我可以节省时间,但会将10k或更多行写入屏幕。
我确定这个例子(实际上我的真实代码)可以重组以保持输出受控制,或者我可以忽略WhatIf的详细程度,但是今天我想知道我是否可以压制它输出...
答案 0 :(得分:2)
我怀疑你可以压制ShouldProcess
输出。要解决此问题,您可以检查-whatif
中是否存在$PSBoundParameters
参数:
if ($PSBoundParameters.ContainsKey('WhatIf'))
{
# do something here without
}
答案 1 :(得分:1)
作为@ martin-brandl答案的扩展,以下是检查隐式使用WhatIf
开关的方法:
if(((Get-PSCallStack).InvocationInfo.BoundParameters.ContainsKey("WhatIf")) `
-and ((Get-PSCallStack).InvocationInfo.BoundParameters.WhatIf -eq $true))
{
# don't do whatever you might have done
}
即:检查调用堆栈以查看-WhatIf
是否作为参数在任何地方提供,并验证某人没有使用-WhatIf:$false
否定它。
尽管对@briantist关于使用$WhatIfPreference
的Martin的答案的评论可能更容易了!
答案 2 :(得分:0)
我解释你的问题的方式,似乎你并没有在这个例子中正确地实现-WhatIf
。 -WhatIf
应该确保没有任何改变。如果您只想跳过指纹识别但仍然对每个文件执行某些操作,那么您应该实现自己的开关,如-NoFingerprint
并使用它的值。
你应该继续实现-WhatIf
,它根本不会处理文件(在这种情况下,保持输出所有行可能是有意义的。)
答案 3 :(得分:0)
我遇到了类似的情况,即使提供了-WhatIf,我也想写入日志文件。
您可以记录-WhatIf的状态,暂时将其关闭,手动控制要执行的操作,然后恢复-WhatIf的原始状态:
$MyWhatIf= $WhatIfPreference
$WhatIfPreference= $False
If (! $MyWhatIf) { Do-YourThing }
$WhatIfPreference= $MyWhatIf