Public/Licensing/Get-AzureAdUserLicense.ps1
# Module: TeamsFunctions # Function: Licensing # Author: David Eberhardt # Updated: 01-APR-2020 # Status: Live function Get-AzureAdUserLicense { <# .SYNOPSIS Returns License information for an Object in AzureAD .DESCRIPTION Returns an Object containing all Licenses found for a specific Object Licenses and ServicePlans are nested in the respective parameters for further investigation .PARAMETER UserPrincipalname The UserPrincipalname or ObjectId of the Object. .PARAMETER FilterRelevantForTeams Filters the output and displays only Licenses relevant to Teams .EXAMPLE Get-AzureAdUserLicense [-UserPrincipalname] John@domain.com Displays all licenses assigned to User John@domain.com .EXAMPLE Get-AzureAdUserLicense -UserPrincipalname John@domain.com,Jane@domain.com Displays all licenses assigned to Users John@domain.com and Jane@domain.com .EXAMPLE Get-AzureAdUserLicense -UserPrincipalname Jane@domain.com -FilterRelevantForTeams Displays all relevant Teams licenses assigned to Jane@domain.com .EXAMPLE Import-Csv User.csv | Get-AzureAdUserLicense Displays all licenses assigned to Users from User.csv, Column UserPrincipalname, ObjectId or Identity. The input file must have a single column heading of "UserPrincipalname" with properly formatted UPNs. .INPUTS System.String .OUTPUTS System.Object .NOTES Requires a connection to Azure Active Directory .COMPONENT Licensing .FUNCTIONALITY Returns a list of Licenses assigned to a specific User depending on input .LINK https://github.com/DEberhardt/TeamsFunctions/tree/main/docs/Get-AzureAdUserLicense.md .LINK https://github.com/DEberhardt/TeamsFunctions/tree/main/docs/about_Licensing.md .LINK https://github.com/DEberhardt/TeamsFunctions/tree/main/docs/about_UserManagement.md .LINK https://github.com/DEberhardt/TeamsFunctions/tree/main/docs/ #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidGlobalVars', '', Justification = 'Required for performance. Removed with Disconnect-Me')] [CmdletBinding()] [OutputType([PSCustomObject])] param( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName, HelpMessage = 'Enter the UPN or login name of the user account, typically <user>@<domain>.')] [Alias('ObjectId', 'Identity')] [ValidateScript( { If ($_ -match '@' -or $_ -match $script:TFMatchGuid) { $True } else { throw [System.Management.Automation.ValidationMetadataException] 'Value must be a valid UPN or ObjectId' } })] [string[]]$UserPrincipalName, [Parameter(HelpMessage = 'Displays only Licenses relevant to Teams')] [switch]$FilterRelevantForTeams ) #param begin { Show-FunctionStatus -Level Live $Stack = Get-PSCallStack $Called = ($stack.length -ge 3) Write-Verbose -Message "[BEGIN ] $($MyInvocation.MyCommand)" # Asserting AzureAD Connection if ( -not $script:TFPSSA) { $script:TFPSSA = Assert-AzureADConnection; if ( -not $script:TFPSSA ) { break } } # Setting Preference Variables according to Upstream settings if (-not $PSBoundParameters.ContainsKey('Verbose')) { $VerbosePreference = $PSCmdlet.SessionState.PSVariable.GetValue('VerbosePreference') } if (-not $PSBoundParameters.ContainsKey('Confirm')) { $ConfirmPreference = $PSCmdlet.SessionState.PSVariable.GetValue('ConfirmPreference') } if (-not $PSBoundParameters.ContainsKey('WhatIf')) { $WhatIfPreference = $PSCmdlet.SessionState.PSVariable.GetValue('WhatIfPreference') } if (-not $PSBoundParameters.ContainsKey('Debug')) { $DebugPreference = $PSCmdlet.SessionState.PSVariable.GetValue('DebugPreference') } else { $DebugPreference = 'Continue' } if ( $PSBoundParameters.ContainsKey('InformationAction')) { $InformationPreference = $PSCmdlet.SessionState.PSVariable.GetValue('InformationAction') } else { $InformationPreference = 'Continue' } # preparing Output Field Separator $OFS = ', ' # do not remove - Automatic variable, used to separate elements! } #begin process { Write-Verbose -Message "[PROCESS] $($MyInvocation.MyCommand)" foreach ($User in $UserPrincipalName) { try { $UserObject = $null $UserLicenseDetail = $null #New Graph Equivalent to be rolled out through Refactor in Orbit #$UserObject = Get-MgUserLicenseDetail -UserId "$User" -WarningAction SilentlyContinue -ErrorAction STOP $UserObject = Get-AzureADUser -ObjectId "$User" -WarningAction SilentlyContinue -ErrorAction STOP #New Graph Equivalent to be rolled out through Refactor in Orbit #$UserLicenseDetail = Get-MgUserLicenseDetail -UserId "$User" -WarningAction SilentlyContinue -ErrorAction STOP $UserLicenseDetail = Get-AzureADUserLicenseDetail -ObjectId "$User" -WarningAction SilentlyContinue -ErrorAction STOP } catch { #Write-Error -Message "Error ocurred for User '$User': $($_.Exception.Message)" -Category InvalidResult throw $_ continue } [string]$DisplayName = $UserObject.DisplayName if ( $UserLicenseDetail ) { # Querying Licenses $UserLicenses = Get-UserLicensesFromLicenseDetailObject -UserLicenseDetail $UserLicenseDetail @args # Querying Service Plans $UserServicePlans = Get-UserServicePlansFromLicenseDetailObject -UserLicenseDetail $UserLicenseDetail @args } # Filter if ( $FilterRelevantForTeams.IsPresent ) { $UserLicenses = $UserLicenses | Where-Object { $_.IncludesTeams -or $_.IncludesPhoneSystem } $UserServicePlans = $UserServicePlans | Where-Object RelevantForTeams } # Determining Phone System Status $PhoneSystemLicense = ('MCOEV' -in $UserServicePlans.ServicePlanName) $PhoneSystemVirtual = ('MCOEV_VIRTUALUSER' -in $UserServicePlans.ServicePlanName) if ( $PhoneSystemLicense ) { $PhoneSystemProvisioningStatus = $UserServicePlans | Where-Object ServicePlanName -EQ 'MCOEV' if ( $PhoneSystemProvisioningStatus.Count -gt 1 ) { # PhoneSystem assigned more than once! Write-Warning -Message "User '$User' Multiple assignments found for PhoneSystem. Please verify License assignment." $PhoneSystemStatus = ($PhoneSystemProvisioningStatus | Select-Object -ExpandProperty ProvisioningStatus) -join ', ' } else { $PhoneSystemStatus = $PhoneSystemProvisioningStatus.ProvisioningStatus } } elseif ( $PhoneSystemVirtual ) { $PhoneSystemStatus = ($UserServicePlans | Where-Object ServicePlanName -EQ 'MCOEV_VIRTUALUSER').ProvisioningStatus } else { $PhoneSystemStatus = 'Unassigned' } # Calling Plans $currentCallingPlan = ($UserLicenses | Where-Object LicenseType -EQ 'CallingPlan').ProductName # Output $output = [PSCustomObject][ordered]@{ PSTypeName = 'PowerShell.TeamsFunctsions.AzureAdUserLicense' UserPrincipalName = $UserObject.UserPrincipalName DisplayName = $DisplayName #UserId = $UserObject.Id ObjectId = $UserObject.ObjectId UsageLocation = $UserObject.UsageLocation Licenses = $UserLicenses ServicePlans = $UserServicePlans AudioConferencing = $('MCOMEETADV' -in $UserServicePlans.ServicePlanName) CommonAreaPhoneLicense = $('MCOCAP' -in $UserLicenses.SkuPartNumber) PhoneSystemVirtualUser = $PhoneSystemVirtual PhoneSystem = $PhoneSystemLicense PhoneSystemStatus = $PhoneSystemStatus CallingPlanDomestic120 = $('MCOPSTN5' -in $UserServicePlans.ServicePlanName -or 'MCOPSTN_5' -in $UserServicePlans.ServicePlanName) CallingPlanDomestic = $('MCOPSTN1' -in $UserServicePlans.ServicePlanName -or 'MCOPSTN_1' -in $UserServicePlans.ServicePlanName) # also covering MCOPSTN_1_GOV CallingPlanInternational = $('MCOPSTN2' -in $UserServicePlans.ServicePlanName -or 'MCOPSTNEAU2' -in $UserServicePlans.ServicePlanName) OtherCallingPlan = $('MCOPSTNEAU2' -in $UserServicePlans.ServicePlanName -or 'BUSINESS_VOICE_MED2_TELCO' -in $UserServicePlans.ServicePlanName) CommunicationsCredits = $('MCOPSTNC' -in $UserServicePlans.ServicePlanName) CallingPlan = $currentCallingPlan } # Adding Script Method to Licenses and ServicePlans if ( $output.Licenses ) { $output.Licenses | Add-Member -MemberType ScriptMethod -Name ToString -Value { $this.ProductName } -Force } if ( $output.ServicePlans ) { $output.ServicePlans | Add-Member -MemberType ScriptMethod -Name ToString -Value { $this.ProductName } -Force } Write-Output $output } } #process end { Write-Verbose -Message "[END ] $($MyInvocation.MyCommand)" } #end } #Get-AzureAdUserLicense |