Behandelte Themen unter "Die Variablen"
0.
1.
Beispiel 1: verschiedene Typen von benutzerdefinierten Variablen
Beispiel 2: Ein kleiner Blick hinter die Kulissen von Wertetypen wie Int32, Double oder Boolean
1.1
1.1.1
Beispiel 1: verschiedene initiale Typen von benutzerdefinierten Variablen
Beispiel 2: Implizite Typkonvertierung
1.1.2
Beispiel 1: Explizite Zuweisung von Variablen zu Typen
Beispiel 2: Umwandlung eines Arrays in einen String
Beispiel 3: Alphanumerische Zufallswerte erzeugen
1.2
1.2.1
1.2.1.1
1.2.1.1.1
Beispiel 1: Anzeige der InstanzEigenschaften und InstanzMethoden von [System.String]
Beispiel 2a: Beginn und Ende eines Strings vergleichen
Beispiel 2b: Umwandlung in Groß- und Kleinbuchstaben
Beispiel 2c: Länge eines Strings bestimmen
1.2.1.1.2
Beispiel 1: Anzeige der statischen Methoden und Eigenschaften von [System.String]
Beispiel 2a: Ist eine Variable Empty oder Null?
Beispiel 2b: Vergleich zweier Strings
1.2.1.1.3
Beispiel 1: verschiedene Konstruktoren der Klasse [System.String]
1.2.1.2
Beispiel 1: Expanding String mit einer Variable, einem Ausdruck und Sonderzeichen mit EscapeCharacter
Beispiel 2: Maskieren mit dem EscapeCharakter (=Backtick) und Zeilenumbruch im Code
Beispiel 3: Literalstrings
1.2.1.3
Beispiel 1: Definition eines Multilinestrings
Beispiel 2: Auskommentieren einer längeren Passage im Code
1.2.2
Beispiel 1: Eigenschaften von Int32
Beispiel 2: Eigenschaften von Double
Beispiel 3: Eigenschaften von Boolean
1.2.3
Beispiel 1a: Definition einer ScriptBlock-Variable
Beispiel 1b: Methoden einer Skriptblock-Variablen
Beispiel 1c: Ausführen eines Skriptblock-Variablen mit dem Call-Operator
Beispiel 1d: Eine For-Schleife und eine If-Bedingung mit je einem Skriptblock
Beispiel 2: Parameterübergabe in einen Skriptblock
Beispiel 3: Parametrisieung des Powershell-Codes
2.
2.1
Beispiel 1: $OFS (Output Field Separator)
Beispiel 2: erlaubte Anzahl an Variablen
Beispiel 3: Bestimmen der aktuell verwendeten Zahl von Variablen
Beispiel 4: Bestimmen der aktuellen Anzahl der Aliase
2.2
2.2.1
Beispiel 1: Ausgabe von Verbosemeldungen
Beispiel 2: Einsatz von Write-Verbose mit dem Commonparameter "Verbose"
2.2.2
2.2.3
Beispiel 1a: Unterdrücken von Errormeldungen ohne Abbruch des Skripts für einen Befehl (- Erroraction SilentlyContinue oder -EA 0).
Beispiel 1b: Unterdrücken von Errormeldungen ohne Abbruch des Skripts skriptweit (- Erroraction SilentlyContinue)
Beispiel 2: Ausgabe der ersten Errormeldung mit Abbruch des Skripts (-ErrorAction Stop oder –EA 1)
Beispiel 3: Ausgabe der Errormeldungen ohne Abbruch des Skripts (-ErrorAction Continue oder –EA 2)
Beispiel 4: Unterbrechung des Skripts mit Rückfrage beim User (-ErrorAction Inquire oder –EA 3)
2.2.4
Beispiel 1: Errormessages in einer Errorvariablen speichern
2.2.5
Beispiel 1: Warnungen und ihre Folgen
2.2.6
Beispiel 1: Warnungen und ihre Folgen
2.2.7
Beispiel 1: Ausgabe auf den Bildschirm und gleichzeitig in eine Variable
2.2.8
******************************************************************************************************
0 Einleitung
Powershell unterscheidet nach diesem Technetartikel
1) benutzerdefinierte Variablen
Das sind vom Programmierer erstellte Variable, die nach dem Beenden der Powershell aus dem Speicher gelöscht werden.
$zahl=5
$text="Powershell"
2) Preference Variables und CommonParameter
Die Preference Variables wirken sich auf das Verhalten eines Powershellskripts insgesamt aus. Beispielsweise ob bei Fehlern im Skript abgebrochen, eine Warnung ausgegeben oder still weitergemacht werden soll. Mit den Commonparametern kann man das Verhalten sogar einzelner Anweisungen des Skripts abweichend von den Preference Variables beeinflussen.
Technet:
Technet:
3) Automatic Variables
dabei handelt es um etwa 50 Variablen, die Powershell mitbringt und auf die wir Anwender nur lesenden Zugriff haben. Diese Variablen können sich innerhalb eines Skript und sogar innerhalb einer Befehlszeile verändern. Einige dieser Variablen sind es, die die Powershell so mächtig machen wie beispielsweise die Variable "$_".
"$_" ist die Grundlage für das Pipelining der Powershell, das in fast jedem Powershellskript vorkommt.
Auch andere Automatischen Variablen tauchen neben "$_" immer wieder in Beispielskripten auf, sind dort aber nicht immer erklärt. Ein Blick in die Liste dieses Variablentyps hilft dann weiter.
Technet:
Zusätzlich zu den drei genannten Variablentypen, möchte ich als vierten Typ die Umgebungsvariablen oder "Environment Variables" nennen. Auf diese Variablen bin ich im Kapitel
1 benutzerdefinierte Variable
Benutzerdefinierte Variablen sind immer Objekte mit bestimmten Eigenschaften und Methoden. Diese Eigenschaften sind abhängig von den Klassen, von denen die Objekte abgeleitet wurden.
Variablen können
- einfache Wertetypen [System.ValueTypes] wie Integer, Double oder Boolean (auch Literale genannt)
- StringObjekte
- Arrays [system.array]
- Scriptblocks
- Hashtables [system.object]
- WMI-Objekte [System.Management.ManagementBaseObject]
- .Net-Objekte aller Art
sein.
ALLE diese Variablen sind Objekte, was unter VBS noch nicht durchgängig der Fall war.
1.1 implizite und explizite Typzuweisung
MSDN:
Bei der Verwendung von Variablen übernimmt Powershell die korrekte Zuweisung von Varaiblen zu passenden Klassen meist selbst. Sollte sich herausstellen, daß die gewählte Klasse im Laufe des Programmablaufs doch nicht die richtige war, so versucht Powershell die Variable in eine andere Klasse automatisch so zu konvertieren, daß keine Informationen verloren gehen.
Meist muß sich der Programmierer um nichts kümmern.
Ich habe bewusst eben zweimal das Wörtchen "meist" verwendet. Trifft der Fall zu und der Programmierer muß tatsächlich nicht eingreifen, so spricht man von einer "impliziten Typzuweisung".
Powershell bietet natürlich auch die Möglichkeit an, Variable von Beginn an selbst einer Klasse zuzuweisen oder ein in einen gewünschten Typ zu konvertieren (= casten). Dann spricht man von einer "expliziten Typzuweisung"
Beide Arten der Typzuweisung beschreibe ich in den nächsten beiden Unterkapiteln
1.1.1 implizite Typzuweisung
In der Powershell müssen Variablen vor ihrer Verwendung nicht deklariert werden. Powershell weist einer neuen Variable implizit einer (meist) passenden Klasse zu. Im folgenden Beispiel 1 sind dazu einige Beispiel aufglistet.
Beispiel 1: verschiedene initiale Typen von benutzerdefinierten Variablen
In den folgenden Beispielen weise ich Variablen verschiedene Werte zu und frage anschliessend den Variablentyp ab. In 99% der Fälle passt der von Powershell ausgewählte Variablentyp.
remove-variable a -ErrorAction silentlycontinue #damit keine Missverständnisse durch eventuelle Vorbelegungen dieser Variablen auftreten
$a=2 #WertObjekt der Klasse Int32
$a.gettype() | Format-Table Name,BaseType -auto
#Ausgabe
Name BaseType
---- --------
Int32 System.ValueType
remove-variable b -ErrorAction silentlycontinue#damit keine Missverständnisse durch eventuelle Vorbelegungen dieser Variablen auftreten
$b=5.5 #WertObjekt der Klasse Double
$b.gettype() | Format-Table Name,BaseType -auto
#Ausgabe
Name BaseType
---- --------
Double System.ValueType
remove-variable c -ErrorAction silentlycontinue #damit keine Missverständnisse durch eventuelle Vorbelegungen dieser Variablen auftreten
$c=(4 -lt 6) #Objekt der Klasse Boolean
$c.gettype() | Format-Table Name,BaseType -auto
#Ausgabe
Name BaseType
---- --------
Boolean System.ValueType
remove-variable d -ErrorAction silentlycontinue #damit keine Missverständnisse durch eventuelle Vorbelegungen dieser Variablen auftreten
$d="hello" #Objekt der Klasse String
$d.gettype() | Format-Table Name,BaseType -auto
#Ausgabe
Name BaseType
---- --------
String System.Object
remove-variable e -ErrorAction silentlycontinue #damit keine Missverständnisse durch eventuelle Vorbelegungen dieser Variablen auftreten
$e=1,2,6,9 #System.Array-Objekt
$e.gettype() | Format-Table Name,BaseType -auto
#Ausgabe
Name BaseType
---- --------
Object[] System.Array
remove-variable f -EA 0 #damit keine Missverständnisse durch eventuelle Vorbelegungen dieser Variablen auftreten
$f=@{Projektleiter="Karl Napf";TechnischerRedakteur="Heinz Kunz"} #Hashtabelle
$f.gettype() | Format-Table Name,BaseType -auto
#Ausgabe
Name BaseType
---- --------
Hashtable System.Object
remove-variable g -EA 0 #damit keine Missverständnisse durch eventuelle Vorbelegungen dieser Variablen auftreten
$g=get-wmiobject win32_bios #Managementobjekt oder WMIObjekt
$g.gettype() | Format-Table Name,BaseType -auto
#Ausgabe
Name BaseType
---- --------
ManagementObject System.Management.ManagementBaseObject
remove-variable h -EA 0 #damit keine Missverständnisse durch eventuelle Vorbelegungen dieser Variablen auftreten
$h=([io.directoryinfo]"C:\") #.Net-Objekt der Klasse DirectoryInfo
$h.gettype() | Format-Table Name,BaseType -auto
#Ausgabe
Name BaseType
---- --------
DirectoryInfo System.IO.FileSystemInfo
remove-variable i -EA 0 #damit keine Missverständnisse durch eventuelle Vorbelegungen dieser Variablen auftreten
$i = [system.Enum]::GetValues([System.Environment+SpecialFolder]) | #System Array
$i.gettype() | Format-Table Name,BaseType -auto
#Ausgabe
Name BaseType
---- --------
SpecialFolder[] System.Array
Beispiel 2: Implizite Typkonvertierung
Remove-variable a -EA 0
$a=6 #WertObjekt der Klasse Int32
$a.gettype() | Format-Table Name,BaseType -auto
$a=$a+0.5
$a.gettype() | Format-Table Name,BaseType -auto
##Ausgabe
Name BaseType
---- --------
Int32 System.ValueType
Name BaseType
---- --------
Double System.ValueType
Die Variablenzuweisung "$a=6" interpretiert Powershell default als ein Objekt der Klasse Int32 mit einem ganzzahligen Wertebereich von etwa -2 Milliarden bis +2 Milliarden. Für viele Situationen ist dies die passende Wahl. Sollte später mal die Variable einen Nachkommaanteil erhalten "$a=$a+0.5", so wandelt Powershell $a automatisch in ein Objekt der Klasse Double um.
remove-variable b -ErrorAction silentlycontinue
$b=6 #WertObjekt der Klasse Int32
$b.gettype() | Format-Table Name,BaseType -auto
#[int32]::maxvalue #2147483647
$b=$b+2147483647
$b.gettype() | Format-Table Name,BaseType -auto
#Ausgabe
Name BaseType
---- --------
Int32 System.ValueType
Name BaseType
---- --------
Double System.ValueType
Die Variablenzuweisung "$a=6" interpretiert Powershell default als ein Objekt der Klasse Int32 mit einem ganzzahligen Wertebereich von etwa -2 Milliarden bis +2 Milliarden. Für viele Situationen ist dies die passende Wahl. Sollte später mal die Variable den Wertebereich von [Int32] übersteigen", so wandelt Powershell $a automatisch in ein Objekt der Klasse Double um.
Remove-variable c -EA 0
[int16]$b=6 #WertObjekt der Klasse Int32
$c.gettype() | Format-Table Name,BaseType -auto
[int16]::maxvalue # 32767
$c=$c+32767
#Ausgabe
Cannot convert value "32773" to type "System.Int16". Error: "Der Wert für einen Int16 war zu groß oder zu klein."
At line:20 char:3
+ $c <<<< =$c+32767
+ CategoryInfo : MetadataError: (:) [], ArgumentTransformationMetadataException
+ FullyQualifiedErrorId : RuntimeException
Daß die implizite Typumwandlung nicht immer funktioniert, zeigt dieses Beispiel einer Variable vom Typ [Int16]. Läßt man deren Wert über den Maimalwert steigen, so erhält man einen Fehler. Offenbar haben die Powershellentwickler den Typ [Int32] im Gegensatz zu anderern Typen mit besonderen Schutzmechanismen ausgestattet
Wenn kein trifftiger Grund vorliegt, würde ich ganze Zahlen im Defaulttyp [Int32] speichern. In Zeiten von 64-Bit Betriebssystemen dürfte die Speicherersparnis durch den Einsatz kleinerer Typen bei Skripten kaum eine Rolle mehr spielen.
1.1.2 explizite Typzuweisung
Natürlich kann man auch eine Variable einer bestimmten Klasse zuweisen (casten) oder eine bereits mit einem Wert gefüllte Variable in eine andere Klasse konvertieren, sofern Powershell dies als möglich erachtet.
MSDN:
Beispiel 1: Explizite Zuweisung von Variablen zu Typen
remove-variable a
[int32]$a=7
$a.gettype() | Format-Table Name,BaseType -auto
$a=[int64]$a
$a.gettype() | Format-Table Name,BaseType -auto
$a
$a=[int32]$a
$a.gettype() | Format-Table Name,BaseType -auto
$a
#Ausgabe
Name BaseType
---- --------
Int32 System.ValueType
Name BaseType
---- --------
Int64 System.ValueType
7
Name BaseType
---- --------
Int32 System.ValueType
7
Anmerkung: Die Variable a wird ohne Wertverlust von [Int32] nach [Int64] und auch wieder zurück konvertiert
Beispiel 2: Umwandlung eines Arrays in einen String
$a=@() #a ist als Array definiert. Die Elemente können beliebige Typen haben
#[string[]]$a $a ist als Array definiert, dessen Elemente nur Strings sein dürfen
$a="Karl"," ","Napf"
"Ausgabe als Array"
$a
"`nAusgabe als umgewandelten String"
[string]$a
#Ausgabe
Ausgabe als Array
Karl
Napf
Ausgabe als umgewandelten String
Karl Napf
Technet:
Beispiel 3: Alphanumerische Zufallswerte erzeugen
Hier ein etwas praxisnäheres Beispiel:
Function get-alphanumericRandom{
param($digits=8,[string]$flag='111', $SpaceFrequency=4,[boolean]$LineFeed=$false)
$RandomPool=$null
$flag=[Convert]::ToInt32($flag, 2)
$min_lower=[int][char]'a' #97
$max_lower=[int][char]'z' #122
$min_upper=[int][char]'A' #65
$max_upper=[int][char]'Z' #90
$min_number=[int][char]'0' #48
$max_number=[int][char]'9' #57
$space =[int][char]' ' #32
if($flag -band 1){
$randompool=[char[]]($min_lower..$max_lower)
}
if($flag -band 2){
$randompool+=[char[]]($min_upper..$max_upper)
}
if($flag -band 4){
$randompool+=[char[]]($min_number..$max_Number)
}
if($flag -band 8){
for($i=1;$i -le $spaceFrequency;$i++){
$randompool +=" "
} #for
}
#Benutzerdefinierte zusätzliche Zeichenketten
for($i=1;$i -le 3;$i++){
$randompool +="Karl"
}
for($i=1;$i -le 2;$i++){
#if($linebreak){$randompool +="`n"} #Zeilenumbruch
if($linefeed){$randompool +=[Environment]::NewLine}
}
$ofs = ''
[string](get-random -input $randompool -count $digits)
}#function Ende
#BeispielAufruf
get-alphanumericRandom -digits 10 -flag 1111
#Ausgabe
y5C DBWtw4
Dieses Beispiel ist mir beim Schreiben des Kapitels
Das cmdlet Get-Random
Anwendungsbeschreibung der Funktion get-AlphanumericRandom:
Die obige Funktion hat drei (optionale) Parameter und kann auch innerhalb des Codes noch etwas angepasst werden
a) digits (Default 8): gibt an, aus wievielen Zeichen der Zufallsstring bestehen soll
b) flag (default '0111'): ein vierstelliger binärer Flag mit folgendem Aufbau:
- die erste (niedrigste) Stelle beschreibt, ob im Zufallsstring Kleinbuchstaben vorkommen sollen
- die zweite Stelle beschreibt, ob im Zufallsstring Großbuchstaben vorkommen sollen
- die dritte Stelle beschreibt, ob im Zufallsstring Zahlen vorkommen sollen
- die vierte Stelle beschreibt, ob im Zufallsstring Leerzeichen vorkommen sollen
c) SpaceFrequency (Default 4): steuert, mit welcher Wahrscheinlichkeit Leerzeichen im Zufallstring vorkommen. Je höher, desto wahrscheinlicher
Durch diese Parameter, sowie die Möglichkeit im Funktionscode eigene Strings und Charakter für das InputArray eingeben zu können, eignet sich die Funktion ganz gut, um zufällige Datei- und Ordnernamen zu erzeugen, aber auch zum erstellen von längeren Textdateien.
Beides benötige ich wiegesagt, um etwas Testmaterial für das Kapitel Filesystem zu bekommen. Auch die Erzeugung einigermaßen zufälliger Passwörter wäre ein möglicher Einsatz dieser Funktion.
1.2 Typen von Variablen
Im vorangegangenen Kapitel
Trotzdem gibt es ein paar interessante Punkte zu den wichtigsten Variablentypen zu sagen, deren Kenntnis zum Verständnis ganz bestimmt nicht schadet.
Daher verzichte ich in diesem Kapitel auf Vollständigkeit im Bezug auf alle Typen und beschränke mich auf die Typen [System.String], [System.Int32], [System.Double], [System.Boolean], sowie [System.Management.Automation.ScriptBlock]
1.2.1 Strings
Strings sind natürlich wieder Objekte, die aus der zugehörigen .Net-Klasse [System.String] erstellt werden. Kaum ein Skript kommt ohne Strings aus.
Dieses Unterkapitel dreht sich um die Stringklasse mit ihren Methoden, Eigenschaften und Konstruktoren ansich. Das Auffinden bestimmter Patterns oder die Manipulation von Strings innerhalb von Texten behandle ich im Kapitel "
Strings haben in der Powershell einige Besonderheiten, wie die einfachen und doppelten Anführungszeichen (Literal und Expandingstring), den Escapecharacter (`)und die Multilinestrings. Diese Punkte möchte ich neben der Klassenbeschreibung im Folgenden behandeln.
1.2.1.1 die .Net Klasse [system.string]
MSDN:
Wie schon erwähnt, möchte ich mich in diesem Kapitel "Die Variablen" nicht zu sehr auf Textmanipulationen eingehen, sondern eher den Schwerpunkt auf das Thema "Strings als einer von mehreren Variablentypen" setzen und nur einen Überblick über die Klasse [System.String] geben mit nur ein paar Beispielen.
Im Kapitel "
1.2.1.1.1 InstanzMethoden und InstanzEigenschaften der String-Klasse
Beispiel 1: Anzeige der InstanzEigenschaften und InstanzMethoden von [System.String]
$a = "Napf"
#Gleichbedeutend mit
$a=[system.string]"Napf"
$a | gm
#Ausgabe gekürzt
TypeName: System.StringNamhttps://www.powershellpraxis.de/typo3/backend.phpe MemberType Definition
---- ---------- ----------
StartsWith Method bool StartsWith(string value), bool StartsWith(string valu
…
ToUpper Method System.String ToUpper(), System.Stri
…
Length Property System.Int32 Length {get;}
Es ist Geschmackssache ob man sich die InstanzMethoden und -Eigenschaften auf diese Weise ausliest, oder in in der MSDN nachsieht: MSDN:
Beispiel 2a: Beginn und Ende eines Strings vergleichen
Für die Methoden und Eigenschaften der Stringklasse, die wir uns in Beispiel 1 angesehen haben, ein paar kleine Beispiele
[system.string]$a="KarlNapf" #die explizite Typeangabe ist natürlich nicht notwendig und hat nur nochmal verdeutlichenden Charakter
$a.startswith("Karl")
$a.endswith("Erwin")
#Ausgabe
True
False
Beispiel 2b: Umwandlung in Groß- und Kleinbuchstaben
$a="KarlNapf"
$a.ToUpper()
#Ausgabe
KARLNAPF
Beispiel 2c: Länge eines Strings bestimmen
$a="KarlNapf"
$a.Length
#Ausgabe
8
1.2.1.1.2 statische Eigenschaften und Methoden der String-Klasse
Statische Methoden und Eigenschaften werden direkt auf die Klasse angewandt werden. Die Stringklasse hat hiervon ein paar sehr nützliche im Gepäck
Beispiel 1: Anzeige der statischen Methoden und Eigenschaften von [System.String]
[string] | get-member -static
TypeName: System.String
Name MemberType Definition
---- ---------- ----------
Compare Method static int Compare(string strA, string strB), s
CompareOrdinal Method static int CompareOrdinal(string strA, string s
Concat Method static string Concat(System.Object arg0), stati
Copy Method static string Copy(string str)
Equals Method static bool Equals(string a, string b), static
Format Method static string Format(string format, System.Obje
Intern Method static string Intern(string str)
IsInterned Method static string IsInterned(string str)
IsNullOrEmpty Method static bool IsNullOrEmpty(string value)
Join Method static string Join(string separator, string[] v
ReferenceEquals Method static bool ReferenceEquals(System.Object objA,
Empty Property static System.String Empty {get;}
Es ist Geschmackssache ob man sich die statischen Methoden und -Eigenschaften auf diese Weise ausliest, oder in in der MSDN nachsieht:
MSDN:
Für die Methoden und Eigenschaften der Stringklasse, die wir uns in Beispiel 1 angesehen haben, ein paar kleine Beispiele
Beispiel 2a: Ist eine Variable Empty oder Null?
MSDN:
$a=5
[string]::isnullorempty($a)
remove-variable a # identisch zu $a=$null
[string]::isnullorempty($a)
#Ausgabe
False
True
Der Unterschied zwischen einer leeren Variablen und einer Variablen mit dem Wert $null ist durchaus wichtig und kann bei Nichtbeachten unangenehme Fehler verursachen.
Möchte man Userkonten aus dem Activedirectory herausfiltern, die keine Beschreibung haben, so möchte man meist sowohl Konten erkennen, deren Beschreiubngsfeld noch nie (=$Null) belegt war, wie auch Konten deren Beschreibung (=$Empty) gelöscht wurde.
Beispiel 2b: Vergleich zweier Strings
$a="KarlNapf"
$b="KarlNapf"
[string]::Compare($a, $b, $True)
#Ausgabe
0
Über die MSDN
Kleiner als 0 - strA ist kleiner als strB.
0 (null) - strA ist gleich strB.
Größer als 0 - strA ist größer als strB.
1.2.1.1.3 Konstruktoren der String-Klasse
Konstruktoren sind ebenos Elemente einer .Net Klasse wie Eigenschaften oder Methoden. Konstruktoren erzeugen beim Aufruf einer Klasse mit dem cmdlet new-object eine Instanz, also ein Objekt aus einer Klasse.
Eine Klasse kann -meistens hat sie das auch- mehrere Konstruktoren besitzen, die sich durch Art und Anzahl der zu übergebenden Parameter unterscheiden. Klassen mit mehr als einem Konstruktor nennt man "überladen". Je nachdem, welchen Konstruktor man verwendet, erhält man ein etwas anderes Objekt.
Die verschiedenen Konstruktoren einer .Net Klasse kann man sich in der MSDN in der Klassenbeschreibung ansehen.
Beispiel 1: verschiedene Konstruktoren der Klasse [System.String]
Mit get-member erhält man, wie iim voran gegangenen Kapitel gezeigt, schon eine ganze Reihe von Möglichkeiten zurück, was man mit Strings über statische und nichtstatitische Methoden und Eigenschaften anstellen kann.
Es gibt noch weitere Anwendungsmöglichkeiten über die Konstruktoren, die nur durch einen Blick auf die Klassenbeschreibung in der Technet ersichtlich sind MSDN:
MSDN:
Angabe des ersten Zeichens(5) und der Länge(4)
$a = new-object System.string("Karl_Napf",5,4)
$a
#Ausgabe
Napf
MSDN:
Wiederholung eines Unicode-Zeichens ("K"), so of wie angegeben (5)
$a = new-object System.string("K",5)
$a
#Ausgabe
KKKKK
Auch dieses Beispiel hat wieder eher verdeutlichenden Charakter. In der Praxis würde man meistens einen String wohl eher durch eine Anweisung wie $a=5*"K" vervielfachen, was dann auch bei Strings mit mehr als einem Zeichen funktioniert.
$a = "KarlNapf"*5
$a
#Ausgabe
KarlNapfKarlNapfKarlNapfKarlNapfKarlNapf
MSDN:
$a = new-object system.string("KarlNapf")
$a -is [System.String]
#Ausgabe
True
$a= new-object system.string("KarlNapf") wird jeder in der Praxis natürlich mit $a="KarlNapf" abkürzen
1.2.1.2 Expandingstrings, Escapecharakter, Literalstrings
Technet:
Zeichenfolgen werden in Powershellskripten entweder in einfache oder doppelte Anführungszeichen gesetzt.
Doppelte Anführungszeichen bewirken, daß in einem String
- Variablen durch ihre Werte ersetzt werden "Der Wert ist $i" -> "Der Wert ist 5"
- Ausdrücke ausgewertet werden "Der Wert ist $(2+3)" -> "Der Wert ist 5"
- Sonderzeichen mit dem Escape_Character umgesetzt werden "Der Wert ist:`t 5" -> "Der Wert ist 5"
Man spricht von einem Expanding String
Beispiel 1: Expanding String mit einer Variable, einem Ausdruck und Sonderzeichen mit EscapeCharacter
$var="KarlNapf"
$a="User `t`t $env:username `nOS `t`t $env:OS `nVar `t`t$var `nAusdruck`t`t$(2+3)"
$a
#Ausgabe
User j184710
OS Windows_NT
Var KarlNapf
Ausdruck 5
Anmerkung 1: die Sonderzeichen `t und `n stehen für “horizontal tab” und “new line”. siehe Escapecharacter im nächsten Beispiel
Anmerkung 2: Es werden die zwei Umgebungsvariablen username und OS verwendet. Umgebungsvariaben siehe
Anmerkung 3: Wenn die Ausgabe vernünftig formatiert sein soll, seht euch das Kapitel
Der Escapecharakter leitet einige Sonderzeichen der Powershell ein, die in der Technet unter
`0 Null
`a Benachrichtigung
`b Rückschritt
`f Seitenvorschub
`n Zeilenwechsel
`r Wagenrücklauf
`t Horizontaler Tabstopp
`v Vertikaler Tabstopp
Der Escapecharakter hat noch zwei weitere Funktionen in der Powershell. Zum einen maskiert er in einem Expanding String eine Variable, wodurch diese nicht ersetzt wird, zum anderen zeigt er in einem Skript an, daß der Befehl in der nächsten Zeile des Codes weitergeschrieben wird. Der Escapecharakter wird außerhalb der Powershell auch häufiger als Backtick bezeichnet
Beispiel 2: Maskieren mit dem EscapeCharakter (=Backtick) und Zeilenumbruch im Code
$a=5
"Die Variable `$a soll nicht ersetzt werden, außerdem ist `
diese Codezeile erst hier fertig"
#Ausgabe
Die Variable $a soll nicht ersetzt werden, außerdem ist
diese Codezeile erst hier fertig
Ohne den Backtick vor $a wäre die Variable a durch ihren Wert 5 ersetzt worden und ohne den Backtick am Ende der zweiten Zeile hätte es eine Fehlermeldung gegeben.
Beispiel 3: Literalstrings
$a=5
'Die Variable $a soll nicht ersetzt werden, was in "Literalstrings" sowieso nicht geschieht'
#Ausgabe
Die Variable $a soll nicht ersetzt werden, was in "Literalstrings" sowieso nicht geschieht.
Literalstrings sind Strings in einfachen Anführungszeichen. In diesen Strings werden keine Ersetzungen vorgenommen, dafür können Sonderzeichen wie doppelte Anführungszeichen ohne Maskierung eingebaut werden. Weitere Beispiele, wie man Anführungszeichen in Strings einbaut, findet ihr in dem oben schon angebenen Technet Artikel
1.2.1.3 Multiline Strings (Here Strings)
Ein Multiline- oder Herestring ist intern ein normaler String der Klasse [System.String]. Powershell macht uns mit diesen Strings nur das Leben bei der Definition längerer Zeichenketten, die sich über mehrere Zeilen hinziehen können, einfacher.
Beispiel 1: Definition eines Multilinestrings
$a =@"
Erste Zeile
Zweite Zeile
Dritte Zeile
"@
$a
$a.Length
$a.gettype() | Format-Table Name,BaseType -auto
#Ausgabe
Erste Zeile
Zweite Zeile
Dritte Zeile
39
Name BaseType
---- --------
String System.Object
Here-Strings können mehrere Zeilen umfassen und werden mit @" und "@ ( expanding String) bzw @‘ und ‘@ (literal string) begrenzt. Beide Begrenzungen müssen in einer eigenen, vom eigentlichen String getrennten Zeile stehen.
Here-Strings sind normale Strings [System.String], auf die alle .Net-Methoden und Eigenschaften der String-Klasse angewendet werden können. Here-Strings werden beim Verfassen größerer Texte, z.B. für die OnlineHilfe eines Skriptes, eingesetzt.
Beispiel 2: Auskommentieren einer längeren Passage im Code
Ebenfalls nützlich sind Here-Strings zum schnellen Auskommentieren grösserer Skriptpassagen. Dann allerdings sollte man Powershell durch die Variable $null mitteilen, dass der String nicht gespeichert werden braucht
$null=@" #$null speichert nichts, $a würde den ganzen Here-String zwischenspeichern
Hier beginnt ein langer Kommentar
..
Hier endet ein langer Kommentar
"@
1.2.2. Int32 / Double / Boolean
Interessante Informationen der Klasse [system.Int32] erhält man über die statischen Eigenschaften dieser Klasse
Beispiel 1: Eigenschaften von Int32
[system.int32] | gm -static
#Ausgabe
TypeName: System.Int32
Name MemberType Definition
---- ---------- ----------
MaxValue Property static System.Int32 MaxValue {get;}
MinValue Property static System.Int32 MinValue {get;}
Mit diesen Informationen lässt sich der Wertebereich einer Int32 Variablen anzeigen
[int32]::MinValue
[system.int32]::MaxValue
#Ausgabe
-2147483648
2147483647
Dieser Wertebereich ist für die meisten Anwendungen sicher ausreichend. Beim Skripten besteht glaube ich nur selten die Notwendigkeit auf kleinere Typen zum Einsparen von Speicherplatz auszuweichen.
Beispiel 2: Eigenschaften von Double
[double]::MinValue
[system.double]::MaxValue
#Ausgabe
-1,79769313486232E+308
1,79769313486232E+308
Double hat einen Wertebereich von einer negativen Zahl -17 mit 307 Nullen dahinter, bis zu einer positiven Zahl +17 mit 307 Nullen dahinter. Mir ist nicht bekannt, ob irgendeine reale Größe diesen Wertebereich ausschöpft, vielleicht sowas wie Atome im Weltall
Beispiel 3: Eigenschaften von Boolean
[boolean] | gm -static TypeName: System.Boolean
#Ausgabe gekürzt
Name MemberType Definition
---- ---------- ----------
...
FalseString Property static System.String FalseString {get;}
TrueString Property static System.String TrueString {get;}
Mit diesen Informationen lassen sich die Werte für Wahr und Falsch anzeigen
[boolean]::TrueString
[boolean]::FalseString
#Ausgabe
True
False
1.2.3 Skriptblocks
Skriptblocks sind aus Sicht des Programmierers ein Mittelding zwischen Funktionen und Variablen. Einer Variable werden Anweisungen zugewiesen, die an beliebiger Stelle beliebig oft aufgerufen werden können. Der VariablenTyp ist tatsächlich "Skriptblock" und nicht wie bei Funktionen entweder ein Array oder ein ValueType (abhängig von der Return-Anweisung in der Funktion)
Ein Skriptblock ist der rechte Teil einer For-Schleife oder einer If-Bedingung, der zwischen den geschweiften Klammern steht (siehe Beispiel 1d)
Beispiel 1a: Definition einer ScriptBlock-Variable
$ScriptBlock={
$a=8
$b=7
"{0} + {1} = {2}" -f $a,$b,$($a+$b)
}
"Inhalt der Variable Scriptblock: $Scriptblock"
"Typ der Variable Scriptblock: $($ScriptBlock.GetType().Name)"
#Ausgabe
Inhalt der Variable Scriptblock:
$a=8
$b=7
"{0} + {1} = {2}" -f $a,$b,$($a+$b)
Typ der Variable Scriptblock: ScriptBlock
Die Variable Scriptblock enthält also tatsächlich Code, der aber in diesem Beispiel noch nicht ausgeführt wird. Dies kann durch den Einsatz des CallOperators "&$ScriptBlock" oder über die Methode Invoke "$ScriptBlock.Invoke()" geschehen, wie in den nachfolgenden Beispielen gezeigt wird.
Beispiel 1b: Methoden einer Skriptblock-Variablen
$ScriptBlock={
$a=8
$b=7
"{0} + {1} = {2}" -f $a,$b,$($a+$b)
}
"`nEigenschaften und Methoden eines Skriptblocks"
$ScriptBlock | Get-Member
#Ausgabe gekürzt
TypeName: System.Management.Automation.ScriptBlock
Name MemberType Definition
---- ---------- ----------
GetType Method type GetType()
Invoke Method System.Collections.ObjectModel.Collection[psobject]
InvokeReturnAsIs Method System.Object InvokeReturnAsIs(Params System.Object[] args)
ToString Method string ToString()
Die Methoden GetType() und ToString() sind in jeder Klasse dabei und nichts Besonderes. Die beiden Methoden Invoke() und InvokeReturnAsIs() sind dagegen etwas interessanter, wie die nachfolgenden Beispiele zeigen werden
MSDN:
Beispiel 1c: Ausführen eines Skriptblock-Variablen mit dem Call-Operator
$ScriptBlock={GET-WMIObject Win32_Bios}
$(&$ScriptBlock).BiosVersion # "&" ist der sogenannte "Call"-Operator
#mögliche Ausgabe
A M I - 10000602
BIOS Date: 10/02/06 17:12:27 Ver: 08.00.12
BIOS Date: 10/02/06 17:12:27 Ver: 08.00.12
Technet:
Durch Anwendung des CallOperators wird in diesem Beispiel der Code der ScriptBlock-Variablen "&" ausgeführt.
Beispiel 1d: Eine For-Schleife und eine If-Bedingung mit je einem Skriptblock
$ScriptBlock={$i}
For($i=1;$i -lt 3; $i+=1){&$ScriptBlock}
$ScriptBlock={"`nHallo Karl"}
if(2 -gt 1){&$ScriptBlock}
#Ausgabe
1
2
Hallo Karl
In einem Skriptblock kann auch längerer Code verarbeitet werden. Man kann beispielsweise den Code aus Beispiel 1a unter
Beispiel 2: Parameterübergabe in einen Skriptblock
MSDN:
MSDN:
Laut MSDN ist die Methode InvokeReturnAsIs() effizienter.
$ScriptBlock={
$Args[0]
Get-WMIObject Win32_Bios -Computername $Args[0]
}
$ReturnValue = $ScriptBlock.Invoke("PC1")
$ReturnValue
#mögliche Ausgabe
SMBIOSBIOSVersion : 0701
Manufacturer : American Megatrends Inc.
Name : BIOS Date: 10/02/06 17:12:27 Ver: 08.00.12
SerialNumber : System Serial Number
Version : A M I - 10000602
Die übergebenen Parameter sind innerhalb des SkriptBlocks als Elemente des Arrays $args ansprechbar.
Übergibt man nur wenige Parameter und braucht nur einen einzigen Rückgabewert, so sind Skriptblocks den Funktionen sehr ähnlich.
Technet:
Technet:
Beispiel 3: Parametrisieung des Powershell-Codes
Etwas "verrückt" ist die Möglichkeit, selbst den eigentlichen PS-Code parametrisieren zu können. Ob es für dieses Beispiel einen praktischen Einsatz gibt, weiß ich nicht. Ich finds dennoch geil :-)
$ScriptBlock={
Get-WMIObject Win32_$($args[0])
}
$Arguments=@("Bios","Service","Process")
$Arguments | foreach{
$($ScriptBlock.Invoke($_))
}
In diesem Beispiel werden also die WMI-Klassen Win32_Bios, Win32_Service und Win32_Process nacheinander aufgerufen.
args[0] komplettiert bei jedem Durchlauf die Befehlszeile "Get-WMIObject Win32_"
2 Preference Variables und CommonParameter
2.1 Preference Variables
Mit den sogenannte "preference variables" werden grundsätzliche Powershellparameter wie die maximale Anzahl (Variable: $MaximumVariableCount) oder das Verhalten bei Fehlern im Skript (Variable: $ErrorActionPreference") definiert.
In der Powershellhilfe in den "conceptual help topics" oder in der Technet unter
get-help about_preference_variables
#gekürzte Ausgabe
The following table lists the preference variables and their default
values.
Variable Value
-------- -----
$ConfirmPreference High
$DebugPreference SilentlyContinue
$ErrorActionPreference Continue
…
$MaximumHistoryCount 64
$MaximumVariableCount 4096
$OFS (Space character (" "))
…
$WarningPreference Continue
$WhatIfPreference 0
$WsmanMaxRedirectionCount 5
Eine Preference Variable wirkt immer auf das gesamte Skript. Einige "preference variables" können allerdings durch einen Common Parameter, die im
Man kann den Wert einer "preference variables" durch eine einfache Zuweisung überschreiben, wie im folgenden Beispiel gezeigt,
Beispiel 1: $OFS (Output Field Separator)
$OFS hat default den Space character (" "). Der Preference Parameter $OFS wird benutzt wird, sobald ein Feld als String ausgegeben wird.
$array="test1","test2","test3"
[string]$array
#Ausgabe
test1 test2 test3
$OFS wird zu "+++"
$OFS="+++"
$array="test1","test2","test3"
[string]$array
#Ausgabe
test1+++test2+++test3
Löschen von OFS (default)
Remove-Variable OFS
#Beachte: OFS nicht $OFS
Die PreferenceVariable $OFS gilt, wie üblich bei Variablen, nur für die aktuelle Powershellsession. Will man die $OFS in jeder PowershellSession setzen, so muss dies in der Profildatei geschehen
Beispiel 2: erlaubte Anzahl an Variablen
Interessant sind auch die Maximum…Parameter, die bestimmen, wieviele Aliase oder Variablen in einer Session erlaubt sind. Zu den Variablen werden alle Variablen aus dem laufenden Skript, aus den Profilskripten und auch die PreferenceVariables gezählt
get-help about_preference_variables
#gekürzte Ausgabe der default values (fast am Anfang der OnlineHilfe)
….
$MaximumAliasCount 4096
$MaximumDriveCount 4096
$MaximumErrorCount 256
$MaximumFunctionCount 4096
$MaximumHistoryCount 64
$MaximumVariableCount 4096
Beispiel 3: Bestimmen der aktuell verwendeten Zahl von Variablen
(get-variable).count
#Ausgabe
60
Beispiel 4: Bestimmen der aktuellen Anzahl der Aliase
(get-alias).count
#Ausgabe
138
Ansich sind alle PreferenceVariables Wert behandelt zu werden. Da in dem bereits erwähnten "Conceptual help topic" about_preferencevariables die Preference Variablen ausführlich besprochen werden, erspare ich mir hier weitere Details und erwähne nur die Parameter, die sich mit den CommonParameters überschneiden wie beispielsweise das Errorhandling.
2.2 CommonParameter
Möchte man eine über eine "preference variable" definierten Eigenschaft der Powershell nur für einen Befehl ändern, so nimmt man dazu den passenden CommonParameter. Dieser CommonParameter wird als Option an das cmdlet angehängt und gilt dann nur für diesen Befehl.
Bei Aufruf der Onlinehilfe eines cmdlets mit der Option "-detailed" werden die von diesem cmdlet supporteten commonparameters im Parameterblock angezeigt. Nicht jeder Commonparameter muss belegt sein
get-help get-process -detailed
#gekürzte Ausgabe
SYNTAX
Get-Process [-ComputerName <string[]>] ... [<CommonParameters>]
#und am Ende der Parameterliste im Detail
PARAMETERS
…
<CommonParameters>
This cmdlet supports the common parameters: -Verbose, -Debug,
-ErrorAction, -ErrorVariable, -WarningAction, -WarningVariable,
-OutBuffer and -OutVariable. For more information, type,
"get-help about_commonparameters".
Bei den Commonparameters handelt es sich um die folgenden acht Parameter, sowie zwei weitere Parameter (Whatif, Confirm) zur Risikoverringerung. Die Tabelle zeigt die Commonparameter mit ihren Entsprechungen der PreferenceVariables. Nicht jeder CommonParameter hat eine korrespondierende PreferenceVariable.
Kapitel | CommonParameter | PreferenceVariable |
2.2.1 | Verbose | $VerbosePreference |
2.2.2 | Debug | $DebugPreference |
2.2.3 | ErrorAction | $ErrorActionPreference |
2.2.4 | ErrorVariable |
|
2.2.5 | WarningAction | $WarningActionPreference |
2.2.6 | WarningVariable |
|
2.2.7 | OutVariable |
|
2.2.8 | OutBuffer |
|
2.2.9 | WhatIf | $WhatIfPreference |
2.2.10 | Confirm | $ComfirmPreference |
Die Liste der Commonparameters stammt aus "about_commonparameters" im Block "Long Description".
2.2.1 Verbose (PreferenceVariable: $VerbosePreference)
Den Commonparameter -Verbose können Skriptprogrammierer einsetzen, um dem Anwender besonders detaillierte Informationen zum Skript zu geben, die nicht für den Normalanwender. sondern nur für PowerUser interessant sind. Der PowerUser gibt dazu beim Skriptaufruf den Übergabeparameter "Verbose_Mode=1" ein. Das Vorhandensein dieses Parameters kann im Skript in einer If-Abfrage geprüft werden, in der die Verbose-Ausgaben definiert sind.
Das cmdlet write-verbose sendet Ausgaben an den Verbose-Stream. Dessen Output ist farblich und durch das Wort VERBOSE: hervorgehoben.
Wenn es aber nur um eine farbliche Hervorhebung einer Ausgabe geht, kann man diese auch sehr einfach mit "write-host" erreichen.
write-host "diese Ausgabe erscheint in Magenta" -foregroundcolor "Magenta"
Beispiel 1: Ausgabe von Verbosemeldungen
für das folgende Beispiel vergewissert Euch bitte, dass die Preference Variable $VerbosePreference den Defaultwert "silentlycontinue" besitzt. Sonst startet bittr die Powershell neu oder weist "SilentlyContinue" der Variablen $Verbosepreference zu
$VerbosePreference
#Ausgabe
SilentlyContinue
gültige Werte für $VerbosePreference (Quelle: about_preference_variables)
Stop | Displays the verbose message and an error message and then stops executing |
Inquire | Displays the verbose message and then displays a prompt that asks you whether you want to continue |
Continue | Displays the verbose message and then continues with execution. |
SilentlyContinue | Does not display the verbose message. Continues executing (Default) |
Beispiel 2: Einsatz von Write-Verbose mit dem Commonparameter "Verbose"
function demo_Verbose{
param($verbose_mode=0)
write-output "dies ist eine normale Ausgabe `n"
write-verbose "generell wichtige Info: `n" -verbose
write-verbose "noch eine wichtige Info, die aber nur angeziegt wird, `
wenn `$VerbosePreference = `"continue`"ist: `n"
if($verbose_mode -eq 1) {
write-verbose "Info wird nur angezeigt, wenn `$verbose_mode = 1 ist" -verbose
}
}
demo_Verbose 1 # Aufruf der Funktion. $verbose_mode wird auf 1 gesetzt
Setzt man die PreferenceVariable vor der Ausführung des Scripts auf "continue", so werden auch Ausgaben von write-verbose angezeigt, die keinen commonparameter haben
$VerbosePreference="continue"
#Ausgabe:
dies ist eine normale Ausgabe
VERBOSE: generell wichtige Info:
VERBOSE: noch eine wichtige Info, die aber nur angeziegt wird,
wenn $VerbosePreference = "continue"ist:
VERBOSE: Info wird nur angezeigt, wenn $verbose_mode = 1 ist
2.2.2 Debug (PreferenceVariable: $DebugPreference)
Die Debugvariable soll dem Anwender/ Entwickler durch spezielle Informationen helfen, Fehler zu finden. Die Anwendung dieses Parameters ist synonym zu Verbose aus 2.1.
Anstelle von Write-Verbose ist Write-Debug zu benutzen und die Preferencevariable lautet $DebugPreference
2.2.3 Erroraction (PreferenceVariable: $ErrorActionPreference)
Treten in einem Skript Fehler auf, die nicht unbedingt zu einem Abbruch dieses Skriptes führen müssen, wie beispielsweise der Versuch eine nicht vorhandenen Datei zu öffnen, so spricht man von “non-terminating Errors”. Der Programmierer kann bei diesen Fehlern mittels dem Commonparameter -Erroraction entscheiden, wie mit solchen Fehlern verfahren will.
Der Commonparameter –Erroraction überschreibt die PreferenceVariable $ErrorActionPreference für genau einen Befehl. Folgende Verhalten sind mit dem Commonparameter –Erroraction bei einem “non-terminating Error” wählbar
Value | Kurzform | Verhalten |
-ErrorAction SilentlyContinue | -EA 0 | Die Fehlermeldungen wird unterdrückt und das Skript weiterausgeführt |
-ErrorAction Stop | -EA 1 | Die Fehlermeldung wird ausgegeben und das Skript wird gestoppt |
-ErrorAction Continue | -EA 2 | Die Fehlermeldung wird ausgegeben und das Skript weiterausgeführt |
-ErrorAction Inquire | -EA 3 | Die erste Fehlermeldung wird ausgegeben und eine Abfrage an den User gestellt wird, ob das Skript weiter ausgeführt werden soll |
Im Gegensatz dazu stehen die sogenannten “terminating Errors” wie fehlende Berechtigung oder Syntaxfehler, die von dem Commonparameter -Erroraction nicht beeinflusst werden können.
Die Erroraction kann entweder hinter einem Befehl angegeben und gilt dann auch nur für diesen (Beispiel 1a), oder in einer eigenen Zeile mit der Variablen $ErrorActionPreference für alle folgenden Zeilen gesetzt werden (Beispiel 1b).
Beispiel 1a: Unterdrücken von Errormeldungen ohne Abbruch des Skripts für einen Befehl (- Erroraction SilentlyContinue oder -EA 0).
$processes="system","notepad","Dr.No","powershell" #der Prozess "Dr.No" exisitiert nicht
foreach ($process in $processes) {
get-process $process -ErrorAction SilentlyContinue #gilt nur für diesen Befehl
}
#Ausgabe
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
1509 0 0 236 2 12,05 4 System
40 3 1256 3772 32 0,70 5460 notepad
466 8 44392 15372 160 1,64 3292 powershell
Beispiel 1b: Unterdrücken von Errormeldungen ohne Abbruch des Skripts skriptweit (- Erroraction SilentlyContinue)
$processes="system","notepad","Dr.No","powershell" #der Prozess "Dr.No" exisitiert nicht
$ErrorActionPreference = "silentlycontinue" #Gilt ab jetzt für alle folgenden Befehle
foreach ($process in $processes) {
get-process $process
}
$ErrorActionPreference = "stop" #setzt die Fehlerbehandlung auf den DefaultStandard zurück
Beispiel 2: Ausgabe der ersten Errormeldung mit Abbruch des Skripts (-ErrorAction Stop oder –EA 1)
$processes="system","Dr.No","powershell"
foreach ($process in $processes) {
get-process $process -ErrorAction Stop
}
#Ausgabe
# Der system-Prozess existiert natürlich und wird ausgegben.
# Beim "Dr.No"-Prozess tritt ein Fehler auf, der das Skript unterbricht
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
1511 0 0 236 2 12,42 4 System
Get-Process : Command execution stopped because the preference variable "ErrorActionPreference" or common parameter is set to Stop: Cannot find a process with the name 'notepad'. Verify the process name and call the cmdlet again.
At line:2 char:12
+ get-process <<<< $process -ErrorAction Stop
+ CategoryInfo : OperationStopped: (:) [Get-Process], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : ActionPreferenceStop,Microsoft.PowerShell.Commands.GetProcessCommand
Beispiel 3: Ausgabe der Errormeldungen ohne Abbruch des Skripts (-ErrorAction Continue oder –EA 2)
$processes="system","notepad","Dr.No","powershell"
foreach ($process in $processes) {
get-process $process –EA 2
}
#Ausgabe
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
1509 0 0 236 2 12,78 4 System
Get-Process : Cannot find a process with the name 'Dr.No'. Verify the process name and call the cmdlet again.
At line:2 char:12
+ get-process <<<< $process -EA 2}
+ CategoryInfo : ObjectNotFound: (Dr.No:String) [Get-Process], ProcessCommandException
+ FullyQualifiedErrorId : NoProcessFoundForGivenName,Microsoft.PowerShell.Commands.GetProcessCommand
436 8 44684 18604 160 1,98 3292 powershell
Beispiel 4: Unterbrechung des Skripts mit Rückfrage beim User (-ErrorAction Inquire oder –EA 3)
$processes="system","notepad","Dr.No","powershell"
foreach ($process in $processes) {
get-process $process -EA 3}
#Ausgabe
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
1509 0 0 236 2 13,08 4 System
Confirm
Cannot find a process with the name 'notepad'. Verify the process name and call the cmdlet again.
[Y] Yes [A] Yes to All [H] Halt Command [S] Suspend [?] Help (default is "Y"): y
Anmerkungen:Beim Ausführen des Skripts in der Powershell_ISE.exe erfolgt die Abfrage über ein eigenes Fenster
Wie bei Debug "write-debug" und bei Verbose "write-verbose" gibt es für ErrorAction das cmdlet "write-error", mit dem gezielt Errormeldungen im Skript ausgegeben werden können.
write-error "Errormeldung" -Erroraction continue
write "Fehler, aber ich mache weiter"
#Ausgabe
: Errormeldung
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException
Fehler, aber ich mache weiter
2.2.4 Errorvariable
Eine Errorvariable bietet die Möglichkeit Errormessages in einer Variablen abzuspeichern oder Errormessages an bereits bestehende Messages anzuhängen. Damit lassen sich auch bei der Verwendung von SilentlyContinue Fehlermeldungen analysieren.
Beispiel 1: Errormessages in einer Errorvariablen speichern
$processes="system","notepad","Dr.No","powershell","Dr. Yes"
foreach ($process in $processes) {
get-process $process -ErrorAction SilentlyContinue -ErrorVariable +a
} #das + von +a bewirkt ein Anhängen der neuen Fehlermeldung
"`nAusgabe aller bisherigen Fehler:`n$a"
#Ausgabe
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
1118 0 0 228 2 125,78 4 System
419 9 49156 13404 168 5,53 2668 powershell
306 8 25104 284 140 2,38 2720 powershell
Ausgabe aller bisherigen Fehler:
Cannot find a process with the name 'notepad'. Verify the process namewith the name 'Dr.No'. Verify the process name and call the cmdlet again.
2.2.5 WarningAction (PreferenceVariable: $WarningPreference)
Der CommonParameter "WarningAction" arbeitet genauso wie der "
Beispiel 1: Warnungen und ihre Folgen
write-warning "erstes mal: Letzte Warnung"
write-warning "zum zweiten Mal: Letzte Warnung" -warningAction continue
write-warning "zum dritten Mal: Letzte Warnung" -warningAction silentlycontinue #hört aber keiner
write-warning "zum vierten Mal: Letzte Warnung" -warningAction inquire
write-warning "zum fünften und letzen Mal: Letzte Warnung" -warningAction stop
#Aufruf des Skripts in der Console
.\demo-WarningAction.ps1
WARNING: erstes mal: Letzte Warnung
WARNING: zum zweiten Mal: Letzte Warnung
WARNING: zum vierten Mal: Letzte Warnung
Confirm
Continue with this operation?
[Y] Yes [A] Yes to All [H] Halt Command [S] Suspend [?] Help (default is "Y"): y
WARNING: zum fünften und letzen Mal: Letzte Warnung
Write-Warning : Command execution stopped because the preference variable "WarningPreference" or common parameter is se
t to Stop.
At C:\Powershell\website\skripte\commonparameters\demo-WarningAction.ps1:5 char:14
+ write-warning <<<< "zum fünften und letzen Mal: Letzte Warnung" -warningAction stop
+ CategoryInfo : OperationStopped: (:) [Write-Warning], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : ActionPreferenceStop,Microsoft.PowerShell.Commands.WriteWarningCommand
2.2.6 WarningVariable
Der CommonParameter " WarningVariable" arbeitet genauso wie der "
2.2.7 Outvariable
Die Ausgabe eines Befehls lässt sich einfach in eine Variable schreiben.
$a=get-process powershell
# Eine Ausgabe von "get-process powershell" in der Console erfolgt nicht
Mit dem Einsatz des Commonparameters Outvariable wird dagegen die Ausgabe des Befehls in eine Variable geschrieben und gleichzeitig auch am Bildschirm ausgegeben
Beispiel 1: Ausgabe auf den Bildschirm und gleichzeitig in eine Variable
get-process powershell -outvariable a
# man beachte, dass Variablen ohne $-Zeichen benannt sind. Nur die Ausgabe # von Variablen erfordert ein $-Zeichen
#Ausgabe
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
344 8 44072 28720 160 1,56 2584 powershell
360 9 27972 39088 139 1,03 3436 powershell
#$a enthält die Ausgabe ebenfalls
$a
#Ausgabe
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
344 8 44072 28720 160 1,58 2584 powershell
360 9 27972 39088 139 1,03 3436 powershell
Mit einem + Zeichen werden Ausgaben an bestehende Meldungen angehängt
get-process powershell -outvariable a
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
420 8 44072 28852 160 1,58 2584 powershell
get-process notepad -outvariable +a #<---Hier steht das + Zeichen
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- ----------
60 2 1160 4140 30 0,05 1816 notepad
$a
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
420 8 44072 28852 160 1,59 2584 powershell
60 2 1160 4140 30 0,05 1816 notepad
2.2.8 OutBuffer
Der OutBuffer ist ein Parameter, um das Verhalten der Pipeline zu beeinflussen. Da mir nicht viel zu diesem Parameter einfällt und keine weiteren Hinweise gefunden habe, zitiere ich nur die Powershellhilfe
get-help about_commonparameter
#Ausgabe gekürzt
-OutBuffer <Int32>
Determines the number of objects to accumulate in a buffer before
any objects are sent through the pipeline. If you omit this parameter,
objects are sent as they are generated.
This resource management parameter is designed for advanced users.
When you use this parameter, Windows PowerShell does not call the
next cmdlet in the pipeline until the number of objects generated
equals OutBuffer + 1. Thereafter, it sends all objects as they are
generated.
3 automatic Variables
Technet:
Über viele Variablen - manchmal sind etwas merkwürdig benamste darunter - im täglichen Powershellleben macht man sich kaum Gedanken, sondern verwendet oder übernimmt diese einfach aus irgendeinem Beispielcode. Gute Beispiele dafür sind die Variablen "$_", $false, $true oder $pwd.
Wie schon anfangs in der Einleitung erwähnt, bringt Powershell etwa 50 derartiger Variablen mit, die unter dem Topic "automatische Variablen" zusammenbefasst sind.
Teilweise enthalten die automatischen Variablen bestimmte Pfade, wie unter
Jede einzelne automatic-Variable zu erklären, ist hier meines Erachtens wenig sinnvoll, da erstens im oben genannten Technet-Link die Variablen sehr gut erklärt sind und zweitens die Variablen im praktischen Zusammenhang bei anderen Themen erklärt werden müssen, wie etwa $Error beim Thema "Fehlerbehandlung" oder $_ beim Thema Pipelining.