Office 365 License Reconciliation

This script that I am sharing has been written to assist with our provisioning process:

As you are aware when you provisioin new exchnage onine mailbox, if license is not applied, you have 30 days to assign the license.

To detect these mailboxes and applying the Exchange license –> this solution has been written (I have included SkOB license along with it)

Command that is being used inside the script to fetch the accounts that needs license reconciliation is :

Get-MsolUser -LicenseReconciliationNeededOnly

After fetching the accounts, these are checked against Exchange Online for their existence, if these exists than

it is checked if main license is assigned to them is E3 or K1 than accordingly Exchange Online and Skype for Bussiness billet is activated.

Download and extract the script from below link:(Update the variables)

https://github.com/VikasSukhija/Downloads/blob/master/LicenseReconcilation.zip

####################

$licenseE3 = “Company:ENTERPRISEPACK”

$licenseF1 = “Company:DESKLESSPACK”

$smtpserver = “smtp.labtest.com”

$from = “AutomateA@labtest.com”

$erroremail = “Reports@labtest.com”

#####################userid/password###############

$userId = “MGMT-SVC@labtest.com”

$encrypted1 = “01000000d08c9ddf0115”

##############################################

I have included the script to encrypt the password(run the encrypt.bat, it will prompt you for password and encrypt it in password1.txt file)

copy the encrypted password and paste it inside the license reconciliation ps1.

 

You can schedule the script to run daily after Exchange Mailbox provisioning process is completed.

logs folder will contain transcript logs, report folder will have two types of csv report. (one of which is error report)

Both these reports are saved and sent via email.

If everything is processed correctly than below is the report:

If there are errors in aplying license or user did not have E3 or F1 license applied(LicensenotFound) than below is the report that is generated.

I have added the code at the end of the script to recycle the logs/report after 60 days.(You can change that as per your requirement)

$limit = (Get-Date).AddDays(-60)

Here is the whole powershell Script.

