Public/GraphUserLicenseServicPlan/Get-GraphUserLicenseServicePlan.ps1

# Module: Orbit.Users
# Function: Licensing
# Author: David Eberhardt
# Updated: 01-APR-2020
# Status: Live

#TODO Refactor cmdlet name to GraphUserLicenseServicePlan, add Alias to Get-GraphUserLicenseServicePlan and Get-GraphUserLicenseServicePlan
#TODO Repeat for all TeamsUserLicenseServicePlan Cmdlets

function Get-GraphUserLicenseServicePlan {
  <#
  .SYNOPSIS
    Returns License information (ServicePlans) for an Object in Graph
  .DESCRIPTION
    Returns an Object containing all Teams related ServicePlans (for Licenses assigned) for a specific Object
  .PARAMETER UserPrincipalName
    The UserPrincipalName, ObjectId or Identity of the Object.
  .PARAMETER DisplayAll
    Displays all ServicePlans, not only relevant Teams Service Plans
    Also displays AllLicenses and AllServicePlans object for further processing
  .EXAMPLE
    Get-GraphUserLicenseServicePlan [-UserPrincipalName] John@domain.com
 
    Displays all licenses assigned to User John@domain.com
  .EXAMPLE
    Get-GraphUserLicenseServicePlan -UserPrincipalName John@domain.com,Jane@domain.com
 
    Displays all licenses assigned to Users John@domain.com and Jane@domain.com
  .EXAMPLE
    Import-Csv User.csv | Get-GraphUserLicenseServicePlan
 
    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/Orbit/tree/main/docs/Orbit.Users/Get-GraphUserLicenseServicePlan.md
  .LINK
    https://github.com/DEberhardt/Orbit/tree/main/docs/about/about_Licensing.md
  .LINK
    https://github.com/DEberhardt/Orbit/tree/main/docs/about/about_UserManagement.md
  .LINK
    https://github.com/DEberhardt/Orbit/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 ($script:OrbitRegexUPN.isMatch($_) -or $script:OrbitRegexGuid.isMatch($_)) { $True } else {
          throw [System.Management.Automation.ValidationMetadataException] 'Value must be a valid UPN or ObjectId'
        } })]
    [string[]]$UserPrincipalName,

    [Parameter(HelpMessage = 'Displays all ServicePlans, not only Teams relevant ones')]
    [switch]$DisplayAll
  ) #param

  begin {
    Show-OrbitFunctionStatus -Level Live
    Write-Verbose -Message "[BEGIN ] $($MyInvocation.MyCommand)"

    # Asserting Graph Connection
    if ( -not (Test-GraphConnection) ) { throw 'Connection to Microsoft Graph not established. Please validate connection' }

    # Setting Preference Variables according to Upstream settings
    if (-not $PSBoundParameters['Verbose']) { $VerbosePreference = $PSCmdlet.SessionState.PSVariable.GetValue('VerbosePreference') }
    if (-not $PSBoundParameters['Confirm']) { $ConfirmPreference = $PSCmdlet.SessionState.PSVariable.GetValue('ConfirmPreference') }
    if (-not $PSBoundParameters['WhatIf']) { $WhatIfPreference = $PSCmdlet.SessionState.PSVariable.GetValue('WhatIfPreference') }
    $DebugPreference = if (-not $PSBoundParameters['Debug']) { $PSCmdlet.SessionState.PSVariable.GetValue('DebugPreference') } else { 'Continue' }
    $InformationPreference = if ( $PSBoundParameters['InformationAction']) { $PSCmdlet.SessionState.PSVariable.GetValue('InformationAction') } else { 'Continue' }

    # preparing Output Field Separator
    $OFS = ', ' # do not remove - Automatic variable, used to separate elements!

    if ($PSBoundParameters['DisplayAll']) {
      $previousFEL = $global:FormatEnumerationLimit
      $global:FormatEnumerationLimit = -1
    }
  } #begin

  process {
    Write-Verbose -Message "[PROCESS] $($MyInvocation.MyCommand)"
    foreach ($User in $UserPrincipalName) {
      try {
        $UserObject = Get-MgUser -UserId "$User" -WarningAction SilentlyContinue -ErrorAction STOP
        $UserLicenseDetail = Get-MgUserLicenseDetail -UserId "$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 Service Plans
        $UserServicePlans = Get-GraphUserServicePlansFromLicenseDetailObject -UserLicenseDetail $UserLicenseDetail @args
      }

      # Filter
      if ( -not $DisplayAll.IsPresent ) {
        $UserServicePlans = $UserServicePlans | Where-Object RelevantForTeams
      }

      Write-Information "INFO: User '$User' - Service Plans for User '$DisplayName':"
      if ( $DisplayAll.IsPresent ) {
        Write-Output $UserServicePlans
      }
      else {
        Write-Output $UserServicePlans | Where-Object RelevantForTeams
      }
    }
  } #process

  end {
    if ($PSBoundParameters['DisplayAll']) {
      $global:FormatEnumerationLimit = $previousFEL
    }

    Write-Verbose -Message "[END ] $($MyInvocation.MyCommand)"
  } #end
} #Get-GraphUserLicenseServicePlan