Home
%3CLINGO-SUB%20id%3D%22lingo-sub-571844%22%20slang%3D%22en-US%22%3EO365%20Tidbit%20-%20Script%20to%20collect%20license%20info%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-571844%22%20slang%3D%22en-US%22%3E%0A%20%26lt%3Bmeta%20http-equiv%3D%22Content-Type%22%20content%3D%22text%2Fhtml%3B%20charset%3DUTF-8%22%20%2F%26gt%3B%3CSTRONG%3EFirst%20published%20on%20TECHNET%20on%20Apr%2003%2C%202018%20%3C%2FSTRONG%3E%20%3CBR%20%2F%3E%20Hello%20All%2C%20%3CBR%20%2F%3E%20%3CBR%20%2F%3E%20Recently%20I%20had%20a%20customer%20who%20had%20questions%20about%20what%20licenses%20their%20users%20had%20assigned%20to%20them%20in%20O365%2C%20specifically%20the%20questions%20were%20%3CBR%20%2F%3E%20%3CBR%20%2F%3E%20How%20many%20E3%20SKU%E2%80%99s%20are%20assigned%20to%20users%20without%20an%20E1%3F%20%3CBR%20%2F%3E%20%3CBR%20%2F%3E%20How%20many%20E5%20SKU%E2%80%99s%20are%20assigned%20to%20users%20without%20an%20E1%3F%20%3CBR%20%2F%3E%20%3CBR%20%2F%3E%20Since%20they%20were%20not%20able%20to%20get%20a%20satisfactory%20answer%20from%20support%20or%20tools%2C%20I%20jumped%20into%20PowerShell%20and%20came%20up%20with%20this%20script.%20%3CBR%20%2F%3E%20%3CBR%20%2F%3E%20NOTE%3A%20Full%20script%20is%20available%20%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2FChristwe%2FPowerShellReporsitory%2Fblob%2Fmaster%2FGetLicenceInfo.ps1%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%22%3E%20here%20%3C%2FA%3E%20%3CBR%20%2F%3E%20%3CBR%20%2F%3E%20First%20I%20made%20sure%20that%20MSOnline%20was%20installed%20and%20then%20I%20import%20the%20module%20thru%20the%20following%20lines%20%3CBR%20%2F%3E%20%23Trust%20repository%20so%20we%20can%20automate%20install%20of%20MSOnline%20%3CBR%20%2F%3E%20Set-PSRepository%20-Name%20PSGallery%20-InstallationPolicy%20Trusted%20%3CBR%20%2F%3E%20%3CBR%20%2F%3E%20%23PowerShellGet%20requires%20NuGet%20%3CBR%20%2F%3E%20If(!(Get-PackageProvider%20-Name%20NuGet))%20%3CBR%20%2F%3E%20%7B%20%3CBR%20%2F%3E%20Install-PackageProvider%20-Name%20NuGet%20-Force%20%3CBR%20%2F%3E%20%7D%20%3CBR%20%2F%3E%20%3CBR%20%2F%3E%20%23Verify%20MSOnline%20is%20installed%20or%20Update%5CInstall%20MSOnline%20module%20%3CBR%20%2F%3E%20if%20(Get-InstalledModule%20-Name%20MSOnline)%20%3CBR%20%2F%3E%20%7B%20%3CBR%20%2F%3E%20Update-Module%20MSOnline%20%3CBR%20%2F%3E%20Import-Module%20MSOnline%20%3CBR%20%2F%3E%20%7DElse%20%3CBR%20%2F%3E%20%7B%20%3CBR%20%2F%3E%20Install-Module%20MSOnline%20%3CBR%20%2F%3E%20Import-Module%20MSOnline%20%3CBR%20%2F%3E%20%7D%20%3CBR%20%2F%3E%20With%20the%20module%20imported%20and%20connecting%20via%20Connect-MsolService%20I%20then%20perform%20two%20things%2C%20the%20first%20is%20to%20get%20a%20high%20level%20look%20at%20the%20license%20by%20using%20the%20following%20lines%20%3CBR%20%2F%3E%20Get-MsolAccountSku%20%7C%20ForEach-Object%20%7B%20%3CBR%20%2F%3E%20%24Plan%20%3D%20%24_.SkuPartNumber%20%3CBR%20%2F%3E%20%24ActiveUnits%20%3D%20%24_.ActiveUnits%20%3CBR%20%2F%3E%20%24ConsumedUnits%20%3D%20%24_.ConsumedUnits%20%3CBR%20%2F%3E%20%24LockedOutUnits%20%3D%20%24_.LockedOutUnits%20%3CBR%20%2F%3E%20Add-Content%20-Path%20%22%24OutputFolder%5C%24TenantLicenseFile%22%20-Value%20%22%24Plan%2C%24ActiveUnits%2C%24ConsumedUnits%2C%24LockedOutUnits%2C%2C%22%20%3CBR%20%2F%3E%20%24_.ServiceStatus%20%7C%20ForEach-Object%20%7B%20%3CBR%20%2F%3E%20%24Service%20%3D%20%24_.ServicePlan.ServiceName%20%3CBR%20%2F%3E%20%24ServiceStatus%20%3D%20%24_.ProvisioningStatus%20%3CBR%20%2F%3E%20Add-Content%20-Path%20%22%24OutputFolder%5C%24TenantLicenseFile%22%20-Value%20%22%2C%2C%2C%2C%24Service%2C%24ServiceStatus%22%20%3CBR%20%2F%3E%20%7D%20%3CBR%20%2F%3E%20%7D%20%3CBR%20%2F%3E%20Then%20I%20gather%20the%20sku%20information%20for%20each%20user%20using%20the%20following%3A%20%3CBR%20%2F%3E%20Get-MsolUser%20%7C%20ForEach-Object%20%7B%20%3CBR%20%2F%3E%20%24User%20%3D%20%24_.UserPrincipalName%20%3CBR%20%2F%3E%20if(%24_.IsLicensed)%20%3CBR%20%2F%3E%20%7B%20%3CBR%20%2F%3E%20%24_.Licenses%20%7C%20ForEach-Object%20%7B%20%3CBR%20%2F%3E%20%24Plan%20%3D%20%24_.AccountSkuId%20%3CBR%20%2F%3E%20Switch%20-Wildcard%20(%24Plan)%7B%20%3CBR%20%2F%3E%20%22*ENTERPRISEPREMIUM%22%20%7B%24E5%20%3D%20%24true%7D%20%3CBR%20%2F%3E%20%22*ENTERPRISEPACK%22%20%7B%24E3%20%3D%20%24true%7D%20%3CBR%20%2F%3E%20%22*STANDARDPACK%22%20%7B%24E1%20%3D%20%24true%7D%20%3CBR%20%2F%3E%20%7D%20%3CBR%20%2F%3E%20ForEach(%24Service%20in%20%24_.ServiceStatus)%20%3CBR%20%2F%3E%20%7B%20%3CBR%20%2F%3E%20%24ServiceName%20%3D%20%24Service.ServicePlan.ServiceType%20%3CBR%20%2F%3E%20%24ServiceStatus%20%3D%20%24Service.ProvisioningStatus%20%3CBR%20%2F%3E%20Add-Content%20-Path%20%22%24OutputFolder%5C%24UserLicenseFile%22%20-Value%20%22%24User%2C%24Plan%2C%24Servicename%2C%24ServiceStatus%22%20%3CBR%20%2F%3E%20%7D%20%3CBR%20%2F%3E%20%7D%20%3CBR%20%2F%3E%20%7D%20%3CBR%20%2F%3E%20Then%20I%20complete%20the%20script%20by%20updating%20variables%20and%20providing%20the%20responses%20in%20a%20text%20file.%26nbsp%3B%20While%20this%20script%20is%20very%20specific%20hopefully%20it%20will%20help%20you%20to%20manipulate%20the%20data%20out%20there%20to%20get%20answers%20for%20your%20own%20questions.%20%3CBR%20%2F%3E%20%3CBR%20%2F%3E%20Pax%3C%2FLINGO-BODY%3E%3CLINGO-TEASER%20id%3D%22lingo-teaser-571844%22%20slang%3D%22en-US%22%3EFirst%20published%20on%20TECHNET%20on%20Apr%2003%2C%202018%20Hello%20All%2CRecently%20I%20had%20a%20customer%20who%20had%20questions%20about%20what%20licenses%20their%20users%20had%20assigned%20to%20them%20in%20O365%2C%20specifically%20the%20questions%20wereHow%20many%20E3%20SKU%E2%80%99s%20are%20assigned%20to%20users%20without%20an%20E1%3F%20How%20many%20E5%20SKU%E2%80%99s%20are%20assigned%20to%20users%20without%20an%20E1%3FSince%20they%20were%20not%20able%20to%20get%20a%20satisfactory%20answer%20from%20support%20or%20tools%2C%20I%20jumped%20into%20PowerShell%20and%20came%20up%20with%20this%20script.%3C%2FLINGO-TEASER%3E%3CLINGO-LABS%20id%3D%22lingo-labs-571844%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3ELicense%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3ELicensing%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3EO365%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3EPowerShell%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3ESharePoint%20Online%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3ESPO%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E
First published on TECHNET on Apr 03, 2018
Hello All,

