2015-09-07 24 views
10

Sto usando PSVersion 2.0 e mi chiedevo se esistesse un equivalente allo traceroute per questo?Esiste un tracert equivalente a PowerShell che funzioni nella versione 2?

Sono consapevole che su PowerShell v4 c'è il cmdlet Test-NetConnection per fare tracert ma v2 ?! Si può fare come:

Test-NetConnection "IPaddress/HOSTaname" -TraceRoute 

Grazie

+1

È possibile utilizzare l'originale 'tracert.exe' da PowerShell, è sufficiente analizzare l'output da soli –

+0

Grazie uomo, mi hai aiutato molto !!! – Sylca

risposta

17

Come accennato nel commento, è possibile rendere il proprio "poveri-mans-PowerShell-tracert" analizzando l'output di 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 
     } 
    } 
} 

Per impostazione predefinita, i formati PowerShell oggetti con 5 o più proprietà in una lista, ma è possibile ottenere una potenza tracert -come con Format-Table:

enter image description here

+0

Hai sicuramente fatto il miglio supplementare qui. Ottimo lavoro! –

+0

Grazie amico! Sono d'accordo con @MikeShepard – Sylca

3

Devo ammettere che volevo vedere se qualcuno lo ha già fatto.

È possibile utilizzare il Net Framework per implementare un non-così-poveri-mans-traceroute come PowerShell script

Ecco un primer, che funziona veloce, ma pericoloso. Inoltre, nessuna statistica.

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

Rimosso alcuni dei pericolo con l'aggiunta di un'istruzione catch. L'unica pericolo che è ancora presente è il fatto che inviamo una sola richiesta per hop, il che potrebbe significare che noi non arriviamo un salto a causa di un innocente pacchetto goccia. La risoluzione di questo problema rimane un esercizio riservato ai lettori. Suggerimento: (Pensa ai loop all'interno dei loop)

Bonus: Ora cerchiamo di ottenere l'ingresso DNS di ogni salto!

+0

Bel approccio "nativo", fantastico! Forse spiegare il "pericolo" coinvolto? :-) –

+1

Beh, il pericolo che correva era la mancanza di ridondanza (se un singolo messaggio icmp si perde non otteniamo il risultato per quel particolare salto) + non abbiamo preso il PingException. – MrPaulch

4

Corretti alcuni bug nella versione "Mid-Waged-Mans-Tracert", modularizzati e aggiunti alcuni pezzi di personalizzazione. @MrPaulch ha avuto un ottimo 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 
}