web-dev-qa-db-ja.com

バージョン2で機能するPowerShell相当のtracertはありますか?

私はPSVersion 2.0を使用していますが、tracerouteに相当するものはあるのでしょうか。

PowerShell v4にtracertを実行するTest-NetConnectionコマンドレットがあることを知っていますが、v2ですか?それは次のように行うことができます:

Test-NetConnection "IPaddress/HOSTaname" -TraceRoute

ありがとう

13
Sylca

コメントで述べたように、tracert.exeからの出力を解析することで、独自の「poor-mans-PowerShell-tracert」を作成できます。

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つ以上のプロパティを持つオブジェクトをフォーマットしますが、Format-Tableを使用してtracertに似た出力を取得できます。

enter image description here

25

「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
}
4
Brandon Helms

私は誰かがすでにこれをしたかどうかを見たかったことを認めなければなりません。

.Net Frameworkを使用して、not-so-poor-mans-traceroutePowershellスクリプトとして実装できます。

ここではプライマーは速く動作しますが、危険です。また、統計はありません。

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

編集:

Catchステートメントを追加して、dangerの一部を削除しました。まだ存在している唯一のdangerは、ホップごとに1つのリクエストのみを送信するという事実です。つまり、reachinnocentパッケージのドロップによるホップ。その問題を解決することは、読者の課題のままです。ヒント:(ループ内のループについて考える)

ボーナス:各ホップのDNSエントリの取得を試みます!

3
MrPaulch