Powershell Voodoo – Teil 1

Hallo zusammen,

in dieser Serie stelle ich einige Powershell CMDlets vor, die euch hoffentlich das Leben etwas leichter machen. Einige davon kommen aus dem privaten Bereich, andere von meiner Tätigkeit als IT-Consultant und Administrator, auf jeden Fall habe ich die Befehle irgendwann mal als nützlich empfunden und wollte sie euch nicht vorenthalten.
Disclaimer: Alle diese Commands sind bestimmt noch nicht 100%ig perfekt, können und sollten ggf. verbessert werden, oder die Informationen können auch anderweitig abgefragt, oder dargestellt werden. Über Vorschläge und Diskussionen freue ich mich in den Kommentaren. Die meisten der Befehle sind grundsätzlich Einzeiler, jedoch zur besseren Lesbarkeit mit dem „Backtick“ (`) auf mehrere Zeilen verteilt.

Batch-Videokonvertierung

Mit folgendem Befehl werden alle Dateien in einem Ordner, die mit *.avi enden (also Videodateien), einmal mittels ffmpeg ins MKV-Format konvertiert. Der Befehl setzt voraus, dass ffmpeg unter C:\Programme (x86)\ffmpeg installiert ist:

Get-ChildItem `
| Where-Object {$_.Name.EndsWith(".avi")} `
| ForEach-Object { &'C:\Program Files (x86)\ffmpeg\bin\ffmpeg.exe' -i `".\$_`" `".\$_.mkv`" }

Known issues: Als Ergebnisdatei erhaltet ihr hierbei eine Datei im gleichen Ordner, die denselben Dateinamen wie das Original trägt, jedoch „.mkv“ als Dateiendung angehängt bekommt. Die resultierende Datei heißt dann beispielsweise „Video.avi.mkv“ – bisher hat es mich aber noch nicht genug gestört, dass ich eine Behandlung für die Dateinamen in dem Command eingebaut hätte 🙂

PC-Neustart zu bestimmter Zeit

Eine Möglichkeit, den Rechner/PC/Server zu einer bestimmten Zeit neu zu starten bietet dieser Befehl. Er setzt auf der bekannten „shutdown.exe“ auf, die man auch über eine normale Eingabeaufforderung nutzen kann, jedoch kümmert sich der Powershell-Teil darum, dass man die gewünschte Uhrzeit zum Herunterfahren nicht wie sonst in Sekunden angeben muss, sondern zum einen das aktuelle Datum herangezogen wird (Get-Date), darauf ein Tag addiert wird, und auf das resultierende Datum noch einmal 3 Stunden hinzugezählt werden. Dann wird die Zeitdifferenz zum aktuellen Datum (und der Uhrzeit) in Sekunden zurückgegeben. In dem Beispiel wird der PC also um 3 Uhr früh am Folgetag neugestartet.

shutdown -r -t ([decimal]::round(((Get-Date).AddDays(1).Date.AddHours(3) - (Get-Date)).TotalSeconds))

Das Neustarten kann dann wiederum mit „shutdown -a“ abgebrochen werden (auch von der Eingabeaufforderung aus). Ich finde diese Variante einen Neustart zu planen grundsätzlich sehr charmant, wegen der Fire&Forget-Funktion. Hat man beispielsweise einen Server gepatcht (Windows-Updates…) oder durch Softwareinstallationen an den Rand eines Neustarts gebracht, spricht man sich kurz mit den Usern ab, dass auch niemand um 3 Uhr morgens auf die Idee kommt, noch mit dem Gerät zu arbeiten, feuert den Befehl ab, und arbeitet am nächsten Tag zu einer christlichen Zeit wieder weiter. Copy and Paste funktioniert meistens auch schneller als die Aufgabenplanung von Windows zu bemühen, und im Zweifelsfall sind die Daten, wann der Neustart erfolgen soll auch sehr schnell angepasst.

Überprüfung der VSS-Writer

Falls Ihr Probleme mit der VSS-Sicherung von Windows-Systemen haben solltet, und die registrierten VSS-Writer kontrollieren wollt, könnt ihr euch mit folgendem Befehl nur die VSS-Writer anzeigen lassen, die aktuell den Status „Fehlgeschlagen / Failed“ haben:

vssadmin list writers `
| Select-String -Context 0,4 'Verfassername:' `
| Where-Object $_.Context.PostContext[2].Trim() -ne "Status: [1] Stabil"} `
| select @{E="Line";N="FailedWriters"}

Der Befehl listet alle Writer über das bekannte Tool „vssadmin“ auf, und über die Select-String Direktive werden 4 Zeilen nach dem Vorkommen des Wortes „Verfassername:“ ausgegeben, daraufhin über das Where-Object selektiert, in welchem dieser Vorkommnisse nicht der Status „Stabil“ steht, und dieses Endergebnis daraufhin als „FailedWriters“ in den Output der Powershell ausgegeben. Um zu wissen, welcher Writer zu welchem Produkt/Dienst gehört, könnt ihr beispielsweise diesen Artikel von Arcserve nutzen.

VMware – virtuelle Portgruppen kopieren

Und zum Abschluss des ersten Teils noch ein kleines Schmankerl für VMware. Falls ihr mehrere ESXi-Server betreut, die „nur“ über eine Essentials-Lizenz verfügen, also keine Distributed Switche verwenden können, aber trotzdem mehrere virtuelle Netzwerke nutzen, um VMs voneinander zu trennen, hilft euch das hier hoffentlich weiter:

# ESXi Server, von dem die Portgruppen kopiert werden sollen
$CopyFromServer = "Hostname_oder_IP"
Connect-VIServer $CopyFromServer
# Auswahlkriterien der Netzwerke
$Networks = Get-VirtualPortGroup | Where-Object {$_.VLanId -ne "99"}
# Verbindung wieder schließen
Disconnect-VIServer -Server $CopyFromServer -Force

# ESXi Server, auf den die Portgruppen kopiert werden sollen 
$CopyToServer = "Hostname_oder_IP" 
Connect-VIServer $CopyToServer 
ForEach ($network in $networks) 
{
     New-VirtualPortGroup -Name $network.Name.ToString() -VLanId $network.VLanId.ToString() -VirtualSwitch $network.VirtualSwitch.ToString() -Server $copytoserver 
}

Die Einträge „Hostname_oder_IP“ und die Auswahlkriterien müssen natürlich auf eure Umgebung angepasst werden. Zum Ausführen des Scripts benötigt Ihr die PowerCLI-Erweiterung für die Powershell, entweder direkt von VMware oder besser über die PowerShell-Gallery.

Zunächst verbindet sich das Script auf einen ESXi-Server, auf dem die Netzwerke bereits konfiguriert sind. Beim Ausführen von Connect-VIServer werdet ihr nach den Anmeldedaten gefragt, das Script läuft also nicht (ohne Weiteres) vollautomatisch. Daraufhin wird eine Variable „Networks“ mit allen VirtualPortGroups des Servers befüllt, in diesem Beispiel wird aber die Portgruppe mit der VLAN-ID 99 ausgelassen (Where-Object -> VLAN-ID nicht gleich 99), da diese bereits als Management-Interface auf dem neuen Server konfiguriert ist. Welche Kriterien eventuell sonst noch Sinn machen, ist von der jeweiligen Umgebung abhängig – alle anderen Portgruppen werden in die Variable übernommen, und die Verbindung zum Quellserver wieder geschlossen.

Bei der folgenden Verbindung zum Zielserver werden die Netzwerke aus der Variable als neue Portgruppen hinzugefügt. Hierbei werden Name, VLAN-ID und der virtuelle Switch, auf dem die Portgruppe angelegt war auf dem neuen Server eingetragen.

Mit diesem Script könnt ihr der Essentials-Edition von vSphere auch einen Hauch von DistributedSwitchen zuteil werden lassen 😉

Viele Grüße,
Hannes

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert