Powershell - 如何将-whatif与-confirm结合起来?

时间:2016-02-04 20:39:36

标签: powershell

我在我的搜索中提到了这个问题:how to use 'dry-run' in powershell,我已经得到了它的意思。

我的问题是:

我是否可以使用调用-whatif的Powershell脚本,然后返回确认提示以运行实际命令?

一个例子:

#Disable Exchange access
set-casmailbox $1.samaccountname -ewsallowentourage $false -ecpenabled $false -ewsallowoutlook $false -ewsallowmacoutlook $false -activesyncenabled $false -owaenabled $false -OWAforDevicesEnabled $false -mapihttpenabled $false -ewsenabled $false -mapienabled $false

我希望上面包含-WhatIf,然后提示确认是否运行实际命令。

我想通过使用:

,我可以做得有点草率
#Check what happens if I disable Exchange Access
set-casmailbox $1.samaccountname -ewsallowentourage $false -ecpenabled $false -ewsallowoutlook $false -ewsallowmacoutlook $false -activesyncenabled $false -owaenabled $false -OWAforDevicesEnabled $false -mapihttpenabled $false -ewsenabled $false -mapienabled $false -whatif
#Prompt for Confirmation to actually disable Exchange Access
set-casmailbox $1.samaccountname -ewsallowentourage $false -ecpenabled $false -ewsallowoutlook $false -ewsallowmacoutlook $false -activesyncenabled $false -owaenabled $false -OWAforDevicesEnabled $false -mapihttpenabled $false -ewsenabled $false -mapienabled $false -confirm

但我很好奇是否有更好的方法,特别是因为上面是一个简单的单行命令而不是foreach等。

1 个答案:

答案 0 :(得分:2)

这必须在您调用的cmdlet中实现。你可以用自己的功能来解决这个问题:

function Invoke-WhatIfThenConfirm {
[CmdletBinding(SupportsShouldProcess=$true)]
param(
    [Parameter(
        Mandatory=$true
    )]
    [ScriptBlock]
    $ScriptBlock ,

    [Switch]
    $Force
)

    if ($PSCmdlet.ShouldProcess('Calling scriptblock')) {
        $prefSave = $WhatIfPreference
        try {
            $WhatIfPreference = 'Stop'
            & $ScriptBlock
        } finally {
            $WhatIfPreference = $prefSave
        }
        $confSave = $ConfirmPreference
        try {
            $ConfirmPreference = if ($Force) {
                'None'
            } else {
                'High'
            }
            & $ScriptBlock
        } finally {
            $ConfirmPreference = $confSave
        }
    }
}

然后称之为:

Invoke-WhatIfThenConfirm -ScriptBlock {
    set-casmailbox $1.samaccountname -ewsallowentourage $false -ecpenabled $false -ewsallowoutlook $false -ewsallowmacoutlook $false -activesyncenabled $false -owaenabled $false -OWAforDevicesEnabled $false -mapihttpenabled $false -ewsenabled $false -mapienabled $false
}

如果您使用-Force,则不应强制确认。

这整件事只是在这里打字而且我根本没有测试过,所以我不确定它会起作用,但它可能是一个很好的起点。

替代

您可以使用splatting将params放入哈希表并修改开关:

$params = @{
    Identity = $1.samaccountname 
    ewsallowentourage = $false 
    ecpenabled = $false 
    ewsallowoutlook = $false 
    ewsallowmacoutlook = $false 
    activesyncenabled = $false 
    owaenabled = $false 
    OWAforDevicesEnabled = $false 
    mapihttpenabled = $false 
    ewsenabled = $false 
    mapienabled = $false
}

set-casmailbox @params -WhatIf
set-casmailbox @params -Confirm

第二个选项更简单,可能更不容易出错,但最适合在这里或那里调用大多数参数不会改变的单个cmdlet。

第一个选项更适用于处理许多不同的cmdlet并更自然地调用它们。