Aufgabe: traceroute + ping loggen

zed187

Enthusiast
Thread Starter
Mitglied seit
16.11.2006
Beiträge
1.242
Hallo an alle Batch und Powershell Fans,

ich war gerade dabei mich über meinen Provider aufzuregen, weil ich ständig zu gewissen Uhrzeiten mit hohen Latenzen geplagt werde etc.

Um das Problem besser analysieren zu können wollte ich mir eigentlich mal kurz eine Batch bauen, die ich dann in so einer Highping Phase kurz anklicke.

Diese soll einen TRACERT auf bspw. Google ausführen und anschließend die ersten 5 Hops anpingen. Eigentlich kein Problem, aber da sich die Route ständig ändert wollte ich es gerne etwas dynamischer haben und bin nun an FINDSTR gescheitert^^

Das statische Ding sieht also so aus:
Code:
@echo on
echo ----------------------------------------- >> trace.log
echo Start Trace at %Date% %Time% >> trace.log
echo ----------------------------------------- >> trace.log
tracert www.google.de >> trace.log
ping -n 20 83.169.155.126 >> trace.log
ping -n 20 88.134.196.142 >> trace.log
ping -n 20 83.169.128.217 >> trace.log
ping -n 20 83.169.128.5 >> trace.log
ping -n 20 83.169.128.61 >> trace.log
echo ----------------------------------------- >> trace.log
echo End Trace at %Date% %Time% >> trace.log
echo ----------------------------------------- >> trace.log
pause

Hat jemand die Lösung, um anhand des vorhergehenden tracert die entspr. IP-Adressen dynamisch zu verwenden? :)

:banana:
 
Wenn Du diese Anzeige nicht sehen willst, registriere Dich und/oder logge Dich ein.
Was ich zu FINDSTR finden kann:
Findstr

Es klappt also nur wenn die Ausgabe von tracert in einer Datei steht.
Leider bin ich in Punkto Batch-Dateien nicht sehr bewandert, da ich diese mit Windows 98 zusammen fallen gelassen habe.

Vielleicht ist die Powershell das bessere Werkzeug?
Auch wenn es an deiner Fragestellung vorbei geht, werde ich mal was in der PowerShell zusammenstricken.

Jetzige Version:

Code:
$path = "C:\Users\[Benutzername hier]\result.txt"

Add-Content $path $(Get-Date)
Add-Content $path "`n"

$tracertResult = tracert -h 6 www.google.de

Add-Content $path $tracertResult

$hops = @()
for($i = 3; $i -le $tracertResult.Length; $i++ )
{
	if ($tracertResult[$i] -match "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}")
	{
		$hops = $hops + $matches[0]
	}
	else
	{
		Break 
	}
}

Add-Content $path $hops

foreach($hop in $hops)
{
	$pingResult =  ping -n 3 $hop
	Add-Content $path $pingResult
}

Add-Content $path "`n"
Add-Content $path $(Get-Date)

Nun kann man beliebig viele Hops pingen.

Doku (PDF): MEGAUPLOAD - The leading online storage and file delivery service

Die aktuelle Powershell für "ältere" Windows-Versionen gibt's hier: http://technet.microsoft.com/de-de/scriptcenter/dd742419
Alternativ zur PowerShell ISE gibt es noch die (wirklich gute) PowerGUI: http://powergui.org/downloads.jspa
 
Zuletzt bearbeitet:
Super, funktioniert wie gewollt. Ich musste $i auf 4 setzen, da im Tracert der erste Hop immer eine Zeitüberschreitung gibt und es dann stoppt.

Ich hatte bisher auch noch nichts mit Powershell gemacht und auf dem Batch weg scheints in dem Fall auch nicht so einfach zu funktionieren, da das Zeichen [ mit FINDSTR nicht gefunden werden kann. Mit einer FOR Schleife würde es evtl noch gehen...

Achja, wer mit Powershell das erste mal ein Script ausführen will muss "Set-ExecutionPolicy RemoteSigned" eingeben. Das Script habe ich mit der Dateiendlung .ps1 gespeichert.

Danke dir für diesen kurzen Einblick in Powershell und die tolle Doku zu deinem Script ;)
 
Danke, freut mich dass ich helfen konnte.

Stimmt, die Execution Policy habe ich vergessen.
Die Powershell ist ein sehr guter Weg, in der Microsoft-Welt die Arbeit zu vereinfachen.
Wenn du dich mit der Powershell befassen willst, das Microsoft Technet bietet viele Gute Artikel und eine umfangreiche Dokumentation aller PowerShell-Befehle und CmdLets.
Auch Google ist eine gute Anlaufstelle für Tutorials zur Powershell allgemein und wenn man z.B. wissen will, wie Schleifen, If-Entscheidungen, Arrays usw. in der PowerShell funkionieren.

Eines noch:
Ein Kernstück der Powershell sind die sog. Cmdlets.

Dies sind "Befehle", die meist aus Verb+Objekt bestehen.

Anstelle von "echo" schreibt man beispielsweise:
Code:
Write-Host "Hallo Welt"

Sehr viel mächtiger als "dir" ist:
Code:
Get-ChildItem

Oder auch das im Script verwendete:
Code:
Add-Content

Wenn du ein Erklärung der Befehle brauchst, geht dies so:
Code:
Get-Help Get-ChildItem
für eine Erklärung des Befehls
oder
Code:
Get-Help Get-ChildItem -examples
für eine Erklärung mit Beispielen zur Verwendung des Befehls.

Wie du bereits sehen konntest, kann man alte DOS-Befehle weiter verwenden. Diese rufen entweder tatsächlich den DOS-Befehl auf oder leiten den Aufruf an das Equivalent der PowerShell weiter.

Schönes WE.

mhrpcler.
 
Wenn ich über eine Symbolleiste in der Taskleiste in den Ordner gehe und dann mit Rechtsklick und "Mit Powershell ausführen" klicke, wird nichts in die log Datei geschrieben. Wenn ich aber nun direkt ein Explorer-Fenster öffne, geht es auf dem Weg.

Windows 7 ist manchmal komisch
 
Hallo zed187

Wenn Du Linux einsetzen kannst, würde ich dir mal empfehlen einen Blick auf "MTR" und "Smokeping" zu werfen.

Gruss Mete
 
Danke für den Tip, ich hab hier nen Ubuntu netbook stehen, aber die kiste is rapellvoll. Muss ma schaun ob das da noch rauf passt^^

Zu dem Powershell Script noch eine Idee:

Ist es möglich, die Prozesse mit Netzwerkaktivität auszulesen und ins log zu schreiben?^^

// MTR hab ich mal gerade getestet, pingt alle Hops und zeigt min,max, average Ping an + Packet loss. Ziemlich übersichtlich. Aber habe da keine logging funktion gefunden.

Smokeping konnte ich nicht runterladen, 404 not Found mit Ubuntu 9.10.

// WinMTR kann auch das komplette Ergebnis in die Zwischenablage kopieren und sogar in Excel oder als HTML Code. Das noch etwas handlicher wie die Linux Version.
 
Zuletzt bearbeitet:
Ich weis nicht, ob's auch eleganter geht, der Befehl netstat wäre schonmal ein Einfang.

Über nestat -o bekommt man alle offenen Verbindungen und die zugehörige PID aufgelistet.
Wenn man diesen Befehl nun so verwendet wie tracert im Script oben und mit dem Ergebnis des Powershell Cmdlets "Get-Process" kombiniert, kann man sich was bauen.

Die ersten Zeilen der Ausgabe von "Get-Process":
Code:
Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    157      15     2344       7528    72            1760 AppleMobileDeviceService
    528      61    16408      23092   125     5,97   4372 AsusAudioCenter
    267      10     2776       6792    78            1228 atieclxx
    121       7     1728       4388    33             948 atiesrxx
    120       9    14612      15296    49            5832 audiodg
    [COLOR="Red"]459      35    45556      49676   163    26,58   3988 Dropbox[/COLOR]

Dazu ein paar Zeilen von "netstat -o":
Code:
  Proto  Lokale Adresse         Remoteadresse          Status           PID
[COLOR="Red"]  TCP    127.0.0.1:19872        xxxxxxxx:49168         HERGESTELLT     3988[/COLOR]
  TCP    127.0.0.1:27015        xxxxxxxx:49166         HERGESTELLT     1760
  TCP    127.0.0.1:49157        xxxxxxxx:49158         HERGESTELLT     2296
  TCP    127.0.0.1:49158        xxxxxxxx:49157         HERGESTELLT     2296

Nun muss man noch Übereinstimmungen suchen, wobei man beispielsweise Dropbox findet.

Das Ergebnis kann man dann z.B ausgeben um die Prozessnamen zu "googlen" oder an das Cmdlet "Stop-Process" weiterleiten und so nacheinander alle Prozesse beenden.

Du kannst ja mal anfangen ein Script zu schreiben, wenn Du Interesse daran hast.
Wenn ich jetzt noch damit anfange, wird's zu spät.
Solche "Aufgaben" sind gut zum Üben :)

M.f.G.

mhrpcler
 
Zuletzt bearbeitet:
Ich habe eine einfachere Idee:

"netstat -e 10" gibt eine Statistik über die empfangenen und gesendeten Bytes alle 10 Sekunden aus. Das könnte man ein mal ausgeben, abbrechen und dann die Differenz loggen. Somit haben wir den Traffic in Bytes über 10 Sekunden.

Anschließend kommt der Tracert + Ping.

Vielleicht probiere ich mich mal in den nächsten Tagen bei Gelegenheit daran, dein Script etwas anzupassen. Wahrscheinlich gibt es auch noch bessere Methoden.
 
Prozesse mit Netzwerkaktivität ermitteln:

Code:
# Dateipfad zusammensetzen:
# Pfad zu Eigene Dokumente ermitteln mit Hilfe der .NET-Klasse Environment
# und Anhängen des Dateinamens.
$path = [Environment]::GetFolderPath("MyDocuments")
$path += "\\Netzwerkprozesse.txt"

# Die Ausgabe von netstat in einer Avriablen speichern.
$networkConnections = netstat -o

# Eine Leere Liste für die Prozessobjekte erstellen.
$processList = New-Object System.Collections.ArrayList

# Die Prozess-IDs aus der Ausgabe von netstat -o parsen,
# den Zugehörigen Prozess ermitteln und an die Prozessliste
# anhängen.
foreach ($line in $networkConnections)
{
	if($line -match "[a-z]{1,3}\s*\S*\s*\S*\s*\S*\s*(\d{1,4})")
	{
		$processList.Add((Get-Process -Id $Matches[1]))
	}
}

# Die Prozessliste: sortieren,		als Tabelle formatieren,		in eine Datei schreiben.
$processList | sort ProcessName | Format-Table Name,Id -AutoSize | Out-File -FilePath $path
 
Super, damit habn wir dann die Prozesse mit Netzwerkaktivität :)

Hab auch mal geschaut, mit Get-process wird nur Arbeitsspeicher etc. ausgegeben, können wir also nur gebrauchen um netstat -o einen Prozess zuzuordnen wie du es bereits gemacht hast.

Bleibt wohl nur noch netstat -e um unter die Prozessliste noch den entstandenen Traffic auszugeben.

Habe mich gerade dran versucht, aber ich schaffe es nicht mal, die Ausgabe von netstat -e auf die empfangenen Bytes zu filtern, geschweige denn dann eine Differenz zu errechnen. Ich kenne die ganzen Methoden einfach nicht, mit welchen Werkzeugen man sowas am sinnvollsten anstellt. Also ohne da zuvor einige Tutorials durch zu ackern, kann man mit Powershell nicht wirklich intuitiv arbeiten. Man muss halt wissen wie.
 
Mein Hauptproblem mit "netstat -e [Sekunden]" ist, dass es nicht endet.
Ich habe es weder über "Start-Process", noch mit Hilfe von "Start-Job", "Stop-Job" und "Receive-Job" geschafft, die Ausgabe von netstat irgenendwie zu "fangen" und zu speichern um sie auswerten zu können.
Leider beziehen sich alle funktionierenden Beispiele auf PowerShell-Cmdlets.

Möglicherweise bietet das .NET-Framework die Mittel für eine Lösung, sowas kann ich aber nicht aus dem Hut zaubern.
Entweder verwendet man die .NET-Klassen direkt in der Powershell oder baut sich mit Visual Basic / C# ein Programm oder Cmdlet.

Das muss ich mir mal in aller Ruhe ansehen.

M.f.G.

mhrpcler
 
Ich wollte eigentlich netstat -e in ein array packen, es filtern und dann ein "wait" machen für 10 sekunden (alernativ nen ping -n 10) und erneut netstat -e in ein neues array und dann eine differenz bilden. Bis zum Wait-Problem bin ich gar nicht erst gekommen, da ich shcon am filtern gescheitert bin^^ Hab mich aber auch nur ma halbe Stunde mit beschäftigt. Bzw. letztendlich müsste man beim Wait Step auch die prozesse auslesen etc.
 
Zuletzt bearbeitet:
Man kann "netstat -e" ja auch ohne Sekundenangabe starten.
Dann ist es ja doch nicht so schlimm.
Wer lesen kann ist klar im Vorteil... :wall:

Code:
# Variable für Dateipfad
$path = [Environment]::GetFolderPath("MyDocuments")
$path += "\Bytes.txt"


# Variable für die Wartezeit in Sekunden
$s = 3

# GetBytes ist eine Funktion und gibt als Ergebnis das $Matches Array zurück.
# Diese Array enthält an Position 1 die Empangenen Bytes,
# an Position 2 die gesendeten Bytes.
function GetBytes
{
	$netstat = netstat -e 
	if($netstat[4] -match "\w*\s*(\d+)\s*(\d+)")
	{
		# Matches[1] = Empfangene Bytes
		# Matches[2] = Gesendete Bytes
		$Matches
	}
}
# Der Variable $bytes wird das $Matches-Array zugewiesen
$bytes = GetBytes

# x Sekunden warten.
Start-Sleep -Seconds $s

# Berechnen der Differenzen und speichern in Variablen
$differenzEmpfangen = $(GetBytes)[1] - $bytes[1] 
$differenzGesendet = $(GetBytes)[2] - $Bytes[2]

# Zusammenbau der Bildschirm- und Dateiausgabe
$title = "Netzwerkverkehr:`n"
$textSent = "Empfangene Bytes letzte $s Sekunden:`t $differenzEmpfangen"
$textReceived = "Gesendete Bytes letzte $s Sekunden:`t $differenzGesendet"

# Bildschirmausgabe
Write-Host $title
Write-Host $textSent
Write-Host $textReceived

# Dateiausgabe
Add-Content $path $title
Add-Content $path $textEmpfagen 
Add-Content $path $textGesendet

Zum Thema "Reguläre Ausdrücke" in der PowerShell:
Chapter 13. Text and Regular Expressions - Master-PowerShell | With Dr. Tobias Weltner - Powershell.com

Code:
# Zum Thema Filtern:
# Einen String in der Variable $text speichern:
$text = "Address: 192.168.1.254"

# Ein Pattern erstellen:
$pattern = "(\w+:)\s*(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"
# Das Pattern ist wie folgt aufgebaut:
#
# \w = ein beliebiges Wortzeichen
# + = das Zeichen kommt mind. einmal vor.
#
# : = einfach ein Doppelpunkt
#
# \s = space character (Leerzeichen / Tab)
# * = kein oder beliebig viele Vorkommen
#
# \d = digit (Ziffer)
# {1,3} = kommt ein bis dreimal vor
#
# \. = ein Punkt. Dieser muss mit einem \ "escaped" werden,
# da der Punkt normalerweise als Platzhalter für ein
# beliebiges Zeichen steht.
#
# Die Klammern bilden Gruppen, die sich im Ergebnis $Matches wiederfinden.
# Die erste Array-Position [0] enthält immer die gesamte überprüfte
# Zeichenkette, die Nachfolgenden Positionen dann die mittels Klammern
# definierten Gruppen.
#
# Dies ist nur ein kleiner Ausschnit aus dem Arsenal der
# regulären Ausdrücke.
#
# Die Variable $Matches (Array) ausgeben, wenn das Pattern (Muster)
# auf den Text passt.
if ($text -match $pattern) { $Matches }


Ich hoffe es hilft.

M.f.G.
 
Zuletzt bearbeitet:
Ich hab das alles nun mal zusammen gefasst, ein paar Bildschirmausgaben eingebaut, einen kleinen Fehler in den Variablen des letzten Teils korrigiert, globale Variablen am Anfang eingebaut und die Bytes in Kilobytes umgerechnet :)

Hier die Version 2 des ... ähm... nennen wir es erstmal irgendwie... CheckInet-Script^^

Code:
####################
## Start Settings ##
####################

# Variable für Dateipfad
$path = "result.txt"

# Anzahl der Pings pro Hop
$PingCount = 5
# Anzahl der Hops
$TracertCount = 10
# Wartezeit zum ermitteln des Traffics
$WaitforTraffic = 5
# Ziel für Tracert + Ping
$Target = "www.google.de"

# Traffic und Prozesse ermitteln?
$Traffic = 1
# Tracert und Ping?
$Tracert = 1

###################
## End Settings ##
###################

if ($Traffic -or $Tracert)
{
    Add-Content $path $(Get-Date)
    Add-Content $path "`n"
}

if ($Traffic)
{
    ###############################
    ##  Start: Traffic ermitteln ##
    ###############################

    Write-Host "Ermittle Traffic..."

    # GetBytes ist eine Funktion und gibt als Ergebnis das $Matches Array zurück.
    function GetBytes
    {
    	$netstat = netstat -e 
    	if($netstat[4] -match "\w*\s*(\d+)\s*(\d+)")
    	{
    		# Matches[1] = Empfangene Bytes
    		# Matches[2] = Gesendete Bytes
    		$Matches
    	}
    }

    # Der Variable $bytes wird das $Matches-Array zugewiesen
    $bytes = GetBytes

    # x Sekunden warten.
    Start-Sleep -Seconds $WaitforTraffic
    
        ###############################
        ## Start: Prozesse ermitteln ##
        ###############################
        
        Write-Host "Ermittle Prozesse...`n"
        
        # Die Ausgabe von netstat in einer Avriablen speichern.
        $networkConnections = netstat -o

        # Eine Leere Liste für die Prozessobjekte erstellen.
        $processList = New-Object System.Collections.ArrayList

        # Die Prozess-IDs aus der Ausgabe von netstat -o parsen,
        # den Zugehörigen Prozess ermitteln und an die Prozessliste
        # anhängen.
        foreach ($line in $networkConnections)
        {
        	if($line -match "[a-z]{1,3}\s*\S*\s*\S*\s*\S*\s*(\d{1,4})")
        	{
        		$processList.Add((Get-Process -Id $Matches[1]))
        	}
        }

        #############################
        ## End: Prozesse ermitteln ##
        #############################
    
    # Berechnen der Differenzen und speichern in Variablen
    $differenzEmpfangen = ($(GetBytes)[1] - $bytes[1]) / 1024 
    $differenzGesendet = ($(GetBytes)[2] - $bytes[2]) / 1024

    # Zusammenbau der Bildschirm- und Dateiausgabe
    $title_process = "Aktive Prozesse mit Netzwerkaktivität:`n"
    $title_traffic = "Netzwerkverkehr letzte $WaitforTraffic Sekunden:"
    $textSent = ("Empfangen:`t {0:n2}kb" -f $differenzEmpfangen)
    $textReceived = ("Gesendet:`t {0:n2}kb`n" -f $differenzGesendet)

    # Bildschirmausgabe
    Write-Host $title_traffic
    Write-Host $textSent
    Write-Host $textReceived

    # Die Prozessliste: sortieren,		als Tabelle formatieren,		in eine Datei schreiben.
    Add-Content $path $title_process
    $processList | sort ProcessName | Format-Table Name,Id -AutoSize | Out-File -FilePath $path -Encoding UTF8 -Append

    # Dateiausgabe
    Add-Content $path $title_traffic
    Add-Content $path $textSent
    Add-Content $path $textReceived

    #############################
    ##  End: Traffic ermitteln ##
    #############################
}

If ($Tracert)
{
    ##################################
    ## Start: Tracert + Ping loggen ##
    ##################################

    Write-Host "Starte Tracert...`n"

    $tracertResult = tracert -h $TracertCount $Target

    Add-Content $path $tracertResult

    $hops = @()
    for($i = 4; $i -le $tracertResult.Length; $i++ )
    {
    	if ($tracertResult[$i] -match "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}")
    	{
    		$hops = $hops + $matches[0]
    	}
    	else
    	{
    		Break 
    	}
    }

    Write-Host "Pinge Hops...`n"

    #Add-Content $path $hops
    foreach($hop in $hops)
    {
    	$pingResult =  ping -n $PingCount $hop
    	Add-Content $path $pingResult
        Write-Host $hop
    }

    ################################
    ## End: Tracert + Ping loggen ##
    ################################
}

Add-Content $path "`n"
Add-Content $path $(Get-Date)

if ($Traffic -or $Tracert)
{
    Write-Host "Vorgang abgeschlossen und Log geschrieben!"
}
else
{
    Write-Host "Nichts gemacht!"
}

Download mit Kurzanleitung: http://www.file-upload.net/download-3493426/CheckInetv2.rar.html

Optimierung suche ich noch im Bereich "Start-Sleep -Seconds", während dessen sollen die Prozesse ermittelt werden. Die angegebenen Sekunden für den Traffic sind durch die unterschiedliche Ermittlungsdauer der Prozesse nicht ganz korrekt... Sonst muss man das ma verschieben und einfacherst Traffic und dann Prozesse, dachte das Traffic ergebnis wäre besser wenn man während des wartens die prozesse holt.
 
Zuletzt bearbeitet:
Man kann dort noch ein bischen sortieren, was die Reihenfolge angeht.
Eine möglichkeit für möglichst genaue x Sekunden Wartezeit:

Code:
$traffic1 = netstat -e
Start-Sleep -Seconds 5
$traffic2 = netstat -e

Dann kannst du später die Werte aus den beiden Arrays voneinander abziehen.

Es gibt die Möglichkeit mit "Start-Job", "Receive-Job" und "Stop-Job" Aufgabe im Hintergrung laufen zu lassen. Dies dauert zusammen mit dem Abgreifen des Ergebnisses auch einen Moment.

M.f.G.

mhrpcler
 
Hardwareluxx setzt keine externen Werbe- und Tracking-Cookies ein. Auf unserer Webseite finden Sie nur noch Cookies nach berechtigtem Interesse (Art. 6 Abs. 1 Satz 1 lit. f DSGVO) oder eigene funktionelle Cookies. Durch die Nutzung unserer Webseite erklären Sie sich damit einverstanden, dass wir diese Cookies setzen. Mehr Informationen und Möglichkeiten zur Einstellung unserer Cookies finden Sie in unserer Datenschutzerklärung.


Zurück
Oben Unten refresh