Public/Get-InforcerAuditEvent.ps1
|
<# .SYNOPSIS Retrieves audit events from the Inforcer API. Required API scope(s): Audit.Read (API key, unconfirmed — see docs/API-REFERENCE.md); Activity permission (API client, unconfirmed). .DESCRIPTION POST /auditEvents/search on both login types (API key: /beta, client credentials: /v1). With client credentials the response has no ClientId or Message fields. When -DateFrom and -DateTo are omitted, uses a wide default range (10 years ago to now). When -EventType is not specified, no event-type filter is sent and the API searches all types (one search, both login types). Events come back in the API's order. The -EventType tab-completion list is not refreshed by this cmdlet; run Get-InforcerSupportedEventType for that. Use -Id to retrieve a specific event by its event ID. Use -CorrelationId to retrieve all events sharing a correlation ID. Both perform a broad search and filter client-side. .PARAMETER Id Retrieve a specific audit event by its event ID (GUID). Searches all event types and filters client-side. .PARAMETER CorrelationId Retrieve all audit events sharing this correlation ID. Searches all event types and filters client-side. .PARAMETER EventType Event types to include. Omit for all types (tab-complete with supported event types). .PARAMETER DateFrom Start of date/time range (inclusive). Omit with DateTo = 10 years ago to now; if only DateTo set = 30 days before DateTo. .PARAMETER DateTo End of date/time range (inclusive). Omit with DateFrom = now (UTC). .PARAMETER User Filter events server-side by this user (matches the `user` field in the API request body). .PARAMETER PageSize Page size per API request. Default 100. .PARAMETER MaxResults Maximum events to return. 0 = no limit (default). .PARAMETER Format Raw (default). .PARAMETER OutputType PowerShellObject (default) or JsonObject. JSON output uses Depth 100. .EXAMPLE Get-InforcerAuditEvent .EXAMPLE Get-InforcerAuditEvent -Id "00000000-0000-0000-0000-00000000000a" Retrieves a single audit event by its ID. .EXAMPLE Get-InforcerAuditEvent -CorrelationId "00000000-0000-0000-0000-00000000000b" Retrieves all audit events sharing a correlation ID. .EXAMPLE Get-InforcerAuditEvent -DateFrom (Get-Date).AddDays(-7) -DateTo (Get-Date) .EXAMPLE Get-InforcerAuditEvent -EventType authentication,failedAuthentication -DateFrom $from -DateTo $to .EXAMPLE Get-InforcerAuditEvent -OutputType JsonObject Returns a JSON string (a JSON array on v1 even for zero or one event); output objects do not include a metadata property (flattened to top-level fields). .OUTPUTS PSObject or String (JSON array when -OutputType JsonObject) .LINK https://github.com/royklo/InforcerCommunity/blob/main/docs/CMDLET-REFERENCE.md#get-inforcerauditevent .LINK Connect-Inforcer #> function Get-InforcerAuditEvent { [CmdletBinding()] [OutputType([PSObject], [string])] param( [Parameter(Mandatory = $false)] [string]$Id, [Parameter(Mandatory = $false)] [string]$CorrelationId, [Parameter(Mandatory = $false)] [ArgumentCompleter({ param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) $prefix = if ($wordToComplete) { $wordToComplete } else { '' } if ($prefix -match ',') { $prefix = ($prefix -split ',' | ForEach-Object { $_.Trim() })[-1] } $prefix = $prefix.Trim() # Dynamic: read $global:InforcerCachedEventTypes populated by Get-InforcerSupportedEventType.ps1 # at module import (static fallback) and refreshed with live data after any authenticated # Get-InforcerSupportedEventType call. Two-item minimum fallback covers the case where a user # somehow imports only Get-InforcerAuditEvent without the sibling file. $types = if ($global:InforcerCachedEventTypes -and $global:InforcerCachedEventTypes.Count -gt 0) { $global:InforcerCachedEventTypes } else { @('authentication', 'failedAuthentication') } $filterByPrefix = $prefix -and $prefix -notmatch '^[./\\]' if ($filterByPrefix) { $filtered = @($types | Where-Object { $_ -like "$prefix*" }) $exactMatch = $filtered | Where-Object { $_ -ceq $prefix } if ($exactMatch.Count -ne 1) { $types = $filtered } } foreach ($t in $types) { [Management.Automation.CompletionResult]::new($t, $t, [Management.Automation.CompletionResultType]::ParameterValue, $t) } })] [string[]]$EventType, [Parameter(Mandatory = $false)] [DateTime]$DateFrom, [Parameter(Mandatory = $false)] [DateTime]$DateTo, [Parameter(Mandatory = $false)] [string]$User, [Parameter(Mandatory = $false)] [int]$PageSize = 100, [Parameter(Mandatory = $false)] [int]$MaxResults = 0, [Parameter(Mandatory = $false)] [ValidateSet('Raw')] [string]$Format = 'Raw', [Parameter(Mandatory = $false)] [ValidateSet('PowerShellObject', 'JsonObject')] [string]$OutputType = 'PowerShellObject' ) if (-not (Test-InforcerSession)) { Write-Error -Message 'Not connected yet. Please run Connect-Inforcer first.' -ErrorId 'NotConnected' -Category ConnectionError return } # No -EventType: eventTypes is omitted and the API searches every type (both logins; checked live on # beta, where it returns the same events as listing all types). $isV1 = $script:InforcerSession.ApiVersion -eq 'v1' $eventTypes = @($EventType | Where-Object { -not [string]::IsNullOrWhiteSpace($_) }) # Date range $dateFromVal = $DateFrom $dateToVal = $DateTo if ($dateFromVal -and -not $dateToVal) { $dateToVal = [DateTime]::UtcNow } if ($dateToVal -and -not $dateFromVal) { $dateFromVal = $dateToVal.AddDays(-30) } if (-not $dateFromVal -and -not $dateToVal) { $dateToVal = [DateTime]::UtcNow $dateFromVal = $dateToVal.AddYears(-10) } $dateFromStr = $dateFromVal.ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ') $dateToStr = $dateToVal.ToUniversalTime().ToString($(if ($isV1) { 'yyyy-MM-ddTHH:mm:ssZ' } else { 'yyyy-MM-ddTHH:mm:ss.fffZ' })) $allItems = [System.Collections.Generic.List[object]]::new() $bodyObj = @{ dateFrom = $dateFromStr dateTo = $dateToStr pageSize = $PageSize } if ($eventTypes.Count -gt 0) { $bodyObj['eventTypes'] = $eventTypes } if ($User) { $bodyObj['user'] = $User } Write-Verbose 'Searching audit events...' $searchErr = @() $found = @(Invoke-InforcerPagedRequest -Endpoint '/auditEvents/search' -Method POST -Body $bodyObj -ObjectType AuditEvent -MaxResults $MaxResults -ErrorVariable searchErr) if ($searchErr.Count -gt 0) { return } foreach ($item in $found) { if ($item -is [PSObject]) { $null = Add-InforcerPropertyAliases -InputObject $item -ObjectType AuditEvent $item.PSObject.TypeNames.Insert(0, 'InforcerCommunity.AuditEvent') $allItems.Add($item) } } # Filter by -Id or -CorrelationId when specified if (-not [string]::IsNullOrWhiteSpace($Id)) { $idTrimmed = $Id.Trim() $allItems = [System.Collections.Generic.List[object]]@($allItems | Where-Object { $idProp = $_.PSObject.Properties['id'] $idProp -and $idProp.Value -and $idProp.Value.ToString() -eq $idTrimmed }) if ($allItems.Count -eq 0) { Write-Warning "No audit event found with ID '$idTrimmed'." return } } if (-not [string]::IsNullOrWhiteSpace($CorrelationId)) { $corrTrimmed = $CorrelationId.Trim() $allItems = [System.Collections.Generic.List[object]]@($allItems | Where-Object { $corrProp = $_.PSObject.Properties['correlationId'] $corrProp -and $corrProp.Value -and $corrProp.Value.ToString() -eq $corrTrimmed }) if ($allItems.Count -eq 0) { Write-Warning "No audit events found with CorrelationId '$corrTrimmed'." return } } if ($OutputType -eq 'JsonObject') { if ($isV1) { return ConvertTo-Json -InputObject @($allItems) -Depth 100 } return $allItems | ConvertTo-Json -Depth 100 } else { $allItems } } |