tuxhunt3r
Goto Top

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:
  1. Eine Liste von Servern und Netzwerkkomponenten durchpingen
  2. 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.
  3. Das Eventlog aller in der Liste angegebenen Server überprüfen. Es werden von jedem Server alle heutigen Errors + Warnings vom System- und Applicationlog aufgelistet
  4. Ein Logfile mit den Ergebnissen der oberen Checks anlegen
  5. 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 face-smile ):
#*********************************************************************************************** 
# 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"  
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.

$netzwerkkomponentenliste = get-content "netzkomponentenliste.txt"  
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.

$logfile = "AdmincheckLog_" + $datum + ".txt"  
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.

$tmpfolder = "c:\temp"  
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.

[int]$GB = 1
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.

bmail.exe -s <SMTP-Server> -t <Ziel-Adresse> -f <Quelladresse, beliebig wählbar> -a "ADMINCHECK.PS1 Logfile" -m "$logfile"  
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:
  1. "<SMTP-Server>" durch euren Postausgangsserver ersetzen (seht zu, dass die Rules so definiert sind, dass diese Mails durchgehen)
  2. "<Ziel-Adresse>" durch eine existierende Mailadresse ersetzen
  3. "<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.

Content-ID: 86612

Url: https://administrator.de/tutorial/powershell-for-runaways-part-ii-86612.html

Ausgedruckt am: 22.12.2024 um 06:12 Uhr

TuXHunt3R
TuXHunt3R 21.05.2008 um 23:18:38 Uhr
Goto Top
So........

Ich hab ein wenig Zeit gefunden, das Script etwas zu verbessern. Dies ist also die Version 1.1 des Scripts. Folgende Sachen wurden verbessert:
- Die temporären Dateien werden nun auch am Ende des Scripts gelöscht.
- Die bmail.exe wird nicht mehr benötigt, das Mail mit dem Logfile als Inhalt wird nun mit PowerShell-Bordmitteln verschickt.
Die einzelnen Angaben wie SMTP-Server, Zieladresse, Quelladresse, etc müssen aber weiterhin von jedem Scriptnutzer individuell angepasst werden.

#*********************************************************************************************** 
# 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.1
#*********************************************************************************************** 


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



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


# Temporäre Dateien aufräumen
$tmpfolder2 = $tmpfolder + "\*.*"  
remove-item -path $tmpfolder2 -force


# Logfile per Mail schicken
$SmtpServer = "<SMTP-Server>"  
$SmtpClient = new-object system.net.mail.smtpClient
$SmtpClient.host = $SmtpServer

$Nachricht = new-object system.net.mail.MailMessage
$Nachricht.From = ("<Quelladresse, beliebig wählbar>")  
$Nachricht.To.Add("<Ziel-Adresse>")  
$Nachricht.Subject = ("ADMINCHECK.PS1 Logfile")  
$Nachricht.Body = get-content $logfile | out-string

$SmtpClient.Send($Nachricht)

Viel Spass damit.

Grüsse aus der schönen Schweiz
TuXHunT3R
Biber
Biber 21.05.2008 um 23:52:20 Uhr
Goto Top
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:
....
$tmpfolder2 = $tmpfolder + "\*.*"  
remove-item -path $tmpfolder2 -force
nicht eher so heißen:
$tmpfolder2 = $tmpfolder + "\eventlogquery_admincheck_application*.*"  
remove-item -path $tmpfolder2 -force
denn nur das sind doch die Dateien, die Du erzeugt hast?

Oder übersehe ich etwas?

Grüße
Biber
TuXHunt3R
TuXHunt3R 22.05.2008 um 08:56:43 Uhr
Goto Top
Du hast recht, habe ich übersehen.

Hab es in der zweiten Fassung entfernt.
TuXHunt3R
TuXHunt3R 28.07.2008, aktualisiert am 18.10.2012 um 18:36:02 Uhr
Goto Top
Hier noch eine Ergänzung:
Powershell Logfile Frage
AndreasA
AndreasA 24.09.2008 um 12:23:17 Uhr
Goto Top
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 face-wink

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 face-sad.
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
  1. Zuerst mal das Datum in das richtige Format bringen:
$Datum = Get-Date -Format yyyyMMdd
... hmm?? Erklär mir mal bitte warum so? Bei mir waren leider nicht alle erwarteten Einträge im Logfile aufgelistet.
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" face-wink
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 face-wink
So long AndreasA
mrindia
mrindia 24.09.2008 um 14:22:41 Uhr
Goto Top
Hallo Jungs,

wie kann ich den mit powershell die EventLogs löschen?

z.B. will ich die Event system und Applikation von einem oder mehreren Servern auf einem schlag löschen....

