Dec 29 2022 02:27 AM
Hi all,
Merry Xmas and have a happy new year to start.
Now to my question, I am looking into the script here https://learn.microsoft.com/en-us/azure/active-directory/enterprise-users/licensing-ps-examples which removes direct licenses for users with group licenses - the script from the article found below and I have set these sections to have the group ID and SKUId of the license I am working with just to test how the script works and for any logic issues.
#BEGIN: executing the script #the group to be processed $groupId = "48ca647b-7e4d-41e5-aa66-40cab1e19101" #license to be removed - Office 365 E3 $skuId = "contoso:ENTERPRISEPACK" #minimum set of service plans we know are inherited from groups - we want to make sure that there aren't any users who have more services enabled #which could mean that they may lose access after we remove direct licenses $servicePlansFromGroups = ("EXCHANGE_S_ENTERPRISE", "SHAREPOINTENTERPRISE", "OFFICESUBSCRIPTION")
The issue I am having is that when it runs I am not seeing the license being remove that were directly assigned even though I know they are.
UserId OperationResult ------ --------------- 6294ea82-64e0-4773-8006-744de05721e6 User has no direct license to remove. Skipping.
The other issue is that I have one group that currently provides 3 licenses so I need to make this work on the basis of that one group, I assume I can use this logic.
#BEGIN: executing the script #the group to be processed $groupId = "48ca647b-7e4d-41e5-aa66-40cab1e19101,48ca647b-7e4d-41e5-aa66-40cab1e19101. etc." #license to be removed - Office 365 E3 $skuId = "contoso:ENTERPRISEPACK,contoso:WINDOWS_STORE" #minimum set of service plans we know are inherited from groups - we want to make sure that there aren't any users who have more services enabled #which could mean that they may lose access after we remove direct licenses $servicePlansFromGroups = ("EXCHANGE_S_ENTERPRISE", "SHAREPOINTENTERPRISE", "OFFICESUBSCRIPTION")
Full Script
#BEGIN: Helper functions used by the script #Returns TRUE if the user has the license assigned directly function UserHasLicenseAssignedDirectly { Param([Microsoft.Online.Administration.User]$user, [string]$skuId) $license = GetUserLicense $user $skuId if ($license -ne $null) { #GroupsAssigningLicense contains a collection of IDs of objects assigning the license #This could be a group object or a user object (contrary to what the name suggests) #If the collection is empty, this means the license is assigned directly - this is the case for users who have never been licensed via groups in the past if ($license.GroupsAssigningLicense.Count -eq 0) { return $true } #If the collection contains the ID of the user object, this means the license is assigned directly #Note: the license may also be assigned through one or more groups in addition to being assigned directly foreach ($assignmentSource in $license.GroupsAssigningLicense) { if ($assignmentSource -ieq $user.ObjectId) { return $true } } return $false } return $false } #Returns TRUE if the user is inheriting the license from a specific group function UserHasLicenseAssignedFromThisGroup { Param([Microsoft.Online.Administration.User]$user, [string]$skuId, [Guid]$groupId) $license = GetUserLicense $user $skuId if ($license -ne $null) { #GroupsAssigningLicense contains a collection of IDs of objects assigning the license #This could be a group object or a user object (contrary to what the name suggests) foreach ($assignmentSource in $license.GroupsAssigningLicense) { #If the collection contains at least one ID not matching the user ID this means that the license is inherited from a group. #Note: the license may also be assigned directly in addition to being inherited if ($assignmentSource -ieq $groupId) { return $true } } return $false } return $false } #Returns the license object corresponding to the skuId. Returns NULL if not found function GetUserLicense { Param([Microsoft.Online.Administration.User]$user, [string]$skuId, [Guid]$groupId) #we look for the specific license SKU in all licenses assigned to the user foreach($license in $user.Licenses) { if ($license.AccountSkuId -ieq $skuId) { return $license } } return $null } #produces a list of disabled service plan names for a set of plans we want to leave enabled function GetDisabledPlansForSKU { Param([string]$skuId, [string[]]$enabledPlans) $allPlans = Get-MsolAccountSku | where {$_.AccountSkuId -ieq $skuId} | Select -ExpandProperty ServiceStatus | Where {$_.ProvisioningStatus -ine "PendingActivation" -and $_.ServicePlan.TargetClass -ieq "User"} | Select -ExpandProperty ServicePlan | Select -ExpandProperty ServiceName $disabledPlans = $allPlans | Where {$enabledPlans -inotcontains $_} return $disabledPlans } function GetUnexpectedEnabledPlansForUser { Param([Microsoft.Online.Administration.User]$user, [string]$skuId, [string[]]$expectedDisabledPlans) $license = GetUserLicense $user $skuId $extraPlans = @(); if($license -ne $null) { $userDisabledPlans = $license.ServiceStatus | where {$_.ProvisioningStatus -ieq "Disabled"} | Select -ExpandProperty ServicePlan | Select -ExpandProperty ServiceName $extraPlans = $expectedDisabledPlans | where {$userDisabledPlans -notcontains $_} } return $extraPlans } #END: helper functions #BEGIN: executing the script #the group to be processed $groupId = "48ca647b-7e4d-41e5-aa66-40cab1e19101" #license to be removed - Office 365 E3 $skuId = "contoso:ENTERPRISEPACK" #minimum set of service plans we know are inherited from groups - we want to make sure that there aren't any users who have more services enabled #which could mean that they may lose access after we remove direct licenses $servicePlansFromGroups = ("EXCHANGE_S_ENTERPRISE", "SHAREPOINTENTERPRISE", "OFFICESUBSCRIPTION") $expectedDisabledPlans = GetDisabledPlansForSKU $skuId $servicePlansFromGroups #process all members in the group and get full info about each user in the group looping through group members. Get-MsolGroupMember -All -GroupObjectId $groupId | Get-MsolUser -ObjectId {$_.ObjectId} | Foreach { $user = $_; $operationResult = ""; #check if Direct license exists on the user if (UserHasLicenseAssignedDirectly $user $skuId) { #check if the license is assigned from this group, as expected if (UserHasLicenseAssignedFromThisGroup $user $skuId $groupId) { #check if there are any extra plans we didn't expect - we are being extra careful not to remove unexpected services $extraPlans = GetUnexpectedEnabledPlansForUser $user $skuId $expectedDisabledPlans if ($extraPlans.Count -gt 0) { $operationResult = "User has extra plans that may be lost - license removal was skipped. Extra plans: $extraPlans" } else { #remove the direct license from user Set-MsolUserLicense -ObjectId $user.ObjectId -RemoveLicenses $skuId $operationResult = "Removed direct license from user." } } else { $operationResult = "User does not inherit this license from this group. License removal was skipped." } } else { $operationResult = "User has no direct license to remove. Skipping." } #format output New-Object Object | Add-Member -NotePropertyName UserId -NotePropertyValue $user.ObjectId -PassThru | Add-Member -NotePropertyName OperationResult -NotePropertyValue $operationResult -PassThru } | Format-Table #END: executing the script
Anyone else used this before?