Recently I had a customer who had questions about what licenses their users had assigned to them in O365, specifically the questions were

How many E3 SKU’s are assigned to users without an E1?

How many E5 SKU’s are assigned to users without an E1?

Since they were not able to get a satisfactory answer from support or tools, I jumped into PowerShell and came up with this script.

NOTE: Full script is available here

First I made sure that MSOnline was installed and then I import the module thru the following lines
#Trust repository so we can automate install of MSOnline
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted

#PowerShellGet requires NuGet
If(!(Get-PackageProvider -Name NuGet))
{
Install-PackageProvider -Name NuGet -Force
}

#Verify MSOnline is installed or Update\Install MSOnline module
if (Get-InstalledModule -Name MSOnline)
{
Update-Module MSOnline
Import-Module MSOnline
}Else
{
Install-Module MSOnline
Import-Module MSOnline
}
With the module imported and connecting via Connect-MsolService I then perform two things, the first is to get a high level look at the license by using the following lines
Get-MsolAccountSku | ForEach-Object {
$Plan = $_.SkuPartNumber
$ActiveUnits = $_.ActiveUnits
$ConsumedUnits = $_.ConsumedUnits
$LockedOutUnits = $_.LockedOutUnits
Add-Content -Path "$OutputFolder\$TenantLicenseFile" -Value "$Plan,$ActiveUnits,$ConsumedUnits,$LockedOutUnits,,"
$_.ServiceStatus | ForEach-Object {
$Service = $_.ServicePlan.ServiceName
$ServiceStatus = $_.ProvisioningStatus
Add-Content -Path "$OutputFolder\$TenantLicenseFile" -Value ",,,,$Service,$ServiceStatus"
}
}
Then I gather the sku information for each user using the following:
Get-MsolUser | ForEach-Object {
$User = $_.UserPrincipalName
if($_.IsLicensed)
{
$_.Licenses | ForEach-Object {
$Plan = $_.AccountSkuId
Switch -Wildcard ($Plan){
"*ENTERPRISEPREMIUM" {$E5 = $true}
"*ENTERPRISEPACK" {$E3 = $true}
"*STANDARDPACK" {$E1 = $true}
}
ForEach($Service in $_.ServiceStatus)
{
$ServiceName = $Service.ServicePlan.ServiceType
$ServiceStatus = $Service.ProvisioningStatus
Add-Content -Path "$OutputFolder\$UserLicenseFile" -Value "$User,$Plan,$Servicename,$ServiceStatus"
}
}
}
Then I complete the script by updating variables and providing the responses in a text file.  While this script is very specific hopefully it will help you to manipulate the data out there to get answers for your own questions.

Pax