skip to Main Content

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

Using: https://learn.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 '[email protected]' -WhatIf

2

Answers


  1. You can use $PSCmdlet.ShouldProcess

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

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

    Login or Signup to reply.
  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, i.e.:

    Get-MsolUser -EnabledFilter DisabledOnly -MaxResults 5 | Remove-License -WhatIf
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search