o365Skus.psm1
<#
=========================================================================== Created with: PowerShell ISE Created on: 11/28/2020 1:52 AM Created by: DataTraveler1 Organization: Filename: o365Skus.psd1 ------------------------------------------------------------------------- Module Manifest ------------------------------------------------------------------------- Module Name: o365Skus =========================================================================== #> <# .SYNOPSIS Fetches the list of Office 365 SKUs with string ID and friendly name. .DESCRIPTION Parses the content of "https://docs.microsoft.com/en-us/azure/active-directory/enterprise-users/licensing-service-plan-reference" into a array. Note: This page stopped being updated by Microsoft in September of 2020. A new source for this information is needed. .INPUTS None. .OUTPUTS [array] .EXAMPLE Get-o365ProductSKUs #> function Get-o365ProductSKUs { [OutputType([array])] [CmdletBinding()] $text_info = (Get-Culture).TextInfo $global:ProgressPreference = 'SilentlyContinue' Try { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 } Catch { [string]$error_message = $Error | Select-Object -First 1 | Select-Object -ExpandProperty Exception Write-Host "Unable to set security to Tls12 due to [$error_message]. Exiting." } [System.Management.Automation.CommandInfo]$check_command = Get-Command -Name "Invoke-WebRequest" If ($check_command.Name -ne "Invoke-WebRequest") { Write-Host "Error! Somehow the Invoke-WebRequest cmdlet is not available? Exiting." Exit } [string]$url = "https://docs.microsoft.com/en-us/azure/active-directory/enterprise-users/licensing-service-plan-reference" [hashtable]$parameters = @{ } $parameters.Add("UseBasicParsing", $true) $parameters.Add("Uri", $url) $Error.Clear() Try { [Microsoft.PowerShell.Commands.WebResponseObject]$html_content = Invoke-WebRequest @parameters } Catch { [string]$error_message = $Error | Select-Object -First 1 | Select-Object -ExpandProperty Exception Write-Host "Unable to invoke web request due to [$error_message]. Exiting." Exit } $ProgressPreference = 'Continue' [int]$html_content_status_code = $html_content.StatusCode If ($html_content_status_code -ne 200) { Write-Host "Error! Did not receive code 200 (success) from Invoke-WebRequest. Please check into this." Exit } [string]$html_content_raw = $html_content.RawContent If ($html_content_raw.Length -eq 0) { Write-Host "Error! Somehow the HTML content is empty. Please check into this." Exit } If ($html_content_raw -notlike "*<tbody>*" -or $html_content_raw -notlike "*</tbody>*") { Write-host "Error! Somehow the HTML does not contain the expected content. Exiting." Exit } $Error.Clear() Try { [int]$start_index = $html_content_raw.IndexOf("<tbody>") [int]$end_index = $html_content_raw.IndexOf("</tbody>") + 8 [string]$html_content_edited = $html_content_raw[$start_index .. $end_index] -join '' -replace '<td></td>' } Catch { [string]$error_message = $Error | Select-Object -First 1 | Select-Object -ExpandProperty Exception | Select-Object -ExpandProperty Message Write-Host "Error! Unable to format the HTML content due to [$error_message]" } Try { [xml]$html_xml = [xml]$html_content_edited } Catch { Write-Host "Error! Unable to convert the filtered HTML content into a valid XML object. Exiting." Exit } [array]$initial_product_array = $html_xml | Select-Object -ExpandProperty tbody | Select-Object -ExpandProperty tr [int]$initial_product_array_count = $initial_product_array.Count If ($initial_product_array_count -eq 0) { Write-Host "Error! Somehow there are 0 products in the product array. Something must be wrong. Exiting." Exit } [array]$product_list = ForEach ($product in $initial_product_array) { [array]$product_expanded = $product | Select-Object -ExpandProperty td [string]$product_name_raw = $product_expanded | Select-Object -First 1 [string]$product_name = ($text_info.ToTitleCase($product_name_raw.ToLower())) -replace "`t", " " [string]$product_string_id = $product_expanded | Select-Object -Skip 1 -First 1 [string]$product_guid = $product_expanded | Select-Object -Skip 2 -First 1 If ($product_guid.length -ne 36) { Write-Host "Error! Somehow the product GUID for [$product_name] was not 36 characters in length. There must be a problem. Exiting." Exit } ElseIf ($product_string_id -like "* *") { Write-Host "Error! Somehow the product string ID contains spaces. This should never happen. There must be a problem. Exiting." Exit } ElseIf ($product_name.Length -eq 0) { Write-Host "Error! Somehow the product name is 0 characters in length. This should never happen. There must be a problem. Exiting." Exit } [PSCustomObject]@{ Product_GUID = $product_guid; Product_String_ID = $product_string_id; Product_Name = $product_name; } } Return $product_list } |