Last active
June 21, 2023 14:23
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.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