web-dev-qa-db-fra.com

Existe-t-il un tracert équivalent PowerShell qui fonctionne dans la version 2?

J'utilise PSVersion 2.0 et je me demandais s'il y avait un équivalent au traceroute pour ça?

Je sais que le PowerShell v4 il existe une applet de commande Test-NetConnection pour faire tracert mais v2?! Cela peut se faire comme:

Test-NetConnection "IPaddress/HOSTaname" -TraceRoute

Merci

13
Sylca

Comme mentionné dans le commentaire, vous pouvez créer votre propre "pauvre-mans-PowerShell-tracert" en analysant la sortie de 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
        }
    }
}

Par défaut, powershell formate les objets avec 5 propriétés ou plus dans une liste, mais vous pouvez obtenir une sortie semblable à tracert avec Format-Table:

enter image description here

25
Mathias R. Jessen

Correction de quelques bugs dans la version "Mid-Waged-Mans-Tracert", modularisation et ajout de quelques éléments de personnalisation. @MrPaulch avait un grand 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
}
4
Brandon Helms

Je dois admettre que je voulais voir si quelqu'un avait déjà fait ça.

Vous pouvez utiliser le .Net Framework pour implémenter un pas-si-pauvre-mans-traceroute comme Powershell Script

Voici une amorce, qui fonctionne vite, mais dangereuse. En outre, aucune statistique.

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

Modifier:

Suppression d'une partie du danger en ajoutant une déclaration catch. Le seul danger qui soit toujours présent est le fait que nous n'envoyons qu'une seule demande par bond, ce qui pourrait signifier que nous ne le faisons pas atteindre un bond en raison d'une innocente chute de paquet. Résoudre ce problème reste un exercice de lecture. Astuce: (pensez aux boucles dans les boucles)

Bonus: Nous essayons maintenant d'obtenir l'entrée DNS de chaque saut!

3
MrPaulch