Home » Software » Skripting » Powershell [Einführungstutorial]
- Anzeige -
Software Asset Management beim Fachmann

Powershell - Ein Einführungstutorial

Jetzt lerne ich Power-Shell! Maus-Schubsen ist Out, Powershell ist angesagt. Gerade am Anfang sitzt man aber doch gerne wie der sprichwörtliche "Ochs vor dem Berg". Hier hilft dieses Tutorial weiter:

Einleitung

Grundsätzlich sollte man nicht mit der normalen Powershell anfangen, sondern die Windows-Powershell ISE verwenden. Grund? Hier hat man eine Command-Line-Completion sowie eine ausführlichere Hilfe.

Powershell - Ein Einführungstutorial

Teilweise müssen für bestimmte Aufgaben (z.B. Microsoft Exchange) Module nachgeladen werden.

Die Namensgebung der meisten Befehle besteht aus:

Grundsätzlich liegen alle Befehle in der foglenden Form vor:

Verb-Substantiv [optinale Parameterlistr]

Es gibt aber auch andere Verben als Get, Set und Remove. Aber hiermlit lassen sich zumindest ansatzweise schon einige Befehle erraten. Häufig wird eine bestimmte Gross-Kleinschreibung angegeben, diese kann jedoch vernachlässigt werden. Vergisst man notwenige Parameter, fragt Powerhsell interaktiv nach.

Hilfe zu den Befehlen lässt sich durch die Eingabe der folgenden Befehlsfolge aufrufen:

get-help BEFEHL

Beim ersten Start wird die entsprechende Hilfe nachgeladen. Verwirrend ist hier, dass keinerlei Fortschrittsmeldung erscheint. Bei meiner Labor-Installation ohne Internet-Zugriff kam keinerlei Fehlermeldung und ich musste den Befehl mit Ctrl-Pause Break abbrechen.

Powershell - Ein Einführungstutorial

Aber selbst mit der Basis-Hilfe, die erscheint, wenn sich die Hilfedatei nicht herunterladen kösst, kann man häufig schon was anfangen. Beispiel GET-VM:

Powershell - Ein Einführungstutorial

Kommentare

Zeilenweise Kommentare werden durch ein # eingeleitet.

Ausgabeformt in Powershell festlegen - Tabelle oder Liste

An Beispiel des Befehle "GET-VM" werden hier verschiedene mögliche Parameter gezeigt. Die Auswahl von Werten und das Ausgabeformat funktioniert aber auch bei anderen Powershell-Befehlen.

get-vm

ergibt

Powershell - Ein Einführungstutorial

Ausgabeformt Liste mit fl festlegen

Mittels fl (format list) lässt sich ein Ergebnis in Listenformat darstellen.

Get-VM | fl
Powershell - Ein Einführungstutorial

Ausgabeformt Tabelle mit ft festlegen

Mittels ft (format table) lässt sich ein Ergebnis in Tabellenform darstellen. Häufig ist das die Standarform. Man könnte daher beim nächsten Befehl das ft auch weglassen und würde die gleiche Ausgabe erhalten.

Get-VM | ft

Augabewerte einschränken

Nehmen wir an, es soll nur name, state und status angezeigt werden:

Get-Vm | ft name,state,status
Powershell - Ein Einführungstutorial

Die Ausgabe sieht noch etwas arg auseinandergerissen aus. Daher setzen wir hier noch den Parameter autosize dazu:

Get-Vm | ft name,state,status -autosize
Powershell - Ein Einführungstutorial

Mittels...

Get-VM | fl *

...kommt man an die komplette Liste aller abfragbaren Werte. Aus diesem Ergebnis kann man sich die nötigen Namen heraussuchen.

get-vm | ft name,id 

Jetzt lassen wir uns nur name und id ausgeben.

Powershell - Ein Einführungstutorial

Die Aufteilung ist optisch leider noch nicht ideal. Hier hilft wieder der Parameter "Autosize"

Powershell - Ein Einführungstutorial

Ausgabe eines Befehls im nächsten weiterverarbeiten

Das Ergebnis eines Befehls lässt sich auch in einem weiteren weiterverarbeiten. Zwischen beiden Befehlen steht das Pipe-Zeichen. Beispiel:

Get-VMsnapshot -VMname * | Remove-VMsnapshot

Der erste Befehl zeigt alle Snapshots und der zweite löscht diese.

Scripting mit Powershell

