Hey everyone! I'm working on a PowerShell script to manage M365 licensing. The goal is to add a specific license (NewSKU1) to user accounts while removing an old license (OriginalSKU). Here's a snippet of the script I've put together:
```powershell
$UPNS = Import-Csv .UPN.csv | select -ExpandProperty UPN
$NewSKU1 = dcf0408c-aaec-446c-afd4-43e33683943ea
$NewSKU2 = 7e31c0d9-9551-471d-836f-32ee72be4a01
$OriginalSKU = 05e9a617-0261-4cee-bb44-138d3ef5d965
foreach($UPN in $UPNS){
$User = Get-MgUser -UserId $UPN -Property AssignedLicenses
$Status = Set-MgUserLicense -UserId $User.UserId -AddLicenses @{SkuId = $NewSKU1; DisabledPlans = $DisabledServicePlansToUse} `
-RemoveLicenses @() -ErrorAction SilentlyContinue
If (!($Status)) {
Write-Host "Error assigning license - please check availability" -ForegroundColor Red
} Else {
Write-Host ("{0} license assigned to account {1}" -f ($TenantSkuHash[$NewSKU1]), $User.DisplayName )
# Now to remove the old license
$Status = Set-MgUserLicense -UserId $User.UserId -AddLicenses @() -RemoveLicenses $OriginalSku -ErrorAction SilentlyContinue
If ($Status) {
Write-Host ("{0} license removed from account {1}" -f ($TenantSkuHash[$OriginalSKU]), $User.DisplayName )
}
}
}
```
I'm curious if the foreach loop will function correctly. Any advice would be appreciated!
3 Answers
Using group-based licensing is definitely the way to go! Setting up groups in Entra and assigning licenses to those groups is a game changer. It helps keep everything organized and scalable. Just something to consider!
I think you're on the right track! Just to tweak your foreach, try this:
```powershell
$UPNS = Import-Csv .UPN.csv
foreach($SingleUPN in $UPNS){
$User = Get-MgUser -UserId $SingleUPN.upn -Property AssignedLicenses
...
}
```
This way, you’re not flattening existing rich objects. Also, why not consider adding/removing the group at the same time? It sounds like it could simplify things! And make sure you define `$DisabledServicePlansToUse` properly. Also, are you using `$NewSKU2` anywhere? Just some thoughts!
Exactly! It would help to have a clear definition for all your variables to avoid any runtime issues. Definitely keep refining this!
I agree with the suggestion about using groups, but your foreach loop isn't bad! Just a tip: you might want to clear the variables at the start of the loop to avoid any unintended data retention. Overall, it looks solid!

Good points! I'm planning to keep the new license active before removing the old one as a fallback. The `$DisabledServicePlansToUse` is meant to be defined when fetching license packages, but I might need to revisit its setup. As for `$NewSKU2`, it's part of a transition we're working on, but it's not essential yet.