【问题标题】:Powershell Function -WhatIf for cmdlet without the -WhatIf support?Powershell 函数 -WhatIf for cmdlet 没有 -WhatIf 支持?
【发布时间】:2023-02-07 22:46:26
【问题描述】:

对于下面的这些 cmdlet,我尝试使用 [CmdletBinding(SupportsShouldProcess)] 行创建函数,但不确定它是否有效。

使用:https://learn.microsoft.com/en-us/powershell/module/msonline/set-msoluserlicense?view=azureadps-1.0

如何修改脚本以支持-WhatIf参数?

function Remove-License {
    [CmdletBinding(SupportsShouldProcess)]
    param ([String] $UserPrincipalName )
    
    $AssignedLicense = (Get-MsolUser -UserPrincipalName $UserPrincipalName).licenses.AccountSkuId

    $AssignedLicense |
    ForEach-Object {
        Write-Host "Removing $($UserPrincipalName) License $($AssignedLicense)..." -ForegroundColor Red
        Set-MsolUserLicense -UserPrincipalName $upn -RemoveLicenses $_ -Verbose
    }

}

Remove-License -UserPrincipalName 'User.Name@domain.com' -WhatIf

【问题讨论】:

    标签: azure powershell azure-active-directory office365 azure-powershell


    【解决方案1】:

    您可以使用 $PSCmdlet.ShouldProcess

    if($PSCmdlet.ShouldProcess("Some text to display")){ 
        Set-MsolUserLicense -UserPrincipalName $upn -RemoveLicenses $_ -Verbose
     }
    

    微软文档: https://learn.microsoft.com/en-us/powershell/scripting/learn/deep-dives/everything-about-shouldprocess?view=powershell-7.2

    【讨论】:

    • 嗨 @guiwhatsthat,谢谢你的回复,所以即使 learn.microsoft.com/en-us/powershell/module/msonline/… 中没有 -WhatIf 参数,我认为它仍然可能吗?
    • 抱歉,我没有查看命令,它不会工作,所以只有一个选项。将更新我的答案
    • @SeniorSystemsEngineer 如果您询问是否会显示 WhatIf 消息,答案是肯定的。如果您希望 Set-MsolUserLicense 成为具有 -WhatIf 开关的那个,那么您需要围绕此 cmdlet 的代理命令包装器
    【解决方案2】:

    补充guiwhatsthat helpful answer,如果你想你的功能支持Common Parameter包括-WhatIf以及-Confirm$PSCmdlet.ShouldProcess就是你的做法。

    相反,如果您希望 Set-MsolUserLicense 支持它,则需要围绕此 cmdlet 创建一个 proxy command / 代理函数以扩展其功能。

    这些博客演示了如何做到这一点:


    要解决代码中的一些问题,您应该注意 -RemoveLicensesstring[] 作为输入,这意味着您可以传递整个数组要删除的许可证作为论据。

    您可以使用 Write-Verbose 而不是 Write-Host 来显示有关函数正在执行的操作的信息(因为您的函数已经支持 -Verbose,所以这是合乎逻辑的)。此外,-Verbose 始终在 Set-MsolUserLicense 上使用,如果使用您的函数的其他人不想看到冗长的消息(这在下面的示例中解决),这可能会造成混淆。

    您也可以使用 ConfirmImpact 设置为高的, 这样一来,假设 -WhatIf 未被使用,该函数将始终在处理任何许可证删除之前要求确认。-Confirm:$false 成为避免此类确认消息的替代方法。

    function Remove-License {
        [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')]
        param(
            [Parameter(ValueFromPipeline, ValueFromPipelineByPropertyName)]
            [string] $UserPrincipalName
        )
    
        process {
            if($PSCmdlet.ShouldProcess([string] $UserPrincipalName, 'Remove License')) {
                $licenses = (Get-MsolUser -UserPrincipalName $UserPrincipalName).licenses.AccountSkuId
                $param    = @{
                    UserPrincipalName = $UserPrincipalName
                    RemoveLicenses    = $licenses
                    Verbose           = $PSBoundParameters['Verbose'] 
                }
                Set-MsolUserLicense @param
            }
        }
    }
    

    现在该函数支持pipeline processing,您可以通过将其管道化到其他 cmdlet 来处理多个用户,即:

    Get-MsolUser -EnabledFilter DisabledOnly -MaxResults 5 | Remove-License -WhatIf
    

    【讨论】:

    • 哇,谢谢@Santiago,这太酷了,我非常感谢。
    猜你喜欢
    • 2021-10-10
    • 2019-10-11
    • 2011-11-03
    • 2018-07-03
    • 2015-05-20
    • 2011-12-20
    • 1970-01-01
    • 1970-01-01
    • 2018-04-20
    相关资源
    最近更新 更多