Im zweiten Beitrag der Beitragsreihe "Evolution of dPEX" beschäftigen wir uns mit dem mehrfachen Verbindungsaufbau zur DSM SOAP Schnittstelle und ergänzen das dPEX Modul.
Problem mit New-WebserviceProxy -Namespace
Wird eine Verbindung zum DSM Administrationservice aufgebaut, so wird mit dem Commandlet „New-WebserviceProxy“ eine Referenz auf die Funktionen und Variablen des Administrationservice erzeugt. Alle Funktionen werden dabei in den Namespace „DSM“ eingeordnet.
PS > New-DSMScriptingEnvironment Solsv001
PS > $administrationService.GetType().fullname
DSM.AdministrationService

Es gibt allerdings keine Möglichkeit den Namespace wieder aufzulösen, sodass ein weiterer Versuch einer Verbindung (zum gleichen oder anderen DSM Administrationsservice) fehlschlägt.

Erzeugt man eine Verbindung ohne „-Namespace DSM“, erhält man immer einen automatisch neu generierten „Namespace“.
PS > $administrationService2 = New-WebServiceProxy
–Uri "http://solsv001:8080/blsadministration/administrationservice.asmx"
-UseDefaultCredential
PS > $administrationService2.GetType().Fullname
Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceP
roxy4ion_administrationservice_asmx.AdministrationService
Man könnte diesen Namspace nun einfach benutzen, was aber Probleme mit der Adressierung von Objekttypen im Modul nach sich zieht. Die Lösung dieses Problems findet man in den TypeAcceleratoren.
TypeAccelerators
Powershell benutzt zur einfacheren Adressierung einiger Objekttypen sog. TypeAccelerators. Ein sehr bekanntes Beispiel dafür ist „xml“. Man kann ein neues Objekt erzeugen, indem man einfach
PS > $obj = new-object xml
eingibt. Schaut man sich das Objekt danach an, erkennt man, dass eigentlich ein Objekt vom Typ: „System.Xml.XmlDocument“ erzeugt wurde.
PS > $obj.gettype()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False XmlDocument System.Xml.XmlNode
PS > $obj.GetType().fullname
System.Xml.XmlDocument
Man kann diese TypeAccelerators einsehen und bearbeiten.
PS > $TAType = [System.Management.Automation.PSObject].Assembly.GetType('System.Management.Automation.TypeAccelerators', $true, $true)
PS > $TAType | GM -Static
TypeName: System.Management.Automation.TypeAccelerators
Name MemberType Definition
---- ---------- ----------
Add Method static System.Void Add(string typeName, type type)
Equals Method static bool Equals(System.Object objA, System.Obj...
ReferenceEquals Method static bool ReferenceEquals(System.Object objA, S...
Remove Method static bool Remove(string typeName)
Get Property System.Collections.Generic.Dictionary`2[[System.S...
PS > $TAType::get
Key Value
--- -----
int System.Int32
long System.Int64
string System.String
char System.Char
bool System.Boolean
byte System.Byte
double System.Double
decimal System.Decimal
float System.Single
single System.Single
regex System.Text.RegularExpressions.Regex
array System.Array
xml System.Xml.XmlDocument
scriptblock System.Management.Automation.ScriptB...
switch System.Management.Automation.SwitchP...
hashtable System.Collections.Hashtable
type System.Type
ref System.Management.Automation.PSRefer...
psobject System.Management.Automation.PSObject
pscustomobject System.Management.Automation.PSObject
psmoduleinfo System.Management.Automation.PSModul...
powershell System.Management.Automation.PowerShell
runspacefactory System.Management.Automation.Runspac...
runspace System.Management.Automation.Runspac...
ipaddress System.Net.IPAddress
wmi System.Management.ManagementObject
wmisearcher System.Management.ManagementObjectSe...
wmiclass System.Management.ManagementClass
adsi System.DirectoryServices.DirectoryEntry
adsisearcher System.DirectoryServices.DirectorySe...
psprimitivedictionary System.Management.Automation.PSPrimi...
Zur einfacheren Verarbeitung habe ich 3 Funktionen geschrieben, welche TypeAccelerators lesen, setzen/hinzufügen und löschen können. Ähnliche Codebeispiele findet man auch auf mehreren Webseiten.
Add-TypeAccelerator
Get-TypeAccelerator
Remove-TypeAccelerator
dPEX Modulerweiterung
Mit diesen Informationen passen wir das dPEX Modul an.
- Wir integrieren die Funktionen „TypeAccelerators“ ins Modul
- Bei jedem Verbindungsaufbau über „New-DSMScriptingEnvironement“ werden TypeAccelerators auf alle exportierten Funktionen des Administrationsservice gesetzt.
- Beim entfernen des Moduls werden die TypeAccelerators entfernt.
In dPEX.psm1 wird das Skript mit den 3 „TypeAccelerator“-Funktionen geladen.

In dPEX.Base.ps1 definieren wir eine Variable, die die aktuell gesetzten TypeAccelerators des Administrationsservice speichert ($acceleratedTypes).

Zusätzlich erweitern wir die Funktion “New-DSMScriptingEnvironment” um das Setzen der TypeAccelerators und entfernen die Option „-Namespace DSM“ von „New-WebserviceProxy“.

Weil wir nicht alle Skripte überarbeiten wollen, setzen wir die TypeAccelerators so, dass der Typename jedes Accelerators „DSM.xxx“ ist.
PS > Get-TypeAccelerator -TypeName DSM.GetServerInfoRequest | FL
Typename : DSM.GetServerInfoRequest
Type : Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy1ion_admini
strationService_asmx.GetServerInfoRequest
Beim Entfernen des Moduls dPEX werden alle gesetzten TypeAccelerators wieder entfernt (dPEX.psm1).

Mit dieser Änderung ist eine mehrfache Ausführung der Funktion "New-DSMScriptingenvironment" in einer Powershell-Session ohne weiteres möglich, ohne den bestehenden Code der restlichen Funktionen überarbeiten zu müssen.
Ausblick
Im kommenden Blog kümmern wir uns um die Optimierung und Erweiterung einiger grundlegender Funktionen und gehen dabei auf das Handling der Powershell Pipeline ein.