Behandelte Themen

  1. Bestimmung der .Net-Klasse hinter einem cmdelt
    Beispiel 1: Untersuchen des cmdlets get-date
    Beispiel 2: Anwenden der Klasse System.DateTime

  2. der ObjectBrowser

  3. TypeAccelerators

  4. Assemblies
    Beispiel 1: Auflisten der geladenen Assemblies
    Beispiel 2: Nachladen einer Assembly

*********************************************************************************************************************

1 Bestimmung der .Net-Klasse hinter einem cmdelt


Beispiel 1: Untersuchen des cmdlets get-date

Dieses Beispiel zeigt, wie die dem Powershell-cmdlet "get-date" zugrunde liegende  .Net-Klasse "system.datetime" mit get-member bestimmt wird.

get-date | get-member

#verkürzte Ausgabe

   TypeName: System.DateTime

Name                 MemberType     Definition
----                 ----------     ----------
Add                  Method         System.DateTime Add(System.TimeSpan value)
AddDays              Method         System.DateTime AddDays(double value)
AddHours             Method         System.DateTime AddHours(double value)

die .Net-Klasse findet sich in der Zeile" TypeName: System.DateTime"

#Alternativ mit gettype()
(get-date).gettype().fullname

#Ausgabe
System.DateTime

 

Beispiel 2: Anwenden der Klasse System.DateTime

MSDN:  DateTime Structure

#Skript

[System.DateTime] $date1 = [System.DateTime]::Now
[System.DateTime] $date2 = [System.DateTime]::UtcNow
[system.datetime] $date3 = [system.DateTime]::Today

"Time is now        = $date1"
"Time in UTC now    = $date2"
"Time Today is      = $date3"

#Ausgabe
Time is now        = 02/15/2010 21:37:32
Time in UTC now    = 02/15/2010 20:37:32


Einige weitere Beispiele, wie Objekte der Klasse Datetime erzeugt werden können, findet ihr im Kapitel Das FileSystem -> 2.2.2 Zeiteigenschaften (CreationTime, LastAccessTime, LastWriteTime)  -> Beispiel 3.

 

2 Der Objectbrowser

Den Objectbrowser ist ein sehr nützliches, grafisches Tool zur Erforschung der .Net-Welt. Man kann damit .Net Klassen finden und deren Methoden und Eigenschaften herauslesen.

Mit VisualStudio2005 lässt sich nur .Net2.0 durchsuchen, ab VisualStudio2008 lässt sich auswählen, welches .Net-Paket durchsucht werden soll.

Der Objektbrowser ist in den völlig freien Express-Versionen von VisualStudio ebenfalls uneingeschränkt verfügbar

Über den Objektbrowser kann man zu jeder Methode/ Eigenschaft eine kurze Erklärung lesen. s.u.  Im Objektbrowser können ausserdem Eigenschaften/ Methoden aufgeführt werden, die in der Powershell nicht direkt aufrufbar sind z.B. die static-Eigenschaft “maxvalue” der Klasse [system.datetime] (s. Beispiel unten)

Über den Objektbrowser kann man zu jeder Methode/ Eigenschaft eine kurze Erklärung lesen. s.u.  Im Objektbrowser können ausserdem Eigenschaften/ Methoden aufgeführt werden, die in der Powershell nicht direkt implementiert sind z.B. die Eigenschaft “maxvalue”

Die Programmierung mittels Powershell-cmdlets und dem direkten Zugriff auf .Net-Klassen ist meist äquivalent. Nicht immer können alle Möglichkeiten der direkten DotNet-Programmierung auch über cmdelts erreicht werden können (z.B. [system.datetime]::maxvalue).

Folgende Beispiele zeigen Entsprechungen zwischen der DotNet und der PowershellSyntax

Dotnet-Syntax

Powershell-Syntax

[system.datetime]::now

get-date  oder  (get-date).datetime

[system.datetime]::now.addDays(3)

(Get-date).addDays(3)

[system.datetime]::maxvalue

Keine direkte Entsprechung, da Static

 

Tipp:

Um sich bei häufig benutzten Klassen Tipparbeit zu sparen, kann man die Klasse am Anfang des Skriptes in eine Variable speichern

#Skript

$datetime=[system.datetime]
$datetime::now

#ist identisch zu
[system.datetime]::now

 

Wann sollte man welche Syntax benutzen?

Wie man oben erkennen kann, kann man mit beiden Schreibweisen die identischen Befehle absetzen, zumindest meistens.

Ausnahmen sind,  zumindest habe ich bis jetzt noch kein Beispielskript gefunden, statische Methoden und Eigenschaften. Dies gelingt nur über die .NET Syntax

Die Powershell-Syntax ist oft kürzer und wird in den meisten Beispielskripten verwendet, natürlich auch die Beispiele in der Powershellhilfe. Mit der DotNet-Schreibweise kann man einheitlich auf die gesamte DotNet Welt zugreifen. Bei weitem nicht für alle Klassen gibt es Powershell-Entsprechungen.  Der Objektkatalog erleichtert die Suche nach der richtigen Klasse sehr.

Ein weiterer Vorteil ist die relativ leichte Portierbarkeit eines Powershellscripts in eine Sprache unter VisualStudio wie z.B. VisualBasic und umgekehr, was insbesondere bei Websuchen nach Beispielscripten sehr hilft.

Im Normalfall nutze ich die Powershell cmdlets. Trotzdem halte ich das Verständnis der dotnet-Syntax für sehr hilfreich, Powershellskripte zu verstehen. Gelegentlich z.B. im Bereich ActiveDirectory bringt der direkte DotNet-Zugriff Ergebnisse, die mit Powershell cmdlets schwieriger zu erreichen gewesen wären.

