Private/Export-ArgusFindingCsv.ps1
|
function Export-ArgusFindingCsv { <# .SYNOPSIS Writes the findings of one check result to a CSV file and returns the file. .DESCRIPTION Columns follow FindingColumns. Values starting with =, +, -, @, tab or carriage return are prefixed with a single quote, so tenant-controlled strings (display names, titles) can't be interpreted as formulas when the CSV is opened in a spreadsheet application. #> [CmdletBinding()] [OutputType([System.IO.FileInfo])] param( [Parameter(Mandatory)] [pscustomobject] $Result, [Parameter(Mandatory)] [string] $Path ) $columns = @($Result.FindingColumns) if ($columns.Count -eq 0 -and @($Result.Findings).Count -gt 0) { $columns = @(@($Result.Findings)[0].PSObject.Properties.Name) } $rows = foreach ($finding in $Result.Findings) { $row = [ordered]@{} foreach ($column in $columns) { $property = $finding.PSObject.Properties[$column] $value = if ($null -eq $property -or $null -eq $property.Value) { '' } elseif ($property.Value -is [datetime]) { $property.Value.ToString('o') } elseif ($property.Value -is [System.Collections.IEnumerable] -and $property.Value -isnot [string]) { (@($property.Value) -join '; ') } else { [string]$property.Value } if ($value -match '^[=+\-@\t\r]') { $value = "'$value" } $row[$column] = $value } [pscustomobject]$row } $fullPath = [System.IO.Path]::GetFullPath($Path, (Get-Location).ProviderPath) @($rows) | Export-Csv -LiteralPath $fullPath -NoTypeInformation -Encoding utf8BOM Get-Item -LiteralPath $fullPath } |