我正在编写支持ShouldProcess的Powershell cmdlet。我没有固定的ConfirmImpact值,而是想要一个“动态”值,该值取决于传递给cmdlet的参数的值。让我举例说明。

假设我是网络托管服务提供商。我有很多网站,每个网站都属于以下类别之一,按重要性排序:ProductionTestDevelopment。作为托管管理的一部分,我有一个Remove-WebSite cmdlet用于销毁网站。以下代码说明了这一点:

Class WebSite {
    [string] $Name
    [string] $Category # Can be one of: Production, Test, Development
}

Function Remove-WebSite {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$true)]
        [WebSite] $WebSite
    )
    Write-Host "$($WebSite.Name) was destroyed"
}

目前,网站未经确认即被销毁。尽管这很方便,但是太多的实习生误将生产站点破坏了,因此我想利用Powershell的ShouldProcess功能在Remove-WebSite cmdlet上多加一点安全网。

因此,我将SupportsShouldProcessConfirmImpact值添加到CmdletBinding属性。我的cmdlet定义变为:
Function Remove-WebSite {
    [CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact='High')]
    Param(
        [Parameter(Mandatory=$true)]
        [WebSite] $WebSite
    )

    if ($PSCmdlet.ShouldProcess("$($WebSite.Category) site $($WebSite.Name)")) {
        Write-Host "$($WebSite.Name) was destroyed"
    }
}

使用此定义,现在要求任何调用Remote-Website cmdlet的人确认他们确实要破坏该站点。现在几乎没有任何生产站点被错误地破坏,除非Web开发人员抱怨其自动化脚本已停止工作。

我真正想要的是cmdlet的ConfirmImpact值在运行时根据网站类别的重要性而有所不同-生产站点的High,测试站点的Medium和开发站点的Low。以下函数定义对此进行了说明:
Function CategoryToImpact([string]$Category) {
    Switch ($Category) {
        'Production' {
            [System.Management.Automation.ConfirmImpact]::High
            break
        }
        'Test' {
            [System.Management.Automation.ConfirmImpact]::Medium
            break
        }
        'Development' {
            [System.Management.Automation.ConfirmImpact]::Low
            break
        }
        default {
            [System.Management.Automation.ConfirmImpact]::None
            break
        }
    }
}

Function Remove-WebSite {
    [CmdletBinding(SupportsShouldProcess=$true<#,ConfirmImpact="Depends!"#>)]
    Param(
        [Parameter(Mandatory=$true)]
        [WebSite] $WebSite
    )

    # This doesn't work but I hope it illustrates what I'd *like* to do
    #$PSCmdLet.ConfirmImpact = CategoryToImpact($WebSite.Category)

    if ($PSCmdlet.ShouldProcess("$($WebSite.Category) site $($WebSite.Name)")) {
        Write-Host "$($WebSite.Name) was destroyed"
    }
}

假设有可能,该怎么办?

这是粘贴完整脚本和一些测试代码的代码:http://pastebin.com/kuk6HNm6

最佳答案

这并不是您所要的(我认为严格来说是不可能的),但这可能是一个更好的方法。
保留ConfirmImpact而不是prompt the user with $PSCmdlet.ShouldContinue()
根据Requesting Confirmation from Cmdlets(重点是我的)中给出的指导:

进一步:

在此指导下,我提出以下更改:

Function Remove-WebSite {
    [CmdletBinding(SupportsShouldProcess=$true)]
    Param(
        [Parameter(Mandatory=$true)]
        [WebSite] $WebSite ,
        [Switch] $Force
    )

    if ($PSCmdlet.ShouldProcess("$($WebSite.Category) site $($WebSite.Name)")) {
        $destroy =
            $Force -or
            $WebSite.Category -ne 'Production' -or
            $PSCmdlet.ShouldContinue("Are you sure you want to destroy $($WebSite.Name)?", "Really destroy this?")
        if ($destroy) {
            Write-Host "$($WebSite.Name) was destroyed"
        }
    }
}

关于powershell - 具有 'dynamic' ConfirmImpact属性设置的Powershell Cmdlet,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37488778/

10-12 20:49