Applications.ps1
<# The Get-GraphServicePrincipal function reworks work on service principals which was published by Justin Grote at https://github.com/JustinGrote/JustinGrote.Microsoft.Graph.Extensions/blob/main/src/Public/Get-MgO365ServicePrincipal.ps1 https://github.com/JustinGrote/JustinGrote.Microsoft.Graph.Extensions/blob/main/src/Public/Get-MgManagedIdentity.ps1 and https://github.com/JustinGrote/JustinGrote.Microsoft.Graph.Extensions/blob/main/src/Public/Get-MgAppRole.ps1 and licensed by him under the same MIT terms which apply to this module (see the LICENSE file for details) Portions of this file are Copyright 2021 Justin Grote @justinwgrote The remainder is Copyright 2018-2021 James O'Neill #> using namespace Microsoft.Graph.PowerShell.Models function Get-GraphServicePrincipal { <# .Synopsis Returns information about Service Principals .Description A replacement for the SDK's Get-MgServicePrincipal That has orderby which doesn't work - it's in the Docs but the API errors if you try It doesn't have find by name, or select Application or Managed IDs .Example PS > Get-GraphServicePrincipal "Microsoft graph*" Id DisplayName AppId SignInAudience -- ----------- ----- -------------- 25b13fbf-2f44-457a-9e68-d3414fc97915 Microsoft Graph 00000003-0000-0000-c000-000000000000 AzureADMultipleOrgs 4e71d88a-0a46-4274-85b8-82ad86877010 Microsoft Graph Change Tracking 0bf30f3b-4a52-48df-9a82-234910c4a086 AzureADMultipleOrgs ... Run with a name the command returns service principals with matching names. .Example PS >Get-GraphServicePrincipal 25b13fbf-2f44-457a-9e68-d3414fc97915 -ExpandAppRoles Value DisplayName Enabled Id ----- ----------- ------- -- AccessReview.Read.All Read all access reviews True d07a8cc0-3d51-4b77-b3b0-32704d1f69fa AccessReview.ReadWrite.All Manage all access reviews True ef5f7d5c-338f-44b0-86c3-351f46c8bb5f ... In this example GUID for Microsoft Graph was used from the previous example, and the command has listed the roles available to applications #> [CmdletBinding(DefaultParameterSetName='List1')] [OutputType([Microsoft.Graph.PowerShell.Models.IMicrosoftGraphAppRole],ParameterSetName=('AllRoles','FilteredRoles'))] [OutputType([Microsoft.Graph.PowerShell.Models.IMicrosoftGraphPermissionScope],ParameterSetName=('AllScopes','FilteredScopes'))] [OutputType([Microsoft.Graph.PowerShell.Models.IMicrosoftGraphServicePrincipal],ParameterSetName=('Get2','List1','List2','List3','List4'))] param ( [Parameter(ParameterSetName='AllRoles', Mandatory=$true, Position=0, ValueFromPipeline=$true)] [Parameter(ParameterSetName='FilteredRoles', Mandatory=$true, Position=0, ValueFromPipeline=$true)] [Parameter(ParameterSetName='AllScopes', Mandatory=$true, Position=0, ValueFromPipeline=$true)] [Parameter(ParameterSetName='FilteredScopes', Mandatory=$true, Position=0, ValueFromPipeline=$true)] [Parameter(ParameterSetName='Get2', Mandatory=$true, Position=0, ValueFromPipeline=$true)] #The GUID(s) for ServicePrincipal(s). Or SP objects. If a name is given instead, the command will try to resolve matching Service principals $ServicePrincipalId, [Parameter(ParameterSetName='List5')] [string]$AppId, #Produces a list filtered to only managed identities [Parameter(ParameterSetName='List2')] [switch]$ManagedIdentity, #Produces a list filtered to only applications [Parameter(ParameterSetName='List3')] [switch]$Application, #Produces a convenience list of office 365 security principals [Parameter(ParameterSetName='List4')] [switch]$O365ServicePrincipals, #Select properties to be returned [Alias('Select')] [String[]]$Property, #Filters items by property values [Parameter(ParameterSetName='List1')] [String]$Filter, #Returns the list of application roles to those the role name, displayname or ID match the parameter value. Wildcards are supported [Parameter(ParameterSetName='AllRoles', Mandatory=$true)] [switch]$ExpandAppRoles, #Filters the list of application roles available within a SP [Parameter(ParameterSetName='FilteredRoles', Mandatory=$true)] [string]$AppRoleFilter, #Returns the list of (user) oauth scopes available within a SP [Parameter(ParameterSetName='AllScopes', Mandatory=$true)] [switch]$ExpandScopes, #Filters the list of oauth scopes to those where the scope name, displayname or ID match the parameter value. Wildcards are supported [Parameter(ParameterSetName='FilteredScopes', Mandatory=$true)] [string]$ScopeFilter ) begin { [String]$managedIdentityFilter = @( '00000001-0000-0000-c000-000000000000' #Azure ESTS Service '00000007-0000-0000-c000-000000000000' #Common Data Service '0000000c-0000-0000-c000-000000000000' #Microsoft App Access Panel' '00000007-0000-0ff1-ce00-000000000000' #Microsoft Exchange Online Protection '00000003-0000-0000-c000-000000000000' #Microsoft Graph '00000006-0000-0ff1-ce00-000000000000' #Microsoft Office 365 Portal '00000012-0000-0000-c000-000000000000' #Microsoft Rights Management Services '00000008-0000-0000-c000-000000000000' #Microsoft.Azure.DataMarket '00000002-0000-0ff1-ce00-000000000000' #Office 365 Exchange Online '00000003-0000-0ff1-ce00-000000000000' #Office 365 SharePoint Online '00000009-0000-0000-c000-000000000000' #Power BI Service '00000004-0000-0ff1-ce00-000000000000' #Skype for Business Online '00000002-0000-0000-c000-000000000000' #Windows Azure Active Directory ).foreach{"appId eq '$PSItem'"} -join ' or ' if ($ExpandScopes) {$ScopeFilter = '*'} if ($ExpandAppRoles) {$AppRoleFilter = '*'} $webparams = @{ AsType = ([MicrosoftGraphServicePrincipal]) ExcludeProperty = @('@odata.context','createdDateTime','disabledByMicrosoftStatus', 'keyCredentials','resourceSpecificApplicationPermissions','verifiedPublisher') Headers = @{'ConsistencyLevel'= 'Eventual'} } } process { if ( -not $ServicePrincipalId) { if ($ManagedIdentity) {$filter = "?`$filter=servicePrincipaltype eq 'ManagedIdentity'"} elseif ($Application) {$filter = "?`$filter=servicePrincipaltype eq 'Application'"} elseif ($AppId) {$filter = "?`$filter=appid eq '$AppId'" } elseif ($PSBoundParameters['Filter'] -and $O365ServicePrincipal ) {$filter = "?`$filter=( $($PSBoundParameters['Filter']) ) and $managedIdentityFilter"} elseif ($PSBoundParameters['Filter']) {$filter = "?`$filter=$($PSBoundParameters['Filter'])"} elseif ($O365ServicePrincipals) {$filter = "?`$filter=$managedIdentityFilter"} if ($Property -and $filter) {$filter += '&$select=' +($property -join ',')} elseif ($Property) {$filter = '?$select=' +($property -join ',')} Invoke-GraphRequest "$GraphUri/servicePrincipals$filter" -ValueOnly @webparams | Sort-Object displayname } else { foreach ($sp in $ServicePrincipalId) { $result = $null if ($sp -match $GUIDRegex) { $webparams['uri'] = "$GraphUri/servicePrincipals/$sp" if ($Property) {$webparams['uri'] += '?$select=' +($property -join ',')} try {$result = Invoke-GraphRequest @webparams} catch { if ($_.Exception.Response.StatusCode.value__ -eq 404) { Write-Warning "$sp was not found as a service principal ID. It may be an App ID."; continue } else {throw $_.Exception } } } else { $webparams['uri'] = "$GraphUri/servicePrincipals?`$filter=" + (FilterString $sp) if ($Property) {$webparams['uri'] += '&$select=' +($property -join ',')} $result = Invoke-GraphRequest -ValueOnly @webparams } if ($AppRoleFilter) { $(foreach ($r in $result) {$r.approles | Where-Object {$_.id -like $AppRoleFilter -or $_.DisplayName -like $AppRoleFilter -or $_.value -like $AppRoleFilter } | Add-Member -PassThru -NotePropertyName ServicePrincipal -NotePropertyValue $r.Id} ) | Sort-Object -Property Value } elseif ($ScopeFilter) { $(foreach ($r in $result) {$r.Oauth2PermissionScopes | Where-Object {$_.id -like $ScopeFilter -or $_.AdminConsentDisplayName -like $ScopeFilter -or $_.value -like $ScopeFilter } | Add-Member -PassThru -NotePropertyName ServicePrincipal -NotePropertyValue $r.Id} ) | Sort-Object -Property Value } else {$result | Sort-Object -Property displayname} } } } } function Get-GraphApplication { <# .Synopsis Returns information about Applications #> [CmdletBinding(DefaultParameterSetName='List1')] [OutputType([Microsoft.Graph.PowerShell.Models.MicrosoftGraphApplication])] param ( [Parameter(ParameterSetName='List3',Position=0)] [string]$Id, #The GUID(s) for Apps(s). Or App objects. If a name is given instead, the command will try to resolve matching App principals [Parameter(ParameterSetName='List2',ValueFromPipelineByPropertyName=$true)] [string]$AppId, #Select properties to be returned [Alias('Select')] [String[]]$Property, #Filters items by property values [Parameter(ParameterSetName='List1')] [String]$Filter ) process { $result = @() $webparams = @{ ExcludeProperty = @('verifiedPublisher', 'applicationTemplateId','addins','@odata.context') Headers = @{'ConsistencyLevel'= 'Eventual'} } if ( -not $Id) { if ($PSBoundParameters['Filter']) {$filter = "?`$filter=$($PSBoundParameters['Filter'])"} elseif ($AppId) {$filter = "?`$filter=AppID eq '$AppId'"} if ($Property -and $filter) {$filter += '&$select=' +($property -join ',')} elseif ($Property) {$filter = '?$select=' +($property -join ',')} $result += Invoke-GraphRequest "$GraphUri/Applications$filter" -ValueOnly @webparams } else { foreach ($app in $Id) { if ($app -match $GUIDRegex) { $webparams['uri'] = "$GraphUri/applications/$app" if ($Property) {$webparams['uri'] += '?$select=' +($property -join ',')} try { $result += Invoke-GraphRequest @webparams} catch { if ($_.Exception.Response.StatusCode.value__ -eq 404) { Write-Warning "$sp was not found as an ID It may be an APPID."; continue } else {throw $_.Exception } } } else { $filter = '?$filter=' + (FilterString $app) if ($Property) {$filter += '&$select=' +($property -join ',')} $result += Invoke-GraphRequest "$GraphUri/applications$filter" -ValueOnly @webparams } } } foreach ($r in $result) { foreach ($p in $r.passwordCredentials) { $p.customKeyIdentifier = [byte[]][char[]]$p.customKeyIdentifier } foreach ($k in $r.keyCredentials) { $k.customKeyIdentifier = [byte[]][char[]]$k.customKeyIdentifier } New-Object -TypeName MicrosoftGraphApplication -Property $r } } } |