Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PowerShell Test-Connection output to file or color results

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:

results

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:

colored_results

like image 685
Draconis Avatar asked Dec 21 '25 13:12

Draconis


2 Answers

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.

like image 117
Santiago Squarzon Avatar answered Dec 24 '25 03:12

Santiago Squarzon


@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:

color results

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:

CSVresult

Parsed into excel:

parsedexcel

like image 38
Draconis Avatar answered Dec 24 '25 05:12

Draconis



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!