Basic reporting for Shibboleth Identity Provider on Windows

This page relates to deployments on Windows. If you're running Linux or similar platforms then IdPBasicReporting may be more useful

The Shibboleth Identity Provider stores logs using the gzip algorithm which is not easy to use on Windows.

The below PowerShell script, which is provided with absolutely no warranty, may be of use to extract data out of the audit logs.

A typical run might look like:

> path\to\report.ps1 -Path \Path\To\Logs -Field 4

Name                                       Value
----                                       -----
https://test.ukfederation.org.uk/entity    43
https://sp.example.ac.uk                   28

Script

Previous versions of the IdP defaulted to logging in a slightly different format with the fields in different positions so you should check the format your IdP is using. Upgraded instances retain the old behaviour.

# PowerShell script to process gzipped pipe-separated files and aggregate values
# (c) Jisc 2026, provided as is with no warranty

param (
	[string]$Path = ".",  # Default to current directory if not specified
	[int]$Field = 4, # Default field to extract
        [string]$Filter = "idp-audit-*.gz" # Default file filter
)

# Initialize a hashtable to store the counts
$valueCounts = @{}

# Get all .gz files in the specified directory
$gzFiles = Get-ChildItem -Path $InputDirectory -Filter $Filter

# Iterate through each gzipped file
foreach ($file in $gzFiles) {
    Write-Verbose "Processing file: $($file.Name)"

    # Open the gzipped file
    $stream = New-Object System.IO.FileStream($file.FullName, [System.IO.FileMode]::Open)
    $gzipStream = New-Object System.IO.Compression.GzipStream($stream, [System.IO.Compression.CompressionMode]::Decompress)
    $reader = New-Object System.IO.StreamReader($gzipStream)

    # Read the file line by line
    while (($line = $reader.ReadLine()) -ne $null) {
        # Split the line by pipe
        $fields = $line -split '\|'

        # Check if the line has at least 4 fields
        if ($fields.Length -ge $Field) {
            # Get the value at position 4 (index 3)
            $value = $fields[$Field - 1]

            # Increment the count for this value
            if ($valueCounts.ContainsKey($value)) {
                $valueCounts[$value]++
            }
            else {
                $valueCounts[$value] = 1
            }
        }
    }

    # Close streams
    $reader.Close()
    $gzipStream.Close()
    $stream.Close()
}

# Sort the results by count in descending order
$sortedCounts = $valueCounts.GetEnumerator() | Sort-Object Value -Descending

# Output the results
$sortedCounts | Format-Table -AutoSize