Windows PowerShell

Grundlagen - Tutorials - Befehle - Beispiele

Vorbereitung: .NET Framework & PowerShell updaten


PowerShell Update herunterladen:

https://msdn.microsoft.com/de-de/powershell/wmf/readme
(Bestandteil des Windows Management Framework)

PowerShell Grundlagen / Basics


Variabel Deklarationen

Ähnlich wie in PHP wird einer Variabel in PowerShell ein Dollarzeichen '$' vorangestellt. Ein Variabel-Namen darf nur alphanumerische Zeichen (a-z, A-Z, 0-9) enthalten. Außnahme: Der Unterstrich '_'.
Beispiele für gültige Variabel-Deklarationen:
$testVar
$Testvar_1
Beispiele für ungültige Variabel-Deklarationen:
$test-Var
Testvar_1
$test-Var ist ungültig, da '-' verboten ist im Variabel-Namen.
Testvar_1 ist ungültig, da '$' fehlt zu Beginn des Variabel-Namens.

Variabeln einen Wert zuweisen

Um einer Variabel einen Wert zuzuweisen, wird folgendermaßen vorgegangen:
$testVar = 1 + 2
Neben dem klassischen '=' als Operator verfügt Powershell noch über 7 weitere:
OperatorDescription
=Sets the value of a variable to the specified value.
+=Increases the value of a variable by the specified value, or appends the specified value to the existing value.
-=Decreases the value of a variable by the specified value.
*=Multiplies the value of a variable by the specified value, or appends the specified value to the existing value.
/=Divides the value of a variable by the specified value.
%=Divides the value of a variable by the specified value and then assigns the remainder (modulus) to the variable.
++Increases the value of a variable, assignable property, or array element by 1.
--Decreases the value of a variable, assignable property, or array element by 1.
Beispiel-Berechnungen, die alle das selbe Ergebnis bewirken, nämlich den Wert '3':
$testVar1 = 1 + 2

$testVar2 = 1
$testVar2 += 2

$testVar3 = 4
$testVar3 -= 1

$testVar4 = 1.5
$testVar4 *= 2

$testVar5 = 6
$testVar5 /= 2

$testVar6 = 7
$testVar6 %= 4

$testVar7 = 2
$testVar7++

$testVar8 = 4
$testVar8--

Code auskommentieren / Kommentare

Code auszukommentieren ist sinnvoll, um das Skript anderen mit beschreibenden Worten verständlicher zu machen, oder um eine Funktion, die in Teilen nicht mehr ausgeführt werden soll, ignorieren zu lassen. In Powershell gibt es zwei Möglichkeiten um Code auszukommentieren.
  1. Auskommentieren des Restes einer Zeile durch das '#' Symblol.
    $testVar # Unsere Variabel
    $testVar = 1 + 2 # macht 3
  2. Auskommentieren eines ganzen Blockes durch das einschließen in '<#' am Anfang und '#>' am Ende des Blocks.
    <# Ein ganzer Block,
    der über mehrere Zeilen
    auskommentiert werden soll. #>

Array Deklarationen

Einen leeren Array erzeugen Sie folgendermaßen:
$myArray = @()
Sollen bei der Deklaration auch gleich Werte zugewiesen werden, so wird folgendermaßen vorgegangen:
$myStrings = @("Tiger","Katze","Luchs")
[int[]] $myInteger = 12,64,8,61,12
Die Beispiele zeigen, wie eine explizite Zuweisung von Werten zu einem Array generell erfolgt. Es handelt sich dabei um die Syntax, bei der man der Variabel eine kommaseparierte Liste übergibt.

Arrays befüllen, ändern, sortieren, prüfen

Einen leeren Array können Sie nachträglich noch um weitere Elemente befüllen:
$farben = @()
$farben += "Gelb"
$farben += "Orange"
$farben += "Rot"
Ein einzelner Wert eines Arrays lässt sich austauschen. Hierbei ist zu beachten, dass beim Ansprechen der Elemente eines Arrays bei 0 angefangen wird zu zählen. Nimmt man das gerade befüllte $farben-Array als Beispiel, so befindet sich an Stelle 1 die Farbe 'Orange'. Dieser soll nun durch den Wert 'Blau' ersetzt werden.:
$farben[1] = "Blau"
Aufsteigend sortieren können Sie einen Array folgendermaßen:
[int[]]$integers = 3,2,4,1,5
$integers | Sort-Object
Überprüfen, ob ein Wert in einem Array vorhanden ist (als Antwort würde in diesem Fall 'false' zurückgegeben werden):
$integers -contains 7

Case-Sensitivität in PowerShell

PowerShell behandelt Variabeln nicht Case-Sensitiv.
Das bedeutet, dass eine Variabel, die als $testVar deklariert wurde, beispielsweise auch mit $TESTvar angesprochen werden kann.

Ausgaben von Variabeln und Funktionen


Konsolen-Ausgabe einer Variabel

Um den aktuellen Wert einer Variabel auszugeben, gibt es verschiedene Möglichkeiten:
  1. Die einfachste ist die Funktion echo aka. write-output, welche direkt den Output-Stream verwendet:
    $testVar = 1 + 2
    echo $testVar
    Skript ausführen (F5) - Ausgabe:
    PS C:\Users\Home> $testVar = 1 + 2
    echo $testVar
    3
  2. Die zweite Möglichkeit ist die Funktion write-host, welche direkt zur Konsole des Clients schreibt und Formatierungs-Möglichkeiten bietet.
    Write-Host -ForegroundColor Green "Test mit grüner Schrift!"
    PS C:\Users\Home> Write-Host -ForegroundColor Green "Test mit grüner Schrift!"
    Test mit grüner Schrift!
    Trotz der Formatierungs-Möglichkeiten ist in den meisten Fällen von dieser Funktion abzusehen, da sie lediglich die .ToString() Methode des Inputs aufruft. In folge dessen, wird der Output in der CommandLine bzw PowerShell ISE dargestellt, lässt sich jedoch nach dem Schreiben des Outputs weder durch ein Redirect (z.B. in ein Text-File) noch durch eine Pipeline '|' um-/weiterleiten. Mehr dazu folgt im nächsten Abschnitt.

Umleiten einer Ausgabe

Um eine Ausgabe in eine Text-Datei zu schreiben wird das Zeichen '>' verwendet.
Beispiel:
$testVar = 1 + 2
echo $testVar > test.log
PS C:\Users\Home> $testVar = 1 + 2
echo $testVar > test.log
3
Zusätzlich zu der Ausgabe der Zahl 3 in der PowerShell ISE Console erscheint als Ergebnis in dem ausführenden Verzeichnis der PowerShell (hier 'C:\Users\Home') eine 'test.log', welche die Zahl 3 enthält.

Merke: Der selbe Befehl mit write-host statt echo erstellt nach dem darstellen der Zahl 3 in der PowerShell ISE Console lediglich eine leere 'test.log' unter 'C:\Users\Home'!!!

Output weiter 'pipen'

Um das Ergebnis eines Aufrufes weiter zu verarbeiten nutzt PowerShell das '|' Zeichen.
Für das folgende Beispiel wird die vordefinierte Funktion Get-Service verwendet.
Diese gibt eine Liste an Objekten zurück, wobei jedes Objekt einen Windows-Dienst darstellt (bekannt aus der 'services.exe').
Um diese große Liste an Objekten weiter zu verarbeiten, werden wir den Output von Get-Service an einen Filter pipen Select-Object -First 5.
echo (Get-Service | Select-Object -First 4)
PS C:\Users\Home> echo (Get-Service | Select-Object -First 4)
Status Name DisplayName
------ ---- -----------
Running AeLookupSvc Anwendungserfahrung
Stopped ALG Gatewaydienst auf Anwendungsebene
Running AudioEndpointBu... Windows-Audio-Endpunkterstellung
Running Audiosrv Windows-Audio

If-Else Blöcke und Schleifen


IF Else

