Forum Discussion
Remove direct licenses for users with group licenses
It seems that the script is not properly detecting users who have direct licenses assigned. One possible reason for this is that the script is not properly checking for licenses with an empty GroupsAssigningLicense collection, which is the case for users who have never been licensed via groups in the past. To address this, you can modify the UserHasLicenseAssignedDirectly function as follows:
#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 or contains only the user's own ID, 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) -or ($license.GroupsAssigningLicense.Count -eq 1 -and $license.GroupsAssigningLicense[0] -ieq $user.ObjectId))
{
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
}This modified version of the function checks whether the GroupsAssigningLicense collection is empty or contains only the user's own ID, in addition to checking whether the collection contains the ID of the user object, to determine whether the license is assigned directly.
Regarding your second question, if you want to process multiple groups and/or multiple SKUs, you can modify the script as follows:
#BEGIN: executing the script
#the groups to be processed
$groupIds = @("48ca647b-7e4d-41e5-aa66-40cab1e19101", "48ca647b-7e4d-41e5-aa66-40cab1e19102", ...)
#licenses to be removed - Office 365 E3 and Windows 10 Enterprise E3
$skuIds = @("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")
#process each group and SKU
foreach ($groupId in $groupIds)
{
foreach ($skuId in $skuIds)
{
Write-Host "Processing group $groupId and SKU $skuId"
#get all users in the group
$users = Get-MsolUser -All -UserPrincipalName *@contoso.com | where {$_.ProxyAddresses -like "*$groupId*"}
#remove direct licenses for users with group licenses
foreach ($user in $users)
{
if (UserHasLicenseAssignedDirectly $user $skuId)
{
if ($user.Licenses.ServiceStatus | where {$_.ServicePlan.ServiceName -in