Interessant wird das Skripting, also das Aneinanderreihen von mehreren Befehlen in einer Datei. Diese kann dann wiederum ausgeführt werden.

Hierzu wird, am Besten in der ISE, eine entsprechende Datei mit der Endung .ps1 angelegt. Gg. muss hierzu in der ISE noch der Skript Pane bzw. Deutsch Skriptbereich aktiviert werden.

Powershell - Ein Einführungstutorial
Powershell - Ein Einführungstutorial

Schauen wir uns das folgende Skript an:

$VMname = Read-Host "Geben Sie den Namen der neuen VM ein"
Write-Host "Erstelle neue VM: $VMname"
New-VM -Name $VMname

Mit dem Skript oben haben wir gleichzeitig Variablen unter Powershell kennen gelernt. Diesen wird einfach ein $ vorangestellt. Sie können direkt im Text ausgegeben werden. Der erste Befehlt liesst den Namen einer VM vom Benutzer interaktiv ein, der zweite gibt den Namen zur Kontrolle aus und der dritte erstellt eine neue VM (ohne zusätzliche Parameter).

Ein solches Skript, dass mit der Endung ps1 gespeichert wird, startet jedoch nicht durch Doppelklick, sondern es muss immer zwangsläufig innerhalb einer Powershell gestartet werden.

Zeitgesteuertes Ausführen eines Powershell-Skriptes

Da Powershell-Skripte nie direkt, sondern immer nur innerhalbe einer Powerhsell ausgeführt werden können, gilt es einiges zu beachten beim zeitgesteuerten Ausführen.

Unter "program/script" trägt man den Pfad zur Powershell ein.

%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe

Unter "Add arguments (optional)" den Skriptnamen inkl. Pfad mit vorangestelltem ".command", also z.B.

-command "C:\Windows\bat\myscript.ps1"

Schleifen und if-Abfragen in Powershell

Ich lerne am liebsten anhand von Beispielen. Auf mcseboard.de habe ich ein schönes Powershell-Beispiel gefunden, was anschaulich Schleifen und if-Abfragen zeigt. Auch hier sieht man wieder eine gewisse Verwandschaft zu PHP in der Powershell-Syntax.

Das folgende Skript listet alle Dienste auf (get-service) und führt darüber eine Schleife aus (foreach). Dann prüft es, ob der aktuelle Dienst den Status "Running" hat und färbt den Eintrag entsprechend. Die Ausgabe auf die Konsole erfolgt mit dem Parameter write-host.

$svcs = get-service | Sort-Object Name
foreach($sv in $svcs)
    {
    if($sv.Status -eq "Running")
        {
        write-host -ForegroundColor Green $sv.Status $sv.Name $sv.DisplayName
        }
    else
        {
        write-host -ForegroundColor Red $sv.Status $sv.Name $sv.DisplayName
        }
    }

Vergleichsoperationen in Powershell

Im obigen Beispiel haben wir bereits den Vergleichoperator

-eq

kennen gelernt. Er prüft auf Gleicheit. Welche weiteren Operatoren sind verfügbar?

-ne

ungleich

-lt

kleiner

-le

kleiner oder gleich

-gt

grösser

-ge

grösser oder gleich

-and

und

WMI-Abfragen mit Powershell

Auch WMI-Abfragen lassen sich relativ leicht mit Powershell realisieren. Häufig kommt man bereit mit dem folgenden kurzen Befehl an die Seriennummer eines Servers.

Get-WmiObject Win32_BIOS

WMI und Powershell Praxis-Beispiel. Temperaturüberwachung von HP Proliant-Server

Machen wir noch ein praktisches Beispiel. HP-Server haben jede Menge Temperatursensoren verbaut. Einer dafür eignet sich dazu, die Umgebungstemperatur zu überwachen.

$colItems = get-wmiobject -class "HP_NumericSensor" -namespace "root\hpq" -computername "."

foreach ($objItem in $colItems) 
{
      if ($objItem.Name -eq "Temperature Sensor 1")
      {
        $date = (get-date).ToShortDateString()
        $time = (get-date).ToShortTimeString()

        $temperature = $objItem.CurrentReading
        write-host  "$date $time Umgebungstemperatur: $temperature Grad"
      }      
}

Nur der Sensor mit dem Namen "Temperature Sensor 1" liefert den relavanten Wert, daher wird auch nur dieser abgefragt.

