Home Getting licenses assigned to user accounts
Post
Cancel

Getting licenses assigned to user accounts

Create a report of licenses assigned to Azure AD user accounts using the Microsoft Graph API

This is a rewrite from here practical365.com

My misson was to rewrite the script to use the Microsoft Graph API instead of the MgGraph PowerShell module.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

$ClientID = ''
$ClientSecret = ''
$tenant_Id = ''

# Connect to Graph #

$Body = @{    
    Grant_Type    = "client_credentials"
    resource      = "https://graph.microsoft.com"
    client_id     = $clientId
    client_secret = $clientSecret
} 
  
$ConnectGraph = Invoke-RestMethod -Uri "https://login.microsoft.com/$tenant_Id/oauth2/token?api-version=1.0" -Method POST -Body $Body

# Variable Collections #

$CSVOutputFile = "c:\temp\Microsoft365LicensesReport.CSV"
$today = Get-Date

$Headers = @{
    'Content-Type'  = "application/json"
    'Authorization' = "Bearer $($ConnectGraph.access_token)"
}

$token = $ConnectGraph.access_token

# Force TLS 1.2.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

function Get-GraphData {
    param (
        [parameter(Mandatory)]
        [string]$AccessToken,
      
        [parameter(Mandatory)]
        [string]$Uri
    )

    $Headers = @{
        'Authorization' = "Bearer $AccessToken"
    }

    do {
        $Results = Invoke-RestMethod -Uri $Uri -Headers $Headers -ErrorAction Stop

        $QueryResults += $Results.value

        $Uri = $Results.'@odata.nextLink'
    } while ($Uri)

    return $QueryResults
}

#This request get SecureScore

[array]$Skus = Get-GraphData -AccessToken $Token -Uri "https://graph.microsoft.com/beta/subscribedSkus"
#[Array]$Skus = Get-MgSubscribedSku

# Generate CSV of all product SKUs used in tenant
[array]$Sku = $Skus | Select-Object SkuId, SkuPartNumber
# Generate list of all service plans used in SKUs in tenant
$SPData = [System.Collections.Generic.List[Object]]::new()
ForEach ($Sk in $Skus) {
    ForEach ($SP in $Sk.ServicePlans) {
        $SPLine = [PSCustomObject][Ordered]@{  
            ServicePlanId          = $SP.ServicePlanId
            ServicePlanName        = $SP.ServicePlanName
            ServicePlanDisplayName = $SP.ServicePlanName 
        }
        $SPData.Add($SPLine)
    }
}

$SkuHashTable = @{}
ForEach ($Line in $Sku) { 
    $SkuHashTable.Add([string]$Line.SkuId, [string]$Line.skuPartNumber) 
}
$ServicePlanHashTable = @{}
ForEach ($Line2 in $SPData) { $ServicePlanHashTable.Add([string]$Line2.ServicePlanId, [string]$Line2.ServicePlanDisplayName) }

[Array]$Users = Get-GraphData -AccessToken $Token -Uri "https://graph.microsoft.com/beta/users"
$Report = [System.Collections.Generic.List[Object]]::new()

ForEach ($User in $users) {
    If ([string]::IsNullOrWhiteSpace($User.AssignedLicenses) -eq $true) {
       # Only process account if it has some licenses
       Write-Host "Processing" $User.DisplayName
       [array]$LicenseInfo = $Null; [array]$DisabledPlans = $Null
       ForEach ($License in $User.AssignedLicenses) {
          If ($SkuHashTable.ContainsKey($License.SkuId) -eq $True) {
             # We found a match in the SKU hash table
             $LicenseInfo += $SkuHashTable.Item($License.SkuId) 
          }
          Else {
             # Nothing doing, so output the SkuID
             $LicenseInfo += $License 
          }
          # Report any disabled service plans in licenses
          If ([string]::IsNullOrWhiteSpace($License.DisabledPlans) -eq $False ) {
             # Check if disabled service plans in a license
             ForEach ($DisabledPlan in $License.DisabledPlans) {
                # Try and find what service plan is disabled
                If ($ServicePlanHashTable.ContainsKey($DisabledPlan) -eq $True) {
                   # We found a match in the Service Plans hash table
                   $DisabledPlans += $ServicePlanHashTable.Item($DisabledPlan) 
                }
                Else {
                   # Nothing doing, so output the Service Plan ID
                   $DisabledPlans += $DisabledPlan 
                }
             } # End ForEach disabled plans
          } # End if check for disabled plans  
       } # End Foreach Licenses
       # Report information
       [string]$DisabledPlans = $DisabledPlans -join ", "
       [string]$LicenseInfo = $LicenseInfo -join (", ")
       $ReportLine = [PSCustomObject][Ordered]@{  
          User             = $User.DisplayName
          UPN              = $User.UserPrincipalName
          Country          = $User.Country
          Department       = $User.Department
          Title            = $User.JobTitle
          Licenses         = $LicenseInfo
          "Disabled Plans" = $DisabledPlans 
       }
       Write-Host $ReportLine
       $Report.Add($ReportLine)
    } #end If account is licensed
    Else { $UnlicensedAccounts++ }
 } # End ForEach Users
 $Report | Export-CSV -NoTypeInformation $CSVOutputFile


This post is licensed under CC BY 4.0 by the author.