2015-09-07 5 views
10

Ich benutze PSVersion 2.0 und ich frage mich, gibt es ein Äquivalent zu der traceroute dafür?Gibt es einen PowerShell-entsprechenden Tracert, der in Version 2 funktioniert?

Ich bin mir bewusst, dass auf PowerShell v4 Test-NetConnection-Cmdlet Tracer zu tun ist, aber v2 ?! Es kann wie geschehen:

Test-NetConnection "IPaddress/HOSTaname" -TraceRoute 

Dank

+1

Sie können das Original 'tracert.exe' von Powershell verwenden, müssen Sie nur die Ausgabe selbst –

+0

Dank Mann zu analysieren, Sie haben mir sehr geholfen !!! – Sylca

Antwort

17

Wie bereits erwähnt in dem Kommentar, können Sie Ihren eigenen "schlecht-Mans-Powershell-tracert" machen, indem die Ausgabe von tracert.exe Parsen:

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 
     } 
    } 
} 

standardmäßig Objekte Powershell-Formate mit 5 oder mehr Objekte in einer Liste, aber Sie können einen tracert -ähnlichen Ausgang mit Format-Table erhalten:

enter image description here

+0

Sie sind definitiv die extra Meile hier gegangen. Gut gemacht! –

+0

Danke Mann! Ich stimme @MikeShepard – Sylca

3

Ich muss zugeben, ich wollte sehen, ob jemand das schon getan hat.

können Sie .NET Framework verwenden, um eine nicht so schlecht-Mans-trace als Powershell-Skript

Hier ein Primer zu implementieren, die schnell funktioniert, aber gefährlich. Auch keine Statistik.

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

einige der Gefahr beseitigt durch eine catch-Anweisung hinzufügen. Die einzige Gefahr, die noch vorhanden ist, ist die Tatsache, dass wir nur eine einzige Anforderung pro Hop senden, was bedeuten könnte, dass wir nicht erreichen ein Sprung aufgrund eines unschuldig Paket fallen. Die Lösung dieses Problems bleibt eine Übung für den Leser. Hinweis: (Denken Sie an Schleifen innerhalb von Schleifen)

Bonus: Wir versuchen jetzt, die DNS-Eintrag von jedem Hop zu bekommen!

+0

Nizza "native" Ansatz, super! Vielleicht die "Gefahr" erklären? :-) –

+1

Nun, die Gefahr, die damit verbunden war, war der Mangel an Redundanz (wenn eine einzelne ICMP-Nachricht verloren geht, erhalten wir das Ergebnis für diesen speziellen Sprung überhaupt nicht) + wir haben die PingException nicht abgefangen. – MrPaulch

4

Behebung einiger Fehler in der "Mid-Waged-Mans-Tracert" Version, Modularisierung und Hinzufügen einiger Anpassungsteile. @MrPaulch hatte ein tolles 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 
}