简体   繁体   中英

Powershell Function -WhatIf for cmdlet without the -WhatIf support?

For these cmdlets below, I try to create the function with the [CmdletBinding(SupportsShouldProcess)] line, but not sure that it will work.

Using: https://docs.microsoft.com/en-us/powershell/module/msonline/set-msoluserlicense?view=azureadps-1.0

How can the script be modified to support the -WhatIf parameter?

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

Thanks

You can use $PSCmdlet.ShouldProcess

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

MS Docs: https://docs.microsoft.com/en-us/powershell/scripting/learn/deep-dives/everything-about-shouldprocess?view=powershell-7.2

To complement guiwhatsthat helpful answer , if you want your function to support Common Parameter including -WhatIf as well as -Confirm , $PSCmdlet.ShouldProcess is how you do it.

If instead you want Set-MsolUserLicense to support it, you would need to create a proxy command / proxy function around this cmdlet to extend it's functionality.

These blogs demonstrate how to do it:


To address some issues on your code, you should note that -RemoveLicenses takes string[] as input, this means you can pass the whole array of licenses to remove as argument.

You could use Write-Verbose instead of Write-Host to display information about what the function is doing (since your function already supports -Verbose , this would be logical). Also, -Verbose is being used always activated on Set-MsolUserLicense which can be confusing if someone else using your function does not want to see verbose messages (this is addressed on the example below).

You can also use ConfirmImpact set to High , this way the function will always ask for confirmation before processing any license removal assuming -WhatIf was not being used. -Confirm:$false becomes the alternative to avoid such confirmation messages.

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
        }
    }
}

Now the function supports pipeline processing , you can process multiple users by piping it into other cmdlets, ie:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM