Windows PowerShell Tutorial

(Last Updated On: 13. April 2016)

Download und Installation der PowerShell

die Powershell wird seit Windows Vista standardmäßig auf allen Client-Rechnern und seit Windows Server 2008 auf allen Server-Betriebssystemen ausgeliefert. Auf allen Systemen, in denen die PowerShell nicht oder nicht mehr installiert ist, kann sie nachinstalliert werden. Die PowerShell steht hier zum Download bereit.cd

Erste Schritte

Startet die Windows PowerShell. Standardmäßig wird euch dann eine Kommandozeile mit blauem Hintergrund und weißer Schrift ausgeliefert. Bevor ihr startet, solltet ihr das LAyout eurer PowerShell bearbeiten. Schiebt die Powershell an den absolut linken Rand eures Monitors. Rechtsklickt dazua uf den Fenstertitel der Windows PoweRShell und wählt Eigenschaften. Dort klickt ihr auf den Reiter Layout. Ändert unter Fensterpuffergörße die Breite des powershell-Fensters so ab, dass die PowerShell bestenfalls die gesamte Breite des Bildschirms einnimmt. Stellt danach unter FEnstergröße die Breite auf den selben WErt ein. So stellt ihr sicher, dass für Ausgaben, die sehr viel Platz brauchen, auch genügend Platz vorhanden ist.

Mit dem Kommando

get-help <Thema>

könnt ihr euch Hilfe über ein bestimmtes Thema anzeigen lassen. Wenn ihr Hilfe über get-help selbst haben wollt, gebt ihr beispielsweise ein:

get-help get-help

wenn ihr hingegen Hilfe bezüglich Powershell-Kommandos haben wollt, die mit Windows-Diensten zu tun haben, gebt ihr ein

get-help services

Mit dem Parameter -online werdet ihr euch die Microsoft Knowledge Base weitergeleitet, wo ihr euch Online-Artikel zum Thema ansehen könnt.

get-help services -online

Grundsätzlich ist die PowerShell abwärtskompatibel zur alten DOS-Eingabeaufforderung, und zwar in dem Sinne, dass alle Kommandos, die unter der Windows-Eingabeaufforderung funktionieren, auhc in der PowerShell laufen. Ich gehe in diesem Tutorial davon aus, dass ihr schon einmal grundlegend mit der Windows-Eingabeaufforderung gearbeitet habt und dass euch dementsprechend Befehle wie dir, cd, echo, cls usw. schon etwas sagen.

Und das gute ist, dass Sie mit diesem kommando auch sehr einfach ein passendes Kommando für Ihren Bedarf finden können. Nehmen wir beispielsweise einmal an, Sie wollen irgendetwas mit Ihren Windows Logs machen. DAnn würden Sie einfach nach passenden Kommandos suchen über

get-help *log*

und schon bekommen Sie eine Liste mit allen PowerShell-Themen, die auf irgendeine Art und Weise mit Logs zu tun haben – inklusive Beschreibung.

Wenn Sie hingegen eine Liste mit allen Befehlen haben wollen, kölnnen Sie das Komamndo get-command, kurz gcm, nutzen

gcm -noun *log* -CommandType cmdlet

Ohne den PArameter -CommandType würdne Sie auch .ddl-Dateien etc. bekommen, was wir hier natürlich nicht wollen.

Nun fangen wir aber in den Grundlagen bereits an, die ersten cmdlets der PowerShell zu nutzen. Nehmen wir beispielsweise an, ihr wollt euch die Eigenschaften einer Datei in der Powershell anzeigen lassen. In dem FAll tippen wir einfach ein.

get-itemproperty <datei>

Wichtig zu verstehen ist hier, dass die Powershell nicht einfach so seine Ausgabe in die kommandozeile schreibt, sondenr ein Objekt erzeugt, dessen Ausgabe man manipulieren kann. DAs heißt die Powershell gibt standardmäßig die hier angezeiten Informationen über ein Objekt aus, welches mit get-itemproperty abgefragt wurde. Ihr könnt das Objekt aber an einen anderen Befehl weiterleiten und somit die Ausgabe manipulieren. Wie unter Linux geschieht dieses Weiterleiten über eine Pipe. Wir leiten unser Objekt mal an den Befehl format-list weiter.

get-itemproperty <datei> | format-list

Ihr merkt, dass nun andere informationen dargestellt. Um vollends zu verstehen, wie das mit den ganzen Objekten nun funktioniert, könnt ihr einfach mal den Befehl dir in einem Ordner eingeben. Für jede Datei, die das kommando dir ausgibt, wird ein extra Objekt erzeugt, welche ihr gebündelt an andere Kommandos weiterleiten und prozessieren lassen könnt. Beispielsweise

dir | get-itemproperty | format-list

Ziemlich cool, oder? Vielleicht habt ihr jetzt schon eine Idee davon bekommen, warum die Powershell so mächtig ist, nämlich, weil man jetzt sozusagen objektorientiert Skripten kann.

Kennt ihr noch das Konzept aus alten Tagen, wo ihr die Ausgabe der Windows-Eingabeaufforderung nach einem Befehl über > in eine Datei umgeleitet habt? Natürlich würde diese Variante auhc noch über die Powershell gehen, denn diese ist ja abwärtskompatibel. Jedoch macht es durchaus Sinn, auch hier wieder objektorientiert zu arbeiten. Deswegen hat die Powershell hierfür einen extra Befehl, out-file. Der folgende Bvefehl gibt die Ausgabe des oberen Befehls in eine Datei test.txt aus.

dir | get-itemproperty | format-list | out-file test.txt

Beispielsweise gibt es verschiedene out-Kommands, auf die man die Ausgabe eines ovrangehenden Befehls pipen kann, beispielsweise dir | out-gridview zeigt die Ergebnisse in einem extra Windows-Fenster im Tabellen-Layout an.

get-service | export-csv c:\services.csv

