Строковая переменная в файле журнала теряет возвращаемые символы

#powershell-2.0 #traceroute

#powershell-2.0 #трассировка маршрута

Вопрос:

Я использую powershell для выполнения команды tracert и ввода результата в переменную.

 $TraceResult = tracert $server 
  

При использовании write-host вывод выглядит нормально на экране, каждый переход на новую строку.

 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.
  

Когда я вывожу переменную в файл с помощью add-content, возвращаемые символы теряются, а форматирование выглядит ужасно, поскольку оно находится в одной строке:

 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.
  

Есть идеи, где я ошибаюсь?

         $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."

    }
  

Комментарии:

1. Проблема не в выводе tracert , а в том, что вы делаете с этим содержимым в своей LogWrite функции. Ваш вывод tracert — это не одна строка, а скорее массив строк (по одной на строку), и он пытается объединить их все в одну строку (в основном, объединяя их). Фактически, поскольку эта функция в настоящее время написана, это не приведет к результатам, которые, я думаю, вы ожидаете — вы смешиваете однострочный формат с разделителями табуляции с многострочными данными.

Ответ №1:

Вывод tracert обрабатывается PowerShell не как отдельная строка, а скорее как массив строк (по одной на строку), и он пытается объединить их все в одну строку (в основном, объединяя их).

Предполагая, что вы согласны с выводом, подобным этому:

 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.
  

Вам нужно будет сделать это:

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

Это объединит все элементы $TraceResult массива в одну строку с CRLFмаркером EOL.

Комментарии:

1. Ах!!! Так просто, когда знаешь как!!!!! Большое спасибо. Я действительно изо всех сил пытался понять, что происходит. Ты суперзвезда !!! 🙂