Public/Functions/Licensing/Get-AzureAdLicenseServicePlan.ps1
# Module: TeamsFunctions # Function: Licensing # Author: Philipp, Scripting.up-in-the.cloud # Updated: 01-DEC-2020 # Status: RC function Get-AzureAdLicenseServicePlan { <# .SYNOPSIS License information for AzureAD Service Plans related to Teams .DESCRIPTION Returns an Object containing all Teams related License Service Plans .EXAMPLE Get-TeamsLicense Returns 39 Azure AD Licenses that relate to Teams for use in other commands .NOTES Source https://scripting.up-in-the.cloud/licensing/o365-license-names-its-a-mess.html With very special thanks to Philip Reads https://docs.microsoft.com/en-us/azure/active-directory/users-groups-roles/licensing-service-plan-reference .COMPONENT Teams Migration and Enablement. License Assignment .ROLE Licensing .FUNCTIONALITY Returns a list of License Service Plans .LINK Get-TeamsTenantLicense Get-TeamsUserLicense Set-TeamsUserLicense Test-TeamsUserLicense Add-TeamsUserLicense (deprecated) Get-TeamsLicense Get-TeamsLicenseServicePlan Get-AzureAdLicense Get-AzureAdLicenseServicePlan #> [CmdletBinding()] [OutputType([Object[]])] param( [Parameter()] [switch]$FilterRelevantForTeams ) #param begin { Show-FunctionStatus -Level RC Write-Verbose -Message "[BEGIN ] $($MyInvocation.MyCommand)" [System.Collections.ArrayList]$Plans = @() [System.Collections.ArrayList]$PlansNotAdded = @() $planServicePlanNames = @{} } #begin process { #read the content of the Microsoft web page and extract the first table $url = "https://docs.microsoft.com/en-us/azure/active-directory/users-groups-roles/licensing-service-plan-reference" [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $content = (Invoke-WebRequest $url -UseBasicParsing).Content $content = $content.SubString($content.IndexOf("<tbody>")) $content = $content.Substring(0, $content.IndexOf("</tbody>")) #eliminate line feeds so that we can use regular expression to get the table rows... $content = $content -replace "`r?`n", '' $rows = (Select-String -InputObject $content -Pattern "<tr>(.*?)</tr>" -AllMatches).Matches | ForEach-Object { $_.Groups[1].Value } #on each table row, get the column cell content # 1st cell contains the product display name # 2nd cell contains the Sku ID (called 'string ID' here) # 3rd cell contains the included service plans (with string IDs) # 3rd cell contains the included service plans (with display names) $rows | ForEach-Object { $cells = (Select-String -InputObject $_ -Pattern "<td>(.*?)</td>" -AllMatches).Matches | ForEach-Object { $_.Groups[1].Value } $srcServicePlan = $cells[3] $srcServicePlanName = $cells[4] if (($srcServicePlan.Trim() -ne '') -and ($srcServicePlanName.Trim() -ne '')) { #store the service plan string IDs for later match $srcServicePlan -split "<br.?>" | ForEach-Object { $planServicePlanName = ($_.SubString(0, $_.LastIndexOf("("))).Trim() $planServicePlanId = $_.SubString($_.LastIndexOf("(") + 1) if ($planServicePlanId.Contains(")")) { $planServicePlanId = $planServicePlanId.SubString(0, $planServicePlanId.IndexOf(")")) } if (-not $planServicePlanNames.ContainsKey($planServicePlanId)) { $planServicePlanNames.Add($planServicePlanId, $planServicePlanName) } } #get te included service plans $srcServicePlanName -split "<br.?>" | ForEach-Object { $planProductName = ($_.SubString(0, $_.LastIndexOf("("))).Trim() $planServicePlanId = $_.SubString($_.LastIndexOF("(") + 1) if ($planServicePlanId.Contains(")")) { $planServicePlanId = $planServicePlanId.SubString(0, $planServicePlanId.IndexOf(")")) } # Add RelevantForTeams if ( $planServicePlanNames[$planServicePlanId] ) { if ( $planServicePlanNames[$planServicePlanId].Contains('TEAMS') -or $planServicePlanNames[$planServicePlanId].Contains('MCO') ) { $Relevant = $true } else { $Relevant = $false } } else { $Relevant = $false } # reworking ProductName into TitleCase $TextInfo = (Get-Culture).TextInfo $planProductName = $TextInfo.ToTitleCase($planProductName.ToLower()) $planProductName = Format-StringRemoveSpecialCharacter -String $planProductName -SpecialCharacterToKeep "()+ -" # Building Object if ($Plans.ServicePlanId -notcontains $planServicePlanId) { try { [void]$Plans.Add([TFTeamsServicePlan]::new($planProductName, "$($planServicePlanNames[$planServicePlanId])", "$planServicePlanId", $Relevant)) } catch { Write-Verbose "[TFTeamsServicePlan] Couldn't add entry for $planProductName" if ( $planProductName -ne "Powerapps For Office 365 K1") { $PlansNotAdded += $planProductName } } } } } } # Manually Adding to List of $Plans [void]$Plans.Add([TFTeamsServicePlan]::new("Communications Credits", "MCOPSTNC", "505e180f-f7e0-4b65-91d4-00d670bbd18c", $true)) [void]$Plans.Add([TFTeamsServicePlan]::new("Phone System - Virtual User", "MCOEV_VIRTUALUSER", "f47330e9-c134-43b3-9993-e7f004506889", $true)) # Output if ( $PlansNotAdded.Count -gt 0 ) { Write-Warning -Message "The following Products could not be added: $PlansNotAdded" } $PlansSorted = $Plans | Sort-Object ProductName if ($FilterRelevantForTeams) { $PlansSorted = $PlansSorted | Where-Object RelevantForTeams -EQ $TRUE } return $PlansSorted } #process end { Write-Verbose -Message "[END ] $($MyInvocation.MyCommand)" } #end } #Get-AzureAdLicenseServicePlan |