Die Befehle

$date = (get-date).ToShortDateString()
$time = (get-date).ToShortTimeString()

liefern uns Datum und Uhrzeit vernünftig formatiert zurück.

Text-Dateien erzeugen mit Powershell

Das obige Beispiel "Temperaturüberwachung von HP Proliant-Server" lässt sich noch erweitern. Wir können eine INI-Datei erzeugen, die von einem Monitor-Programm ausgewertet werden kann.

$colItems = get-wmiobject -class "HP_NumericSensor" -namespace "root\hpq" -computername "."

foreach ($objItem in $colItems) 
{
      if ($objItem.Name -eq "Temperature Sensor 1")
      {
        $date = (get-date).ToShortDateString()
        $time = (get-date).ToShortTimeString()

        $temperature = $objItem.CurrentReading
        write-host  "$date $time Umgebungstemperatur: $temperature Grad"
        "[Standard]" | out-file -filepath C:\windows\bat\tempcheck\temperature.ini
        "temperature=$temperature" | out-file -append -filepath  C:\windows\bat\tempcheck\temperature.ini
      }      
}

Mittels Out-File lassen sich Ergebnisse von Befehlen oder Variablen in eine Text-Datei schreiben. Ohne die Option -append, wird die Datei immer wieder neu erstellt.

Interessante Powershell-Beispiele

Verschlüsselte GMX-Mails via Powershell versenden:

Falls Sie automatisiert Mails via GMX versenden wollen, geht das nur noch verschlüsselt. Früher war das Tool bat die erste Wahl, das kann jedoch kein SSL mehr. Mit Powershell gehts auch, nur braucht es da einige Schritte.

Nehmen wir an, Ihre Absenderadresse ist:

monitoring.kaktus@gmx.de

Ihr Password wäre (geht nicht, also nicht probieren):

kakti!0815

Ihre Zieladresse ist:

ziel@kaktus.de

Mit folgendem Skript versenden Sie ein Mail:

$smtpServer = "mail.gmx.net"
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$credentials=new-object system.net.networkcredential("monitoring.kaktus@gmx.de","kakti!0815") 
$smtp.credentials = $credentials.getcredential($smtpserver,"25","basic")
$message = New-Object Net.Mail.MailMessage("monitoring.kaktus@gmx.de","ziel@kaktus.de")
$message.Subject = "Hello from Powershell"
$message.Body = "Dieses wunderbare Mail stammt von der Powershell..."
$smtp.Send($message)

Freien Speicherplatz auf lokalen Laufwerken überprüfen:

Eine voll gelaufene Partition ist eins der häuifigsten Fehlerursachen. Sinnvoll wäre es, wenn der Support rechtzeitig einen Fehlerhinweis hierzu bekäme. Auch dies können wir mit Powershell und WMI-Abfragen realisieren:

function Round( $value, [MidpointRounding]$mode = 'AwayFromZero' ) 
{
  [Math]::Round( $value, $mode )
}

function sendmail ($Server, $Device, $Ratio)
{
    $Ratio = $Ratio * 100
    $Ratio = Round $Ratio
    write-host $Server $Device $Ratio
    
    $smtpServer = "mail.gmx.net"
    $smtp = new-object Net.Mail.SmtpClient($smtpServer)
	$credentials=new-object system.net.networkcredential("monitoring.kaktus@gmx.de","kakti!0815") 
	$smtp.credentials = $credentials.getcredential($smtpserver,"25","basic")
	$message = New-Object Net.Mail.MailMessage("monitoring.kaktus@gmx.de","ziel@kaktus.de")
    $message.Subject = "Host: $Server - Lauferk: $Device - Platz wird knapp: $Ratio Prozent"
    $message.Body = "Hallo!`r`n Host: $Server - Lauferk: $Device - Platz wird knapp. $Ratio Prozent.`r`nBitte beachten."
    $smtp.Send($message)
}

Clear-Host

$Computername = "MyHost"
$colItems=Get-WmiObject win32_logicaldisk -ComputerName $Computername -Filter "Drivetype=3" 
write-host $Computername
foreach ($objItem in $colItems) 
{
    
     write-host ---- $objItem.DeviceID ----
     $Size = [decimal]$objItem.size / 1024 / 1024 / 1024
     $Size = Round $Size
     write-host Gesamt: $Size
     $Free = [decimal]$objItem.Freespace / 1024 / 1024 / 1024
     $Free = Round $Free
     write-host Frei: $Free

     $Ratio = $Free/$Size
     write-host Ratio: $Ratio
     if ($Ratio -le 0.1)
     {
         sendmail $Computername $objItem.DeviceID $Ratio

     }
}

Update

Besser scheint es mit dem folgenden Mail-Code zu funktionieren

$EmailTo = "empfaenger@meine-email.com"
$EmailFrom = "absender@gmx.ch"
$Subject = "Host: $Server - Lauferk: $Device - Platz wird knapp: $Ratio Prozent"
$Body = "Hallo!`r`n Host: $Server - Lauferk: $Device - Platz wird knapp. $Ratio Prozent." 
$SMTPServer = "mail.gmx.net" 
$SMTPMessage = New-Object System.Net.Mail.MailMessage($EmailFrom,$EmailTo,$Subject,$Body)
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587) 
$SMTPClient.EnableSsl = $true 
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("monitoring.kaktus@gmx.de","ziel@kaktus.de")
$SMTPClient.Send($SMTPMessage)

Dank an:

Funktionen in Powershell

Funktionen in Powershell werden in dieser Form definiert:

function Funktion( Werte ) 
{
  Anweisungen
}

Powershell macht keine Unterschiede zwischen Prozedur und Funktion. Das was wir von anderen Sprachen als Prozedur kennen, ist in Powershell eine Funktion ohne Rückgabewert.

Rückgabewerte in Powershell verhalten sich komplett anders als in anderen Sprachen, ich werde hier daher erst mal nur sehr kurz darauf eingehen. Wie in anderen Sprachen gibt es zwar das Schlüsselwort return, es kann aber auch leer sein. Es sagt nur, dass alles, was zuvor ausgegeben wurde, zurückgegeben wird.

Ein kleines Beispiel:

function testfunction 
{
$a = "Hello, World"
$a
$a
return
}

Clear-Host 
$result =  testfunction
Write-Host $result

Da $a zwei mal in der Funktion ausgegeben wird ()was aber aufgrund der Kapselung nicht an der Konsole erscheint, wird der Rückgabewert (und die Ausgabe) "Hello, World Hello, World" sein.

WMI

Zurück zur eigentlichen Funktion:

Mit...

$colItems=Get-WmiObject win32_logicaldisk -ComputerName $Computername -Filter "Drivetype=3" 

...werden Laufwerke angesprochen. Durch die Filter-Option wird der Zugriff auf lokale Laufwerke beschränkt.

Mit der Schleife wird Laufwerk für Laufwerk "durchgescannt. Der Rückgabewert in Bytes wird in Gibabytes umgerechnet. Ist das Verhältnis < 0.1, wird die Funktion aufgerufen, die eine Mail verschickt. Mehr Infos zur WMI-Geschichte gibt es unter Working with WMI providers to PowerShell.

Buchempfehlung

Weitere Beispiele

FAQ Windows Powershell

Windows Powershell ISE fehlt

Windows Powershell ISE ist auf Windows-Servern ein Feature, das nachinstalliert werden muss. Sie finden es unter "Rollen und Features hinzufügen".

Powershell - Ein Einführungstutorial

Powershell-Skripte können nicht ausgeführt werden

Erhalten Sie die Meldung "Die Datei ... kann nicht geladen werden, da die Ausführung von Skripts auf diesem System deaktiviert ist. Weitere Informationen finden Sie unter 'about_Execution_Policies' (http://go.microsoft.com/fwlink/?LinkID=135170).", so müssen Sie zunächst die Ausführung von Powershell-Skripten freischalten. Hierzu rufen Sie die Powershell bzw. die Powershell-ISE mit administrativen Rechten auf. Anschliessend geben Sie den folgenden Befehl ein.

Set-ExecutionPolicy Unrestricted

Nun ist das System aber offen für nicht signierte und eventuell für bösartige Zwecke geschriebene Powershell-Skripte.

Weitere Lernmöglichkeiten für PowerShell



War der Artikel hilfreich? Ich freue mich sehr über Likes, Shares oder Links von Deiner Website darauf. Danke Dir.

it-zeugs.de ist auch auf Facebook...

Schreibe einen Kommentar - aber kein SPAM - der wird zuverlässig gefiltert!

  • Erforderliche Felder sind markiert mit *.

If you have trouble reading the code, click on the code itself to generate a new random code.