In Powershell werden If-Else-Blöcke folgendermaßen verwendet:
if(Bedingung){
 # Etwas machen
}else{
 # Etwas anderes machen
}
Ein etwas konkreteres Beispiel:
$zufallsZahl = Get-Random -maximum 10

if($zufallsZahl -lt 5){
  echo ("Zahl ist < 5 (" + $zufallsZahl + ")")
}else{
  echo ("Zahl ist >= 5 (" + $zufallsZahl + ")")
}
Zufällige Beispiel-Ausgabe:
Zahl ist < 5 (3)

While Schleifen

Folgendes Beispiel einer While-Schleife führt die Wiederholung solange durch, bis die Variabel $counter nicht mehr kleiner als 5 ist.
$counter = 0
while($counter -lt 5){
  $counter++
  echo $counter
}
Ausgabe:
1
2
3
4
5

For Schleifen

Das Ergebnis der While-Schleife ist auch mit einer For-Schleife zu erreichen. Folgendes Beispiel einer For-Schleife führt die Wiederholung solange durch, bis die Variabel $i nicht mehr kleiner als 5 ist.
for ($i=1; $i -le 5; $i++) {echo $i}
Ausgabe:
1
2
3
4
5

PowerShell Beispiele


Powershell: Verbinden mit einem MSSQL Server und absenden von (z.B.: SELECT, UPDATE, DELETE oder EXEC).

function SendSQL($SqlQuery)
{
  write-host $SqlQuery
  $SQLServer = "YourServer.Full.Qualified" # Enter your Database Host / Server
  $SQLDBName = "MyDatabase" # Name of the Database
  $SqlConnection = New-Object System.Data.SqlClient.SqlConnection
  $SqlConnection.ConnectionString = "Server = $SQLServer; Database = $SQLDBName; Integrated Security = True;"
  #$SqlConnection.ConnectionString = "Server = $SQLServer; Database = $SQLDBName; User ID = $uid; Password = $pwd;"
  $SqlCmd = New-Object System.Data.SqlClient.SqlCommand
  $SqlCmd.CommandText = $SqlQuery
  $SqlCmd.Connection = $SqlConnection
  $SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
  $SqlAdapter.SelectCommand = $SqlCmd
  $DataSet = New-Object System.Data.DataSet
  $SqlAdapter.Fill($DataSet)
  $SqlConnection.Close()
  if($SqlQuery -like "Select *" -OR $SqlQuery -like "Update *"){
    return ,$DataSet #Oder direkt '.Tables[0]' #as array
  }else{
    if($SqlQuery -like "EXEC *"){
      return ,$DataSet
    }else{
      return (@())
    }
  }
}
function Main
{
  $DataSetReturner = SendSQL("SELECT * FROM tbl_Test")
  #$DataSetReturner = SendSQL("EXEC myStoredProcedure 'testString'")
  #$DataSetReturner = SendSQL("DELETE FROM tbl_Test WHERE ID = 191")
  try{
   foreach($DataRow in $DataSetReturner.Tables[0].Rows)
   {
     echo $DataRow
   }
  }catch{
    echo "Ausgabe nicht möglich. Haben Sie einen Delete ausgeführt?"
  }
}
Main

Powershell: Codesigning automatisch auf einem ganzen Ordnerinhalt ausführen

$Ordner = "C:\temp\CodeToBeSigned\"
Get-ChildItem cert:\CurrentUser\My -codesigning
$files = Get-ChildItem $Ordner
for ($i=0; $i -lt $files.Count; $i++) {
  echo $outfile = $files[$i].FullName
  Set-AuthenticodeSignature $files[$i].FullName @(Get-ChildItem cert:\CurrentUser\My -codesigning)[0]
}

Powershell: EMail-Versand

