如何支持 PowerShell 的 -WhatIf & - 确认调用其他 Cmdlet 的 Cmdlet 中的参数吗?
我有一个支持 -WhatIf
的 PowerShell 脚本 cmdlet -确认
参数。
它通过在执行更改之前调用 $PSCmdlet.ShouldProcess()
方法来实现此目的。
这按预期工作。
我遇到的问题是,我的 Cmdlet 是通过调用其他 Cmdlet 来实现的,并且 -WhatIf
或 -Confirm
参数不会传递到我调用的 Cmdlet。
如何将 -WhatIf
和 -Confirm
的值传递到我从 Cmdlet 调用的 Cmdlet?
例如,如果我的 Cmdlet 是 Stop-CompanyXyzServices
并且它使用 Stop-Service
来实现其操作。
如果 -WhatIf
传递给 Stop-CompanyXyzServices
我希望它也传递给 Stop-Service。
这可能吗?
I have a PowerShell script cmdlet that supports the -WhatIf
& -Confirm
parameters.
It does this by calling the $PSCmdlet.ShouldProcess()
method before performing the change.
This works as expected.
The problem I have is that my Cmdlet is implemented by calling other Cmdlets and the -WhatIf
or -Confirm
parameters are not passed along to the Cmdlets I invoke.
How can I pass along the values of -WhatIf
and -Confirm
to the Cmdlets I call from my Cmdlet?
For example, if my Cmdlet is Stop-CompanyXyzServices
and it uses Stop-Service
to implement its action.
If -WhatIf
is passed to Stop-CompanyXyzServices
I want it to also be passed to Stop-Service.
Is this possible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
显式传递参数
您可以使用
$WhatIfPreference
和$ 传递
-WhatIf
和-Confirm
参数确认首选项变量。以下示例通过参数splatting< /a>:如果在包含函数上使用
-WhatIf
开关,$WhatIfPreference.IsPresent
将为True
。使用包含函数上的-Confirm
开关暂时将$ConfirmPreference
设置为low
。隐式传递参数
由于
-Confirm
和-WhatIf
临时设置了$ConfirmPreference
和$WhatIfPreference< /code> 自动变量,是否有必要传递它们?
考虑这个例子:
ShouldTestCaller
从ShouldProcess()
得到True
,即使
ShouldTestCaller -Confirm
产生确认提示我没有通过开关。编辑
@manojlds 答案让我意识到我的解决方案始终将
$ConfirmPreference
设置为“低”或“高”。我已更新我的代码,仅在确认首选项为“低”时设置-Confirm
开关。Passing parameters explicitly
You can pass the
-WhatIf
and-Confirm
parameters with the$WhatIfPreference
and$ConfirmPreference
variables. The following example achieves this with parameter splatting:$WhatIfPreference.IsPresent
will beTrue
if the-WhatIf
switch is used on the containing function. Using the-Confirm
switch on the containing function temporarily sets$ConfirmPreference
tolow
.Passing parameters implicitly
Since the
-Confirm
and-WhatIf
temporarily set the$ConfirmPreference
and$WhatIfPreference
variables automatically, is it even necessary to pass them?Consider the example:
ShouldTestCaller
results inTrue
fromShouldProcess()
ShouldTestCaller -Confirm
results in an confirm prompt even though I didn't pass the switch.Edit
@manojlds answer made me realize that my solution was always setting
$ConfirmPreference
to 'Low' or 'High'. I have updated my code to only set the-Confirm
switch if the confirm preference is 'Low'.经过一番谷歌搜索后,我想出了一个很好的解决方案,用于将通用参数传递给被调用的命令。您可以使用 @ splatting 运算符来传递传递给命令的所有参数。例如,如果
Start-Service -Name ServiceAbc @PSBoundParameters
位于脚本正文中,powershell 会将传递给脚本的所有参数传递给 Start-Service 命令。唯一的问题是,如果您的脚本包含一个 -Name 参数,它也会被传递,并且 PowerShell 会抱怨您两次包含 -Name 参数。我编写了以下函数,将所有公共参数复制到一个新字典中,然后将其展开。
最终结果是您将 -Verbose 等参数传递给脚本中调用的命令,并且它们尊重调用者的意图。
After some googling I came up with a good solution for passing common parameters along to called commands. You can use the @ splatting operator to pass along all the parameters that were passed to your command. For example, if
Start-Service -Name ServiceAbc @PSBoundParameters
is in the body of your script powershell will pass all the parameters that were passed to your script to the Start-Service command. The only problem is that if your script contains say a -Name parameter it will be passed too and PowerShell will complain that you included the -Name parameter twice. I wrote the following function to copy all the common parameters to a new dictionary and then I splat that.
The end result is you pass parameters like -Verbose along to the commands called in your script and they honor the callers intention.
这是基于 @Rynant 和 @Shay Levy 的答案的完整解决方案:
我们必须查看
-WhatIf
是否也单独传递,以便将 Whatif 传递到各个 cmdlet。ActualCmdletProcess
基本上是一种重构,这样您就不会仅为WhatIf
再次调用同一组命令。希望这对某人有帮助。Here is a complete solution based on @Rynant and @Shay Levy's answers:
We have to see if
-WhatIf
is passed separately as well so that the whatif can be passed on to the individual cmdlets.ActualCmdletProcess
is basically a refactoring so that you don't call the same set of commands again just for theWhatIf
. Hope this helps someone.根据 @manojlds 评论进行更新
将 $WhatIf 和 $Confirm 转换为布尔值并将值传递给底层 cmdlet:
Updated per @manojlds comment
Cast $WhatIf and $Confirm to Boolean and pass the values to the the underlying cmdlet:
为了避免您因这个问题和此处的答案而困扰几个小时,我建议您改为阅读这篇文章:
https://powershellexplained.com/2020-03-15-Powershell-shouldprocess-whatif-confirm-shouldcontinue-everything/#suppressing-nested-confirm-prompts
这里提供的答案对很多人来说并不适用我发现人们在不了解基本原理的情况下实施这里的答案是危险的。
以下是如何破解它以跨脚本模块工作:
Just so you wont get run around the block for hours by this question and the answers here, I would suggest that you read this article instead:
https://powershellexplained.com/2020-03-15-Powershell-shouldprocess-whatif-confirm-shouldcontinue-everything/#suppressing-nested-confirm-prompts
The answers presented here does not work for many cases and I see a danger in people implementing the answers here, without understanding the fundamentals.
Here is how a hacked it to work across scriptmodules: