.. include:: Abbrev.txt Variablen und Datentypen ************************ .. topic:: Überblick * Notwendigkeit von Variablen * Notwendigkeit von Datentypen * Beispielhafte Datentypen (int, string, double) * Ergebnis von Datentypen und darauf wirkende Operatoren * Casten (Umwandlen des Datentyps) einer Variable * Konstante * Automatische Powershell-Variablen * Umgebungsvariablen * Gültigkeit von Variablen Variablen speichern Informationen, um sie für andere Dinge zu benutzen. Sie sind somit ein Platzhalter/Stellvertreter für den gespeicherten Wert. Über den Namen der Variablen kann auf den Wert zugegriffen werden. Variablen werden in der Powershell mit einem $-Symbol eingeleitet. Anschließend kann eine fast beliebige Zeichenfolge benutzt werden. Die Namen sind nicht case-sensitive, d.h. Groß- und Kleinschreibung wird nicht unterschieden. .. code-block:: sh $netto = 120 $MWStSatz = 0.19 $USt = $netto * $MWStSatz $USt $result = $netto + $USt $text = "Nettowert $netto macht brutto $result" $text $text = "Nettowert $netto macht brutto $netto + $USt" $text .. image:: images/variable_1.png .. image:: images/variable_2.png .. image:: images/variable_3.png .. NOTE:: .. image:: images/note.png Nicht immer erhält man das, was man erwartet !! Durch den + - Operator innerhalb des Strings werden die beiden Variablen nicht addiert, sondern hintereinander angefügt. Die Klammer um die beiden Variablen sorgt dafür, dass erst die Berechnung innerhalb der Klammer ausgeführt wird, bevor die Übergabe an die $text-Variable erfolgt .. admonition:: . .. image:: images/note.png Zuweisungsoperator ================== Mit Hilfe des Gleichheitszeichen **=** wird einer Variable ein Wert zugewiesen. Will man den Wert einer Variable erfahren, muss man nach Eingabe des Variablenmanes lediglich drücken. Dabei wird man feststellen, dass eine VAriable durchaus auch mehr *Inhalt* aufweisen kann. .. code-block:: sh $listing = Get-ChildItem c:\ $listing Directory: Microsoft.PowerShell.Core\FileSystem::C:\ Mode LastWriteTime Length Name ---- ------------- ------ ---- d---- 06.26.2007 15:36 2420 d---- 05.04.2007 21:06 ATI (..) Daten zwischen Variablen austauschen ==================================== Eine Variable kann auch den Wert einer anderen Variablen erhalten .. code-block:: sh $a = "Kurt" $b = "Sabine" $a = $b $a $b = $b $a Variablen finden ================ Alle während einer |PS|-Session erzeugten Variablen bleiben erhalten, obwohl man sie durch das Scrollen des Bildschirms nicht mehr erkennen kann. Um sich einen Überblick über die derzeit benutzbaren Varaibeln zu verschaffen, kann man sich ein Listing des "*Variablen-Verzeichnissses*" geben lasssen. .. code-block:: sh Dir variable: Ist man am Wert einer Variable interessiert kann man folgendes eingeben: .. code-block:: sh Dir variable:variablenname* .. image:: images/dir_variable.png Um zu überprüfen, ob eine Variable existiert, kann man mit Hilfe des Cmd-Lets *test-Path* prüfen, ob sie vorhanden ist. .. code-block:: sh # Verify whether the variable $value2 exists: Test-Path variable:\value2 True # verify whether the variable $server exists: Test-Path variable:\server False Das Löschen einer Variablen läuft wie in normalen Verzeichnissen auch mit Hilfe des Befehls *del* .. code-block:: sh # create a test variable: $test = 1 # verify that the variable exists: Dir variable:\te* # delete variable: del variable:\test # variable is removed from the listing: Dir variable:\te* Konstanten ========== Normalerweise können Variablen immer wieder mit neuen Werten überschrieben werden. Die sist aber nicht immer gewünscht, so. z.B. bei dem Wert von Pi. Variable, deren Wert sich nicht ändern soll, werden **Konstante** genannt. Sie sind auch in Powershell zu definieren, allerdings etwas umständlich. .. code-block:: sh # Create new variable with description and write-protection: New-Variable test -value 100 -description "test variable with write-protection" -option ReadOnly $test 100 # Variable contents cannot be modified: $test = 200 The variable "test" cannot be overwritten since it is a constant or read-only. At line:1 char:6 + $test <<<< = 200 Wurden Variablen auf diese Weise erzeugt, können Sie zumindest noch gelöscht werden. Um auch dies zu verhindern, kann man das New-Variable-Cmdlet mit der Option *constant* versehen. .. code-block:: sh #New-Variable cannot write over existing variables: New-Variable test -value 100 -description "test variable with copy protection" -option Constant New-Variable : A variable named "test" already exists. At line:1 Char:13 + New-Variable <<<< test -value 100 -description "test variable with copy protection" -option Constant # If existing variable is deleted, New-Variable can create # a new one with the "Constant" option: del variable:\test -force New-Variable test -value 100 -description "test variable with copy protection" -option Constant # variables with the "Constant" option may neither be # modified nor deleted: del variable:\test -force Remove-Item : variable "test" may not be removed since it is a constant or write-protected. If the variable is write-protected, carry out the process with the Force parameter. At line:1 Char:4 + del <<<< variable:\test -force "Automatische" Powershell-Variablen =================================== Beim Erzeugen einer |PS|-Session sind bereits einige Variablen vorbelegt. Eine Übersicht finden sie hier :ref:`powershell_variablen` Weitere Variablen finden Sie mit Hilfe des bereits oben erwähnten Dir-Befehls .. code-block:: sh dir variable: Umgebungsvariablen ================== Häufig will man auch auf die Umgebungsvariablen des Betriebssystems zugreifen wollen. |PS| kennt dazu das *Verzeichnis env*, über welches man den Zugriff auf diese Werte bekommt. .. code-block:: sh dir env: cd $env:homepath .. image:: images/variable_env.png Umgebungsvariablen können wie *normale* Variablen angepasst und hinzugefügt werden. Diese bleiben allerdings nur in der jeweiligen Powershell-Sitzung erhalten. Um sie permanent zu ändern, muss man das .NET-Framework zu Hilfe nehmen. .. code-block:: sh $oldValue = [environment]::GetEnvironmentvariable("Path", "User") $newValue = ";c:\myTools" [environment]::SetEnvironmentvariable("Path", $newValue, "User") Gültigkeit von Variablen ======================== Unter Gültigkeit wird verstanden, wann eine Variable für |PS| nutzbar ist. Erläutern Sie die Ausgabe in folgender Abbildung: .. image:: images/scope_1.png |PS| erzeugt für jedes Skript eine eigene Variablenumgebung, die zunächst nichts miteinander zu tun hat. Der Aufruf des Skripts innerhalb der gleichen Umgebung mit Hilfe von *.\test.ps1* führte zum Erzeugen einer neuen Umgebung. Erst der richtige Aufruf innerhalb der Konsole führt dazu, dass das Skript gleichsam in der eigenen Variablenumgebung läuft. Finden Sie den kleinen Unterschied zum ersten Bild ?? .. image:: images/scope_2.png Erst ween das Skript "dot-sourced" aufgerufen wird, befindet es sich in der gleichen Variablenumgebung wie die Konsole und benutzt nun die gleichen Variablen. .. image:: images/scope_3.png Die Gültigkeit von Variablen war mit den bisherigen Verfahren entweder als "ganz oder gar nicht" zu bezeichnen. |PS| kennt noch eine andere Art, um die Gültigkeit von Variablen zu definieren., nämlich mit Hilfe der Modifier **private, local, script, global**. .. image:: images/scope_4.png .. todo:: detaillierter über die Konsequenzen der verschiedenen Scopes werden .. note:: Tafelbild Tafelbild zu Scope .. image:: images/scope_5.png .. image:: images/scope_6.png Typisiert vs. untypisiert ========================= Die Werte, die einer Variable zugewiesen werden können, stellen häufig einen numerischen Wert oder einen Zeichenwert dar. Man spricht deshalb vom **Typ** einer Variable, bzw. dem sog. **Datentyp**. Dies kann z.B. eine Ganzzahl (int) oder eine Gleitkommazahl (double) sein. Wichtig an dieser Tatsache ist, dass die Festlegung einer Variable auf einen bestimmten Typ Auswirkungen auf die weitere Benutzung hat. Insbesondere bei der Verbindung mit **Operatoren** erhält man manchmal überraschende Ausgaben, wie die obigen bilder gezeigt haben. Manche Programmiersprachen legen Wert darauf, dass die Variablen bei der Deklaration einen Datentyp **explizit** zugewiesen bekommen müssen (sog. typisierte Programmiersprachen, z.B. c#). Andere Programmiersprachen machen diese Zuweisung zu einem Datentyp **implizit**, d.h. ohne Zutun des Programmierers wird einer Variablen ein Datentyp zugewiesen. |PS| lässt zunächst eine untypisierte Schreibweise zu; intern arbeitet es aber mit der typisierten Form der Variable. Um den Datentyp einer Varibalen zu erhalten, kann man hinter die Variable den Befehl GetType().Name stellen. Beispiel: .. code-block:: sh (12).GetType().Name Int32 (1000000000000).GetType().Name Int64 (12.5).GetType().Name Double (12d).GetType().Name Decimal ("H").GetType().Name String (Get-Date).GetType().Name DateTime Powershell sucht den am besten passenden Datentyp automatisch heraus, was als sog. *weakly typed* bezeichnet wird. Dies kann auch negative Konsequenzen haben, weshalb man häufig explizit einen Datentyp angibt. Viele Datentypen haben auch ihre eigenen Hilfsfunktionen, die nur bei der korrekten Zuweisung des Datentyps vorhanden sind. Beispiel: .. code-block:: sh $date = "November 12, 2010" $date November 12, 2004 # als datetime bietet die Variable mehr Möglichkeiten [datetime]$date = "November 12, 2004" $date Friday, November 12, 2004 00:00:00 $date.AddDays(60) Tuesday, January 11, 2005 00:00:00 #auch xml-Dateien sind plötzlich sehr einfach # PowerShell stores a text in XML format as a string: $t = "" + "" $t # If you assign the text to a data type[xml], you'll # suddenly be able to access the XML structure: [xml]$list = $t $list.servers server ------ {PC1, PC2} $list.servers.server name ip ---- -- PC1 10.10.10.10 PC2 10.10.10.12 # Even changes to the XML contents are possible: $list.servers.server[0].ip = "10.10.10.11" $list.servers name ip ---- -- PC1 10.10.10.11 PC2 10.10.10.12 # The result could be output again as text, including the # modification: $list.get_InnerXML() Typ erzwingen ============= PowerShell kennt im Gegensatz zu C# keine Datentypen und ist damit untypisiert; man kann dieses Verhalten aber erzwingen, indem man den Datentyp in eckigen Klammern voranstellt. .. code-block:: sh PS> $a = "hello" # Implizites Zuweisen des Datentyps string zur Variable [int]$b = 5 # Explizites Zuweisen des Datentyps int $a.GetType(); IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True String System.Object $b.getType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Int32 System.ValueType Powershell kennt und benutzt die Datentypen des .NET-Frameworks. Eine Übersicht über gängige Datentypen und deren Eigenschaften finden Sie unter http://msdn.microsoft.com/de-de/library/1dhd7f2x.aspx Aufruf von Befehlen über eine Variable ====================================== You can use the PowerShell call operator "&". Here is a simple example: $a = "Get-Process" & $a There is a caveat with using this since the call operator can only operate against a single command. If you were to modify the above like this: $a = "Get-Process w*" & $a you will get an error. To get around this use Invoke-Expression as follows: $a = "Get-Process w*" Invoke-Expression $a See Get-Help Invoke-Expression -examples to get more examples on the usage of Invoke-Expression. .. _powershell_datentypen: Powershell-Datentypen --------------------- :: ====================================================== Typ Beschreibung ====================================================== array Liste von Werten bool Ja-Nein-Wert char Unicode Zeichen byte Integer 8 Bit datetime Datumswert decimal Dezimal double Gleitkomma guid Eindeutige Zahl hashtable int 16/32/64 Ganzzahl sbyte single string Zeichenkette timespan Zeitspanne xml .... ====================================================== Zusammenfassung =============== - Variablen speihern jede Art von Information - Sie beginnen immer mit dem "$"-Zeichen. Anschließend können Sie aus alphanumerischen und Sonderzeichen (z.B. Unserscore) bestehen - Groß- und Kleinschreibung spielt keine Rolle - "Konstante" Variablen ändern ihren Wert nicht mehr - |PS| hat schon selbst gewisse Variablen definiert (automatische Variablen) - |PS| sorgt dafür, dass der Typ einer Variable zum Typ des zu speichernden Wertes passt (weakly typing) - |PS| unterstützt Strong-Typing durch Voranstellen des Datentyps in eckigen Klammern [] - |PS| erstellt die Variablen jeweils innerhalb eines gewissen Gültigkeitsbereichs (local, private, script, global) - An Umgebungsvariablen kann durch $env: zugegriffen werden :ref:`powershell_datentypen` .. index:: Operator, Typisiert, Untypisiert, Variable, Datentyp, case-sensitive, cmdlet, Test-Path, Umgebungsvariable, Gültigkeit, Scope