EasyPIM icon indicating copy to clipboard operation
EasyPIM copied to clipboard

Missing filtering and pagination for the Graph calls

Open MaciejKuklewski opened this issue 7 months ago • 1 comments

Hi, I noticed that the "Get-PIMEntraRoleActiveAssignment" function only fetches the first page of the Graph API response (the default is 50 objects). For large tenants, that's an issue. Please consider implementing pagination handling with the $skiptoken and $filter parameters in the query strings. Other functions may be missing these features as well, but I didn't check. I'm leaving the code snippet for future reference.

BR, Maciej.

`

Build the request parameters

$headers = @{ "Content-Type" = "application/json" } $version = "v1.0" $roleDefinitionId = "966707d0-3269-4727-9be2-8c3a10f19b9d" $endpoint = "/roleManagement/directory/roleAssignmentScheduleInstances" $params = @{ '$filter' = "roleDefinitionId eq '$($roleDefinitionId)'" '$expand' = "principal($select=id),roleDefinition($select=id,displayName)" '$select' = "id,directoryScopeId,assignmentType,memberType,roleDefinitionId,principal,roleDefinition" }

Build query string in the desired order

$queryString = "$filter=$($params['$filter'])&$expand=$($params['$expand'])&$select=$($params['$select'])" $uri = "$($version)$($endpoint)?$($queryString)"

Initialize the $skiptoken variable

$skiptoken = $null

#Initialize the results array $results = @()

Loop until the $skiptoken is null or empty

do { # Add the $skiptoken to the query string if it exists if ($skiptoken) { $queryString = "$filter=$($params['$filter'])&$expand=$($params['$expand'])&$select=$($params['$select'])&$skiptoken=$skiptoken" $uri = "$($version)$($endpoint)`?$($queryString)" }

# Make the API call
$response = Invoke-MgGraphRequest -Method Get -Uri $uri -Headers $headers

# Process the response
$response.value | ForEach-Object {
    $results += [PSCustomObject]@{
        Id                        = $_.Id
        DirectoryScopeId          = $_.DirectoryScopeId
        RoleDefinitionId          = $_.RoleDefinition.Id
        RoleDefinitionDisplayName = $_.RoleDefinition.DisplayName
        PrincipalId               = $_.Principal.Id
        PrincipalType             = $_.Principal."@odata.type"
        AssignmentType            = $_.AssignmentType
        MemberType                = $_.MemberType
    }
}

# Extract the $skiptoken value from the response
Add-Type -AssemblyName System.Web
$url = $response["@odata.nextLink"]
# Parse the URL
$uri = [System.Uri]$url
# Parse the query string
$queryParams = [System.Web.HttpUtility]::ParseQueryString($uri.Query)
# Extract the $skiptoken value
$skiptoken = $queryParams["`$skiptoken"]

} until ( [string]::IsNullOrWhiteSpace($skiptoken) ) `

MaciejKuklewski avatar May 22 '25 08:05 MaciejKuklewski

thanks @MaciejKuklewski for the heads up! Will check this!

kayasax avatar May 22 '25 14:05 kayasax

pagination added in v1.8.3

kayasax avatar May 31 '25 15:05 kayasax

pagination and filter added in v1.8.4 ex: get-pimentraRoleActiveAssignment -tenantID $env:TenantID -userPrincipalName [email protected]

kayasax avatar Jun 02 '25 14:06 kayasax