Есть ли эквивалентный tracert PowerShell, который работает в версии 2?

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

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

Test-NetConnection "IPaddress/HOSTaname" -TraceRoute

спасибо

3 ответов


как упоминалось в комментарии, Вы можете сделать свой собственный "poor-mans-PowerShell-tracert", проанализировав вывод из 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-как выход с Format-Table:

enter image description here


Исправлено несколько ошибок в версии "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
}

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

вы можете использовать .NET Framework для реализации не-такой-бедный-человек-traceroute как Сценарий 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:

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

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