3 TypeAccelearators/ TypeShortcuts

TypeAccelearators bzw. TypeShortcuts sind Abkürzungen von Klassennamen.

TypeShortcut

Full Classname

[Adsi]

[System.DirectoryServices.Directoryentry]

[array]

[System.Array]

[hashtable]

[System.Collections.Hashtable]

[psobject]

[System.Management.Automation.PSObject]

[ref]

[System.Management.Automation.PSReference]

[regex]

[System.Text.RegularExpressions.Regex]

[scriptblock]

[System.Management.Automation.ScriptBlock]

[switch]

[System.Management.Automation.SwitchParameter]

[type]

[System.Type]

[wmi]

[System.Management.ManagementObject]

[wmiclass]

[System.Management.ManagementClass]

[wmisearcher]

[System.Management.ManagementObjectSearcher]

[xml]

[System.Xml.XmlDocument]

Mit diesen Shortcuts kann man sich Tippaufwand sparen und die Syntax ist einprägsamer, als ausgeschriebene Klassennamen. Trotzdem ist wichtig auch die Klassennamen hinter einenTypeAccelerator zu kennen, um z.B. im Objectkatalog eine Klasse zu untersuchen.

Referenzen:

Vgl.  http://blogs.msdn.com/powershell/archive/2006/07/12/type-shortcuts.aspx

Vgl. Windows-Powershell "kurz-gut" "Lee Holmes" 1. Auflage , S54


Die drei folgenden Beispiele zeigen den Einsatz von Typeshortcuts im Vergleich zur ausgeschriebenen Klassen

Beispiel 1 [ADSI]: Verbinden auf ein AD-Objekt 

#Skript

#Variablendefintion
$userDN="CN=Administrator,CN=Users,DC=dom1,DC=de"

# .Net Schreibweise"
$User = [System.DirectoryServices.DirectoryEntry]"LDAP://$userDN"

# Type-Accelerator ADSI 
$user=[ADSI]"LDAP://$userDN"

 

Beispiel 2 [WMI]: Umbenennen eines logischen Laufwerks (USB-Stick)

#mit powershell-cmdlet: get-wmiobject
$drive=get-wmiobject "win32_logicaldisk where name='L:'"
$drive.volumename="TRAVELDRIVE"
$[void]$drive.put()

#mit Typeaccelerator [wmi]
$drv=[wmi] "Win32_LogicalDisk.DeviceID='L:'"
$drv.volumename="TRAVELDRIVE"
$[void]$drv.put()

#mit vollständingem Klassennamen
$drv=[System.Management.ManagementObject]'Win32_LogicalDisk.DeviceID="L:"'
$drv.volumename="TRAVELDRIVE"
$[void]$drv.put()

 

 Beispiel 3 [Array]: Umwandlung (Casten) von skalaren Objekten in ein Feld

#mit dem Typeaccelerator
$a = [array] 6,9
$a[1]

#Ausgabe
9

 

#über die system-Klasse
$a = [system.array] 16,19
$a[1]

#Ausgabe
19

 

#Kurzform
$a = 26,29
$a[1]

#Ausgabe
29

 

 

 

4 Assemblies

Ein Assembly ist unter .Net eine Einheit von ausführbarem Code, der als Bibliothek (*.dll) oder als Programm (*.exe) vorliegt. Eine Assembly kann aus mehreren Dateien bestehen, die aber nur gemeinsam weitergegeben werden können. Auf einem Rechner können  mehrere Versionen von Assemblies nebeneinander existieren.

Assemblies können entweder im sogenannten Global Assembly Cache (GAC) zentral gepeichert sein unter c:\windows\assembly oder im Programmverzeichnis des auszuführenden Programms. Die Struktur von c:\windows\assembly wird übrigens vom Windowsexplorer nicht korrekt angezeigt. Die korrekte Struktur erkennt man z.B. über die Commandline.

 Für die Programmierung unter Powershell ist wichtig, dass die Assemblies die Klassen enthalten. Um die Klassen einer Assembly nutzen zu können, muss die Assembly von Powershell geladen werden. Default lädt Powershell bereits die wichtigsten Assemblies, werden zusätzliche Assemblies benötigt, müssen diese im Code geladen werden.

Beispiel 1: Auflisten der geladenen Assemblies

[appdomain]::currentdomain.getassemblies() |sort -property fullname | format-table fullname

#Ausgabe

FullName
--------
Microsoft.PowerShell.Commands.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
Microsoft.PowerShell.Commands.Management, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
Microsoft.PowerShell.Commands.Utility, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
Microsoft.PowerShell.ConsoleHost, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
Microsoft.PowerShell.Security, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
Microsoft.WSMan.Management, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Configuration.Install, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.DirectoryServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
System.Management, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
System.Management.Automation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
System.Transactions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

 Windows PowerShell Blog > .NET types

Beispiel 2: Nachladen der Assembly

 System.DirectoryServices.Protocols

[void][reflection.assembly]::LoadWithPartialName("System.DirectoryServices.Protocols")
[appdomain]::currentdomain.getassemblies() |sort -property fullname | format-table fullname

#Ausgabe gekürzt
FullName                                                                                                                              
--------                                                                                                                              
...                                                   
System.DirectoryServices, Version=2.0.0.0, Culture=neutral,                                          
System.DirectoryServices.Protocols, Version=2.0.0.0, Culture=neutral, #<---- wurde nachgeladen                             
System.Drawing, Version=2.0.0.0, Culture=neutral,    
.....

 Im VisualStudio entspricht dies dem Hinzufügen eines Verweises