GraphTools.psm1
using namespace System.Management.Automation #Region '.\Classes\completer_iUser_Deleted_DisplayName.ps1' 0 #using namespace System.Management.Automation class completer_iUser_Deleted_DisplayName : IArgumentCompleter { [System.Collections.Generic.IEnumerable[CompletionResult]] CompleteArgument( [string]$CommandName, [string]$ParameterName, [string]$WordToComplete, [Language.CommandAst]$CommandAst, [System.Collections.IDictionary] $FakeBoundParameters ) { $result = [System.Collections.Generic.List[System.Management.Automation.CompletionResult]]::new() if ($wordToComplete) { $wordToComplete = $wordToComplete -replace '"|''', '' arg_gUser_Deleted_DisplayName -WordToComplete $WordToComplete | ForEach-Object DisplayName | Sort-Object | ForEach-Object { $result.Add([System.Management.Automation.CompletionResult]::new("'$_'", $_, ([CompletionResultType]::ParameterValue) , $_) ) } } return $result } } #EndRegion '.\Classes\completer_iUser_Deleted_DisplayName.ps1' 17 #Region '.\Classes\completer_iUser_DisplayName.ps1' 0 #using namespace System.Management.Automation class completer_iUser_DisplayName : IArgumentCompleter { [System.Collections.Generic.IEnumerable[CompletionResult]] CompleteArgument( [string]$CommandName, [string]$ParameterName, [string]$WordToComplete, [Language.CommandAst]$CommandAst, [System.Collections.IDictionary] $FakeBoundParameters ) { $result = [System.Collections.Generic.List[System.Management.Automation.CompletionResult]]::new() if ($wordToComplete) { $wordToComplete = $wordToComplete -replace '"|''', '' arg_gUser_DisplayName -WordToComplete $WordToComplete | ForEach-Object DisplayName | Sort-Object | ForEach-Object { $result.Add([System.Management.Automation.CompletionResult]::new("'$_'", $_, ([CompletionResultType]::ParameterValue) , $_) ) } } return $result } } #EndRegion '.\Classes\completer_iUser_DisplayName.ps1' 17 #Region '.\Private\ArgumentsForCompleters\arg_gUser_Deleted_DisplayName.ps1' 0 function arg_gUser_Deleted_DisplayName { <# .SYNOPSIS Interactive use only. Used for autocompletion of user arguments. .PARAMETER WordToComplete Specifies the user you want to autocomplete at the command line. .NOTES This function only works with the Beta endpoint. #> [CmdletBinding()] param ( [Parameter()] $WordToComplete ) $RestSplat = @{ Uri = "https://graph.microsoft.com/beta/directory/deletedItems/microsoft.graph.user?`$filter={0}&top=50&select=DisplayName" -f ( [System.Web.HttpUtility]::UrlEncode(('startswith({0}, ''{1}'')' -f 'DisplayName', $WordToComplete )) ) Headers = @{ ConsistencyLevel = 'Eventual' Authorization = "Bearer $Script:Token" } Method = 'Get' } (Invoke-RestMethod @RestSplat).value } #EndRegion '.\Private\ArgumentsForCompleters\arg_gUser_Deleted_DisplayName.ps1' 30 #Region '.\Private\ArgumentsForCompleters\arg_gUser_DisplayName.ps1' 0 function arg_gUser_DisplayName { <# .SYNOPSIS Interactive use only. Used for autocompletion of user arguments. .PARAMETER WordToComplete Specifies the user you want to autocomplete at the command line. .NOTES This function only works with the Beta endpoint. #> [CmdletBinding()] param ( [Parameter()] $WordToComplete ) $RestSplat = @{ Uri = "https://graph.microsoft.com/beta/users?`$filter={0}&top=50&select=DisplayName" -f ( [System.Web.HttpUtility]::UrlEncode(('startswith({0}, ''{1}'')' -f 'DisplayName', $WordToComplete )) ) Headers = @{ ConsistencyLevel = 'Eventual' Authorization = "Bearer $Script:Token" } Method = 'Get' } (Invoke-RestMethod @RestSplat).value } #EndRegion '.\Private\ArgumentsForCompleters\arg_gUser_DisplayName.ps1' 30 #Region '.\Private\Connect\Connect-iGraphMI.ps1' 0 function Connect-gGraphMI { <# .DESCRIPTION Connect with Managed Identity to Graph API #> [CmdletBinding()] param () $resourceURI = 'https://graph.microsoft.com/' $tokenAuthURI = $env:IDENTITY_ENDPOINT + "?resource=$resourceURI&api-version=2019-08-01" $tokenResponse = Invoke-RestMethod -Method Get -Headers @{"X-IDENTITY-HEADER" = "$env:IDENTITY_HEADER" } -Uri $tokenAuthURI $Script:Token = $tokenResponse.access_token } #EndRegion '.\Private\Connect\Connect-iGraphMI.ps1' 16 #Region '.\Private\Rest\Invoke-gRestMethod.ps1' 0 function Invoke-gRestMethod { <# .SYNOPSIS Invokes a REST method with various options. This is a private function, only used interally by other functions. .DESCRIPTION This function allows invoking a REST method with customizable parameters such as URI, HTTP method, request body, and eventual consistency. .PARAMETER Uri The URI of the REST API endpoint to invoke. .PARAMETER Method The HTTP method to use for the request. Valid values are GET, POST, DELETE, and PATCH. (Default: GET) .PARAMETER Body The request body to include in the REST request. .PARAMETER Eventual Specifies whether to use eventual consistency for the request. If specified, the 'ConsistencyLevel' header will be set to 'Eventual'. .EXAMPLE Invoke-gRestMethod -Uri 'https://api.example.com/resource' -Method GET Invokes a GET request to the specified URI. .NOTES This is a private function that requires a script-scoped token variable and is meant to be executed only by other functions within the module. #> param ( [Parameter()] $Uri, [Parameter()] [validateset('GET', 'POST', 'DELETE', 'PATCH')] $Method = 'GET', [Parameter()] $Body, [Parameter()] [switch] $Eventual ) $RestSplat = @{ Uri = $Uri Method = $Method Headers = @{ 'Content-Type' = 'application/json' } Verbose = $false } if ($Eventual) { $RestSplat['Headers']['ConsistencyLevel'] = 'Eventual' } if ($Body) { $RestSplat['Body'] = $Body } do { try { $i = 0 while ((-not $script:Token -or ([datetime]::UtcNow -ge $script:TokenExpirationTime)) -and ($i -le 30)) { Connect-gGraph -ClientID $Script:ClientID -TenantID $Script:TenantID -Secret $Script:Secret $i++ } $RestSplat['Headers']['Authorization'] = "Bearer $Script:Token" # Send the response $Response = Invoke-RestMethod @RestSplat $Response # If page, and didn't catch, update Next $RestSplat['Uri'] = $Response.'@odata.nextLink' } catch { if ($_.Exception.Response.StatusCode -eq 429) { Write-Verbose ('IWR ERROR [ 429 ] SLEEPING FOR [ {0} ] SECONDS' -f $_.Exception.Response.Headers.GetValues('Retry-After')[0]) Start-Sleep -Seconds $_.Exception.Response.Headers.GetValues('Retry-After')[0] } elseif ($_.Exception.Response.StatusCode -eq 401) { Write-Verbose ('IWR ERROR [ {0} ] CONNECT THEN SLEEP FOR [ 5 ] SECONDS' -f $_.Exception.Response.StatusCode) Connect-gGraph Start-Sleep -Seconds 5 } else { $PSCmdlet.WriteError($PSItem) Write-Verbose ('STOPPING! IWR ERROR [ {0} ] URI [ {1} ] EXCEPTION [ {2} ]' -f $_.Exception.Response.StatusCode, $RestSplat['Uri'], $_) Return } } } while ($RestSplat['Uri']) } #EndRegion '.\Private\Rest\Invoke-gRestMethod.ps1' 100 #Region '.\Private\Rest\Set-gToken.ps1' 0 function Set-gToken { [CmdletBinding()] param ( [Parameter(Mandatory)] $Token, [Parameter(Mandatory)] $TokenExpirationTime, [Parameter(Mandatory)] $ClientID, [Parameter(Mandatory)] $TenantID, [Parameter(Mandatory)] $Secret ) $Script:Token = $Token $Script:TokenExpirationTime = $TokenExpirationTime $Script:ClientID = $ClientID $Script:TenantID = $TenantID $Script:Secret = $Secret } #EndRegion '.\Private\Rest\Set-gToken.ps1' 27 #Region '.\Private\User\Get-gUserAll.ps1' 0 function Get-gUserAll { [CmdletBinding()] param ( [Parameter()] $ThrottleLimit = 8, [Parameter()] [string] $Select, [Parameter()] [switch] $Beta ) $UserCount = Invoke-gRestMethod -Uri "https://graph.microsoft.com/v1.0/users/`$count" -Method 'GET' -Eventual Write-Verbose "Getting $($UserCount) users. . . " $ModuleBase = $MyInvocation.MyCommand.Module.Path '!#$%&*+-/0123456789=?ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`{|}~'.toCharArray() | ForEach-Object -ThrottleLimit $ThrottleLimit -Parallel { $Character = "$_" Import-Module $using:ModuleBase -Force $TokenSplat = @{ Token = $using:Token TokenExpirationTime = $using:TokenExpirationTime ClientID = $using:ClientID TenantId = $using:TenantID Secret = $using:Secret } Set-gToken @TokenSplat if (-not $using:Beta) { Write-Host "NOT BETA" $Uri = "https://graph.microsoft.com/v1.0/users?`$filter={0}" -f ( [System.Web.HttpUtility]::UrlEncode(('startswith({0}, ''{1}'')' -f 'mailnickname', "$Character" )) ) } else { $Uri = "https://graph.microsoft.com/beta/users?`$filter={0}" -f ( [System.Web.HttpUtility]::UrlEncode(('startswith({0}, ''{1}'')' -f 'mailnickname', "$Character" )) ) } if ($using:Select) { $Uri = '{0}&$Select={1}' -f $Uri, $using:Select } $splat = @{ Uri = $Uri Method = 'GET' ErrorAction = 'Stop' } try { (Invoke-gRestMethod @splat).value } catch { Write-Error -ErrorRecord $_ } } } #EndRegion '.\Private\User\Get-gUserAll.ps1' 67 #Region '.\Private\User\Get-gUserDeletedAll.ps1' 0 function Get-gUserDeletedAll { [CmdletBinding()] param ( [Parameter()] $ThrottleLimit = 8, [Parameter()] [string] $Select, [Parameter()] [switch] $Beta ) $ModuleBase = $MyInvocation.MyCommand.Module.Path '!#$%&*+-/0123456789=?ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`{|}~'.toCharArray() | ForEach-Object -ThrottleLimit $ThrottleLimit -Parallel { $Character = "$_" Import-Module $using:ModuleBase -Force $TokenSplat = @{ Token = $using:Token TokenExpirationTime = $using:TokenExpirationTime ClientID = $using:ClientID TenantId = $using:TenantID Secret = $using:Secret } Set-gToken @TokenSplat if (-not $using:Beta) { $Uri = "https://graph.microsoft.com/v1.0/directory/deletedItems/microsoft.graph.user?`$filter={0}" -f ( [System.Web.HttpUtility]::UrlEncode(('startswith({0}, ''{1}'')' -f 'mailnickname', "$Character" )) ) } else { $Uri = "https://graph.microsoft.com/beta/directory/deletedItems/microsoft.graph.user?`$filter={0}" -f ( [System.Web.HttpUtility]::UrlEncode(('startswith({0}, ''{1}'')' -f 'mailnickname', "$Character" )) ) } if ($using:Select) { $Uri = '{0}&$Select={1}' -f $Uri, $using:Select } $splat = @{ Uri = $Uri Method = 'GET' ErrorAction = 'Stop' # Eventual = $true } try { (Invoke-gRestMethod @splat).value } catch { Write-Error -ErrorRecord $_ } } } #EndRegion '.\Private\User\Get-gUserDeletedAll.ps1' 63 #Region '.\Public\Connect\Connect-gGraph.ps1' 0 function Connect-gGraph { <# .DESCRIPTION Connect with Client Credential Flow to Graph API .PARAMETER ClientID Client ID of the Azure AD App Registration .PARAMETER TenantID Tenant ID of the Azure AD App Registration .PARAMETER Secret The Secret from the Azure AD App Registration .PARAMETER ManagedIdentity If set, connects to the Graph API using Managed Identity .EXAMPLE Connect-gGraph -ClientID "yourClientID" -TenantID "yourTenantID" -Secret "yourSecret" Connects to the Graph API using the specified client credentials. .EXAMPLE Connect-gGraph -ClientID "yourClientID" -TenantID "yourTenantID" -Secret "yourSecret" -Verbose Connects to the Graph API using the specified client credentials with verbose output for interactive execution. .EXAMPLE Connect-gGraph -ManagedIdentity Connects to the Graph API using Managed Identity. #> [CmdletBinding()] param ( [Parameter(ParameterSetName = 'AppReg')] $ClientID, [Parameter(ParameterSetName = 'AppReg')] $TenantID, [Parameter(ParameterSetName = 'AppReg')] $Secret, [Parameter(ParameterSetName = 'ManagedIdentity')] [switch] $ManagedIdentity ) if ($ManagedIdentity) { Connect-gGraphMI } do { try { $Request = @{ Method = 'POST' ErrorAction = 'Stop' Body = @{ Grant_Type = 'client_credentials' Client_Id = $ClientID Client_Secret = $Secret Scope = 'https://graph.microsoft.com/.default' } Uri = 'https://login.microsoftonline.com/{0}/oauth2/v2.0/token' -f $TenantID } $Response = Invoke-RestMethod @Request $Script:ClientID = $ClientID $Script:TenantId = $TenantID $Script:Secret = $Secret } catch { if ($_.Exception -like '*transport*' -or $_.Exception -like '*invalid pointer*' ) { # Transport Error $TransportError++ $PSCmdlet.WriteError($_) Write-Verbose ('Retrying Transport Error. Retried {0} times.' -f $TransportError) if ($TransportError -ge 200) { Write-Verbose ('STOPPING! Retried {0} times. Halting this call!' -f $TransportError) break } } else { # Something unexpected went wrong Write-Verbose ('Continuing ! Something other than Transport Error occurred {0}' -f $_) continue } } } until ($Response.access_token) $Script:TokenExpirationTime = ([datetime]::UtcNow).AddSeconds($Response.expires_in - 10) $Script:Token = $Response.access_token } #EndRegion '.\Public\Connect\Connect-gGraph.ps1' 95 #Region '.\Public\Role\Get-gRoleAssignment.ps1' 0 function Get-gRoleAssignment { <# .SYNOPSIS Retrieves role assignments from the Microsoft Graph API. .DESCRIPTION The Get-gRoleAssignment function retrieves role assignments from the Microsoft Graph API. Role assignments tie together a role definition with members and scopes. This applies to custom and built-in roles. You can retrieve role assignments by RoleDefinitionId, PrincipalId, or Id. .PARAMETER RoleDefinitionId Specifies the RoleDefinitionId for which to retrieve role assignments. May be combined with PrincipalId and/or DirectoryScopeId. .PARAMETER PrincipalId Specifies the PrincipalId for which to retrieve role assignments. May be combined with RoleDefinitionId and/or DirectoryScopeId. .PARAMETER DirectoryScopeId Specifies the DirectoryScopeId for which to retrieve role assignments. May be combined with RoleDefinitionId and/or PrincipalId. .PARAMETER Id Specifies the Id of the role assignment to retrieve. .EXAMPLE Get-gRoleAssignment Retrieves all role assignment .EXAMPLE Get-gRoleAssignment -Id 'lonqqS8SdEyVII7c0ZKCbOElzZegQW9Nuu3_bEgnD_0-1' Retrieves a specific role assignment by the assignments Id .EXAMPLE Get-gRoleAssignment -RoleDefinitionId 'b5a8dcf3-09d5-43a9-a639-8e29ef291470' Retrieves role assignments associated with the specified RoleDefinitionId .EXAMPLE Get-gRoleAssignment -RoleDefinitionId 'b5a8dcf3-09d5-43a9-a639-8e29ef291470' -PrincipalId '725d17ec-cc33-432c-9eb0-83187b9cbee7' Retrieves role assignments associated with the specified RoleDefinitionId and PrincipalId .EXAMPLE Get-gRoleAssignment -RoleDefinitionId 'b5a8dcf3-09d5-43a9-a639-8e29ef291470' -PrincipalId '725d17ec-cc33-432c-9eb0-83187b9cbee7' -DirectoryScopeId '/' Retrieves role assignments associated with the specified RoleDefinitionId, PrincipalId, and DirectoryScopeId .EXAMPLE Get-gRoleAssignment -DirectoryScopeId '/' Retrieves role assignments associated with the specified DirectoryScopeId. .NOTES The Microsoft Graph API for Intune requires an active Intune license for the tenant. #> [CmdletBinding(DefaultParameterSetName = 'placeholder')] param( [Parameter()] $RoleDefinitionId, [Parameter()] $PrincipalId, [Parameter()] $DirectoryScopeId, [Parameter( Mandatory, ParameterSetName = 'Id' )] $Id ) if ($Id) { $filterstring = '/{0}' -f $Id } elseif ($PSBoundParameters.Keys.Count -ge 1) { $filterstring = @() } if ($PrincipalId) { $filterstring += ("PrincipalId eq '{0}'" -f $PrincipalId) } if ($RoleDefinitionId) { $filterstring += ("RoleDefinitionId eq '{0}'" -f $RoleDefinitionId) } if ($DirectoryScopeId) { $filterstring += ("DirectoryScopeId eq '{0}'" -f $DirectoryScopeId) } if ($filterstring.count -ge 1 -and (-not $Id)) { $filterstring = '?$filter={0}' -f (@($filterstring) -join ' and ') } $RestSplat = @{ Uri = 'https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments{0}' -f $filterstring Method = 'GET' } $Response = Invoke-gRestMethod @RestSplat if (-not $Id) { return $Response.value } $Response } #EndRegion '.\Public\Role\Get-gRoleAssignment.ps1' 104 #Region '.\Public\Role\Get-gRoleDefinition.ps1' 0 function Get-gRoleDefinition { <# .SYNOPSIS Returns one or more Azure AD Role Definitions. .DESCRIPTION Retrieves role definitions and role assignments from the RBAC provider called 'directory' (Azure Active Directory). .PARAMETER Role Specifies the Role ID or DisplayName as a string or object. If using the DisplayName of the Role Definition, note that it is not unique in Azure AD and may result in multiple matches. .PARAMETER All Retrieves all Azure AD Role Definitions. .EXAMPLE Import-Csv .\rolelist.csv | Get-gRoleDefinition Retrieves role definitions for each role listed in a CSV file. .EXAMPLE Get-gRoleDefinition -Role 'Knowledge Administrator' Retrieves the role definition with the specified DisplayName. .EXAMPLE Get-gRoleDefinition -Role '62e90394-69f5-4237-9190-012177145e10' Retrieves the role definition with the specified Role ID. .EXAMPLE Get-gRoleDefinition -All Retrieves all Azure AD Role Definitions. .EXAMPLE Get-gRoleDefinition -All | Export-Csv .\RoleDefinitions.csv -NoTypeInformation Retrieves all Azure AD Role Definitions and exports them to a CSV file. #> [CmdletBinding()] param( [Parameter( Mandatory, ValueFromPipeline, ParameterSetName = 'pipeline' )] [object] $Role, [Parameter(ParameterSetName = 'All')] [switch] $All ) begin { if ($All) { $RestSplat = @{ Uri = "https://graph.microsoft.com/beta/roleManagement/directory/roleDefinitions" Method = 'GET' } (Invoke-gRestMethod @RestSplat).value return } } process { foreach ($Item in $Role) { if ($Item.Id -is [string] -and $Item.Id -as [Guid]) { $filterstring = '{0}?' -f $Item.Id } elseif ($Item -is [string] -and $Item -as [Guid]) { $filterstring = '{0}?' -f $Item } elseif ($Item.DisplayName -is [string]) { $filterstring = "?`$filter=DisplayName eq '{0}'" -f $Item.DisplayName } elseif ($Item -is [string]) { $filterstring = "?`$filter=DisplayName eq '{0}'" -f $Item } } if ($filterstring) { $RestSplat = @{ Uri = "https://graph.microsoft.com/beta/roleManagement/directory/roleDefinitions/{0}" -f $filterstring Method = 'GET' } $Result = Invoke-gRestMethod @RestSplat if ($filterstring -like '*filter=*') { return $Result.value } $Result } } } #EndRegion '.\Public\Role\Get-gRoleDefinition.ps1' 91 #Region '.\Public\Role\New-gRoleAssignment.ps1' 0 function New-gRoleAssignment { <# .SYNOPSIS Creates a new role assignment using the Microsoft Graph API. .DESCRIPTION This function creates a new role assignment object using the Microsoft Graph API. The role assignment is created with the specified role definition, principal (user or group), and directory scope. .PARAMETER RoleDefinitionId The ID of the role definition for the role assignment. .PARAMETER PrincipalId The ID of the principal (user or group) for the role assignment. .PARAMETER DirectoryScopeId The identifier of the directory object representing the scope of the assignment. The scope of an assignment determines the set of resources for which the principal has been granted access. Directory scopes are shared scopes stored in the directory that are understood by multiple applications. Use '/' for tenant-wide scope. .EXAMPLE Assigns the User Administrator role to a principal with the tenant scope. New-gRoleAssignment -RoleDefinitionId 'e8cef6f1-e4bd-4ea8-bc07-4b8d950f4477' -PrincipalId '72ae3f1a-c8f1-4aad-af82-51473013fa74' -DirectoryScopeId '/' .EXAMPLE Assigns the User Administrator role to a principal with administrative unit scope. $splat = @{ RoleDefinitionId = '9b895d92-2cd3-44c7-9d02-a6ac2d5ea5c3' PrincipalId = '72ae3f1a-c8f1-4aad-af82-51473013fa74' DirectoryScopeId = '/administrativeUnits/5d107bba-d8e2-4e13-b6ae-884be90e5d1a' } New-gRoleAssignment @splat .EXAMPLE Assigns a principal the Application Administrator role at the application scope. The object ID of the application registration is 661e1310-bd76-4795-89a7-8f3c8f855bfc. $splat = @{ RoleDefinitionId = '9b895d92-2cd3-44c7-9d02-a6ac2d5ea5c3' PrincipalId = '72ae3f1a-c8f1-4aad-af82-51473013fa74' DirectoryScopeId = '/661e1310-bd76-4795-89a7-8f3c8f855bfc' } New-gRoleAssignment @splat #> [CmdletBinding()] param( [Parameter( Mandatory )] $RoleDefinitionId, [Parameter( Mandatory )] $PrincipalId, [Parameter( Mandatory )] $DirectoryScopeId ) $Body = @{ '@odata.type' = '#microsoft.graph.unifiedRoleAssignment' roleDefinitionId = $RoleDefinitionId principalId = $PrincipalId directoryScopeId = $DirectoryScopeId } $RestSplat = @{ Uri = 'https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments' Method = 'POST' Body = $Body | ConvertTo-Json } Invoke-gRestMethod @RestSplat } #EndRegion '.\Public\Role\New-gRoleAssignment.ps1' 77 #Region '.\Public\User\Get-gUser.ps1' 0 function Get-gUser { <# .SYNOPSIS Retrieve the properties and relationships of user objects in Azure Active Directory (AAD). .DESCRIPTION This cmdlet retrieves user objects from AAD and provides various options for filtering and selecting specific properties. Users can be identified by their ID, UserPrincipalName, or DisplayName. Additionally, a list of users can be provided in a CSV file. The cmdlet also supports parallel processing of user objects, with a default throttle limit of 8 threads. .PARAMETER User Specifies the ID, UserPrincipalName, or DisplayName of the user to retrieve. A list of users can also be provided in a CSV file. If the CSV file has headers, they must contain one of the following columns: Id, UserPrincipalName, or DisplayName. DisplayName is not unique in AAD and may result in multiple matches. Note that tab completion is supported for the DisplayName parameter. You can type a few letters and use tab multiple times to cycle through and find matching DisplayNames of users you want more details on. For example, typing 'fr' and pressing tab multiple times may show both 'Frank' and 'Fred' as options. .PARAMETER Select Specifies a comma-separated list of properties to be returned by Microsoft Graph. For example: Get-gUser -Select 'DisplayName,UserPrincipalName,Mail' .PARAMETER IncludeManager If the user has a manager listed in Azure AD, this switch includes the user's manager in the output .PARAMETER All Switch to retrieve all users in the Azure AD Tenant. .PARAMETER Beta Switch to use the beta version of Microsoft Graph API. .PARAMETER ThrottleLimit Only used with the -All switch. Specifies the maximum number of parallel threads or concurrent operations allowed during parallel processing. Default value is 8. .EXAMPLE Import-Csv .\userlist.csv | Get-gUser .EXAMPLE Import-Csv .\userlist.csv | Get-gUser -Select 'DisplayName,UserPrincipalName,Mail' .EXAMPLE Import-Csv .\userlist.csv | Get-gUser -IncludeManager -Select 'DisplayName,UserPrincipalName' .EXAMPLE Get-gUser -User '72ae3f1a-c8f1-4aad-af82-51473013fa74' .EXAMPLE Get-gUser -User 'Kevin Blumenfeld' .EXAMPLE Get-gUser -User 'Kevin Blumenfeld' -Beta Retrieves user information for 'Kevin Blumenfeld' using the beta version of Microsoft Graph API. .EXAMPLE Get-gUser -User 'Kevin Blumenfeld' -Select 'DisplayName,UserPrincipalName' .EXAMPLE Get-gUser -User 'Kevin Blumenfeld' -Select 'DisplayName,UserPrincipalName' .EXAMPLE Get-gUser -User 'Kevin Blumenfeld' -IncludeManager -Select 'DisplayName,UserPrincipalName' .EXAMPLE Get-gUser -All Retrieves all users in the Azure AD Tenant. .EXAMPLE Get-gUser -All -Beta Retrieves all users in the Azure AD Tenant using the beta version of Microsoft Graph API. .EXAMPLE Get-gUser -All -Select 'DisplayName,UserPrincipalName' Retrieves all users in the Azure AD Tenant. .EXAMPLE Get-gUser -All -Beta -Select 'DisplayName,UserPrincipalName' Retrieves all users in the Azure AD Tenant using the beta version of Microsoft Graph API. #> [CmdletBinding()] param ( [Parameter( Mandatory, ValueFromPipeline, ParameterSetName = 'pipeline' )] [ArgumentCompleter([completer_iUser_DisplayName])] [object] $User, [Parameter(ParameterSetName = 'pipeline' )] [string] $Select, [Parameter(ParameterSetName = 'pipeline' )] [switch] $IncludeManager, [Parameter(ParameterSetName = 'pipeline')] [Parameter(ParameterSetName = 'All')] [switch] $Beta, [Parameter(ParameterSetName = 'All')] [switch] $All, [Parameter(ParameterSetName = 'All')] [int] $ThrottleLimit = 8 ) begin { if ($All) { $splat = @{ ThrottleLimit = $ThrottleLimit } if ($Select) { $splat['Select'] = $Select } Get-gUserAll @splat return } } process { foreach ($Item in $User) { if ($Item -is [string] -and $Item -as [Guid]) { $filterstring = '{0}?' -f $Item } elseif ($Item -as [mailaddress]) { $filterstring = "?`$filter=userprincipalname eq '{0}'" -f [System.Web.HttpUtility]::UrlEncode($Item) } elseif ($Item -is [string]) { $filterstring = "?`$filter=DisplayName eq '{0}'" -f $Item } else { if ($Item.Id) { $filterstring = '{0}?' -f $Item.Id } elseif ($Item.UserPrincipalName -as [mailaddress]) { $filterstring = '{0}?' -f $Item.UserPrincipalName } elseif ($Item.DisplayName) { $filterstring = "?`$filter=DisplayName eq '{0}'" -f $Item.DisplayName } } if ($filterstring) { if ($Select) { $filterstring = '{0}&$Select={1}' -f $filterstring, $Select } if ($IncludeManager) { $filterstring = '{0}&$expand=manager' -f $filterstring } if (-not $Beta) { $Uri = 'https://graph.microsoft.com/v1.0/users/{0}' -f $filterstring } else { $Uri = 'https://graph.microsoft.com/beta/users/{0}' -f $filterstring } if ($filterstring -like '*filter=*') { (Invoke-gRestMethod -Method 'GET' -Uri $Uri).value continue } Invoke-gRestMethod -Method 'GET' -Uri $Uri } } } } #EndRegion '.\Public\User\Get-gUser.ps1' 170 #Region '.\Public\User\Get-gUserDeleted.ps1' 0 function Get-gUserDeleted { <# .SYNOPSIS Retrieve the properties and relationships of user objects in Azure Active Directory (AAD). .DESCRIPTION This cmdlet retrieves user objects from AAD and provides various options for filtering and selecting specific properties. Users can be identified by their ID, UserPrincipalName, or DisplayName. Additionally, a list of users can be provided in a CSV file. The cmdlet also supports parallel processing of user objects, with a default throttle limit of 8 threads. .PARAMETER User Specifies the ID, UserPrincipalName, or DisplayName of the user to retrieve. A list of users can also be provided in a CSV file. If the CSV file has headers, they must contain one of the following columns: Id, UserPrincipalName, or DisplayName. DisplayName is not unique in AAD and may result in multiple matches. Note that tab completion is supported for the DisplayName parameter. You can type a few letters and use tab multiple times to cycle through and find matching DisplayNames of users you want more details on. For example, typing 'fr' and pressing tab multiple times may show both 'Frank' and 'Fred' as options. .PARAMETER Select Specifies a comma-separated list of properties to be returned by Microsoft Graph. For example: Get-gUser -Select 'DisplayName,UserPrincipalName,Mail' .PARAMETER IncludeManager If the user has a manager listed in Azure AD, this switch includes the user's manager in the output .PARAMETER All Switch to retrieve all users in the Azure AD Tenant. .PARAMETER Beta Switch to use the beta version of Microsoft Graph API. .PARAMETER ThrottleLimit Only used with the -All switch. Specifies the maximum number of parallel threads or concurrent operations allowed during parallel processing. Default value is 8. .EXAMPLE Import-Csv .\userlist.csv | Get-gUser .EXAMPLE Import-Csv .\userlist.csv | Get-gUser -Select 'DisplayName,UserPrincipalName,Mail' .EXAMPLE Import-Csv .\userlist.csv | Get-gUser -IncludeManager -Select 'DisplayName,UserPrincipalName' .EXAMPLE Get-gUser -User '72ae3f1a-c8f1-4aad-af82-51473013fa74' .EXAMPLE Get-gUser -User 'Kevin Blumenfeld' .EXAMPLE Get-gUser -User 'Kevin Blumenfeld' -Beta Retrieves user information for 'Kevin Blumenfeld' using the beta version of Microsoft Graph API. .EXAMPLE Get-gUser -User 'Kevin Blumenfeld' -Select 'DisplayName,UserPrincipalName' .EXAMPLE Get-gUser -User 'Kevin Blumenfeld' -Select 'DisplayName,UserPrincipalName' .EXAMPLE Get-gUser -User 'Kevin Blumenfeld' -IncludeManager -Select 'DisplayName,UserPrincipalName' .EXAMPLE Get-gUser -All Retrieves all users in the Azure AD Tenant. .EXAMPLE Get-gUser -All -Beta Retrieves all users in the Azure AD Tenant using the beta version of Microsoft Graph API. .EXAMPLE Get-gUser -All -Select 'DisplayName,UserPrincipalName' Retrieves all users in the Azure AD Tenant. .EXAMPLE Get-gUser -All -Beta -Select 'DisplayName,UserPrincipalName' Retrieves all users in the Azure AD Tenant using the beta version of Microsoft Graph API. #> [CmdletBinding()] param ( [Parameter( Mandatory, ValueFromPipeline, ParameterSetName = 'pipeline' )] [ArgumentCompleter([completer_iUser_Deleted_DisplayName])] [object] $User, [Parameter(ParameterSetName = 'pipeline' )] [string] $Select, [Parameter(ParameterSetName = 'pipeline' )] [switch] $IncludeManager, [Parameter(ParameterSetName = 'pipeline')] [Parameter(ParameterSetName = 'All')] [switch] $Beta, [Parameter(ParameterSetName = 'All')] [switch] $All, [Parameter(ParameterSetName = 'All')] [int] $ThrottleLimit = 8 ) begin { if ($All) { $splat = @{ ThrottleLimit = $ThrottleLimit } if ($Select) { $splat['Select'] = $Select } Get-gUserDeletedAll @splat return } } process { foreach ($Item in $User) { if ($Item -is [string] -and $Item -as [Guid]) { $filterstring = '{0}?' -f $Item } elseif ($Item -as [mailaddress]) { $filterstring = "?`$filter=userprincipalname eq '{0}'" -f [System.Web.HttpUtility]::UrlEncode($Item) } elseif ($Item -is [string]) { $filterstring = "?`$filter=DisplayName eq '{0}'" -f $Item } else { if ($Item.Id) { $filterstring = '{0}?' -f $Item.Id } elseif ($Item.UserPrincipalName -as [mailaddress]) { $filterstring = '{0}?' -f $Item.UserPrincipalName } elseif ($Item.DisplayName) { $filterstring = "?`$filter=DisplayName eq '{0}'" -f $Item.DisplayName } } if ($filterstring) { if ($Select) { $filterstring = '{0}&$Select={1}' -f $filterstring, $Select } if ($IncludeManager) { $filterstring = '{0}&$expand=manager' -f $filterstring } if (-not $Beta) { $Uri = 'https://graph.microsoft.com/v1.0/directory/deletedItems/microsoft.graph.user/{0}' -f $filterstring } else { $Uri = 'https://graph.microsoft.com/beta/directory/deletedItems/microsoft.graph.user/{0}' -f $filterstring } if ($filterstring -like '*filter=*') { (Invoke-gRestMethod -Method 'GET' -Uri $Uri).value continue } Invoke-gRestMethod -Method 'GET' -Uri $Uri } } } } #EndRegion '.\Public\User\Get-gUserDeleted.ps1' 169 |