I want to export a list of Test-Connection results either to csv or txt file - either one is fine, but I'm not sure how to do it.
An alternative would be to display the 'online' results in green and 'offline' results in red.
This code shows a neat table that I would like to export to file as well. I've been trying for hours various iterations of export-csv and output file and the file is either empty or not created at all.
## read file and create array
$devices = Get-Content -Path C:\temp\devices.txt
## loop through each device
foreach($device in $devices)
{
$test = Test-Connection -ComputerName $device -Count 1 -Quiet
[pscustomobject]@{
DeviceName = $device
Status = if($test){'ONLINE'}
else{'OFFLINE'}
}
}
Result:

Another thing I tried is show the results in color like this:
## read file and create array
$devices = Get-Content -Path C:\temp\devices.txt
## loop through each device
foreach($device in $devices)
{
$test = Test-Connection -ComputerName $device -Count 1 -Quiet
[pscustomobject]@{
DeviceName = $device
Status = if($test){Write-Host "ONLINE" -ForegroundColor Green}
else{Write-Host "OFFLINE" -ForegroundColor Red}
}
}
But the resulting table formatting gets all messed up:

Regarding coloring the values in the Status property, Write-Host writes output to a different stream than Success, when you write output to different streams in the same pipeline you will see issues as the one you're observing. See about_Output_Streams for more info.
What you can do is to embed VT sequences in your string, as demonstrated in Powershell Different color in strings with echo in array. Also about_ANSI_Terminals is worth a read.
In summary, this is how you can approach your code:
# In pwsh 7+ you can use the `$PSStyle` variable:
#
# $map = @{
# $false = "$($PSStyle.Foreground.BrightRed)OFFLINE$($PSStyle.Reset)"
# $true = "$($PSStyle.Foreground.BrightGreen)ONLINE$($PSStyle.Reset)"
# }
$map = @{
$false = "$([char] 27)[91mOFFLINE$([char] 27)[0m"
$true = "$([char] 27)[92mONLINE$([char] 27)[0m"
}
## read file and create array
$devices = Get-Content -Path C:\temp\devices.txt
## loop through each device
foreach ($device in $devices) {
$test = Test-Connection -ComputerName $device -Count 1 -Quiet
[pscustomobject]@{
DeviceName = $device
Status = $map[$test]
}
}
Regarding outputting to a file, first capture the output to a variable, then use the desired cmdlet (Export-Csv or Out-File)... This has been explained before and you can find many answers in this site.
## read file and create array
$devices = Get-Content -Path C:\temp\devices.txt
## loop through each device
$result = foreach ($device in $devices) {
$test = Test-Connection -ComputerName $device -Count 1 -Quiet
[pscustomobject]@{
DeviceName = $device
Status = if ($test) { 'ONLINE' } else { 'OFFLINE' }
}
}
# pipe to the desired output cmdlet...
$result | Export-Csv C:\path\to\the\File.csv -NoTypeInformation
If, however, what you want is to see the colors in the Excel file itself, note that CSV is a plain-text format. You will need an actual .xlsx file, and for that you can check out How to add colors to Excel output file in Powershell, which uses the ImportExcel Module with Conditional Text.
@santiago-squarzon I just wanted to follow-up with an update and give back to the community! Thanks to your fantastic and simple explanation and examples I was able to learn a lot and refine my script for mass device ping :) Thank you once again!
Here is my final script:
## color definition
$map = @{
$false = "$([char] 27)[91mOFFLINE$([char] 27)[0m"
$true = "$([char] 27)[92mONLINE$([char] 27)[0m"
}
## input file
$devices = Get-Content -Path C:\temp\devices.txt
## fast parallel ping
$pingtask = @{}
$timeout = 1000
foreach ($device in $devices) {
$ping = New-Object System.Net.NetworkInformation.Ping
$pingtask[$device] = $ping.SendPingAsync($device, $timeout)
}
## wait for all pings to complete
[System.Threading.Tasks.Task]::WaitAll($pingtask.Values)
## collect ping results
$pingstatus = @{}
foreach ($device in $pingtask.Keys) {
try {$pingstatus[$device] = ($pingtask[$device].Result.Status -eq 'Success')}
catch {$pingstatus[$device] = $false}
}
## results
foreach ($device in $devices) {
[pscustomobject]@{
DeviceName = $device
Status = $map[$pingstatus[$device]]
}
}
Result:

And here is the version that does the same except instead of displaying the results in PowerShell it saves them to CSV (without the colors):
## input file
$devices = Get-Content -Path C:\temp\devices.txt
## fast parallel ping
$pingtask = @{}
$timeout = 1000
foreach ($device in $devices) {
$ping = New-Object System.Net.NetworkInformation.Ping
$pingtask[$device] = $ping.SendPingAsync($device, $timeout)
}
## wait for all pings to complete
[System.Threading.Tasks.Task]::WaitAll($pingtask.Values)
## collect ping results
$pingstatus = @{}
foreach ($device in $pingtask.Keys) {
try {$pingstatus[$device] = ($pingtask[$device].Result.Status -eq 'Success')}
catch {$pingstatus[$device] = $false}
}
## results
$result = foreach ($device in $devices) {
[pscustomobject]@{
DeviceName = $device
Status = if ($pingstatus[$device]) {'ONLINE'} else {'OFFLINE'}
}
}
## export to csv
$result | Export-Csv C:\temp\pinged_devices.csv -NoTypeInformation
Result:

Parsed into excel:

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