Directly assigned or Inherited Office 365 Licenses ?

Hello, today I am sharing with you an interesting Office 365 script that I hope will help you. This script will tell you how licenses are assigned to a set of user in your Office 365 tenant : Direct or Inherited ?

My script consists of 2 parts, the first determines License Plans assigned to a user account, the second one dertermines the Licenses paths (Direct or Inherited).

function Get-LicensePlan {

    param (

        [Parameter(Mandatory=$true)]
        [String]$SkuId,
        [Parameter(mandatory=$true)]
        [String]$TenantName

    )

    Switch($SkuId){

                      "$($TenantName):AAD_PREMIUM" {return "AAD Premium P1"}
                   "$($TenantName):AX7_USER_TRIAL" {return "D_AX7.0 TRIAL"}
          "$($TenantName):DYN365_ENTERPRISE_P1_IW" {return "D365 ETR P1"}
              "$($TenantName):DYN365_RETAIL_TRIAL" {return "D365 CRM TRIAL"}
                              "$($TenantName):EMS" {return "EMS_E3"}
                       "$($TenantName):EMSPREMIUM" {return "EMS_E5"}
                     "$($TenantName):DESKLESSPACK" {return "F1"}
                     "$($TenantName):STANDARDPACK" {return "E1"}
                   "$($TenantName):ENTERPRISEPACK" {return "E3"}
                "$($TenantName):ENTERPRISEPREMIUM" {return "E5"}
                        "$($TenantName):FLOW_FREE" {return "FLOW FREE"}
                      "$($TenantName):INTUNE_A_VL" {return "INTUNE"}
                       "$($TenantName):MCOMEETADV" {return "SFB PSTN Conf"}
        "$($TenantName):MICROSOFT_BUSINESS_CENTER" {return "MBC"}
                     "$($TenantName):POWER_BI_PRO" {return "PBI PRO"}
                "$($TenantName):POWER_BI_STANDARD" {return "PBI STD"}
        "$($TenantName):POWERAPPS_INDIVIDUAL_USER" {return "PAPPS IND User"}
                  "$($TenantName):POWERAPPS_VIRAL" {return "PAPPS and LOGIC FLOW"}
                   "$($TenantName):PROJECTPREMIUM" {return "PJ Online"}
                           "$($TenantName):STREAM" {return "STREAM"}
                "$($TenantName):VISIOONLINE_PLAN1" {return "VISIO P1"}
              "$($TenantName):WACONEDRIVESTANDARD" {return "OD P1"}
                      "$($TenantName):WIN_DEF_ATP" {return "WDF ATP"}
                                           default {return $SkuId.Replace("$($TenantName):","")}
    }

}

With the function Get-LicensePlan, we know what licenses are assigned to a user based on the SkuId. The following second function Get-LAPATH (Get-LicenseAssingmentPaths) will tell us if the licenses are Direct assigned or Inherited from a group.

 

function Get-LAPATH{

    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$true, ValueFromPipeline=$true)]
        [string]$UPN
    )

    Begin{
        Get-Date
        Write-Host "## Data processing stated at $(Get-date)" -ForegroundColor Yellow
        Write-Host ""
        $TenantName = ((Get-MsolAccountSku).AccountSkuId[0] -split(':'))[0]
    }

    Process{
        
        Write-Host ""
        Write-Host "Working on $UPN" -ForegroundColor Green
        $User = Get-MsolUser -UserPrincipalName $UPN

        #Getting assignment paths
        $LicensesTab = $null
        $LicensePlan = $null
        $LicTabCount = 0
        $LicensesTab = $User.Licenses | Select-Object AccountSkuId, GroupsAssigningLicense

        if($LicensesTab){

            Write-Host "License Enabled : True" -ForegroundColor Yellow

            $i = 0 #(Measure-Object -InputObject $LicensesTab).Count
            $LicTabCount = $LicensesTab.AccountSkuId.Count

            Do{

                #Getting License Plan
                $LicensePlan = Get-LicensePlan -SkuId $LicensesTab[$i].AccountSkuId -TenantName $TenantName

                #Getting License Paths
                [System.Collections.ArrayList]$LicensePath = @()

                if($LicensesTab[$i].GroupsAssigningLicense){

                    foreach ($Guid in $LicensesTab[$i].GroupsAssigningLicense.guid){

                        if($Guid -eq $User.ObjectId.Guid){
                            $LicensePath.Add("Direct") | Out-Null
                        }
                        else{
                            $LicensePath.Add((Get-MsolGroup -ObjectId $Guid).DisplayName) | Out-Null
                        }

                    }
                }
                else{
                    $LicensePath.Add("Direct") | Out-Null
                }

                Write-Host "$LicensePlan : $([String]::Join(",",$LicensePath.ToArray()))" -ForegroundColor Yellow
                $i++

            }
            While ($i -ne $LicTabCount)
        }
        else {
            Write-Host "License Enabled : false" -ForegroundColor Red
        }
    }

    End{
        Write-Host ""
        Write-Host "## Data Processing ended on $(Get-Date)" -ForegroundColor Yellow
    }

}

Now that everything is set, let’s talk about how to use this script to achieve your goal. Of course, for running this script, you need to have Microsoft Online Services PowerShell installed on your computer (PowerShell Module For Office 365) and a read access permissions on your Office 365 Admin portal to see users configuration,  ideally User Management Role.

  • To see Office 365 license assginment paths for one user
"<UserPrincipalName>" | Get-LAPATH

Get-LAPATH_multiples_One

The user james.bond@acidalien.fr has 3 licenses plans assigned:

  1. FLOW FREE inherited from the license group GRP-FLOW-FREE
  2. FLOW FREE directly assigned
  3. DEVELOPERPACK directly assigned
  • To see Office 365 license assignment paths for several users 

From a Powershell table

"<User1 upn>" ,"<User2 upn>","..." | Get-LAPATH

Get-LAPATH_multiples_2

From a file containing the list of UserPrincipalName :

Get-LAPATH_multiples_File

Get-Content -Path <File path.txt> | Get-LAPATH

Get-LAPATH_multiples

Et voilà 🙂