2015-09-07 6 views
10

Я использую PSVersion 2.0, и мне было интересно, есть ли эквивалент traceroute?Есть ли эквивалент трассировки PowerShell, который работает в версии 2?

Я знаю, что на PowerShell v4 есть командлет Test-NetConnection, чтобы сделать tracert, но v2 ?! Это может быть сделано как:

Test-NetConnection "IPaddress/HOSTaname" -TraceRoute 

Благодаря

+1

Вы можете использовать оригинальный 'tracert.exe' из PowerShell, вам просто нужно разобрать выход себя –

+0

Благодаря человеку, вы мне очень помогли !!! – Sylca

ответ

17

Как уже упоминалось в комментариях, вы можете сделать свой собственный «бедных-Ман-PowerShell-ЬгасегЬ» путем анализа вывода из tracert.exe:

function Invoke-Tracert { 
    param([string]$RemoteHost) 

    tracert $RemoteHost |ForEach-Object{ 
     if($_.Trim() -match "Tracing route to .*") { 
      Write-Host $_ -ForegroundColor Green 
     } elseif ($_.Trim() -match "^\d{1,2}\s+") { 
      $n,$a1,$a2,$a3,$target,$null = $_.Trim()-split"\s{2,}" 
      $Properties = @{ 
       Hop = $n; 
       First = $a1; 
       Second = $a2; 
       Third = $a3; 
       Node = $target 
      } 
      New-Object psobject -Property $Properties 
     } 
    } 
} 

По умолчанию форматы PowerShell объекты с 5 или более свойств в списке, но вы можете получить tracert -like выход с Format-Table:

enter image description here

+0

Вы определенно прошли лишнюю милю здесь. Отличная работа! –

+0

Спасибо, человек! Я согласен с @MikeShepard – Sylca

3

Должен признаться, я хотел посмотреть, кто-то уже это сделал.

Вы можете использовать .Net Framework для реализации не так бедных-Ман-трассировку как Powershell Сценарий

Здесь праймер, который работает быстро, но опасно. Также нет статистики.

# 
# Mid-Waged-Mans-Tracert 
# 

$ping = new-object System.Net.NetworkInformation.Ping 
$timeout = 5000 
$maxttl = 64 
$address = [string]$args 
$message = [System.Text.Encoding]::Default.GetBytes("MESSAGE") 
$dontfragment = false 
$success = [System.Net.NetworkInformation.IPStatus]::Success 

echo "Tracing $address" 
for ($ttl=1;$i -le $maxttl; $ttl++) { 
    $popt = new-object System.Net.NetworkInformation.PingOptions($ttl, $dontfragment) 
    $reply = $ping.Send($address, $timeout, $message, $popt) 


    $addr = $reply.Address 
    $rtt = $reply.RoundtripTime 
    try { 
     $dns = [System.Net.Dns]::GetHostByAddress($addr) 
    } catch { 
     $dns = "-" 
    } 

    $name = $dns.HostName 

    echo "Hop: $ttl`t= $addr`t($name)" 
    if($reply.Status -eq $success) {break} 
} 

Edit:

Удалены некоторые опасности, добавив поймать заявление. Единственная опасности, что по-прежнему присутствует тот факт, что мы только отправить один запрос на хоп, что может означать, что мы не достичь хмель из-за падение пакета невиновного. Решение этой проблемы остается задачей читателей. Подсказка: (Подумайте о петлях внутри петель)

Бонус: теперь мы пытаемся получить запись dns каждого прыжка!

+0

Хороший «родной» подход, потрясающий! Может быть, объяснить «опасность»? :-) –

+1

Ну что ж, опасность заключалась в отсутствии избыточности (если одно сообщение icmp get потеряно, мы вообще не получаем результат для этого конкретного хопа) + мы не поймали PingException. – MrPaulch

4

Исправлено несколько ошибок в версии «Mid-Waged-Mans-Tracert», было выполнено его модульное моделирование и добавлены некоторые элементы настройки. У @MrPaulch был отличный PoC.

function Invoke-Traceroute{ 
    [CmdletBinding()] 
    Param(
     [Parameter(Mandatory=$true,Position=1)] 
     [string]$Destination, 

     [Parameter(Mandatory=$false)] 
     [int]$MaxTTL=16, 

     [Parameter(Mandatory=$false)] 
     [bool]$Fragmentation=$false, 

     [Parameter(Mandatory=$false)] 
     [bool]$VerboseOutput=$true, 

     [Parameter(Mandatory=$false)] 
     [int]$Timeout=5000 
    ) 

    $ping = new-object System.Net.NetworkInformation.Ping 
    $success = [System.Net.NetworkInformation.IPStatus]::Success 
    $results = @() 

    if($VerboseOutput){Write-Host "Tracing to $Destination"} 
    for ($i=1; $i -le $MaxTTL; $i++) { 
     $popt = new-object System.Net.NetworkInformation.PingOptions($i, $Fragmentation) 
     $reply = $ping.Send($Destination, $Timeout, [System.Text.Encoding]::Default.GetBytes("MESSAGE"), $popt) 
     $addr = $reply.Address 

     try{$dns = [System.Net.Dns]::GetHostByAddress($addr)} 
     catch{$dns = "-"} 

     $name = $dns.HostName 

     $obj = New-Object -TypeName PSObject 
     $obj | Add-Member -MemberType NoteProperty -Name hop -Value $i 
     $obj | Add-Member -MemberType NoteProperty -Name address -Value $addr 
     $obj | Add-Member -MemberType NoteProperty -Name dns_name -Value $name 
     $obj | Add-Member -MemberType NoteProperty -Name latency -Value $reply.RoundTripTime 

     if($VerboseOutput){Write-Host "Hop: $i`t= $addr`t($name)"} 
     $results += $obj 

     if($reply.Status -eq $success){break} 
    } 

    Return $results 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^