erstellt eine .csv-Datei. HIngegen exportiert

 get-service | export clixml c:\services.xml

eine saubere .xml-Datei. Und mit

get-service | convertto-html

konvertiert die Asugabe in eine HTML-TAbelle. Wenn Sie diese Ausgbae in eine .html-Datei speichern wollen, müssen Sie den Befehl noch auf out-file pipen

get-service | convertto-html | out-file services.html

wenn ihr die Ausgabe eines befehls an einen anderen Befehl piped, muss der nächste befehl irgendwie wissen, welchen Parameter ihr mit dieser Pipe befüllen wollt. Standardmäßig versucht die Powershell über die sogenannte By-Value methode herauszufinden, welcher PArameter des nächsten Kommandos mit der Ausgabe des Vorgängers arbeiten soll. Wenn ihr beispielsweise folgendes kommando absetzt.

get-service | stop-service

dann wird dies nicht funktionieren. Warum ist das so? nun, wenn ihr euch den Befehl get-service anseht über

get-service | gm

Dann seht ihr in der ersten Zeile den sogenannten TypeName. Das ist der Typ des ausgabeobjekts, den der befehl get-service erzeugt. Also den Typ ServiceController.

Jetzt schauen wir uns den befehl stop-serivce an über

help stop-service -full

2016-04-10_13h55_38

Dabei stellt ihr fest, dass stop-service standardmäßig den Parameter -Name (1) erwartet und somit von einem einfachen String ausgeht.  der Befehl get-service erzeug tallerdings einen serviceController, der mit dem PAremater -InputObject angesprochen werden muss (2). Dieser wird allerdings stnadarmdäßig nicht genommen, sondern stop-service erwartet das piping eines strings für den Parameter -Name.

eine andere Mtehode ist die Ausgabe des ersten Kommandos nicht by-Value, sondern by-PropertyName pipen. Dazu müsst ihr erst in der vollen Hilfe des zweiten komandos nach Paramtern suchen, die Pipeline-Input byPropertyName unterstützen. Und das unterstützt unser Parameter -Name zufälligerweise

2016-04-10_16h20_11

Wenn wir uns jetzt nochmal  get-service | gm anschauen, sehen wir, dass get-service eine AliasProperty namens Name hat. Und diese AliasProperty Name wiederum können wir nun an den Parameter -Name des Nachfolgekommandos, nämlich stop-service, pipen. Das ganze geht dann so.

get-service | select -ExpandProperty Name | stop-service

Wir wählen also aus der Ausgabe von get-service nur die Eigenschaft Name aus und pipen diese Eigenschaft Name an das cmdlet stop-service, dessen Parameter -Name wiederum den input byPropertyName akzeptiert und daher den relevanten Service stoppt. Für das cmdlet select gäbe es auch den Paramater -Property, aber manchmal kommt mit -Property eine Eigenscahft immer noch als Objekt raus und nicht als String, wie wir es in diesem Fall gebraucht hätten.

Manchmal kommt es vor, dass ein Kommando mehr Spalten ausigbt als auf den Bidlschirm passen. Also gibt es Dateine in der Powerhsell, die bestimmen, welche Spalten eines Befehls standarmdäßig ausgegeben werdne sollen. Der Befehl get-service beispielweise gibt nur drei Spatlen aus. Es ist aber möglihc, noch wesentlich mehr Spalten auszugeben. Diese findet man heraus über

get-service | get-member

Der Befhel listet alle Spalten, die man explizit einblenden kann,. (vom Typ Property, AliasProperty oder scriptProperty). Andere Datensätze sind beispielsweise vom Typ Method oder Event, die nicht explizitr eingeblendet werden können.

Stattdessen kann man aber mit Events „Befehle“ auf Objekte absetzen, die man zuvor über ein anderes cmdlet gesammelt hat. Wenn wir also beispielsweise über get-service eine Liste aller Dienste gesammelt haben, können wir alle Dienste auf einmal über das event Start starten.

get-service Start

Auch sortieren können wir ganz einfach über die powershell nach diesen spalten. Wenn wir get-service pipen auf get-member, finden wir beispielsweise die Spalte „threads“ als eine der Properties. Und nach dieser Property können wir soriteren.

get-service | sort threads

mit dem Paremter -Ascending oder -Descending kann man die Reihenfolge der Sortierung beeinflussen

get-service | sort threads -Descending

jetzt nehmen wir mal an, wir wollen nur die dienste haben, die laufen (Status RUNNING) und deren Namen die Zeichenkette „SQL“ enthält. So finden wir unter umständen alle laufenden Datenbank-Prozesse

get-service | where-object -FilterScript { $_.Status -eq 'Running' -and $_.Name -like '*SQL*'}

Hierbei durchsuchen wir also die Properties Status und Name der Ausgabe von get-service.

hierbie könnt ihr verschiedene Vergleichsoperatoren wählen wie beispielsweise

  • eq – gleich
  • ceq – case sensitive gleich
  • like – ist wie zeichenkette
  • lt – kleiner als
  • gt – größer als

Input Pipelining

über select

Jetzt mal ein etwas fortgeschritteneres Beispiel. Nehmen wir mal an, ihr lasst euch mit dem Kommando

get-adcomputer -filter *

Infomrationen über die gepflegten „computer“ im Active Directory anzeigen, an denen sich Benutzer anmelden können. Dazu filtert ihr mit * nach allen Computern im Active Directory.

Ihr bekommt einen output und in der Spalte „Name“ findet ihr die Computernamen der einzelnen computer, die im Active Directory für diese Computer hinterlegt sind.

Was ist jetzt, wenn ihr für all diese ComputerNamen bestimmt informationen abfragen wollt, beispielsweise, ihr wollte euch die PRozesse aller Computer anzeigen lassen, die im Active Directory registriert sind und die gerade laufen. Somit könn tihr beispielsweise feststellen, auf welchem Server ein bestimmter Dienst läuft, wenn ihr euch nicht mehr dran erinnern könnt.