function SendMail($to, $subject, $body){
  try{
   send-mailmessage -Encoding ("UTF8") -from "MailSender " -to ($to) -subject ($subject) -body ($body) -smtpServer MailServer.domain.do
   #WEITERE PARAMETER: -Attachments "data.csv" -priority High -dno onSuccess, onFailure
  }Catch
  {
   write-host ("Fehler Bei Mail Versand: "+$error)
  }
}
function Main{
  $user = (get-aduser "TestUser" -properties mail)
  SendMail ($user.mail) ("Test Betreff") ("Guten Tag ...")
}
Main

Powershell: Umbenennen von allen Unterordnern

Get-ChildItem -Path "C:\temp" -Directory -Recurse | select-object FullName,Name | ForEach-Object -Process {
  Rename-item -Path $_.FullName -NewName ($_.Name -replace "IMG_","") -WhatIf
}

Powershell: Auflisten aller Dateien, die größer als 250kb sind

Get-ChildItem -Path "C:\temp" -File -Recurse | select-object length,FullName,Name | ForEach-Object -Process {
 if($_.length -gt 250kb){
   write-host 'Größer als 250kb - ' $_.FullName
 }
}

Impressum

Angaben gemäß § 5 TMG:

Sven-Ole Bittner
Küsterkoppel 19A
25364 Brande-Hörnerkirchen

Kontakt:
Telefon:+49 (0)172 257 67 83
E-Mail:sbittner@gmx.net

Haftungsausschluss (Disclaimer)

Haftung für Inhalte

Als Diensteanbieter sind wir gemäß § 7 Abs.1 TMG für eigene Inhalte auf diesen Seiten nach den allgemeinen Gesetzen verantwortlich. Nach §§ 8 bis 10 TMG sind wir als Diensteanbieter jedoch nicht verpflichtet, übermittelte oder gespeicherte fremde Informationen zu überwachen oder nach Umständen zu forschen, die auf eine rechtswidrige Tätigkeit hinweisen. Verpflichtungen zur Entfernung oder Sperrung der Nutzung von Informationen nach den allgemeinen Gesetzen bleiben hiervon unberührt. Eine diesbezügliche Haftung ist jedoch erst ab dem Zeitpunkt der Kenntnis einer konkreten Rechtsverletzung möglich. Bei Bekanntwerden von entsprechenden Rechtsverletzungen werden wir diese Inhalte umgehend entfernen.

Haftung für Links

Unser Angebot enthält Links zu externen Webseiten Dritter, auf deren Inhalte wir keinen Einfluss haben. Deshalb können wir für diese fremden Inhalte auch keine Gewähr übernehmen. Für die Inhalte der verlinkten Seiten ist stets der jeweilige Anbieter oder Betreiber der Seiten verantwortlich. Die verlinkten Seiten wurden zum Zeitpunkt der Verlinkung auf mögliche Rechtsverstöße überprüft. Rechtswidrige Inhalte waren zum Zeitpunkt der Verlinkung nicht erkennbar. Eine permanente inhaltliche Kontrolle der verlinkten Seiten ist jedoch ohne konkrete Anhaltspunkte einer Rechtsverletzung nicht zumutbar. Bei Bekanntwerden von Rechtsverletzungen werden wir derartige Links umgehend entfernen.

Urheberrecht

Die durch die Seitenbetreiber erstellten Inhalte und Werke auf diesen Seiten unterliegen dem deutschen Urheberrecht. Die Vervielfältigung, Bearbeitung, Verbreitung und jede Art der Verwertung außerhalb der Grenzen des Urheberrechtes bedürfen der schriftlichen Zustimmung des jeweiligen Autors bzw. Erstellers. Downloads und Kopien dieser Seite sind nur für den privaten, nicht kommerziellen Gebrauch gestattet. Soweit die Inhalte auf dieser Seite nicht vom Betreiber erstellt wurden, werden die Urheberrechte Dritter beachtet. Insbesondere werden Inhalte Dritter als solche gekennzeichnet. Sollten Sie trotzdem auf eine Urheberrechtsverletzung aufmerksam werden, bitten wir um einen entsprechenden Hinweis. Bei Bekanntwerden von Rechtsverletzungen werden wir derartige Inhalte umgehend entfernen.

 

© 2017, Sven-Ole Bittner