Skip to content

Instantly share code, notes, and snippets.

@LudovicOmarini
Last active June 21, 2023 14:23
Show Gist options
  • Save LudovicOmarini/ac3c27fc190c999a9ced4786fc5574fe to your computer and use it in GitHub Desktop.
Save LudovicOmarini/ac3c27fc190c999a9ced4786fc5574fe to your computer and use it in GitHub Desktop.
Enable or disable service plan options within each license package while respecting current configuration for each user.
<#
.SYNOPSIS
Enable or disable service plan options within each license package while respecting current configuration for each user.
.DESCRIPTION
Even when using PowerShell, Microsoft doesn’t make it simple when it comes to adjusting licensing in bulk and service plan
options/apps within. Mainly that is because there is no easy way to keep a current configuration –
any license change you apply to a user overwrites their existing setup.
To address that letdown I created a script you can find below.
.WARNING
This script assumes you are already connected to the right services and have all modules installed.
.EXAMPLE
Execute the script and type your choices.
.\Enable_Disable_Service_Plan_O365.ps1
.CREDITS
https://365basics.com/powershell-office-365-enable-or-disable-service-plan-options-within-each-license-package-while-respecting-current-configuration-for-each-user/?unapproved=5799&moderation-hash=91916bee6e5ee3bc6ae3fea3666fc195#comment-5799
#>
# Fonction de vérification de réponse
Function Get-Response ([string]$Prompt,[int]$NumberPossibleAnswers) {
$OKtoProceed = $False
While ($OKToProceed -eq $False) {
[int]$Answer = Read-Host $Prompt
If ($Answer -gt 0 -and $Answer -le $NumberPossibleAnswers) {
$OKtoProceed = $True
Return ($Answer) }
ElseIf ($Answer -eq 0) {
$OKtoProceed = $True
Return ($Answer)}
}
}
#Connexion à Exchange Online et MgGraph (IMPORTANT)
#Connect-ExchangeOnline
#Connect-MgGraph -Scopes "User.ReadWrite.All","Directory.ReadWrite.All"
# Chemin du fichier CSV
$CSVOutputFile = "c:\tmp\logs.csv"
# Recherche des différents type de licences disponible sur le tenant
[array]$Skus = (Get-MgSubscribedSku)
Write-Host " "
Write-Host "Sur quelle licence voulez-vous enlever le service ?"; [int]$i=0
ForEach ($Sku in $Skus) {
$i++
Write-Host $i ":" $Sku.SkuPartNumber }
[Int]$Answer = Get-Response -Prompt "Entrer le nombre correspondant à la licence" -NumberPossibleAnswers $i
If (($Answer -gt 0) -and ($Answer -le $i)) {
$i = ($Answer-1)
[string]$SelectedSku = $Skus[$i].SkuPartNumber
[string]$SelectedSkuId = $Skus[$i].SkuId
Write-Host "La licence selectionné est " $SelectedSku
$ServicePlans = $Skus[$i].ServicePlans | Select ServicePlanName, ServicePlanId | Sort ServicePlanName
}
Elseif ($Answer -eq 0) {
Write-Host "Arret du script..." ; break }
# Selection du service à enlever
Write-Host " "
Write-Host "Quel service voulez-vous supprimer sur la licence" $SelectedSku; [int]$i=0
ForEach ($ServicePlan in $ServicePlans) {
$i++
Write-Host $i ":" $ServicePlan.ServicePlanName }
[Int]$Answer = Get-Response -Prompt "Entrer le nombre correspondant au service à supprimer" -NumberPossibleAnswers $i
If (($Answer -gt 0) -and ($Answer -le $i)) {
[int]$i = ($Answer-1)
[string]$ServicePlanId = $ServicePlans[$i].ServicePlanId
[string]$ServicePlanName = $ServicePlans[$i].ServicePlanName
Write-Host " "
Write-Host ("Le service {0} va être supprimé de la licence {1} pour les utilisateurs assignés." -f $ServicePlanName, $SelectedSku)
}
Elseif ($Answer -eq 0) {
Write-Host "Arret du script..." ; break }
# Utilisation de "Get-ExoMailbox" car nous pouvons filtrer les résultats
[array]$Mbx = (Get-ExoMailbox -RecipientTypeDetails UserMailbox -ResultSize Unlimited | Select DisplayName, UserPrincipalName, Alias, ExternalDirectoryObjectId)
[int]$LicensesRemoved = 0
Write-Host ("Il y a {0} comptes qui corresponde au filtre." -f $mbx.count) -Foregroundcolor red
# Boucle de suppression du service sur les utilisateurs qui on la licence assignée.
$Report = [System.Collections.Generic.List[Object]]::new()
ForEach ($M in $Mbx) {
Write-Host "Vérification de la licence" $M.DisplayName
$User = (Get-MgUser -UserId $M.ExternalDirectoryObjectId)
$i = 0
Foreach ($License in $User.AssignedLicenses) {
If ($License.SkuId -eq $SelectedSkuId)
{
Write-Host ("Suppression du service {0} depuis la licence {1} pour le compte {2}" -f $ServicePlanName, $SelectedSKUId, $M.DisplayName) -foregroundcolor Green
$ExistingDisabledPlans = $Null
ForEach ($S in $User.AssignedLicenses) {
If ($S.SkuId -eq $SelectedSkuId) {
$ExistingDisabledPlans = $S.DisabledPlans }
}
$ExistingDisabledPlans += $ServicePlanId
$LicenseToRemove = New-Object -TypeName Microsoft.Graph.PowerShell.Models.MicrosoftGraphAssignedLicense
$LicenseToRemove.SkuId = $SelectedSkuId
$LicenseToRemove.DisabledPlans = $ExistingDisabledPlans
$Status = Set-MgUserLicense -UserId $User.id -AddLicenses $LicenseToRemove -RemoveLicenses @()
$LicenseUpdateMsg = $ServicePlanName + " a été supprimé du compte " + $M.UserPrincipalName + " on " + (Get-Date) + " from " + $SelectedSku
Write-Host ("Le service {0} a été supprimé de la licence {1} pour {2}" -f $ServicePlanName, $SelectedSku, $M.DisplayName)
$LicensesRemoved++
$ReportLine = [PSCustomObject][Ordered]@{
DisplayName = $M.DisplayName
UPN = $M.UserPrincipalName
Info = $LicenseUpdateMsg
SKU = $SelectedSKUId
"Service Plan" = $ServicePlanName
"ServicePlanId" = $ServicePlanId }
$Report.Add($ReportLine)
}
}
}
Write-Host ("Total de service supprimé : {0}. Le fichier CSV est disponible sous : {1}" -f $LicensesRemoved, $CSVOutputFile)
$Report | Out-GridView
$Report | Export-CSV -NoTypeInformation $CSVOutputFile
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment