PowerShell For Runaways - Part II
Diverse Checks mit der PowerShell durchführen und ein Logfile generieren.
Hallo ans Forum
Leider ist die PowerShell immer noch nicht so verbreitet, wie ich mir das wünschen würde.
Bill Gates, rsp. sein Nachfolger Ballmer haben es verschlampt, die PowerShell in das SP1 für Vista zu integrieren, was mich persönlich ziemlich angurkt.
Manchmal könnte man meinen, Sie glauben nicht an ihr eigenes Produkt....
Immerhin haben Sie es geschafft, die PowerShell in das neue Server-OS (Server 2008) zu integrieren, aber auch dort gibt es wieder eine künstliche Einschränkung.
Man kann die PowerShell nicht im ServerCore-Modus verwenden, da in diesem GUI-losen Betriebsmodus das .NET Framework nicht unterstützt wird.
Wie soll sich das Ding denn verbreiten, wenn es nirgendwo automatisch integriert ist und man das Ding immer nachinstallieren muss????? *Arghhh!*
Naja, genug Frust abgelassen...
Auf jeden Fall melde ich mich nun mit einem PowerShell-Tutorial zurück.
Nach dem es in "PowerShell For Runaways - Part I" ( PowerShell for Runaways - Part I ) vor allem um die Grundlagen ging, geht es hier um die praktische Anwendung der PowerShell anhand eines Beispielscripts.
Ich nenne es <ironie> wahnsinnig originell </ironie> Admincheck.ps1
Das unten gepostete Script macht folgendes:
Zunächst brauchen wir 2 Textfiles. Das eine ist die Liste der Netzwerkkomponenten, das andere ist die Liste der zu überprüfenden Server.
Pro Zeile muss eine IP-Adresse oder ein Servername stehen, also z.B. so:
oder so:
Also, hier kommt das Script (Ich hoffe, ich habe es ausreichend kommentiert. Falls nein, einfach nachfragen, ich beisse nicht ):
Für alle, die nicht so viel Ahnung von Scripting haben und das Script einfach nur verwenden wollen, ohne die Sprache zu lernen:
Die folgenden Zeilen müsst ihr anpassen:
In dieser Variable wird der Zielpfad zu der Liste mit den Server gespeichert. Wenn ihr die Zeile so lasst, müsst ihr die Serverliste einfach in den gleichen Ordner wie das Script speichern und die Liste "serverliste.txt" nennen.
In dieser Variable wird der Zielpfad zu der Liste mit den Netzkomponenten gespeichert. Wenn ihr die Zeile so lasst, müsst ihr die Netzkomponentenliste einfach in den gleichen Ordner wie das Script speichern und die Liste "netzkomponentenliste.txt" nennen.
In dieser Variable wird der Zielpfad zum Logfile gespeichert. Wenn ihr die Zeile so lasst, werden die Logfiles einfach in den gleichen Ordner wie das Script gespeichert.
In diese Variable wird der Ordner geschrieben, in dem die temporären Textdateien geparkt werden, welche vom Script generiert werden. Mein Wissen reicht leider noch nicht so weit, als das ich dieses Script ohne temporäre Textdateien zum Laufen bringen würde. Achtet also darauf, dass ihr auf dem hier angegebenen Ordner zumindest Schreibrechte habt. Ich werde später mal noch eine Variante ohne temporäre Dateien liefern, die dann auch schneller laufen wird.
Hier wird angegeben, wie gross die kritische Grenze sein soll, bei der das Script motzt, dass es auf einer Festplatte zu wenig Speicherplatz hat. Da ich das Script hauptsächlich in meiner Privat-Domäne benutze und dort nicht gross wachsende Datenmengen habe, habe ich den Grenzwert hier auf 1 GB gesetzt. Bei grossen Netzen lohnt es sich eventuell, diesen Wert zu erhöhen.
Hier wird mit dem Tool bmail.exe das Logfile per Mail verschickt. Wenn ihr das Script so lasst, muss sich die bmail.exe im gleichen Pfad wie das Script oder in einem der Pfade der Environment-Variable %path% befinden.
Ansonsten müsst ihr folgendes anpassen:
So, das wäre es bereits gewesen. Fragt nach, wenn etwas unklar ist.
Grüsse aus der Schweiz
TuXHunT3R
PS: Wenn das Script läuft, liefert es keinerlei Bildschirmausgaben. Es ist eigentlich dazu gedacht, dass es einmal pro Nacht ausgeführt wird und der Admin am Morgen das Mail mit dem Logfile kontrollieren kann.
Edit:
PPS: Ja ich weiss, man kann Mails per Script auch ohne Bmail.exe verschicken. Ich habe noch keine Zeit gehabt, eine Lösung ohne bmail.exe zu realisieren. Ich werde das früher oder später mal noch ergänzen.
Hallo ans Forum
Leider ist die PowerShell immer noch nicht so verbreitet, wie ich mir das wünschen würde.
Bill Gates, rsp. sein Nachfolger Ballmer haben es verschlampt, die PowerShell in das SP1 für Vista zu integrieren, was mich persönlich ziemlich angurkt.
Manchmal könnte man meinen, Sie glauben nicht an ihr eigenes Produkt....
Immerhin haben Sie es geschafft, die PowerShell in das neue Server-OS (Server 2008) zu integrieren, aber auch dort gibt es wieder eine künstliche Einschränkung.
Man kann die PowerShell nicht im ServerCore-Modus verwenden, da in diesem GUI-losen Betriebsmodus das .NET Framework nicht unterstützt wird.
Wie soll sich das Ding denn verbreiten, wenn es nirgendwo automatisch integriert ist und man das Ding immer nachinstallieren muss????? *Arghhh!*
Naja, genug Frust abgelassen...
Auf jeden Fall melde ich mich nun mit einem PowerShell-Tutorial zurück.
Nach dem es in "PowerShell For Runaways - Part I" ( PowerShell for Runaways - Part I ) vor allem um die Grundlagen ging, geht es hier um die praktische Anwendung der PowerShell anhand eines Beispielscripts.
Ich nenne es <ironie> wahnsinnig originell </ironie> Admincheck.ps1
Das unten gepostete Script macht folgendes:
- Eine Liste von Servern und Netzwerkkomponenten durchpingen
- Bei allen Harddisks aller Server, die in einer Liste angegeben sind, die Gesamtgrösse + den freien Speicherplatz auslesen und reklamieren, wenn auf einer Disk weniger als 1 GB frei ist.
- Das Eventlog aller in der Liste angegebenen Server überprüfen. Es werden von jedem Server alle heutigen Errors + Warnings vom System- und Applicationlog aufgelistet
- Ein Logfile mit den Ergebnissen der oberen Checks anlegen
- Das Logfile an eine Mailadresse schicken (bmail.exe vonnöten. Gibts bei Google.)
Zunächst brauchen wir 2 Textfiles. Das eine ist die Liste der Netzwerkkomponenten, das andere ist die Liste der zu überprüfenden Server.
Pro Zeile muss eine IP-Adresse oder ein Servername stehen, also z.B. so:
server01
server02
server03
server69
oder so:
192.168.2.25
10.10.12.11
192.168.0.14
Also, hier kommt das Script (Ich hoffe, ich habe es ausreichend kommentiert. Falls nein, einfach nachfragen, ich beisse nicht ):
#***********************************************************************************************
# Admincheck.ps1
# ==============
# Führt folgende Checks auf den Servern und den Netzwerkkomponenten aus:
# - Pingtest
# - Freier Speicherplatz auf den Servern
# - Eventloganalyse der Server
# Ausserdem wird ein Logfile generiert und per Mail an die vorgegebene Adresse geschickt.
# Autor: TuXHunT3R
# Version 1.0
#***********************************************************************************************
# Variablen setzen
$serverliste = get-content "serverliste.txt"
$netzwerkkomponentenliste = get-content "netzkomponentenliste.txt"
$datum = get-date -format d
$zeit = get-date -format t
$user = $env:Username
$logfile = "AdmincheckLog_" + $datum + ".txt"
$tmpfolder = "c:\temp"
# Temp-Ordner leeren, damit das Script nicht durch alte temporäre Dateien in Mitleidenschaft gezogen wird
$tmpfolder2 = $tmpfolder + "\*.*"
remove-item -path $tmpfolder2 -force
# Logfile vorbereiten
"###############################################################################" | out-file -filepath $logfile -encoding default -append
"##***************************************************************************##" | out-file -filepath $logfile -encoding default -append
"##******************************ADMINCHECK-LOG*******************************##" | out-file -filepath $logfile -encoding default -append
"##***************************************************************************##" | out-file -filepath $logfile -encoding default -append
"###############################################################################" | out-file -filepath $logfile -encoding default -append
" " | out-file -filepath $logfile -encoding default -append
"Started:" | out-file -filepath $logfile -encoding default -append
$datum | out-file -filepath $logfile -encoding default -append
$zeit | out-file -filepath $logfile -encoding default -append
" " | out-file -filepath $logfile -encoding default -append
"User:" | out-file -filepath $logfile -encoding default -append
$user | out-file -filepath $logfile -encoding default -append
"_________________________________________________________" | out-file -filepath $logfile -encoding default -append
" " | out-file -filepath $logfile -encoding default -append
" " | out-file -filepath $logfile -encoding default -append
"Pinging the important network-components:" | out-file -filepath $logfile -encoding default -append
"=========================================" | out-file -FilePath $logfile -Encoding default -Append
" " | out-file -filepath $logfile -encoding default -append
# Server pingen
foreach ($server in $serverliste){
ping $server -n 2 | out-null
$PingErgebnisServer = "$lastexitcode"
if ($PingErgebnisServer -eq "0") {
$tmp = "Pinging " + $server + " sucessfully"
$tmp | out-file -filepath $logfile -encoding default -append
} else {
$tmp = "Pinging " + $server + " failed!"
$tmp | out-file -filepath $logfile -encoding default -append
}
}
# Netzwerkkomponenten pingen
foreach ($netzwerkkomponente in $netzwerkkomponentenliste) {
ping $netzwerkkomponente -n 2 | out-null
$PingErgebnisNWKomponente = "$lastexitcode"
if ($PingErgebnisNWKomponente -eq "0") {
$tmp = "Pinging " + $netzwerkkomponente + " sucessfully"
$tmp | out-file -filepath $logfile -encoding default -append
} else {
$tmp = "Pinging " + $netzwerkkomponente + " failed!"
$tmp | out-file -filepath $logfile -encoding default -append
}
}
" " | out-file -filepath $logfile -encoding default -append
" " | out-file -filepath $logfile -encoding default -append
"Checking the free diskspace on all servers:" | out-file -filepath $logfile -encoding default -append
"===========================================" | out-file -FilePath $logfile -Encoding default -Append
# Freier Speicherplatz der Serverdisken auslesen
# Für jedes Typ3-Laufwerk (Festplatten oder Partitionen) auf dem Zielserver wird überprüft, ob mehr als 1 GB frei ist
# Zunächst mal die Vergleichsgrösse in Variable speichern...
[int]$GB = 1
# Dann bei allen Servern (erste Foreach-Schleife) alle Harddisks (zweite foreach-Schleife) durchchecken...
foreach ($server in $serverliste) {
" " | out-file -filepath $logfile -encoding default -append
$server | out-file -filepath $logfile -encoding default -append
foreach ($disk in get-wmiobject -class win32_Logicaldisk -filter "DriveType=3" -computername $server) {
# Freier Speicherplatz auslesen + in GB umrechnen
$freespaceB = $disk.freespace
$freespaceKB = $freespaceB / 1024
$freespaceMB = $freespaceKB / 1024
$freespaceGB = $freespaceMB / 1024
# Gesamtgrösse der Disk auslesen + in GB umrechnen
$DisksizeB = $disk.size
$DisksizeKB = $disksizeB / 1024
$DisksizeMB = $disksizeKB / 1024
$DisksizeGB = $disksizeMB / 1024
# Diskletter auslesen
$diskletter = $disk.deviceid
# ...und vergleichen
if ($freespaceGB -gt $gb) {
$StringForTextfile = "Disk " + $diskletter + " " + $freespaceGB + " / " + $disksizeGB + " GB free ==> Enough free Diskspace!"
$StringForTextfile | out-file -filepath $logfile -encoding default -append
} else {
$StringForTextfile = "Disk " + $diskletter + " " + $freespaceGB + " / " + $disksizeGB + " GB free ==> Disk full, move data!"
$StringForTextfile | out-file -filepath $logfile -encoding default -append
}
}
}
# Eventlog-Analyse
# Zuerst mal das Datum in das richtige Format bringen:
$Datum = Get-Date -Format yyyyMMdd
# Für jeden Server in der Serverliste das Eventlog mit folgenden Bedingungen abfragen:
# Im System- und Applikationlog alle Errors und Warnings des heutigen Tages ausgeben.
" " | out-file -filepath $logfile -encoding default -append
" " | out-file -filepath $logfile -encoding default -append
"Analysing the Eventlog of all Servers (Events from today):" | out-file -filepath $logfile -encoding default -Append
"==========================================================" | out-file -filepath $logfile -encoding default -Append
" " | out-file -filepath $logfile -encoding default -append
foreach ($server in $serverliste) {
$server | out-file -filepath $logfile -encoding default -append
"--------" | out-file -filepath $logfile -encoding default -append
"Systemlog:" | out-file -filepath $logfile -encoding default -append
#Warnungen
$tmplog= $tmpfolder + "\eventlogquery_admincheck_system_warnings_" + $server + ".txt"
get-wmiobject win32_ntlogevent -Filter "Logfile='System' and type='Warning'" -computer $server | select-object type, timewritten, eventcode, sourcename, message | format-table -auto | out-file -filepath $tmplog -encoding default
get-content $tmplog | foreach-object { if ($_.Contains($Datum)) { $_ | out-file -filepath $logfile -encoding default -append}}
#Errors
$tmplog= $tmpfolder + "\eventlogquery_admincheck_system_errors_" + $server + ".txt"
get-wmiobject win32_ntlogevent -Filter "Logfile='System' and type='Error'" -computer $server | select-object type, timewritten, eventcode, sourcename, message | format-table -auto | out-file -filepath $tmplog -encoding default
get-content $tmplog | foreach-object { if ($_.Contains($Datum)) { $_ | out-file -filepath $logfile -encoding default -append}}
" " | out-file -filepath $logfile -encoding default -append
"Applicationlog:" | out-file -filepath $logfile -encoding default -append
#Warnungen
$tmplog= $tmpfolder + "\eventlogquery_admincheck_application_warnings_" + $server + ".txt"
get-wmiobject win32_ntlogevent -Filter "Logfile='Application' and type='Warning'" -computer $server | select-object type, timewritten, eventcode, sourcename, message | format-table -auto | out-file -filepath $tmplog -encoding default
get-content $tmplog | foreach-object { if ($_.Contains($Datum)) { $_ | out-file -filepath $logfile -encoding default -append}}
#Errors
$tmplog= $tmpfolder + "\eventlogquery_admincheck_application_errors_" + $server + ".txt"
get-wmiobject win32_ntlogevent -Filter "Logfile='Application' and type='Error'" -computer $server | select-object type, timewritten, eventcode, sourcename, message | format-table -auto | out-file -filepath $tmplog -encoding default
get-content $tmplog | foreach-object { if ($_.Contains($Datum)) { $_ | out-file -filepath $logfile -encoding default -append}}
" " | out-file -filepath $logfile -encoding default -append
" " | out-file -filepath $logfile -encoding default -append
}
# Logfile per Mail schicken
bmail.exe -s <SMTP-Server> -t <Ziel-Adresse> -f <Quelladresse, beliebig wählbar> -a "ADMINCHECK.PS1 Logfile" -m "$logfile"
Für alle, die nicht so viel Ahnung von Scripting haben und das Script einfach nur verwenden wollen, ohne die Sprache zu lernen:
Die folgenden Zeilen müsst ihr anpassen:
$serverliste = get-content "serverliste.txt"
$netzwerkkomponentenliste = get-content "netzkomponentenliste.txt"
$logfile = "AdmincheckLog_" + $datum + ".txt"
$tmpfolder = "c:\temp"
[int]$GB = 1
bmail.exe -s <SMTP-Server> -t <Ziel-Adresse> -f <Quelladresse, beliebig wählbar> -a "ADMINCHECK.PS1 Logfile" -m "$logfile"
Ansonsten müsst ihr folgendes anpassen:
- "<SMTP-Server>" durch euren Postausgangsserver ersetzen (seht zu, dass die Rules so definiert sind, dass diese Mails durchgehen)
- "<Ziel-Adresse>" durch eine existierende Mailadresse ersetzen
- "<Quelladresse, beliebig wählbar>" durch eine beliebige, nicht unbedingt existierende Mailadresse ersetzen.
So, das wäre es bereits gewesen. Fragt nach, wenn etwas unklar ist.
Grüsse aus der Schweiz
TuXHunT3R
PS: Wenn das Script läuft, liefert es keinerlei Bildschirmausgaben. Es ist eigentlich dazu gedacht, dass es einmal pro Nacht ausgeführt wird und der Admin am Morgen das Mail mit dem Logfile kontrollieren kann.
Edit:
PPS: Ja ich weiss, man kann Mails per Script auch ohne Bmail.exe verschicken. Ich habe noch keine Zeit gehabt, eine Lösung ohne bmail.exe zu realisieren. Ich werde das früher oder später mal noch ergänzen.
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 86612
Url: https://administrator.de/tutorial/powershell-for-runaways-part-ii-86612.html
Ausgedruckt am: 22.12.2024 um 06:12 Uhr
16 Kommentare
Neuester Kommentar
Moin TuXhunter,
danke für Deine Ergänzungen.
Auch wenn ich noch weit davon entfernt bin, Tipps zum Thema PowerShell zu geben - eins kommt mir nicht stimmig vor.
Du räumst hinterher die tmp-Trümmer weg. Gut und löblich.
Aber sollte es dann nicht an den zwei Stellen
(BTW. an zwei Stellen den gleichen CleanUp-Schnipsel aufzurufen könnte man/frau auch über den Aufruf eines codeblocks machen, oder?)
... ähh... sorry, also an den zwei Stellen:
nicht eher so heißen:
denn nur das sind doch die Dateien, die Du erzeugt hast?
Oder übersehe ich etwas?
Grüße
Biber
danke für Deine Ergänzungen.
Auch wenn ich noch weit davon entfernt bin, Tipps zum Thema PowerShell zu geben - eins kommt mir nicht stimmig vor.
Du räumst hinterher die tmp-Trümmer weg. Gut und löblich.
Aber sollte es dann nicht an den zwei Stellen
(BTW. an zwei Stellen den gleichen CleanUp-Schnipsel aufzurufen könnte man/frau auch über den Aufruf eines codeblocks machen, oder?)
... ähh... sorry, also an den zwei Stellen:
....
$tmpfolder2 = $tmpfolder + "\*.*"
remove-item -path $tmpfolder2 -force
$tmpfolder2 = $tmpfolder + "\eventlogquery_admincheck_application*.*"
remove-item -path $tmpfolder2 -force
Oder übersehe ich etwas?
Grüße
Biber
Moin TuXHunT3R
Erst einmal vielen herzlichen Dank für deine ausführliche Anleitung. Für mich als Newbie
in Sachen Powershell eine hilfreiche Lektüre
So hab ich mich denn auch gleich rangesetzt um ein bischen zu probieren.....
Dabei bin ich auch schon auf Unstimmigkeiten bzw Probleme gestoßen.
Dein Skript läßt sich nur auf anderen Computern in der $serverliste ausführen, wenn
der ausführende Skript-Benutzer(Admin)
Ich habe das mal ein bischen modifiziert, um es auch in einer anderen Domäne zu testen...
Im Deklarationsteil frage ich eine Objektvariable $remoteuser ab mit Hilfe des Cmdlets get-credential
Also das leidige Problem wie schon in Batch oder VB bei Remotejobs irgendwo die Usercredentials im Klartext hinterlegen zu müssen bzw auf Tools wie z.B. runasspc ausweichen zu müssen. Ich hatte gehofft mit der WPS kann man das elegant umgehen .
Falls du eine Möglichkeit kennst, diese Abfrage
Denn get-credential erfordert IMMER zwingend eine manuelle Kennworteingabe !!
Das führt mich dann gleich zur nächsten Frage: Bei netzübergreifenden Abfragen sind in der Regel Firewalls ein ziemlicher Hinderungsgrund zum Ausführen der "Remotejobs". Gibt es irgendwo eine Doku, welche Ports die WPS benötigt, um je nach Provider diese Befehle auch ausführen zu können ??
Soviel ersteinmal zum Hauptproblem für mich.
Nun noch einige Anmerkung zu deiner Eventlog-Auswertung....
Du schreibst
Ein
Bei der Auswahl der Ereignistypen muss man auch sehr aufpassen, um welche OS-Language es sich handelt!
Bei deutschem Server 2003 musst du z.B. in Zeile 128 bzw 140 type='Warning' durch type='Warnung' ersetzen.
Sonst ist dein Logfile jungfräulich leer und du freust dich vergeblich über weniger "Arbeit"
Gleiches gilt für Eventtyp Error (durch Fehler ersetzen)
Meine Zeile 128 sieht also eher so aus
So mehr kann ich zum Thema WindowsPowerShell noch nicht beitragen, is noch zu neu für mich.
Viel Spass damit.
Grüsse aus der schönen Schweiz
TuXHunT3R
Den hatte ich schon, wenn auch nich immer im "positiven" Sinne
So long AndreasA
Erst einmal vielen herzlichen Dank für deine ausführliche Anleitung. Für mich als Newbie
in Sachen Powershell eine hilfreiche Lektüre
So hab ich mich denn auch gleich rangesetzt um ein bischen zu probieren.....
Dabei bin ich auch schon auf Unstimmigkeiten bzw Probleme gestoßen.
Dein Skript läßt sich nur auf anderen Computern in der $serverliste ausführen, wenn
der ausführende Skript-Benutzer(Admin)
$user = $env:Username
auch auf den Remotecomputer die entsprechenden Admin-Rechte besitzt (Stichwort gleiche Domäne bzw Vertrauensstellungen)Ich habe das mal ein bischen modifiziert, um es auch in einer anderen Domäne zu testen...
Im Deklarationsteil frage ich eine Objektvariable $remoteuser ab mit Hilfe des Cmdlets get-credential
$remoteuser = get-credential
und in den Abfragen weiter unten (z.B. Zeile 85) wird mit Parameter -credential $remoteuser erweitert. foreach ($disk in get-wmiobject -class win32_Logicaldisk -filter "DriveType=3" -computername $server -credential $remoteuser) {
Das funktioniert sogar recht gut. D.h. der ausführende Skript-User ist ein anderer als der "Remote-Abfrage-User" Nur ein Haken hat diese Sache nun: Es funktioniert nur mit manuellem Starten des Skriptes !!!Also das leidige Problem wie schon in Batch oder VB bei Remotejobs irgendwo die Usercredentials im Klartext hinterlegen zu müssen bzw auf Tools wie z.B. runasspc ausweichen zu müssen. Ich hatte gehofft mit der WPS kann man das elegant umgehen .
Falls du eine Möglichkeit kennst, diese Abfrage
$remoteuser = get-credential
irgendwie automatisierbar zu machen per Skript mit Einlesen aus Objektdatei oder ähnlichem, wäre ich sehr erfreut.Denn get-credential erfordert IMMER zwingend eine manuelle Kennworteingabe !!
Das führt mich dann gleich zur nächsten Frage: Bei netzübergreifenden Abfragen sind in der Regel Firewalls ein ziemlicher Hinderungsgrund zum Ausführen der "Remotejobs". Gibt es irgendwo eine Doku, welche Ports die WPS benötigt, um je nach Provider diese Befehle auch ausführen zu können ??
Soviel ersteinmal zum Hauptproblem für mich.
Nun noch einige Anmerkung zu deiner Eventlog-Auswertung....
Du schreibst
# Eventlog-Analyse
... hmm?? Erklär mir mal bitte warum so? Bei mir waren leider nicht alle erwarteten Einträge im Logfile aufgelistet.- Zuerst mal das Datum in das richtige Format bringen:
Ein
$Datum = Get-Date -uFormat x
brachte bei mir wesentlich mehr Einträge zum Vorschein (oops was is nun richtig?)Bei der Auswahl der Ereignistypen muss man auch sehr aufpassen, um welche OS-Language es sich handelt!
Bei deutschem Server 2003 musst du z.B. in Zeile 128 bzw 140 type='Warning' durch type='Warnung' ersetzen.
Sonst ist dein Logfile jungfräulich leer und du freust dich vergeblich über weniger "Arbeit"
Gleiches gilt für Eventtyp Error (durch Fehler ersetzen)
Meine Zeile 128 sieht also eher so aus
get-wmiobject win32_ntlogevent -Filter "Logfile='System' and type='Warnung'" -computer $server -credential $remoteuser | select-object type, timewritten, eventcode, sourcename, message | format-table -auto | out-file -filepath $tmplog -encoding default
So mehr kann ich zum Thema WindowsPowerShell noch nicht beitragen, is noch zu neu für mich.
Viel Spass damit.
Grüsse aus der schönen Schweiz
TuXHunT3R
Den hatte ich schon, wenn auch nich immer im "positiven" Sinne
So long AndreasA
Hallo TuXHunT3R,
erstmals vielen Dank für das Script. Gerade so mit den ersten Versuchen in der PS ist das wirklich sehr hilfreich.
Wenn es Deine Zeit erlaubt, dann hätte ich folgende Frage:
in Zeile 132 (des überarbeiteten Scripts) wird ja das Logfile des Remoteservers eingelesen:
get-wmiobject win32_ntlogevent -Filter "Logfile='System' and type='Error'" -computer $server | select-object type, timewritten, eventcode, sourcename, message | format-table -auto | out-file -filepath $tmplog -encoding default
Dabei wird ja das ganze Log ausgelesen und erst später auf die Dauer eines Tages gekürzt.
Nachdem meine Anforderung die Abfrage unserer DCs betrifft (in denen die LOGS relativ groß sind), ist mein Ziel
möglichst den Remoteserver das Log filtern zu lassen und nur die gewünschten Ergebnisse zurück zu geben.
Über die Filterfunktion kann ich nach Eventcodes abfragen. Allerdings gelingt es mir nicht die Suchanfrage so einzuschränken,
dass nur beispielsweise die Fehlermeldungen des letzten Tages zurück gegeben werden. Das wäre im Vergleich zur bisherigen Abfrage
eine starke Entlastung der Standleitungen. Gibt es hierfür evtl. einen einfachen Kniff wie das Ganze umgebaut werden kann?
Der Eintrag müsste ja im Bereich '-Filter "Logfile='System' and type='Error' and 'ZeigeNurDieErsten10ErgbnisseAn'" erfolgen, oder?
Viele Grüße aus dem südbayrischen Raum.
Maximilian
erstmals vielen Dank für das Script. Gerade so mit den ersten Versuchen in der PS ist das wirklich sehr hilfreich.
Wenn es Deine Zeit erlaubt, dann hätte ich folgende Frage:
in Zeile 132 (des überarbeiteten Scripts) wird ja das Logfile des Remoteservers eingelesen:
get-wmiobject win32_ntlogevent -Filter "Logfile='System' and type='Error'" -computer $server | select-object type, timewritten, eventcode, sourcename, message | format-table -auto | out-file -filepath $tmplog -encoding default
Dabei wird ja das ganze Log ausgelesen und erst später auf die Dauer eines Tages gekürzt.
Nachdem meine Anforderung die Abfrage unserer DCs betrifft (in denen die LOGS relativ groß sind), ist mein Ziel
möglichst den Remoteserver das Log filtern zu lassen und nur die gewünschten Ergebnisse zurück zu geben.
Über die Filterfunktion kann ich nach Eventcodes abfragen. Allerdings gelingt es mir nicht die Suchanfrage so einzuschränken,
dass nur beispielsweise die Fehlermeldungen des letzten Tages zurück gegeben werden. Das wäre im Vergleich zur bisherigen Abfrage
eine starke Entlastung der Standleitungen. Gibt es hierfür evtl. einen einfachen Kniff wie das Ganze umgebaut werden kann?
Der Eintrag müsste ja im Bereich '-Filter "Logfile='System' and type='Error' and 'ZeigeNurDieErsten10ErgbnisseAn'" erfolgen, oder?
Viele Grüße aus dem südbayrischen Raum.
Maximilian
Hallo,
habe noch ein wenig daran rumgespielt:
Das logging des ping bereichs habe ich in zwei bereiche getrennt: (und eingedeutscht)
Zusätzlich habe ich noch DCDIAG /e eingefügt:
Ist noch ausbaufähig indem man den dcdiag Test in die einzelnen Tests zwecks Übersichtlichkeit aufsplittet.
habe noch ein wenig daran rumgespielt:
Das logging des ping bereichs habe ich in zwei bereiche getrennt: (und eingedeutscht)
"Anpingen der Server:" | out-file -filepath $logfile -encoding default -append
"====================" | Out-File -FilePath $logfile -Encoding default -Append
" " | out-file -filepath $logfile -encoding default -append
# Server pingen
foreach ($server in $serverliste){
ping $server -n 2 | Out-Null
$PingErgebnisServer = "$lastexitcode"
if ($PingErgebnisServer -eq "0") {
$tmp = "Pinging " + $server + " erfolgreich"
$tmp | out-file -filepath $logfile -encoding default -append
} else {
$tmp = "Pinging " + $server + " nicht erfolgreich, ueberprüfen!"
$tmp | out-file -filepath $logfile -encoding default -append
}
}
" " | out-file -filepath $logfile -encoding default -append
" " | out-file -filepath $logfile -encoding default -append
"Anpingen der Lan-Komponenten:" | out-file -filepath $logfile -encoding default -append
"=============================" | Out-File -FilePath $logfile -Encoding default -Append
" " | out-file -filepath $logfile -encoding default -append
# Netzwerkkomponenten pingen
foreach ($netzwerkkomponente in $netzwerkkomponentenliste) {
ping $netzwerkkomponente -n 2 | Out-Null
$PingErgebnisNWKomponente = "$lastexitcode"
if ($PingErgebnisNWKomponente -eq "0") {
$tmp = "Pinging " + $netzwerkkomponente + " erfolgreich"
$tmp | out-file -filepath $logfile -encoding default -append
} else {
$tmp = "Pinging " + $netzwerkkomponente + " nicht erfolgreich, ueberprüfen!"
$tmp | out-file -filepath $logfile -encoding default -append
}
}
Zusätzlich habe ich noch DCDIAG /e eingefügt:
Ist noch ausbaufähig indem man den dcdiag Test in die einzelnen Tests zwecks Übersichtlichkeit aufsplittet.
" " | out-file -filepath $logfile -encoding default -append
" " | Out-File -filepath $logfile -encoding default -append
"DCDIAG TESTS (fuer alle standorte)" | Out-File -filepath $logfile -encoding default -Append
"==================================" | Out-File -filepath $logfile -encoding default -Append
" " | out-file -filepath $logfile -encoding default -append
" " | Out-File -filepath $logfile -encoding default -append
$tmplog= $tmpfolder + "\DCDIAG1.txt"
cmd.exe /c dcdiag.exe /e /F:$tmplog
Get-Content $tmplog | Out-File -filepath $logfile -encoding default -append
Hallo,
habe das Script geändert, so dass die Logdatei nicht mehr als Text in der Email verschickt wird, sondern als Anhang.
Hatte das Problem das der Mail Server (Lotus Notes 8) ab ~42289 Bytes die Email nicht mehr öffnen konnte.
Jetzt scheint es zu funktionieren:
AM Anfang des Scripts sollten folgende Variablen gesetzt werden:
$SmtpServer = "Name oder IP-Adresse des Mail Servers"
$Empfaenger = "Empaenger Adresse"
$Absender = "Absender Adresse"
habe das Script geändert, so dass die Logdatei nicht mehr als Text in der Email verschickt wird, sondern als Anhang.
Hatte das Problem das der Mail Server (Lotus Notes 8) ab ~42289 Bytes die Email nicht mehr öffnen konnte.
Jetzt scheint es zu funktionieren:
AM Anfang des Scripts sollten folgende Variablen gesetzt werden:
$SmtpServer = "Name oder IP-Adresse des Mail Servers"
$Empfaenger = "Empaenger Adresse"
$Absender = "Absender Adresse"
function sendmail($body)
{
$SmtpClient = new-object system.net.mail.smtpClient
$MailMessage = New-Object system.net.mail.mailmessage
$att = new-object Net.Mail.Attachment($logfile)
$SmtpClient.Host = "$SmtpServer"
$mailmessage.from = "$Absender"
$mailmessage.To.add("$Empfaenger")
$mailmessage.Subject = “$datum automatischer Servertest Logfile”
$MailMessage.IsBodyHtml = $true
$mailmessage.Body = $body
$mailmessage.Attachments.Add($att)
$smtpclient.Send($mailmessage)
}
sendmail $body