Public/ConvertFrom-NSPRichCopyLog.ps1
|
function ConvertFrom-NSPRichCopyLog { <# .SYNOPSIS Reads a Unicode RichCopy report and extracts dated records and error paths. #> [CmdletBinding()] param( [Parameter(Mandatory)][ValidateNotNullOrEmpty()][string]$Path, [ValidateSet('Unicode', 'UTF8', 'Default')][string]$Encoding = 'Unicode' ) $resolved = (Resolve-Path -LiteralPath $Path -ErrorAction Stop).ProviderPath $raw = Get-Content -LiteralPath $resolved -Raw -Encoding $Encoding -ErrorAction Stop # RichCopy can continue an operation after CRLF and a comma. The original # parser joins those fragments before matching records. $normalized = [regex]::Replace($raw, '.\r\n,', '.') $lineRegex = New-Object System.Text.RegularExpressions.Regex((Get-NSPLogPattern RichCopyRecord), ([System.Text.RegularExpressions.RegexOptions]::Compiled), ([timespan]::FromSeconds(2))) $pathRegex = New-Object System.Text.RegularExpressions.Regex('(?<Error>.*?)(?<Path>[A-Za-z]:\\[^\r\n]*)$', ([System.Text.RegularExpressions.RegexOptions]::Compiled), ([timespan]::FromSeconds(2))) $lineNumber = 0 foreach ($line in ($normalized -split '\r?\n')) { $lineNumber++ $match = $lineRegex.Match($line) if (-not $match.Success) { continue } $operation = $match.Groups['Operation'].Value $errorPath = $null $errorMessage = $null if ($match.Groups['Code'].Value -ne '0') { $pathMatch = $pathRegex.Match($operation) if ($pathMatch.Success) { $errorPath = $pathMatch.Groups['Path'].Value $errorMessage = $pathMatch.Groups['Error'].Value.Trim() } } [pscustomobject]@{ LineNumber = $lineNumber Date = $match.Groups['Date'].Value Time = $match.Groups['Time'].Value Code = $match.Groups['Code'].Value Operation = $operation ErrorMessage = $errorMessage ErrorPath = $errorPath } } } |