dazu müsstet ihr normalerweise das kommando

get-process -ComputerName <ComputerName>

eingeben, um alle Prozesse dieses speziellen Computers zu bekommen. Dabei müsstet ihr jetzt für jeden einzelnen Computer den computerNamen raussuchen und diesen jeweils hier eintippen.

Das ganze geht aber natürlich einfacher. mit folgendem Kommando lesen wir die spalte name aus der ausgabe des kommandos get-adcomputer aus und speichern diese als Parameter ‚computername‘. Diesen Parmeter ‚computername‘ pipen wir dann an das kommando get-process. Denn get-process besitzt einen Parameter -ComputerName, der die Prozesse des genannten Computers auflistet. Da in unserer Abfrage aber die Computernamen aller computer im Active Directory als Objekt referenziert sind, bekommen wir gleich die Prozesse aller computer eine nach dem anderen ausgegeben.

get-adcomputer -filter * | select @{n='computername';e={$_.name}} | get-process

über .csv-Datei

ihr könnt auch die Parameter eines kommandos über eine .csv-datei füttern. Beispielsweise könntet ihr vor haben, in euem Active directory eine Reihe neuer User anzulegen, die zum Monatsanfang in eurem Unternehmen beginnen. Dazu könnt ihr in der PowerShell für jeden neuen mitarbeiter eine Kommandozeile mit dem Befehl new-aduser anlegen. Die entsprehcenden Parameter des Befehls new-aduser könnt ihr euch wieder über die hilfe ausgeben lassen.

statt jedoch für jeden neuen mitarbeiter eine extra Zeile anzufertigen, könnt ihr auch die Daten der Mitarbeiter in eine .csv-datei speichern. Die .csv-Datei hätte hierbei folgendes format

samaccountname,name,department,title,city
<AD-Accountname Mitarbeiter 1>,<Echter Mitarbeitername Mitarbeiter 1>,<Abteilung Mitarbeiter 1>,<Position Mitarbeiter 1>,<standort Mitarbeiter 1>
<AD-Accountname Mitarbeiter 2>,<Echter Mitarbeitername Mitarbeiter 2>,<Abteilung Mitarbeiter 2>,<Position Mitarbeiter 2>,<standort Mitarbeiter 2>

Wichtig ist, dass die Namen der Attribute in der ersten Zeile samaccount, name, department etc. genau so heißenwie die Parameter des Kommandos new-aduser, was hier der fall ist.

Die übergeben wir dann an den PArameter new-aduser

import-csv neue-mitarbeiter.csv | select samaccountname,name,department,title,city | new-aduser

Ist dem nicht der fall, weil ihr beispielswiese von der Personalabteilung eures unternehmens eine falsch formatierte .csv-Datei bekommen habt, wo die erste Spalte beispielsweise so formatiert ist.

Kontoname,name,department,title,city
<AD-Accountname Mitarbeiter 1>,<Echter Mitarbeitername Mitarbeiter 1>,<Abteilung Mitarbeiter 1>,<Position Mitarbeiter 1>,<standort Mitarbeiter 1>
<AD-Accountname Mitarbeiter 2>,<Echter Mitarbeitername Mitarbeiter 2>,<Abteilung Mitarbeiter 2>,<Position Mitarbeiter 2>,<standort Mitarbeiter 2>

dann könnt ihr diese falsch formatierte Zeile so  umbiegen

import-csv neue-mitarbeiter.csv | select @{n='samaccountname',e={$_.'Kontoname'}},<restliche Parameter>

Seine richtige MAcht entfaltet die Powershell, wie die Linux-Shell auch, wenn man Skripte damit schreibt. Powershell-Skripte werden mit der Dateinendung .ps1 gespeichert und ermöglichen es, dass dieses Skirpt dann von der PowerShell von oben nach unten prozessiert wird.

Die Powershell unterstützt das sogenannte Code-Signing, das heißt mit der Powershell ist es möglich, skripte mit Zertifikaten zu versehen. Dies soll verhindern, dass Skripte von fremdne ausgeführt werden, die unlautere Absichten hegen. Ihr werdet daher feststellen, dass ihr in einer Windows-Standardinstallation zunächst einmal keine .ps1-Skripte ausführen könnt, wenn die Sicherheitseinstellungen entsprechend gesetzt sind. Mit folgendem Befehl könnt ihr als Administrator die Sicherhehitseinstellungen so lockern, dass ihr eure eigenen Skripte ausführen könnt, aber nicht die von Fremden.

set-executionpolicy remotesigned

diese lokale Eisntellung kann durch eine Gruppenrichtlinie überschrieben werden.

Domain -> Default Domain Policy -> Edit -> Computer Configuration -> Policies  -> Amdinsitrative Templates -> Windows Components -> Windows Powershell -> Turn on Script Execution.

Ein weiteres Feature von PowerShell ist, dass man Powershell-Skripte mit einem Zertifikat signieren kann. Davon profitieren vor allem Unternehmen, die bereits eine interne Public Key infrastrcuture (PKI )aufgebaut haben und daher Zertifikate ausstellen könne,n mdenen firmenintern vertraut wird.

Zur Not kann man auch sogenannte self-sgine certificates erstellen, so dass man Skripte zumindest mit einem selbsterstellten Zertifikat signieren kann.

 

formatieren

format-wide

 

PowerShell INtegrated Scripting Environment

Grundsätzlich könnt ihr Powershell-Skripte mit einem ganz normalen TExteditor schrieben. Es empfiehlt sich jedoch, hierfür stattdessen die Windows Powershell ISE zu verwenden.

2016-02-11_11h50_37

 

Variablen

einzelne Werte, aber auch die OBjekte, die ein kommando zurückliefert, können wir in einer Variablen speichern.

Einfache WErte können ganz einfach in Variablen hinterlegt werden

$Text = "Dies ist ein Text"

Der Befehl hinterlegt Dies ist ein Text in der variable $Text. Ausgeben könnt ihr euch den WErt dieser Variablen über die PowerShell dann mittels

Write-Host "$Text"

Viel mehr Sinn macht es allerdings, Objekte in Variablen zu speichern. Beispielsweise könnt ihr so ganz einfach alle Objekte in eine Variable speichern, die das Kommando dir zurückliefert:

$alleDateienInVerzeichnis = dir

Ihr seht also, ihr schreibt hinter dem Variablennamen einfach den Befehl, den ihr ausführen wollt. Die Powershell führt ihn aus und speichert dann alle Objekte in der Variablen $alleDateienInVerzeichnis.

Diese Objekte können wir dann beipsielsweise wieder für get-itemproperty nutzen.

get-itemproperty $alleDateienInVerzeichnis

Ihr könnt in eurem Skript aber auch den User darum bitten, einen Wert einzugeben, der dann in einer Variable gespeichert wird

$name = Read-Host "Wie heißen Sie?"

Das cmdlet Read-Host stellt also dem User die Frage Wie heißen Sie?, woraufhin der User einen Namen eingeben kann, der dann in der Variable gespeichert wird.

Wir können eine Variable auch über ein Eingabefeld einlesen lassen. Sie können beispielsweise einfach mal folgenden Code ausprobieren.

OS>[system.reflection.assembly]::loadwithpartialname('Microsoft.VisualBasic') | Out-Null
OS>$computername = [Microosft.Visualbasic.interaction]::inputbox('Geben Sie einen Namen ein','Frage Titel','Standard-Vorschlag')

 

Alle Variablen sind im PSDrive varaible: aufgelsitet.

Eine VAriable lässt sich mit dem cmdlet REmove-Variable -name ersetzen. Hierbei darf man jedoch nicht die Variable mit dem Dolalrzeichen ansprehcen, sondern man gibt nur den Namen der Varibale an. Um also die VAriable $a zu löschen, gibt man ein

Remove-Variable -name a

natürlich kann man die ausgbae von Befehlen inv Ariablen speichern. das folgende Kommando liest in die Variable services alle gepflegten Windows-Dienste auf dme Systme ein.

$services = get-service

Es können VAriablen mit lEerzeicehn im Namen gesetzt werde, wobei man jedoch folgende syntax verwendne muss

${Alle Services} = get-service

Beim Blegen von Variablen mit String-WErten ist darauf zu achten, dass bei einfachen Anführungszeichen ein $<Name> nicht als VAriable behandelt wird, bei doppelten Anführungszeichen hingegen schon

$x = 'Welt'
$y = 'Hallo $x'
$z = "Hallo $x"
OS>$y
Hallo $x
OS>$z
Hallo Welt

Hallo $x

Aus der Programmierung kennt man vielleicht den VAriablentyp von Arrays, der es erlaubt, mehrere Werte in einer einzigen VAriable zu hinterlegen. Jedes cmdlet, welches mehrere OBjekte erzeugt, legt seine Objekte in einem ARray ab, wenn man die Ausgabe des cmdlets in eine Variable speichert. Beispielsweise gibt

$services = get-service

ein Array zurück. Auf  die ersten zwei SErvices in der liste greift man dann etwa zu über

$services[0]
$services[1]

Parameter übergeben

Wie schon beim Linux Shell Skripting könt ihr auch PArameter an ein Skript übergeben. Beispielsweise könntet ihr an den Anfang eines Skriptes schrieben

param (
$hostname = 'localhost'
)

Wenn jetzt jemand  das Powershell-Skript ausführt, ohne etwas dahinter einzgueben, wird der Stnadardwert localhost verwendet. Ansonsten kann jemand mit

<Pfad zur skriptdatei> -hostname meinhostname

jetzt wird das skript mit dem Wert meinhostname für den Parameter hostname ausgeführt.

KOmmentare

Wie auch bei Batch-Skripten könnt ihr mit PowerShell ganz einfach Kommentare schrieben. Neben den Kommentaren, die mit — eingeleitet werden, die wir schon aus Batch kennen

--dies ist ein Kommentar

können wir auch mehrzielige Kommenatre schreiben.

<#
dies ist ein 
mehrzeiliger
Kommentar
#>

 

Sortieren

Die Asugbae eines Befehls lässt sich sortieren.

Escape Zeichen

Aus verschiedenen Progrmamiersprahcen kennt ihr vielleicht Escape-Zeichen wie \n, \t usw., die es ermöglichen, in die Ausgabe eines befehls einen TAbstopp oder ienen Zeilenumbruch o. Ä. einzufügen.

Auch die Powershell bietet solche Zeichen, sie werden jedoch nicht mit einem Backslash, sondern mit einem ` eingeleitet. Mehr ifnormationen findet ihr über help about_escape_characters

Verzweigungen

if

Eine If-Verzweigung ermöglicht es, eine Aktion auszuführen, wenn eine bestimmte Bedingung eintritt, und auch untershciedliche Aktionen auszuführen, wenn unterschiedliche Bedingungen zutreffen. Die if-Verzweigung prüft, ob die jeweiligen Bedingungen erfüllt werden und die PoweRShell verhält sich dann entsprechend.

Beispielsweise können Sie prüfen, ob eine Datei existiert, bevor Sie überhaupt versuchen, diese zu löschen

$dateiname = test.txt
if (test-path $dateiname) {
 del $dateiname
}

Die if-Verweigung prüft, ob es im aktuellen Ordner eine Datei test.txt gibt, und falls ja, wird diese gelöscht. Trifft die Bedingung nicht zu, springt das Skript an das Ende der geschlossenen geschweiften Klammer } und würde danach weiter machen, ohne den Inhalt der if-Verzweigung auszuführen.

switch

switch eignet sich dafür, wenn man für eine einzige Variable viele verschiedene Fälle unterscheiden möchte

switch ($variable) {
 'wert1' {     
Befehle für Wert 1
break
 }
'wert2' {
Befehle für Wert 2
break
}
default {
 Standardbefehle
}
}

 

Schleifen

foreach

Jetzt da wir aus dem oberen Kapitel wissen, wie man mehrere Objekte in einer Variablen speichert, kommt die foreach-Schleife ziemlich handy. Nehmen wir beispielswiese mla an, ihr wollt von jeder Datei ine ienm Verzeichnis die Eigenschaften aus dem Befehl get-itemproperty in einer extra Datei haben.

$alleDateienInVerzeichnis = dir
foreach ($datei in $alleDateienInVerzeichnis) {
  $infofile = $datei.name + ".info"
  get-itemproperty $datei | format-list | out-file $infofile
}

Diese foreach-Schleife geht jedes Objekt, welches in der Varible $alleDateienInVerzeichnis liegt, einzeln durch und speichert das aktuelle OBjekt in der Variable $datei. Von diesem OBjekt wird die Egienschaft .name, also der Dateinamen, genommen und mit der Dateiendung .info in die Variable $infofile gespeichert.

Danach wird vom aktuellen Objekt noch die Eigenschaftenliste über get-itemproperty | format list geholt und dies dann in eine Datei gespecihert, die den Dateinamen aus der Variable $infofile bekommt.

for

Auch diese Art der Schleife kennen wir bereits aus dem Linux Shell Skritp Tutorial. Die folgende Schliefe zählt von 0-9 hoch und gibt in jedem Schleifendurchlauf die aktuelel Zahl wieder.

for ($i=0; $i -lt 10; $i++) {
  write-host $i
}

PSDrives: Registry und Zertifikate wie ein Dateisystem behandeln

Die Windows PowerShell führt das Knzept der Power Shell Drives (PSDrives) ein, mit denen es beispielsweise die Möglichkeit bietet, die Windows Registry so zu navgiieren, als wäre es ein Dateisystem auf einer Festplattenpartition. Über

cd HKCKU:

kommen Sie beispielsweise in den Registry-Knoten HKEY_CURRENT_USER, über HKLM zum Zweig HKEY_LOCAL_MACHINE.

Somit können Sie die Windows Registry auf die gleiche Art und Weise manipulieren. wie lokale Systemdateien

Nicht nur die Registry, sondenr auch lokal installierte Zertifikate, beispielsweise zur SSL- oder TLS-Kommunikation, lassen sich erforschen. Dazu wechseln Sie in das PSdrive cert:.

Alle verfügbaren psdrives können Sie sich einzeigen lassen über

get-psdrive

Sie können auch seösbt ein neues PSDrive erstellen. So können Sie beispielsweise ein Dateisystem mit einem benannten PSDrive mounten statt mit einem langweiligen LAufwerksbuchstaben.

New-PSDrive -name meinOrdner -PSProvider -Root c:\Ordner

Nach diesem Befehl können wir mit dem kommando

cd meinOrdner:

in dieses Dateisystem wechseln, statt den ursprügnlichen Weg über c:\Ordner zu gehen. Bewusst muss euch natürlich sein, dass ihr dieses LAufwerk nur innerhlab von PoweRshell ansteuern könnt. Alle anderen Windows-Programme werden diesen Mechanismus nicht beherrschen.

Neben DAteisystemen kann man auch beispielsweise UNC-Pfade, Registry-Pfade usw. mounten.

CommonParameters

Wenn Sie vorher mit der cmd.exe oder mit der Linux Shell gearbeitet haben, wissen Sie, dass jedes Kommando seinen eigenen SAtz an PArametern hat. Unter Linux können Sie beispielsweise die Unterordner eines Ordners mit dem Befhel cp -R kopieren. Dabei können Sie aber nicht automatisch erwarten, dass der Befehl zum Ausschneiden/Verschieben, mv, ebenfalls einen Parameter -R hat (hat er nämlich nicht).

Unter PowerShell ist das zumindest zum TEil anders. Denn jeder, und damit wirklich jeder, Powershell-Befehl hat einen SAtz von sogenannten CommonParameters, die für jeden Powershell-Befehl gelten.

Eine Liste aller CommonParmeters bekommt ihr über

get-help about_CommonParameters

Die Hilfe listet Ihnen, was die einzlenen CommonParameters tun, daher lohnt es sich durchaus, sich diese einmal durchzulesen.

Die wichtigsten Befehle

In dieser Überschrift zeige ich Ihnen die wichtigsten Befehle, die Sie am häufigsten mit der Windows PowerShell brauchen werden.

Wenn Sie sich den Inhalt von Textdokumenten anzeigen lassen wollen, können Sie das Kommando

gc <Datei>

verwenden.

Wenn Sie zwei Versionen einer Datei miteinander vergleichen wollen – das Linux-Äquivalent wäre das kommando diff – können Sie Compare-Object verwenden.

Compare-Object -ReferenceObject (import-clixml c:\alt.xml) -DifferenceObject (C:\neu.xml)

Man kann auch beispielsweise ein altes kommando, welches mit  als .xml exportiert wurde, mit der aktuellen Ausgabe eins Kommandos verlgeichen

Compare-Object -ReferenceObject (import-clixml c:\processes-alt.xml) -DifferenceObject (get-process)

Und man kann sogar nur eine bestimmte Eigenschaft eines solchen Ausgabebefehls, der seine Ausgabe in Tabellenstruktur ausgibt, vergleichen.

Compare-Object -ReferenceObject (import-clixml c:\processes-alt.xml) -DifferenceObject (get-process) -property Name

der Befehl vergleicht nur den PArameter Name.

PoweRshell-Skripte anderer USer

Unter powerhell.com/cs/media können Sie sich Funktionen und Skritpe anderer User herunterladen, um IHre Bibliothek zu erweitern.

PowerShell-Snapins und Module

die Powershell ermöglicht das LAden von Modulen. Eine Lsite aller verfügbaren MOdule kriegt man über

get-module -ListAvailable

Hierbei ist zu unterscheiden zwischen der32- und 64-Bit-Powershell. für die 64-Bit-Powershell werden mehr module verfügbar sein als für die 32-bit-Version.

Ein modul lässt sich dann in der PoweRshell laden über

import-module <Name>

dancah können wir uns die Kommandos anzeigen lassen, die mit dem Modul dazu gekommen sind

get-command -module <name>

Das ist besonders nützlich, weil es für viele Administratoinstools unter Windows extra Module für die Powershell gibt, etwa den Gruppenrichjtlinieneditor oder das Acitve Directory.

Man kann die Funktioanlitäten der Powershell mit Snapins erweitern. Eine Liste aller verfügbaren Snapins kriegt man über

Get-PSSnapin -regtistered

Will man solch ein Snapin in der aktuellen PoweRshell-Sessoin nut6zen, muss man dieses Snappin erst hinzufügen

Add-PSSnapin <name Snapin>

Nun könnt ihr euch ansehen, welche KOmmandos das Snapin zur Powershell hinzufügt

get-command -pssnapin <name Snapin>

Powershell-Profile

Unter Linux kann man verschiedene Kommandos automatisch ausführen lassen, wenn sich der Rechner neu startet oder sich beispielsweise ein User anmeldet. Dafür igbt es verschiedene Standardskripts ide unter vordefinierten Verzeichnissen liegen, beispielweise ~/.profile für eine Useranmeldung oder die Skripte unter /etc/rc<runlevel>.d für einen Neustart.

Wenn ihr wollt, dass beim STarten von Powershell verschiedene Komamndos automatishc ausgeführt werden, dann müsst ihr ein Powershell-Profil erstellen. DAs erstellt ihr unter dem Documents-Verzeichnis des Users, also beispielsweise C:\users\<meinuser>\documents\. Dort erstellen wir einen Ordner WindowsPowerShell und darin eine Datei profile.ps1

In dieses Profil  könnt ihr nun Powershell-Kommandos ausführen, die bei jedem STart der Powershell automatisch ausgeführt werden sollen, eintippen und das Skript speichern. Ihr könnt nun beim nächsten Start der PowerShell eventuell eine Fehlermeldung bekommen, dass die ExecutionPolicy die Ausführng des Skripts nicht erlaubt. Diesen behebt ihr mti dem Kommando

set-executionpolicy remotesigned

im elevated Mode.

Ergebnisse von SQL-Statements in eine Datei exportieren

Viele kommandozeilen-Utilities von Datenbankmanagementsystemen unterstützten nicht die Umleitung der Befehlsausgabe in eine Datei über die gewohnten maßnhamen. Wenn Sie beispielsweise mit dem kommandozeilentool slqcmd auf einer MS SQL Server Datenbank sind und versuchen über

SELECT * FROM qs3.DDXTT~ > c:\users\qs3adm\desktop\ddxtt.txt

den inhalt der tabelle DDXTT~ in der Datenbankinstanz qs3 in eine Datei auszugeben, werden sie auf Granit beißen.

Das kommandozeilentool isql von Sybase ASE hingegen erlaubt  zwar eine eingebaute Maßnahme die Ausgbae in eine Datei im format

1>select * from qs3.DDXTT~
2>go > c:\users\qs3adm\desktop\ddxtt.txt

und mysql kennt INTO OUTFILE

MySQL>select * form DDXTT~
MySQL>INTO OUTFILE '<dateipfad>';

das war es aber auch schon.  Diese Möglichkeit ist in isql und mysql von den Programmieren eingebaut worden. Sie können deshalb leider beispielsweise die Ausgabe nicht über die Powershell pipen, etwa so

1>select * from qs3.DDXTT~
2>go | out-gridview

Um diese Schwächen der kommandozeilen-Tools diverser Datenbanken zu umgehen, gibt es verschiedene MÖglihckeiten. Zum einen liefern viele Datenbankmanagementsysteme eigene, dedizierte Tools mit, die den Inhalt von Tabellen in eine Datei exportieren. Sowohl isql als auch sqlcmd beispielsweise nutzen hierfür ein Tool namens bcp

bcp "SELECT Col1,Col2,Col3 FROM MyDatabase.dbo.MyTable" queryout "D:\MyTable.csv" -c -t , -S SERVERNAME -T

Jedoch können Sie jedoch

  1. nicht immer darauf verlassen, dass ein DBMS ein solcehs Tool mitliefert
  2. mit diesem Tool die ausgabe zwar in eine Datei exportieren, aber immer noch nicht an andere powershell-Kommandos pipen, wie etwa an out-gridview

manchmal unterstützen die command line utilities das Pipen, wenn man die Utilities auf PoweRshell-ebene aufruft und das entsprechende SQL-Statement hinten anhängt, also etwa

Powershell>SQLCMD -S <servername> -E -Q "SELECT Col1,Col2,Col3 FROM MyDatabase.dbo.MyTable"
-s "," | out-gridview

Das funktioniert jetdoch auch nicht immer.

Powerhsell-Befehle im Hintergrund ausführen

Normalerweise müsst ihr in der powoerhsell warten, bis ein kommadno fertig ist, bevor ihr einen neuen eingeben könnt. Manche befehle laufen aber etwas länger, sodass ihr normalerweise ein zweites powershell fenster aufmachen müsstet.

stattdessen könnt ihr ein powershell skript im hintergurnd als job ausführen

start-job -command { <kommando> }

solange der job läuft, könnt ihr euch seinen status einzeigen lassen über

get-job

 

Remoting

remoting bezeichnet die Funktion von Powershell, eine Powershell-Kommandozeile nicht nur lokal auf dem eigenen rechner, sondern auch auf einem entfernten Rechner auszuführen, auf dem die Powershell ebenfalls installiert ist.

damit das geht, muss remoting erstmal aktiviert werden. Remoting muss nur auf den Rechnern aktiviert werden, wleche Befehle vona nderen Rechnern empfangen sollen. Die Senderseite muss also nicht extra aktiivert werden. Auf der Empfängerseite geben wir ienfach ein

enable-psremoting

In Enterprise-Umgebungen gehört natürlich mehr dazu. Hierfür müssen dann nämlich Gruppenrichtlinien gesetzt werden.

Das ganze geht über

invoke-command -computer <ip adresse oder hostname entfernter computer> -ScriptBlock { <Kommandozeilen die ausgeführt werden sollen>  }

Die Funktionalität kann auch 1-to-many genutzt werden. Man kann also mit einer einzigen Powershell mehrere remote-rechner fernsteuern.

invoke-command -computer rechner1,rechner2 -ScriptBlock { <komamndos> }

Diese Art des Remotings sendet ein kommando an die rechenr, die im Parmater -computer angegeben werden, und schickt ide ausgabe dieser befehle zurück an die Powershell auf dem eigenen Rechner.

die andere Art, Remoting zu nutzen, ist, sich auf einen anderen server aufzuschalten, um auf diesem Server explizit ein- und ausgabe auszuführen. Dieser modus ist dann vergleich mit einer SSh-Verbindung auf einen Linux/Unix-server. Man verbindet isch auf den Host über

new-pssesssion -ComputerName <hoistname oder ip>

Diese Art des Remoting wird ganz häufig genutzt, wenn man einen Windows Server-rechner mit der core-Option installiert hat, also der Windows Server keine grafische Oberfläche besitzt. Hierüfr muss man sich jedoch häufig mit anderen Anmeldeinfomrationen anmelden. denn der benutzer, der sich auf den entfernen Rechner aufschalten möchte, braucht dazu entsprechende rechte. Will man sich nun mit dem Windows-Benutzerkonto des Systemadministrators des Servers anmelden, gibt man diese Informationen mit dem Parameter -Credential an.

Die remote Session kann man wieder beenden über

exit-psssession

Invoke-commands auf entfernte computer können auch im Hintergrund als Job ausgeführt werdend, sodass man nicht warten muss, bis diese Kommandos ausgeführt sind, bevor man auf der powershell weiterarbeiten kann

invoke-command -computer <hostname> -ScriptBlock {<kommandos> } -asjob -jobname <name>

wir können mehrere Sessions in einer Variable speichern

$sessions = enter-pssesssion -Computername computer1,computer2

$sessions ist hierbei ein Arary. In eine einzelne Session können wir dann  rein über

enter-pssesssion  -session $sessions[0]

Eigene Funktionen

wie schon im shell-Skripting Tutorial werden wir auch mit der Powershell eigene Funktionen schreiben. Die Grundstruktur ist

function MeineFunktoin {
 param (
  $parameter1 = 'Standardwert1',
  $parameter2 = 'Standardwert2'
)
Befehl1
Befehl2
}

Es ist in Powershell sogar möglich, Funktionen zu laden, damit man diese dann nicht nur in einem Skript, sondern auch im interaktiven modus, wenn man quasi die Powershell selber geöffnet hat, nutzen kann. Dazu schreibt ihr ein Skript mit der funktion und ladet die darin definierten Funktionen über

. .\<pfad zum Skript>

damit sind die im Skript befindlichen funktionen nun in eurer PowerShell-Umgebung und ihr könnt die Funktionen interaktiv nutzen.

Ein häfuiger Awnendungsfall einer Funktion ist, dass am Ende der funktion etwas ausgegeben werden soll. Dies erzielt man etwa so

function MeineFunktoin {

$variable1 = irgendeinwert
Befehle, die varaiable1 manipuulieren

Write-Output $variable1
}

MeineFunktion | ConvertTo-HTML | Out-File ergebnis.html

Diese Ausgabes Skript schriebt den Wert der $variable1 in die kommandozeile, konvertiert dieses ins .html-Format und schreibt dann eine DAtie ergebnis.html

Try Cath, ErrorVairable und Trap

Wie beim Shell Skritping gibt es auch in der Powershell einen Try-Catch-Block.

Skritpe können in verschiedene Fehler laufen. Damit unser Skript nicht einfach abbricht, wenn eine bestimmte Fehleristuation eintritt, sondern wir aktiv im Skript etwas dagegen tun können, wollen wir Fehlersituationen abfangen und behandeln.

In einem try-Block schrieben wir die Befehle rein, die wir ausführen wollen.

try {
 Befehl1
Befehl2
}

In einem catch-Block schreiben wir dann rein, was passieren soll, wenn einer der im try-Block stehenden Befehle einen Fehler verursacht

try {
Befehl 1
Befehl 2
}

catch {
Gegenmaßnahme 1
Gegenmaßnahme 2
}

Manche Fehler von Befehlen können nicht standardmäßig „gecacht“ werden. DAs heißt einige Powershell-cmdlets sind standarmdäßig so konfiguriert, dass ihre Fehler nur „hinweise“ sind. ein try-catch-Block kann aber nur solche Fehler abfangen, die zum Stoppen des cmdlets führen würden (sogenannte terminating errors). Wenn euer try-catch-Block nicht funktioniert, obwohl euer Skript fehler wirft, habt ihr vermutlich so ein cmdlet vor euch liegen. Ihr könnt jedoch das Verhalten eines Befehls ändern, indem ihr dem Befehl den APrameter –erroraction STop mitgebt. jedes cmdlet hat diesen Parameter und wenn dieser auf Stop gesetzt ist, würde das Skript anhalten und der Fehler fällt somit in den try-catch-Block mit rein.

Nun fragt ihr euch vielleicht, dass diese Art der Behandlung von Fehleranalyse noch sehr grob ist, weil ihr noch nicht untershcieden könnt,w elche Art von Fehler aufgetereten ist. Ein Backup-:Skritp beispielsweise kann auf viele verschiedene Arten fehl schlagen.  Etwa weil der Festplattenspeicher voll ist , keine Schreibrechte vorhanden sind oider das zu sichernde File schlciht und einfach nicht vorhanden ist.

Viele cmdlets erlauben eine Unterscheidung verschiedener Fehlerkategorien anhand der error codes, die sie schmeißen, wenn etwas schief läuft. Viele cmdlets schmeißen bei unterschiedlcihe error codes, je nachdem, was die URsache für ihr scheitern war.

Wie unter Linux könnt ihr von jedem cmdlet den Fehlercode auslesen. Dazu müsst ihr bei dem cmdlet, welches ihr ausführt, den APramteer –errorvariable mitgeben. Diesem PArameter gebt ihr den Namen einer Variable mit, in welcher der Error Code des cmdlets hinterlegt werden soll. Da ein cmdlet mehrere Fehler auf einmal produzieren kann, ist diese error Variable immer ein Array, welches mehrere Fehlermeldungen aufnehmen kann. Das heißt, wenn wir folgenden Block schreiben

try {
Befehl1 --errorvariable fehlercode
}
catch {
Write-Host $fehlercode[0]
}

dann ist $fehlercode[0] der erste Fehlercode im array $fehlercode, welches durchaus noch weitere Fehlercodes enthalten kann.

Das bedeutet nun, dass ihr in eurem catch-Block das array nach seiner Länge analysieren könnt, um festzustellen, wie viele Fehlermeldungen im Array drin sind, und dann könnt ihr schauen, welche fehler codes genau aufgetreten sind. Mit einer if-Verzweigung beispielsweise könnt ihr dann verschiedene Gegenmaßnahmen einleiten, je nachdem, welche Fehlercodes aufgetreten sind.

Ein Problem haben wir noch: Bisher können wir nur die FEhler auslesen, die einzelne cmdlets ausgeben. Denn nur cmdlets haben den PArameter –errroraction Stop und nur solche werfen daher fehler, die in einem catch-Block abgefangen werden können.

Was wir dezriet noch nicht abfangen können, sind Fehler von Methoden eines cmdlets oder von Methoden innerhlab einer selbst geschriebenen Funktion.

Diese Art von Fehler müssen wir mit einem try-Block abfangen. Der try-Block muss deifniert werden, bevor der Befehl ausgeführt wird, der möglciherweise denFehler wirft. ein trap-Block

Ein guter Artikel zum Error Hnadling in der Powershell ist hier zu finden.

WMI

WMI ist eine super Möglichkeit, um sich HArdwareinformationen vom eignene oder von entfernten Rechnern zu holen. Beispielsweise gibt folgender befehl informationen büer das BIOS bzw. UEFI des Systems aus

Gwmi Win32_BIOS

von einem entfernten Rechner über

Gwmi Win32_BIOS -computer <name oder IP>

WMI hat eine eigene Filtering-Sprache. So kann man beispielsweise mit folgendem Befehl nach Datenträgertypen sortieren

gwmi win32_logicaldisk -Filter "drivetype=3"

hierbie können als Vergleihcsoperatoren wieder die gewöhnlichen Powershell-operatoren wie beispielswiese ceq, eq, lt, gt und like benutzt werden.

Das schwieirge an der ganzen sache ist, erstmal das richtige WMI-Objekt zu finden, welches man für die gewünschte Aufgabe verwenden kann. Dabei können Drittanbietertools sinnvoll sein, wie etwa der Primaltools WMI Explorer

Auch WMI-Objekte können als Job ausgeführt werden. Dazu bedient man sich invoke-command

invoke-command -scriptblock { get-wmiobject -class win32_process } -computer <hostname> -asjob

Auf Datenbanken mit der Powershell zurgeifen

Mit Hilfe der PowerShell ist es möglich, sich auf Datenbanken zu verbinden und auf diese Abfragen abzusetzen. Solche Powershell Skripte werdne aus verschiedenen Anlässen genutzt. Beispielsweise speichern sich Datenbankadministratoren in Powershell-Skripten häufig verwendete SQL-Abfragen, die sie dann nur noch per Doppelklick und anschließender PAssworteingabe asuführen, anstatt die Kommandos jedes mal selbst ausführen zu müssen.

Desweiteren ist es möglich, automatische Backups der Datenabnk über so ein Powershell-Skjript laufen zu lassen, oder etwas jedes mal, wenn sich ein Benutzer am System anmeldet oder eine wichtige Änderung macht, einen Log-Eintrag in eine Datenbank zu schreiben. Das Powershell-Skript könnte man dann über eine Windows Active Directory Gruppenrichtlinie immer laufen lassen, sobald sich ein Nutzer an der domäne anmeldet.

Um mit Datenbanken zu arbeiten, brauchen wir erstmal einige Voraussetzungen:

  • .NET Framework >= 3.5 ist auf dem Sytem installiert
  • PoweRshell 2.0 und Powershell ISE sind installiert
  • desweiteren ist es empfehlenswert, dass ihr nicht die 64-Bit-Version der Powershell für das Skript verwendet, sondern die 32-Bit-Version. Einige Datnebanken haben PRobleme mit der 64-Bit-PowerShell

Danach intiialisierten wir ein benötigtes Objekt über

[assembly.reflection]::loadwithpartialname('System.Data')

Dann brauchen wir einen Connection String

Schleifen

foreach

 

Passwörter über einen Secure Store bekommen

 

Source :

Udemy BLog

Andreas Loibl ist SAP-Berater, Ethical Hacker und Online Marketing Manager und schreibt auf seinem Blog DaFRK Blog über verschiedene Themen in den Sektoren Projektmanagement, Informationstechnik, Persönlichkeitsentwicklung, Finanzen und Zeitmanagement.

DaFRK

Andreas Loibl ist SAP-Berater, Ethical Hacker und Online Marketing Manager und schreibt auf seinem Blog DaFRK Blog über verschiedene Themen in den Sektoren Projektmanagement, Informationstechnik, Persönlichkeitsentwicklung, Finanzen und Zeitmanagement.

Das könnte Dich auch interessieren …

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.