Find and Fix Missing Licenses or Service Plans in Office 365

Issue:

I needed a script using AzureAD 2.0 to find and fix users missing licenses in Office 365 or users with service plans that should not be disabled.

 

Prerequisites:

 

Solution:

#Install-Module -Name AzureAD 
#Update-Module -Name AzureAD 
Import-Module AzureAD
#Review Missing Licences or Service Plans


$username = "Office365GlobalAdmin@contoso.com";
$logfile = 'c:\temp\StudentsMissingLicense.txt';


Set-Content $logfile ''

try
{
    $mycreds = Get-Credential -Message "Office 365 Credential" -UserName $username
    Connect-AzureAD -credential $mycreds;

    #Licensing 
	#licensing that you want each user to have
		$sku = Get-AzureADSubscribedSku | Where { $_.SkuPartNumber -eq "STANDARDWOFFPACK_IW_STUDENT" }
		$license1 = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicense
		$license1.SkuId = $($sku.SkuId)
		#Disable Service Plans
		$license1.DisabledPlans += ($sku.ServicePlans | Where { $_.ServicePlanName -eq "YAMMER_EDU" }).ServicePlanID
		$license1.DisabledPlans += ($sku.ServicePlans | Where { $_.ServicePlanName -eq "FLOW_O365_P2" }).ServicePlanID
		$license1.DisabledPlans += ($sku.ServicePlans | Where { $_.ServicePlanName -eq "POWERAPPS_O365_P2" }).ServicePlanID
		$license1.DisabledPlans += ($sku.ServicePlans | Where { $_.ServicePlanName -eq "MCOSTANDARD" }).ServicePlanID
		$license1.DisabledPlans += ($sku.ServicePlans | Where { $_.ServicePlanName -eq "Deskless" }).ServicePlanID

		#Assign both licenses
		$newLicenses = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicenses
		$newLicenses.RemoveLicenses = $Null
		$newLicenses.AddLicenses += $license1
    
    #End Licensing

    #Review License SkuId's for use later
    #Get-AzureADSubscribedSku | fl

    #Review ServicePlanId's for use later
    #(Get-AzureADSubscribedSku | ?{$_.SkuPartNumber -eq "STANDARDWOFFPACK_IW_STUDENT"}).ServicePlans | Format-Table -AutoSize

    $filter = 'accountEnabled eq true'
    
    #Filter as needed using the Where statement or filter
    $licenseduserList = Get-AzureADUser -All $True -Filter $filter | Where { $_.UserPrincipalName -like '100*'  } | SORT-OBJECT UserPrincipalName
    
    ForEach ($muser in $licenseduserList)
    {
        $upn = $($muser.UserPrincipalName)
        $missingPlan = 0          #becomes 1 then disabled
        $hasSTNlic = 0            #remains 0 then missing
        $lics = $muser.AssignedLicenses
        #$muser | fl
        
        foreach ($lic in $lics)
        {
            #change the guid below to license skuid that you require for all users found
            if ($($lic.SkuId) -eq '00000000-0000-0000-0000-000000000000')          #SkuId of license that should be assigned
            {
                $hasSTNlic = 1
                $disabledPlans = $lic.DisabledPlans
             
                #If the plan is disabled then we found a problem
                foreach ($splan in $disabledPlans)
                {
                    #change the guid below to ServicePlanId for the service plan that should not be disabled
                    if ($splan -eq "00000000-0000-0000-0000-000000000000")  #ServicePlanId that you do not want to be disabled
                    {
                        $missingPlan = 1
                        #Write-Host "$upn Teams Disabled $splan"
                    }
		    #you can add more plan checks as needed
                }
            }
            

        }
        
        if ($hasSTNlic -eq 0)
        {
	    #The license is missing so lets add the license
	    #Assign the UsageLocation
            Set-AzureADUser -ObjectId $upn -UsageLocation "US";
            #Assign the licenses
            Set-AzureADUserLicense -ObjectId $upn -AssignedLicenses $newLicenses
            Start-Sleep -Seconds 2
			
            $licmsg = "$($muser.UserPrincipalName) missing license STANDARDWOFFPACK_IW_STUDENT"
            WRITE-HOST $licmsg
            Add-Content $logfile $licmsg
        }
        if ($missingPlan -eq 1)
        {
            #ServicePlan is disabled so lets fix that
	    $missingPlan = 0
            
			
            #Assign the UsageLocation
            Set-AzureADUser -ObjectId $upn -UsageLocation "US";
            #Assign the licenses
            Set-AzureADUserLicense -ObjectId $upn -AssignedLicenses $newLicenses
            Start-Sleep -Seconds 2
			
            $missingplanmsg = "$upn missing plan TEAMS1"
            WRITE-HOST $missingplanmsg
            Add-Content $logfile $missingplanmsg
        }
    }
}
catch
{
    $ErrorMessage = $_.Exception.Message
    $FailedItem = $_.Exception.ItemName
    WRITE-HOST "FailedItem:  $FailedItem"
    WRITE-HOST "Error:  $ErrorMessage"
    Add-Content $logfile "FailedItem:  $FailedItem"
    Add-Content $logfile "Error:  $ErrorMessage"
}
finally
{
    Disconnect-AzureAD
}

 

Resources:

https://docs.microsoft.com/en-us/powershell/module/azuread/?view=azureadps-2.0

https://www.powershellgallery.com/packages/AzureAD/

http://stackoverflow.com/questions/41872903/example-of-get-azureaduser-filter-string-command

-Filter Examples http://www.odata.org/documentation/odata-version-3-0/url-conventions/

Leave a Reply

%d bloggers like this: