Role Column in Access Request Status Report

Hello,

We are on IdentityIQ 8.4p1 and I am attempting to report on all the roles that have been requested via the Access Request function. There is a column in the Access Request Status report for ‘Entitlement’ and ‘Entitlement Value’ but not for ‘Role’.

It’s strange that this isn’t included OOTB as I would imagine that this is common requirement.

Can anybody assist with adding a column into the report to pull back all roles that have been requested via an access request please?

Kind regards,
Drew

3_LiveReports_FINAL.pptx (7.4 MB)
I reviewed the report and noticed it’s a Java-based report. You’ll need to unzip the relevant identityiq.jar file, locate the associated class, and add the required field. However, please note that having extensive customizations can create challenges during upgrades. i have one document that might help to move further.

Thanks Narayana.

I managed to pull the required data through exporting the IdentityRequest objects and creating a PS script to iterate through them and retrieve the required data.

Thankfully it’s likely to be one off task which we won’t need to rerun.

Kind regards,
Drew

@DrewHamilton Could you please share your knowledge on how you generated the PowerShell script and iterated through the data?

@narayanag Of course. I exported all the IdentityRequest objects via the Object Exporter Task. The PS script targets the folder of SailPoint IdentityRequest XML export files and extracts the ‘AttributeRequest’ blocks under the ‘AccountRequest’ elements where the application is IIQ and the operation is Modify. I included a filter for requests initiated by specific requesters as I am only interested in Access Requests raised by specific users. Finally, it groups the results by request and outputs them as a CSV file.

Here is the PS script:

# Set the folder containing your exported IdentityRequest XML files
$folderPath = "C:\Path\To\ExportedXML"

# Arrays to store results and files that failed to parse
$rawOutput = @()
$failedFiles = @()

# List of requesters to include in the report
$allowedRequesters = @("Requester1", "Requester2")

# Loop through each XML file in the directory
Get-ChildItem -Path $folderPath -Filter *.xml | ForEach-Object {
    $file = $_

    try {
        # Load the raw XML content and remove any DOCTYPE declarations to avoid parser errors
        $rawXml = Get-Content $file.FullName -Raw -ErrorAction Stop
        $cleanXml = $rawXml -replace '<!DOCTYPE[^>]*>', ''
        [xml]$xml = $cleanXml

        # Extract the requesterDisplayName
        $requester = $xml.IdentityRequest.requesterDisplayName

        # Only continue if the requester is one of the allowed requesters
        if ($allowedRequesters -contains $requester) {

            # Select only AccountRequest blocks for IIQ where the operation is Modify
            $iiqAccountRequests = $xml.IdentityRequest.SelectNodes("//AccountRequest[@application='IIQ'][@op='Modify']")

            foreach ($acct in $iiqAccountRequests) {

                # Extract the <entry key="operation" value="..."/> from within the AccountRequest block
                $acctOperation = $acct.SelectSingleNode("Attributes/Map/entry[@key='operation']")
                $acctOperationValue = if ($acctOperation) { $acctOperation.value } else { "" }

                # Get all AttributeRequest blocks inside this AccountRequest
                $attributeRequests = $acct.SelectNodes("AttributeRequest")

                foreach ($ar in $attributeRequests) {
                    $values = @()

                    # Add value directly if it's available as an attribute
                    if ($ar.value) {
                        $values += $ar.value
                    }

                    # Handle <Value><List><String>...</String></List></Value> style blocks
                    $stringNodes = $ar.SelectNodes("Value/List/String")
                    if ($stringNodes) {
                        foreach ($node in $stringNodes) {
                            $values += $node.InnerText
                        }
                    }

                    # Build a single row per AttributeRequest (to group later)
                    $rawOutput += [PSCustomObject]@{
                        FileName         = $file.Name
                        RequestID        = $xml.IdentityRequest.name
                        RequestedFor     = $xml.IdentityRequest.targetDisplayName
                        Requester        = $requester
                        AccountOperation = $acctOperationValue
                        Value            = ($values -join ";")
                    }
                }
            }
        }

    } catch {
        # Catch any XML parsing or file reading issues
        Write-Warning "Failed to parse file: $($file.FullName)"
        $failedFiles += $file.FullName
    }
}

# Group entries by request to combine all values into a single row per request
$groupedOutput = $rawOutput | Group-Object FileName, RequestID, RequestedFor, Requester, AccountOperation | ForEach-Object {
    $first = $_.Group[0]
    [PSCustomObject]@{
        FileName         = $first.FileName
        RequestID        = $first.RequestID
        RequestedFor     = $first.RequestedFor
        Requester        = $first.Requester
        AccountOperation = $first.AccountOperation
        Value            = ($_.Group | ForEach-Object { $_.Value }) -join ";"
    }
}

# Display final output in table format in PowerShell
$groupedOutput | Format-Table -AutoSize

# Export the grouped results to CSV
$csvPath = Join-Path $folderPath "Grouped_Filtered_Requests.csv"
$groupedOutput | Export-Csv -Path $csvPath -NoTypeInformation -Encoding UTF8

# If any files failed to parse, log them
if ($failedFiles.Count -gt 0) {
    $logPath = Join-Path $folderPath "Failed_Xml_Files.txt"
    $failedFiles | Out-File -FilePath $logPath -Encoding UTF8
    Write-Warning "Some files failed to parse. See log: $logPath"
}

Write-Host "`Export complete. CSV saved to:`n$csvPath" -ForegroundColor Green

1 Like