PowerShell
<#     
    .NOTES 
    =========================================================================== 
     Created on:       3/16/2018 1:26 PM 
     Created by:       Vikas Sukhija (http://SysCloudPro.com) 
     Organization:      
     Filename:         LicenseReconciliation.ps1 
    =========================================================================== 
    .DESCRIPTION 
        This script will detect users with Licence reconcliation needed and will apply EOL/SKOB license 
#> 
#############Load Functions################# 
$error.clear() 
try { stop-transcript | out-null } 
catch { $error.clear() } 
 
function Write-Log 
{ 
    [CmdletBinding()] 
    param 
    ( 
        [Parameter(Mandatory = $true)] 
        [array]$Name, 
        [Parameter(Mandatory = $true)] 
        [string]$Ext, 
        [Parameter(Mandatory = $true)] 
        [string]$folder 
    ) 
     
    $log = @() 
    $date1 = get-date -format d 
    $date1 = $date1.ToString().Replace("/""-") 
    $time = get-date -format t 
     
    $time = $time.ToString().Replace(":""-") 
    $time = $time.ToString().Replace(" """) 
     
    foreach ($n in $name) 
    { 
         
        $log += (Get-Location).Path + "\" + $folder + "\" + $n + "_" + $date1 + "_" + $time + "_.$Ext" 
    } 
    return $log 
} 
 
function LaunchEOL 
{ 
    param 
    ( 
        $cred 
    ) 
     
    $UserCredential = $cred 
     
    $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection 
     
    Import-PSSession $Session -Prefix "EOL" -AllowClobber 
} 
Function RemoveEOL 
{ 
     
    $Session = Get-PSSession | where { $_.ComputerName -like "outlook.office365.com" } 
    Remove-PSSession $Session 
     
} 
 
function LaunchMSOL 
{ 
    param 
    ( 
        $cred 
    ) 
    $UserCredential = $cred 
    import-module msonline 
    Write-Host "Enter MS Online Credentials" -ForegroundColor Green 
    Connect-MsolService -Credential $UserCredential 
} 
Function RemoveMSOL 
{ 
     
    Write-host "Close Powershell Window - No disconnect available" -ForegroundColor yellow 
} 
 
##########################Load variables & Logs#################### 
$log = Write-Log -Name "process_o365EOLLicenseReconciliation" -folder logs -Ext log 
$Report1 = Write-Log -Name "o365EOLLicenseReconciliation" -folder Report -Ext csv 
$Report2 = Write-Log -Name "Erroro365EOLLicenseReconciliation" -folder Report -Ext csv 
 
$licenseE3 = "Company:ENTERPRISEPACK" 
$licenseF1 = "Company:DESKLESSPACK" 
 
$service1 = "EXCHANGE_S_ENTERPRISE" 
$service2 = "MCOSTANDARD" 
 
$service1f1 = "EXCHANGE_S_DESKLESS" 
$service2f1 = "MCOIMP" 
 
$collection = @() 
$smtpserver = "smtp.labtest.com" 
$from = "AutomateA@labtest.com" 
$erroremail = "Reports@labtest.com" 
#####################userid/password########################## 
$userId = "MGMT-SVC@labtest.com" 
$encrypted1 = "01000000d08c9ddf0115d1118c7a00c04fuljhvxnlhmxkwh00c000000010000000e140468d5d37jjk00000004800000a000000010000000e217f1a562a51a14cc58536b442e919b200000003dec6fa22cbb8482ebf6c724b74718c7127bf52594c4ac527fa26701fd49b1321400000072da6316c8fd50bd9facca90f475660c24dab279" 
$pwd = ConvertTo-SecureString -string $encrypted1 
$Credential = New-Object System.Management.Automation.PSCredential -ArgumentList $userId$pwd 
##########Start Script main############## 
Start-Transcript -Path $log 
get-date 
try 
{ 
    LaunchEOL -Cred $Credential 
    LaunchMSOL -cred $Credential 
} 
catch 
{ 
    write-host "$($_.Exception.Message)" -foregroundcolor red 
    Send-MailMessage -SmtpServer $smtpserver -From $from -To $erroremail -Subject "Exchange online/MSOL License reconciliation connection Error" -Body $($_.Exception.Message) 
    break 
} 
$AllLicensingPlansE3 = Get-MsolAccountSku | Where-Object{ $_.AccountSkuId -eq $licenseE3 } 
$AllLicensingPlansF1 = Get-MsolAccountSku | Where-Object{ $_.AccountSkuId -eq $licenseF1 } 
 
$getUsersneedingLic = Get-MsolUser -LicenseReconciliationNeededOnly -ALL 
$getUsersneedingLic | ForEach-Object{ 
    $mcoll = "" | select UserPrincipalName, EOLExist, LicenseStatus 
    $upn = $_.UserPrincipalName 
    $mcoll.UserPrincipalName = $upn 
    $eolmbx = Get-EOLMailbox -id $upn -ea silentlycontinue 
    $Error.clear() 
    if ($eolmbx) 
    { 
        $mcoll.EOLExist = "True" 
        ###########Apply EOL/SKOB License############ 
        Write-host "License Processing for .... $upn" -ForegroundColor Green 
         
        $lic = get-msoluser -UserPrincipalName $upn 
        ###########Check for E3 for assigning EOL/SKOB######## 
        if ($lic.Licenses.AccountSkuid -eq $licenseE3) 
        { 
            $sts = $lic.Licenses | where{ $_.AccountSkuId -eq $licenseE3 } 
            $status = $sts.servicestatus 
            if ($status -ne $null) 
            { 
                $collnmsts = @() 
                foreach ($svc in $status) 
                { 
                    $svcnm = $svc.Serviceplan.ServiceName 
                    $svcsts = $svc.ProvisioningStatus 
                    if ((($svcsts -eq "Disabled"-and ($svcnm -ne $service1)) -and 
                        (($svcsts -eq "Disabled"-and ($svcnm -ne $service2))) 
                    { 
                        $collnmsts +$svcnm 
                    } 
                } 
                $O365Licences = $null 
                for ($i = 0; $i -lt $AllLicensingPlansE3.count; $i++) 
                { 
                    $O365Licences = New-MsolLicenseOptions -AccountSkuId $AllLicensingPlansE3[$i].AccountSkuId -DisabledPlans $collnmsts 
                } 
                Set-MsolUserLicense -UserPrincipalName $upn -LicenseOptions $O365Licences 
                if ($error) 
                { 
                    $mcoll.LicenseStatus = "error" 
                    $Error.clear() 
                } 
                else 
                { 
                    Write-Host "Updating License for ...$upn" -ForegroundColor Magenta 
                    $mcoll.LicenseStatus = "Updated" 
                } 
            } 
        } 
        ###########Check for F1 for assigning EOL/SKOB######## 
        if ($lic.Licenses.AccountSkuid -eq $licenseF1) 
        { 
            $sts = $lic.Licenses | where{ $_.AccountSkuId -eq $licenseF1 } 
            $status = $sts.servicestatus 
            if ($status -ne $null) 
            { 
                $collnmsts = @() 
                foreach ($svc in $status) 
                { 
                    $svcnm = $svc.Serviceplan.ServiceName 
                    $svcsts = $svc.ProvisioningStatus 
                    if ((($svcsts -eq "Disabled"-and ($svcnm -ne $service1f1)) -and 
                        (($svcsts -eq "Disabled"-and ($svcnm -ne $service2f1))) 
                    { 
                        $collnmsts +$svcnm 
                    } 
                } 
                $O365Licences = $null 
                for ($i = 0; $i -lt $AllLicensingPlansF1.count; $i++) 
                { 
                    $O365Licences = New-MsolLicenseOptions -AccountSkuId $AllLicensingPlansF1[$i].AccountSkuId -DisabledPlans $collnmsts 
                } 
                Set-MsolUserLicense -UserPrincipalName $upn -LicenseOptions $O365Licences 
                if ($error) 
                { 
                    $mcoll.LicenseStatus = "error" 
                    $Error.clear() 
                } 
                else 
                { 
                    Write-Host "Updating License for ...$upn" -ForegroundColor Magenta 
                    $mcoll.LicenseStatus = "Updated" 
                } 
            } 
        } 
        if($lic.IsLicensed -eq $false) 
        { 
            $mcoll.LicenseStatus = "LicenseNotFound" 
        } 
        ################################################### 
    } 
    else 
    { 
        $mcoll.EOLExist = "False" 
        $mcoll.LicenseStatus = "Not Required" 
    } 
    $collection +$mcoll 
} 
if ($collection) 
{ 
    $reportcoll1=@() 
    $reportcoll1 = $collection | where{ ($_.LicenseStatus -ne "Error"-and ($_.LicenseStatus -ne "LicenseNotFound") } 
    if ($reportcoll1) 
    { 
        $reportcoll1 | Export-Csv $Report1 -NoTypeInformation 
        Send-MailMessage -SmtpServer $smtpserver -From $from -To $erroremail -Subject "Exchange online/MSOL License reconciliation Report" -Attachments $Report1 
    } 
     
    $reportcoll2 = @() 
    $reportcoll2 = $collection | where{ ($_.LicenseStatus -eq "error"-or ($_.LicenseStatus -eq "LicenseNotFound") } 
    if ($reportcoll2) 
    { 
        $reportcoll2 | Export-Csv $Report2 -NoTypeInformation 
        Send-MailMessage -SmtpServer $smtpserver -From $from -To $erroremail -Subject "Error Report - Exchange online/MSOL License reconciliation" -Attachments $Report2 
    } 
} 
 
########################Recycle reports & logs############## 
$path1 = ".\report\" 
$path2 = ".\Logs\" 
$limit = (Get-Date).AddDays(-60) #for report recycling 
Get-ChildItem -Path $path1 | Where-Object { 
    $_.CreationTime -lt $limit 
} | Remove-Item -recurse -Force 
 
Get-ChildItem -Path $path2 | Where-Object { 
    $_.CreationTime -lt $limit 
} | Remove-Item -recurse -Force 
 
get-date 
Write-Host "Script finished" -ForegroundColor green 
Stop-Transcript 
##############################################################################

 

Thanks for reading and downloading

Sukhija Vikas

http://SysCloudPro.com

One thought on “Office 365 License Reconciliation

  1. Pingback: Office 365 License Reconciliation | Cloud Computers Guide

Leave a comment