From 952b721fdf146b188f57a157e2d81a3aba8650b0 Mon Sep 17 00:00:00 2001 From: merill Date: Wed, 23 Aug 2023 19:07:13 +1000 Subject: [PATCH] Optimised the graph endpoint lookup --- .vscode/launch.json | 14 ++++++++++++++ src/Export-Entra.ps1 | 13 ++++++------- src/Get-EEAccessPackageAssignmentPolicies.ps1 | 8 ++++---- src/Get-EEAccessPackageAssignments.ps1 | 10 +++++----- src/Get-EEAccessPackageResourceScopes.ps1 | 8 ++++---- src/internal/Invoke-Graph.ps1 | 12 +++++++++--- 6 files changed, 42 insertions(+), 23 deletions(-) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..47c94dc --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,14 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "PowerShell: Module Interactive Session", + "type": "PowerShell", + "request": "launch", + "script": "Import-Module -Force ${workspaceFolder}/src/EntraExporter.psd1" + } + ] +} \ No newline at end of file diff --git a/src/Export-Entra.ps1 b/src/Export-Entra.ps1 index 4b4fea6..0d85075 100644 --- a/src/Export-Entra.ps1 +++ b/src/Export-Entra.ps1 @@ -1,4 +1,4 @@ -<# +<# .Synopsis Exports Entra's configuration and settings for a tenant .Description @@ -20,7 +20,7 @@ .EXAMPLE .\Export-Entra -Path 'c:\temp\contoso' -All - + Runs a full export of all objects and configuration settings. .EXAMPLE @@ -44,7 +44,7 @@ Function Export-Entra { param ( [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)] - [String]$Path, + [String]$Path, [Parameter(Mandatory = $false)] [ValidateSet('All', 'Config', 'AccessReviews', 'ConditionalAccess', 'Users', 'Groups', 'Applications', 'ServicePrincipals','B2C','B2B','PIM','PIMAzure','PIMAAD', 'AppProxy', 'Organization', 'Domains', 'EntitlementManagement', 'Policies', 'AdministrativeUnits', 'SKUs', 'Identity', 'Roles','Governance')] @@ -72,7 +72,6 @@ Function Export-Entra { exit } if($All) {$Type = @('All')} - $global:TenantID = (Get-MgContext).TenantId $global:Type = $Type #Used in places like Groups where Config flag will limit the resultset to just dynamic groups. if (!$ExportSchema) { @@ -105,7 +104,7 @@ Function Export-Entra { $spacer = '' if($hasParents) { $spacer = ''.PadRight($Parents.Count + 3, ' ') + $Parents[$Parents.Count-1] } - + Write-Host "$spacer $($item.Path)" $command = Get-ObjectProperty $item 'Command' @@ -121,14 +120,14 @@ Function Export-Entra { else { if ($hasParents){ $graphUri = $graphUri -replace '{id}', $Parents[$Parents.Count-1] } try { - $resultItems = Invoke-Graph $graphUri -GraphBaseUri "$((Get-MgEnvironment -Name (Get-MgContext).Environment).GraphEndpoint)" -Filter (Get-ObjectProperty $item 'Filter') -Select (Get-ObjectProperty $item 'Select') -QueryParameters (Get-ObjectProperty $item 'QueryParameters') -ApiVersion $apiVersion + $resultItems = Invoke-Graph $graphUri -Filter (Get-ObjectProperty $item 'Filter') -Select (Get-ObjectProperty $item 'Select') -QueryParameters (Get-ObjectProperty $item 'QueryParameters') -ApiVersion $apiVersion } catch { $e = "" if($_.ErrorDetails -and $_.ErrorDetails.Message) { $e = $_.ErrorDetails.Message } - + if($e.Contains($ignoreError) -or $e.Contains('Encountered an internal server error')){ Write-Debug $_ } diff --git a/src/Get-EEAccessPackageAssignmentPolicies.ps1 b/src/Get-EEAccessPackageAssignmentPolicies.ps1 index ddaceb2..21f7d23 100644 --- a/src/Get-EEAccessPackageAssignmentPolicies.ps1 +++ b/src/Get-EEAccessPackageAssignmentPolicies.ps1 @@ -1,10 +1,10 @@ -<# +<# .Synopsis - Gets the list of accessPackageAssignmentPolicies + Gets the list of accessPackageAssignmentPolicies .Description GET /identityGovernance/entitlementManagement/accessPackageAssignmentPolicies - https://docs.microsoft.com/en-us/graph/api/accesspackageassignmentpolicy-list?view=graph-rest-beta&tabs=http + https://docs.microsoft.com/en-us/graph/api/accesspackageassignmentpolicy-list?view=graph-rest-beta&tabs=http .Example EEAccessPackagesAssignmentPolicies @@ -17,5 +17,5 @@ Function Get-EEAccessPackageAssignmentPolicies { [Parameter(Mandatory = $true)] [string[]]$Parents ) - Invoke-Graph 'identityGovernance/entitlementManagement/accessPackageAssignmentPolicies' -GraphBaseUri "$((Get-MgEnvironment -Name (Get-MgContext).Environment).GraphEndpoint)" -Filter "(accessPackage/id eq '$($Parents[0])')" -ApiVersion 'beta' + Invoke-Graph 'identityGovernance/entitlementManagement/accessPackageAssignmentPolicies' -Filter "(accessPackage/id eq '$($Parents[0])')" -ApiVersion 'beta' } diff --git a/src/Get-EEAccessPackageAssignments.ps1 b/src/Get-EEAccessPackageAssignments.ps1 index d3872ad..b8a2f9c 100644 --- a/src/Get-EEAccessPackageAssignments.ps1 +++ b/src/Get-EEAccessPackageAssignments.ps1 @@ -1,10 +1,10 @@ -<# +<# .Synopsis - Gets the list of accessPackageAssignments + Gets the list of accessPackageAssignments .Description - GET /identityGovernance/entitlementManagement/accessPackageAssignments?$filter=accessPackage/id eq - https://docs.microsoft.com/en-us/graph/api/accesspackageassignment-list?view=graph-rest-beta&tabs=http + GET /identityGovernance/entitlementManagement/accessPackageAssignments?$filter=accessPackage/id eq + https://docs.microsoft.com/en-us/graph/api/accesspackageassignment-list?view=graph-rest-beta&tabs=http .Example Get-EEAccessPackagesAssignments @@ -17,5 +17,5 @@ Function Get-EEAccessPackageAssignments { [Parameter(Mandatory = $true)] [string[]]$Parents ) - Invoke-Graph 'identityGovernance/entitlementManagement/accessPackageAssignments' -GraphBaseUri "$((Get-MgEnvironment -Name (Get-MgContext).Environment).GraphEndpoint)" -Filter "(accessPackage/id eq '$($Parents[0])')" -ApiVersion 'beta' + Invoke-Graph 'identityGovernance/entitlementManagement/accessPackageAssignments' -Filter "(accessPackage/id eq '$($Parents[0])')" -ApiVersion 'beta' } diff --git a/src/Get-EEAccessPackageResourceScopes.ps1 b/src/Get-EEAccessPackageResourceScopes.ps1 index f817ac9..e3b20af 100644 --- a/src/Get-EEAccessPackageResourceScopes.ps1 +++ b/src/Get-EEAccessPackageResourceScopes.ps1 @@ -1,10 +1,10 @@ -<# +<# .Synopsis - Gets the list of businessflowtemplatesRetrieve a list of accessPackage objects. + Gets the list of businessflowtemplatesRetrieve a list of accessPackage objects. .Description GET /identityGovernance/entitlementManagement/accessPackages/{id}?$expand=accessPackageResourceRoleScopes($expand=accessPackageResourceRole,accessPackageResourceScope) - https://docs.microsoft.com/en-us/graph/api/accesspackage-list-accesspackageresourcerolescopes?view=graph-rest-beta&tabs=http + https://docs.microsoft.com/en-us/graph/api/accesspackage-list-accesspackageresourcerolescopes?view=graph-rest-beta&tabs=http .Example Get-EEAccessPackageResourceScopes @@ -17,5 +17,5 @@ Function Get-EEAccessPackageResourceScopes { [Parameter(Mandatory = $true)] [string[]]$Parents ) - Invoke-Graph "identityGovernance/entitlementManagement/accessPackages/$($Parents[0])" -GraphBaseUri "$((Get-MgEnvironment -Name (Get-MgContext).Environment).GraphEndpoint)" -QueryParameters @{expand='accessPackageResourceRoleScopes(expand=accessPackageResourceRole,accessPackageResourceScope)'} -ApiVersion 'beta' + Invoke-Graph "identityGovernance/entitlementManagement/accessPackages/$($Parents[0])" -QueryParameters @{expand='accessPackageResourceRoleScopes(expand=accessPackageResourceRole,accessPackageResourceScope)'} -ApiVersion 'beta' } diff --git a/src/internal/Invoke-Graph.ps1 b/src/internal/Invoke-Graph.ps1 index ed05ee4..6fcf5ec 100644 --- a/src/internal/Invoke-Graph.ps1 +++ b/src/internal/Invoke-Graph.ps1 @@ -38,10 +38,16 @@ function Invoke-Graph{ [int] $BatchSize = 20, # Base URL for Microsoft Graph API. [Parameter(Mandatory = $false)] - [uri] $GraphBaseUri = 'https://graph.microsoft.com/' + [uri] $GraphBaseUri ) - + begin { + if(!$GraphBaseUri){ + if(!(Test-Path variable:global:GraphBaseUri)){ + $global:GraphBaseUri = $((Get-MgEnvironment -Name (Get-MgContext).Environment).GraphEndpoint) + } + $GraphBaseUri = $global:GraphBaseUri + } $listRequests = New-Object 'System.Collections.Generic.List[psobject]' function Format-Result ($results, $RawOutput) { @@ -128,7 +134,7 @@ function Invoke-Graph{ $indexEnd = [System.Math]::Min($iRequest + $BatchSize - 1, $listRequests.Count - 1) $jsonRequests = New-Object psobject -Property @{ requests = $listRequests[$iRequest..$indexEnd] } | ConvertTo-Json -Depth 5 Write-Debug $jsonRequests - + $resultsBatch = Invoke-MgGraphRequest -Method POST -Uri $uriQueryEndpoint.Uri.AbsoluteUri -Body $jsonRequests -OutputType PSObject $resultsBatch = $resultsBatch.responses | Sort-Object -Property id