Search code examples
powershell-2.0traceroute

String variable to log file loses return characters


I am using powershell to perform a tracert command and putting the result into a variable.

$TraceResult = tracert $server 

When using write-host the output looks fine on screen, which each hop on a new line.

Tracing route to fhotmail.com [65.55.39.10]
over a maximum of 30 hops:

  1    <1 ms    <1 ms    <1 ms  BTHomeHub.home [192.168.50.1] 
  2     *        *        *     Request timed out.
  3     *        *        *     Request timed out.
  4     *        *        *     Request timed out.
  5     *        *        *     Request timed out.

When I output the variable to a file using add-content the return characters are lost and the formatting looks terrible as it's on one line:

17/06/2014  14:48:26     Tracing route to fhotmail.com [64.4.6.100] over a maximum of 30 hops:    1    <1 ms    <1 ms    <1 ms  BTHomeHub.home [192.168.50.1]    2     *        *        *     Request timed out.   3     *        *        *     Request timed out.   4     *        *        *     Request timed out.   5     *        *        *     Request timed out.   6     *        *        *     Request timed out.   7     *        *        *     Request timed out.   8     *        *        *     Request timed out.   9     *        *        *     Request timed out.  10     *        *        *     Request timed out.  11     *        *        *     Request timed out.  12     *        *        *     Request timed out.  13     *        *        *     Request timed out.  14     *        *        *     Request timed out.  15     *        *        *     Request timed out.  16     *        *        *     Request timed out.  17     *        *        *     Request timed out.  18     *        *        *     Request timed out.  19     *        *        *     Request timed out.  20     *        *        *     Request timed out.  21     *        *        *     Request timed out.  22     *        *        *     Request timed out.  23     *        *        *     Request timed out.  24     *        *        *     Request timed out.  25     *        *        *     Request timed out.  26     *        *        *     Request timed out.  27     *        *        *     Request timed out.  28     *        *        *     Request timed out.  29     *        *        *     Request timed out.  30     *        *        *     Request timed out.  Trace complete.

Any idea on where I'm going wrong?

        $servers = "localhost","google.com","fhotmail.com"
    $Logfile = "c:\temp\$(Get-Content env:computername).log"  # Sets the logfile as c:\temp\[COMPUTERNAME].log

    # Countdown function with progress bar
    Function Start-Countdown 
    {   
        Param(
            [Int32]$Seconds = 10,
            [string]$Message = "Pausing for 10 seconds..."
        )
        ForEach ($Count in (1..$Seconds))
        {   Write-Progress -Id 1 -Activity $Message -Status "Waiting for $Seconds seconds, $($Seconds - $Count) left" -PercentComplete (($Count / $Seconds) * 100)
            Start-Sleep -Seconds 1
        }
        Write-Progress -Id 1 -Activity $Message -Status "Completed" -PercentComplete 100 -Completed
    }

    # Log Write Function to log a message with date and time (tab delimited)
    Function LogWrite
    {
       Param ([string]$logstring)

       Add-content $Logfile -value "$(get-date -UFormat '%d/%m/%Y') `t$(get-date -UFormat '%T') `t$logstring"
    }

    # Looping script to run ping tests, then countdown for a period, before repeating
    while ($true) {

        # Ping servers and perform tracert if not responding to ping
        foreach ( $server in $servers ) {
                write-Host "Pinging: $server" -ForegroundColor Green
                if ((test-Connection -ComputerName $server -Count 2 -Quiet) -eq $true ) { 
                    # Ping response received.   
                    write-Host "Response Received Sucessfully [$server].`n" -ForegroundColor Green
                    } 
                else { 
                    # Ping response failed, next perform trace route.
                    write-Host "Response FAILED [$server]." -ForegroundColor RED 
                    LogWrite "Ping Response FAILED [$server]."
                    Write-Host "Traceroute: $server - $(get-date -UFormat '%d/%m/%Y - %T')" -ForegroundColor Yellow
                    $TraceResult = tracert $server 
                    LogWrite $TraceResult
                    Write-Host "Traceroute Completed [$server]`n" -ForegroundColor Yellow
                    }                   
        }


        # Pause before repeating
        Start-Countdown -Seconds 60 -Message "Pausing script before restarting tests.  Use CTRL-C to Terminate."

    }

Solution

  • The output of tracert isn't being handled by PowerShell as a single string but rather an array of strings (one per line) and it's trying to force them all into a single string (concatenating them, basically).

    Assuming you're OK with output like this:

    17/06/2014  16:54:07    
    Tracing route to SERVERNAME [IP]
    over a maximum of 30 hops:
    
      1     1 ms    <1 ms    <1 ms  HOP1 
      2     1 ms    <1 ms    <1 ms  IP 
    
    Trace complete.
    

    You'll need to do this:

    $TraceResult = tracert $server 
    LogWrite ($TraceResult -join "`r`n")
    

    This will concatenate all the elements of the $TraceResult array into one string, with CRLF as the EOL marker.