Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I pipe Write-Output to Export-Csv?

Tags:

powershell

I have the following "ping script" in which I would like to use an array along with the Export-Csv cmdlet to write the output to a CSV file rather than a txt file.

I first tried piping Write-Output to Export-Csv until reading that you cannot pipe strings to Export-Csv and must convert them into objects first.

I don't quite understand how to work with arrays in PowerShell.

Param(
    [Parameter(Mandatory=$true, position=0)][string]$csvfile
)

$ColumnHeader = "Hostname"

Write-Host "Reading file" $csvfile
$ipaddresses = Import-Csv $csvfile | Select-Object $ColumnHeader

Write-Host "Started Pinging.."
foreach ($ip in $ipaddresses) {
    if (Test-Connection $ip.("Hostname") -Count 1 -Quiet) {
        Write-Output $ip.("Hostname") "Ping succeeded." |
            Out-File -FilePath "C:\temp\pingresults.txt" -Append
    } else {
        Write-Output $ip.("Hostname") "Ping failed." |
            Out-File -FilePath "C:\temp\pingresults.txt" -Append
    }
}

Write-Host "Pinging Completed."
like image 301
Heisenberg Avatar asked Dec 05 '25 10:12

Heisenberg


1 Answers

Of course you can pipe strings into Export-Csv. It's just that the result probably won't be what you expect, since Export-Csv exports the properties of the input objects as the fields of the output file. ;) String objects only have one property (Length), so you'd end up with an output file listing the lengths of the input strings.

To get an output CSV that lists the hostname (or IP address) along with the ping result you need to construct objects with 2 properties. The best way to do this in PowerShell is a pipeline:

Import-Csv $csvfile | ForEach-Object {
    New-Object -Type PSObject -Property ([ordered]@{
        Hostname = $_.Hostname
        Online   = [bool](Test-Connection $_.Hostname -Count 1 -Quiet)
    }
} | Export-Csv 'C:\path\to\output.csv' -NoType

Since you basically just want to add a property to the input data you can take an even simpler approach and add the ping result with a calculated property:

Import-Csv $csvfile |
    Select-Object Hostname,
        @{n='Online';e={[bool](Test-Connection $_.Hostname -Count 1 -Quiet)}} |
    Export-Csv 'C:\temp\pingresults.csv' -NoType

Appending to an array in a loop is not recommended, because appending essentially creates a new array with increased size, copies all elements from the old array, then adds the new elements to the new (empty) slots and releases the old array.

like image 92
Ansgar Wiechers Avatar answered Dec 07 '25 22:12

Ansgar Wiechers



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!