src/Audit/Get-XrmAuditHistory.ps1
<# .SYNOPSIS Retrieve audit for given record. .DESCRIPTION Get record audit history for given fields changes .PARAMETER XrmClient Xrm connector initialized to target instance. Use latest one by default. (Dataverse ServiceClient) .PARAMETER RecordReference Lookup to target record. (EntityReference) .PARAMETER AttributeFilter Attributes logical names to filter. #> function Get-XrmAuditHistory { [CmdletBinding()] param ( [Parameter(Mandatory = $false, ValueFromPipeline)] [Microsoft.PowerPlatform.Dataverse.Client.ServiceClient] $XrmClient = $Global:XrmClient, [Parameter(Mandatory = $true, ValueFromPipeline)] [Microsoft.Xrm.Sdk.EntityReference] $RecordReference, [Parameter(Mandatory = $false)] [String[]] $AttributeFilter ) begin { $StopWatch = [System.Diagnostics.Stopwatch]::StartNew(); Trace-XrmFunction -Name $MyInvocation.MyCommand.Name -Stage Start -Parameters ($MyInvocation.MyCommand.Parameters); } process { $auditLogs = @(); $retrieveRecordChangeHistoryRequest = New-XrmRequest -Name "RetrieveRecordChangeHistory"; $retrieveRecordChangeHistoryRequest = $retrieveRecordChangeHistoryRequest | Add-XrmRequestParameter -Name "Target" -Value $RecordReference; $retrieveRecordChangeHistoryReponse = Invoke-XrmRequest -XrmClient $XrmClient -Request $retrieveRecordChangeHistoryRequest; $auditDetails = $retrieveRecordChangeHistoryReponse.Results["AuditDetailCollection"].AuditDetails; foreach ($auditDetail in $auditDetails) { $attributes = @(); $auditDetail.NewValue.Attributes | ForEach-Object { $attributes += $_.Key; }; $auditDetail.OldValue.Attributes | ForEach-Object { if (-not $attributes.Contains($_.Key)) { $attributes += $_.Key; } }; foreach ($attributeName in $attributes) { if ($null -eq $attributeName) { # Weird case : sometimes $attributes collection contains only 1 $null value continue; } if ($AttributeFilter -and ($AttributeFilter.Contains($attributeName) -eq $false)) { continue; } $auditRecord = $auditDetail.AuditRecord; $hash = @{}; $hash["Object"] = $auditRecord.FormattedValues["objecttypecode"]; $hash["Id"] = $auditRecord.Id; $hash["ObjectId"] = $auditRecord["objectid"].Id; $hash["Key"] = $RecordReference.Id; $hash["AttributeName"] = $attributeName; $hash["CreatedOn_Value"] = $auditRecord["createdon"]; $hash["CreatedOn"] = $auditRecord.FormattedValues["createdon"]; $hash["User"] = $auditRecord["userid"].Name; $hash["Operation"] = $auditRecord.FormattedValues["operation"]; $hash["Action"] = $auditRecord.FormattedValues["action"]; $hash["OldValue"] = $null; if ($auditDetail.OldValue) { $hash["OldValue"] = $auditDetail.OldValue | Get-XrmAttributeValue -Name $attributeName -FormattedValue; } $hash["NewValue"] = $null; if ($auditDetail.NewValue) { $hash["NewValue"] = $auditDetail.NewValue | Get-XrmAttributeValue -Name $attributeName -FormattedValue; } $auditLog = New-Object PsObject -Property $hash; $auditLogs += $auditLog; } } $auditLogs | Sort-Object -Property CreatedOn_Value -Descending; } end { $StopWatch.Stop(); Trace-XrmFunction -Name $MyInvocation.MyCommand.Name -Stage Stop -StopWatch $StopWatch; } } Export-ModuleMember -Function Get-XrmAuditHistory -Alias *; |