Okay, so I have this array, which is essentially an Import-Csv
of a CSV file. Each object in the array is an entire CSV row. The input file renders properly when I open it with Excel (The columns are correct)
This CSV file is comma delimited, in the following example format:
"first","second","this is all
the third
column","fourth"
I have gotten everything in my script to work properly, except for the part where I need to write this array to a .csv file in a format which will properly render. I have been having issues using Out-File
, Export-Csv
, and I even tried this but it doesn't give me exactly what I need. Each object needs to be a new line in the csv file, appear only once, and must adhere to Excel's rendering of CSV files (i.e. each column needs to be double quoted and comma delimited).
I even got so desperate that I'm trying to manually format this thing correctly by doing this:
$Array | % { $_ -replace "`"@`{","`n`"" } | % { $_ -replace "}`"","`"`n" } | % { $_ -replace "`;","`"`;`"" } | % { $_ -replace "Plugin ID=","" } | % { $_ -replace "CVE=","" } | % { $_ -replace "CVSS=","" } | % { $_ -replace "Risk=","" } | % { $_ -replace "Host=","" } | % { $_ -replace "Protocol=","" } | % { $_ -replace "Port=","" } | % { $_ -replace "Name=","" } | % { $_ -replace "Synopsis=","" } | % { $_ -replace "Solution=","" } | % { $_ -replace "Description=","" } | % { $_ -replace "Plugin Output=","" } | % { $_ -replace "`";`"","`",`"" } | Out-File "$dirResults\$Results-$Time.csv"
Essentially, what I'm doing here is a couple of things:
- Remove @{ from the beginning and } from the end of each object
- Change the delimeter from ; to ,
- Put each column in double quotations
- Remove the ColumnHeader= from the beginning of each value
Here is a snippet of code:
$arrayHeader = @("Plugin ID;CVE;CVSS;Risk;Host;Protocol;Port;Name;Synopsis;Description;Solution;Plugin Output")
$OutterArrayException = Import-Csv "$dirExceptions\$FileException" -Delimiter ","
$InnerArrayScanMe = New-Object System.Collections.ArrayList
# This method keeps the arrays separate types
FOREACH ( $Object in $OutterArrayScanMe )
{ $InnerArrayScanMe.Add("$Object") | Out-Null }
# Note that the OutterArrayException is an Import-Csv from a similarly formatted file as OutterArrayScanMe
FOREACH ( $Exception in $OutterArrayException )
{ $InnerArrayScanMe.Remove("$Exception") }
# This method keeps the arrays separate types
$OutterArrayScanMe = @($arrayHeader) + @($InnerArrayScanMe)
$OutterArrayScanMe | Export-Csv "$dirResults\$FileScanMe-$startTime.csv" -Delimiter ";" -NoTypeInformation
UPDATE:
When I use export-csv, the new lines for an object place the information as a new row in the csv. Thus, something that should look like this gets really messy.
UPDATE2:
There have been some questions about what the format looks like and what the issues are with the format. To clear those up, I have included a single object in the array which demonstrates the issue. Remember, what happens in my script is there is an import-csv of a properly formatted CSV (Has multi line, etc. and renders perfectly), removal of unnecessary objects (using $array.Remove), and then a dump to file (Out-File or Export-Csv). So simple, yet so broken...
Example Array Object (Out-File):
@{Plugin ID=#####; CVE=CVE-####-####; CVSS=#.#; Risk=Medium; Host=###.###.###.###; Protocol=xxx; Port=##; Name=Microsoft ASP.NET xxx; Synopsis=A framework used by the remote web server
vulnerability.; Description=The web server running on the remote host appears to be using Microsoft
ASP.NET, and may be affected by a vulnerability.
Additionally, there is speculation that this vulnerability could result
in unicorns and rainbows if an attacker with physical access to the machine
plugs in.; Solution=Use an magic filter to block requests to naughty sites.; Plugin Output=
Nessus received an naughty page or related error message by requesting
the following URL :
hxxp://###.###.###.###/xxx/xxxxxxxxx
}
Example Array Object (Export-Csv):
#TYPE System.String
"Length"
"616"