Script Repository


Send notification if number of unused Office 365 licenses falls below limit

May 14, 2019
2451

The script sends an email notification if the number of unused licenses for the specified license plans enabled in any of Office 365 tenants falls below a specific limit. You can use the script to receive an email notification when the number of available Office 365 licenses is too low and have time to take appropriate action.

To receive notifications when the limit is reached, you need to create a Scheduled Task configured for the Domain-DNS object type. To add the script to a Scheduled Task, use the Run a program or PowerShell script action.

Parameters:

  • $limit - specifies the minimum number of unused licenses. The script will send an email if the number of available licenses is below this limit;
  • $skus - specifies the SKU Part Numbers of the licenses to check. If set to NULL, the script will check all the enabled licenses.
  • $to - specifies email addresses of the recipient(s) of the report;
  • $subject - specifies the email message subject;
  • $reportHeader - specifies the email message header;
  • $htmlTableCoulmns - specifies columns headers for the table that contains details on the number of licenses in Office 365 license plans;
  • $reportFooter - specifies the email message footer.

How to get the SKU Part Number of a license plan in Adaxes:

  1. In Adaxes Administration Console, expand the service node that represents your Adaxes service.
  2. Navigate to Configuration \ Cloud Services \ Office 365.
  3. Double-click the Office 365 Tenant to which the license belongs.
  4. Click the necessary license plan. The SKU Part Number is displayed below the Display Name field.
Edit Remove
PowerShell
$limit = 5 # TODO: modify me
$skus = @("ENTERPRISEPREMIUM", "ENTERPRISEPACK") # TODO: modify me

# E-mail settings
$to = "recipient@domain.com" # TODO: modify me
$subject = "List of Office 365 plans that have $limit or less licenses available" # TODO: modify me
$reportHeader = "<h2>List of Office 365 plans that have $limit or less licenses available</h2>"
$htmlTableColumns = "
<table border='1'>
    <tr>
        <th>License Plan</th>
        <th>Total Licenses</th>
        <th>Unused Licenses</th>
    </tr>
" # TODO: modify me
$reportFooter = "<hr /><p><i>Please do not reply to this e-mail, it has been sent to you for notification purposes only.</i></p>" # TODO: modify me

# Find all tenants
$office365TenantsPath = $Context.GetWellKnownContainerPath("CloudServicesO365")
$searcher = $Context.BindToObject($office365TenantsPath)
$searcher.SearchFilter = "(objectClass=adm-O365Tenant)"
$searcher.SearchScope = "ADS_SCOPE_SUBTREE"
$searcher.PageSize = 500

try
{
    $searchResultIterator = $searcher.ExecuteSearch()
    $searchResults = $searchResultIterator.FetchAll()
    
    $report = $NULL
    foreach ($searchResult in $searchResults)
    {
        # Bind to the tenant
        $tenant = $Context.BindToObject($searchResult.AdsPath)
        
        # Check licenses
        $htmlTable = $NULL
        foreach ($sku in $tenant.Skus)
        {
            if (($skus -ne $NULL) -and ($skus -notcontains $sku.SkuPartNumber))
            {
                continue
            }
            
            $difference = $sku.TotalUnits - $sku.ConsumedUnits
            if ($difference -gt $limit)
            {
                continue
            }
            
            if ($htmlTable -eq $NULL)
            {
                $htmlTable += "<h3>$($tenant.TenantName)</h3>$htmlTableColumns"
            }
            
            $htmlTable += "<tr><td>$($sku.DefaultDisplayName)</td><td>$($sku.TotalUnits)</td><td>$difference</td></tr>"
        }
        if ($htmlTable -eq $NULL)
        {
            continue
        }
        
        $htmlTable += "</table>"
        $report += $htmlTable
    }
    
    if ($report -eq $NULL)
    {
        return # There are no licenses in any tenant that are below the limit
    }
    
    # Build report
    $html = $reportHeader + $report + $reportFooter
    
    # Send mail
    $Context.SendMail($to, $subject, $NULL, $html)
}
finally
{
    # Release resources
    $searchResultIterator.Dispose()
}


Comments ( 4 )
avatar
Dave T.
May 13, 2019

Can the script be modified to only return values for the select products only or a specific subset of products?
O365_BUSINESS_ESSENTIALS
Office 365 Business

avatar
Support
May 14, 2019

Hello Dave,

Yes, it is possible. We have updated the script with the possibility to specify SKU Part Numbers of the licenses to check.

avatar
Amz
July 29, 2019

Running the script throws an error saying "You cannot call a method on null valued expression". Please help me fix. Have set $skus to NULL to check for all the license enabled in our tenant

avatar
Support
July 30, 2019

Hello,

Could you, please, send us (support[at]adaxes.com) the script you are using with all the modifications and a screenshot of the full error message you are getting?

Leave a comment