wäre sehr Dankbar !!!
TuXHunt3R
TuXHunt3R 25.09.2008 um 15:11:20 Uhr
Goto Top
Hallo Andreas

Werde es anschauen. Allerdings erst in einer Woche oder so, vorher komme ich nicht dazu.
SirMax
SirMax 01.10.2008 um 13:05:11 Uhr
Goto Top
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
bluecon
bluecon 07.04.2009 um 08:52:48 Uhr
Goto Top
Wirds hierzu noch etwas geben?

Gruß,
Adrian
TuXHunt3R
TuXHunt3R 07.04.2009 um 23:25:00 Uhr
Goto Top
Hallo Andreas

Danke schon mal für deinen Beitrag.


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

Da habe ich dir auch keine bessere Lösung als RunasSpc. Eventuell könnte ich man mit VB ein Exe basteln, welches in das in einer Datenbank hinterlegte Passwort für ein bestimmtes Script herausliest und dieses dann mittels runas.exe und dem entsprechenden Passwort ankickt. RunAsSPC ist hier allerdings bestimmt die bessere Lösung.
Ich habe bis jetzt allerdings nur in Umgebungen gearbeitet, welche mit einer Domäne auskommen (und ich arbeite bei einem Grosskonzern).

Bei mir waren leider nicht alle erwarteten Einträge im Logfile aufgelistet.

Hier muss ich nochmals über die Bücher. Ich werde es testen....

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)

Danke für die Warnung. So eine Situation hatte ich ebenfalls noch nie. Hab gedacht, dass Firmen ihre Server sowieso grundsätzlich englisch aufsetzen. Bei uns ist es zumindest so, genauso wie in meiner Domäne zu Hause...
aGeers
aGeers 01.10.2009 um 13:01:33 Uhr
Goto Top
Hallo,

Wie kann ich das Script umschreiben, das er bei weniger als 20% freien Speicherplatz, statt bei einer festen GB Größe eine Fehlermeldung ausgibt?

Ich bin leider was Powershell angeblangt ein Blutiger Anfänger....

Ageers
TuXHunt3R
TuXHunt3R 01.10.2009 um 22:09:41 Uhr
Goto Top
Hallo aGeers

Ich schaus mir morgen oder am Samstag mal an.
Der Ansatz wäre, dass man anhand der Gesamtgrösse und dem freien Speicherplatz die Prozentzahl ausrechnet und dann überprüft, ob diese Prozentzahl < 20 ist.

Aber wie gesagt, ich schaus mir morgen mal an.
TuXHunt3R
TuXHunt3R 04.10.2009 um 19:57:09 Uhr
Goto Top
So, ich habe den Bereich für die Ausrechnung der Festplattenauslastung überarbeitet. Dieser sieht nun so aus:
"Checking the free diskspace on the 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 20 % frei ist

# 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 = [math]::round($freespaceMB / 1024, 2)
		# Gesamtgrösse der Disk auslesen + in GB umrechnen
		$DisksizeB = $disk.size
		$DisksizeKB = $disksizeB / 1024
		$DisksizeMB = $disksizeKB / 1024
		$DisksizeGB = [math]::round($disksizeMB / 1024, 2)
		# Diskletter auslesen
		$diskletter = $disk.deviceid
		
        # % des freien Speicherplatzes ausrechnen 
        $PercentFree = [math]::round(((100/$DisksizeGB) * $freespaceGB), 2)
                
		# ...und vergleichen
		if ($PercentFree -gt 20) {
			$StringForTextfile = "Disk " + $diskletter + " " + $freespaceGB + " / " + $disksizeGB + " GB (" + $PercentFree + " %) free ==> Enough free Diskspace!"  
			$StringForTextfile | out-file -filepath $logfile -encoding default -append
		} else {
			$StringForTextfile = "Disk " + $diskletter + " " + $freespaceGB + " / " + $disksizeGB + " GB (" + $PercentFree + " %) free ==> Disk full, move data!"  
			$StringForTextfile | out-file -filepath $logfile -encoding default -append
		}
	}
}

Zusätzlich zu der Sache mit den 20% werden nun die Werte zwecks besserer Lesbarkeit auf 2 Stellen gerundet. Ist das i.O. für dich?
aGeers
aGeers 05.10.2009 um 12:51:00 Uhr
Goto Top
Hallo Tux,

TOP !!
++
Danke!

Weiß jemand wie das Log für den Datei Replikations dienst heißt. File replication Service, NTFRS usw. funktioniert nicht
aGeers
aGeers 06.10.2009 um 13:58:19 Uhr
Goto Top
Hallo,

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
aGeers
aGeers 13.10.2009 um 16:30:47 Uhr
Goto Top
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"

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