Behandelte Themen
Arbeiten mit COM-Klassen
1.1COM-Klassen des Windows Scripting Hosts
Beispiel 1a) Erstellen eines Shortcuts mit VBS (WshShortcut_Object)
Beispiel 1b) Erstellen eines Shortcuts mit Powershell
1.2COM-Klassen der Script Runtime
Beispiel 1a: Erstelldatum eines Ordners über die Eigenschaft "datecreated" aus dem FileSystemObject feststellen
Beispiel 1b: Erstelldatum eines Ordners über die Eigenschaft "creationtime" der [DirectoryInfo]-Klasse feststellen
1.3Auflisten aller registrierten COM-Klassen
1.4Mit COM-Klassen Office automatisieren
Beispiel 1: Neue Excelmappe öffnen und eine Zelle beschreiben
Beispiel 2: Neue Excelmappe öffnen unter Einsatz des CultureInfo-KlasseSystem.__ComObject
******************************************************************************************************
1 Arbeiten mit COM-Klassen
Die COM Automation ist seit langer Zeit ein Standard zum Skripten von Aufgaben in der Systemadministration. Jeder VBS-Programmierer hat mehr oder weniger unbewusst schon intensiv mit dieser Schnittstelle gearbeitet.
Selbstverständlich stehen die COM-Klassen auch in der Powershell zur Verfügung, wobei viele Aufgaben hier üblicherweise mittels cmdlets und .Net-Klassen erledigt werden. Viele Anwendungen wie das MS-Office Paket bringen ihre eigenen COM-Objekte mit, die man nach wie vor für deren Automation verwenden muss.
Hat man sich ein COM-Objekt aus einer Klasse erstellt, so kann man genauso mit dessen Methoden und Eigenschaften arbeiten, wie mit jedem anderen Powershellobjekt.
Die COM-Klassen sind nicht ganz so einheitlich aufgebaut wie .Net-Klassen, dennoch spricht aus meiner Sicht nichts gegen die Verwendung dieses Automation Interfaces.
Wichtige COM-Klassen befinden sich im
1.1 COM-Klassen des Windows Scripting Hosts
Eine Auflistung der COM-Objekte mit VBS-Beispielen des WSHs findet man unter
Enables an author to sign a script with a digital signature and a recipient to verify the signature's authenticity and trustworthiness. | |
Provides access to most of the objects, methods, and properties in the WSH object model. | |
Gives you access to the entire collection of command-line parameters — in the order in which they were originally entered. | |
Exposes the method CreateScript() that creates a remote script process. | |
Gives you access to the collection of Microsoft Windows system environment variables. | |
Provides access to the named command-line script arguments within the WshArguments object. | |
Gives you access to the shared resources on the network to which your computer is connected. | |
Provides access to the remote script process. | |
Exposes the error information available when a remote script (a WshRemote object) terminates as a result of a script error. | |
Provides status and error information about a script run with Exec, along with access to the stdIn, stdOut, and stdErr channels. | |
Gives you access to the native Windows shell functionality. | |
Allows you to create a shortcut programmatically. | |
Allows you to access the Windows Special Folders. | |
Provides access to the unnamed command-line script arguments within the WshArguments object. | |
Allows you to create a shortcut to an Internet resource, programmatically. |
Beispiel 1a) Erstellen eines Shortcuts mit VBS (WshShortcut_Object)
#VBS-Script
# msdn.microsoft.com/en-us/library/xk6kst2k(VS.85).aspx
set WshShell = WScript.CreateObject("WScript.Shell")
strDesktop = WshShell.SpecialFolders("Desktop")
set oShellLink = WshShell.CreateShortcut(strDesktop & "\Shortcut Script.lnk")
oShellLink.TargetPath = WScript.ScriptFullName
oShellLink.WindowStyle = 1
oShellLink.Hotkey = "CTRL+SHIFT+F"
oShellLink.IconLocation = "notepad.exe, 0"
oShellLink.Description = "Shortcut Script"
oShellLink.WorkingDirectory = strDesktop
oShellLink.Save
Beispiel 1b) Erstellen eines Shortcuts mit Powershell
# Powershellskript
$Shell = new-object -com "Wscript.Shell"
$Desktop=$Shell.SpecialFolders.Item("Desktop")
$ShellLink=$shell.CreateShortcut("$Desktop\Shortcut Powershell2.lnk")
$ShellLink.Targetpath = "powershell.exe"
$ShellLink.WindowStyle=1
$ShellLink.Hotkey ="CTRL+SHIFT+P"
$ShellLink.IconLocation = 'powershell.exe,1'
$ShellLink.Description="Shortcut Powershell"
$ShellLink.WorkingDirectory=$Desktop
$ShellLink.save()

1.2 COM-Objekte der Script Runtime
Eine Auflistung der COM-Objekte der "Script Runtime" mit VBS-Beispielen des WSHs findet man unter:
Explains the concept of the Dictionary object and links to its methods and properties. | |
Links to the FileSystemObject basics and FileSystemObject reference sections. | |
Provides an overview of the Script Encoder command-line tool and links to topics that explain how to use it. |
Beispiel 1a: Erstelldatum eines Ordners über die Eigenschaft "datecreated" aus dem FileSystemObject feststellen
$foldername="C:\Temp"
$fso=new-object -com "Scripting.FileSystemObject"
$folder=$fso.getfolder($foldername)
$folder.datecreated
#Ausgabe
Donnerstag, 14. Januar 2010 12:01:05
Beispiel 1b: Erstelldatum eines Ordners über die Eigenschaft "creationtime" der [DirectoryInfo]-Klasse feststellen
#Skript zum Abfragen des Erstellungsdatums eines Ordners mit .Net
$foldername="C:\Temp"
$a=new-object system.io.directoryinfo("$foldername")
$a.creationtime
#Ausgabe
Donnerstag, 14. Januar 2010 12:01:05
1.3 Auflisten aller registrierten COM-Klassen
#Skript
$a = dir REGISTRY::HKEY_CLASSES_ROOT\CLSID -include PROGID -recurse | foreach {$_.GetValue("")}
$a
#Bzw.
$a|Where{$_ -like "*Scripting*"} #Wscript ist eine andere interessante Bibliothek für VBSler
#Ausgabe
Scripting.Dictionary
Scripting.Encoder
Scripting.FileSystemObject
Scripting.Signer
Mit get-member kann man sehr schön die verfügbaren Methoden und Eigenschaften von Filesystemobject erforschen
New-Object -com scripting.filesystemobject | Get-Member
#gekürzte Ausgabe
TypeName: System.__ComObject#{2a0b9d10-4b87-11d3-a97a-00104b365c9f}
Name MemberType Definition
---- ---------- ----------
...
CreateFolder Method IFolder CreateFolder (string)
CreateTextFile Method ITextStream CreateTextFile (string, bool, bool)
DeleteFile Method void DeleteFile (string, bool)
DeleteFolder Method void DeleteFolder (string, bool)
DriveExists Method bool DriveExists (string)
FileExists Method bool FileExists (string)
...
1.4 Mit COM-Klassen Office automatisieren
Hier folgt nur ein kurzer Abschnitt über Powershell und Office, um in erster Linie die Verwendung von COM-Klassen zu demonstrieren. Eine ausführlichere Beschreibung der Steuerung besonders von Excel findet man im Kapitel
Beispiel 1: Neue Excelmappe öffnen und eine Zelle beschreiben
#deutsches Excel auf deutschem OS
$excel = new-object -com excel.application
$excel.visible=$true
$excel.workbooks.add()
$excel.cells.item(1,1)="4711"
Öffnet entweder eine neue Excelinstanz und schreibt "4711" in die obere, linke Zelle, oder wirft folgenden Fehler aus, wenn ein englisches Excelpaket auf einem deutschem Betriebssystem installiert ist
#Fehler
Ausnahme beim Aufrufen von "Add" mit 0 Argument(en): "Altes Format oder ungültige Typbibliothek. (Ausnahme von HRESULT: 0x80028018 (TYPE_E_INVDATAREAD))"
Bei Zeile:3 Zeichen:21
+ $excel.workbooks.add <<<< ()
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ComMethodTargetInvocation
Abhilfe bringt die CultureInfo-Klasse, wie im nächsten Beispiel gezeigt wird.
Beispiel 2: Neue Excelmappe öffnen unter Einsatz des CultureInfo-Klasse
# Englisches Office auf deutschem OS
$excel = New-object -com Excel.Application
$CI = [System.Globalization.CultureInfo]'en-Us'
$excel.workbooks.psbase.gettype().InvokeMember("Add", [Reflection.BindingFlags]::InvokeMethod, `
$null, $excel.workbooks, $null, $ci)
$workbook.name
#Ausgabe
Book1
Um in Excel Objekte weiter zu erforschen, bietet sich der Objektkatalog an, den man in Excel über die VBA -Umgebung ("Alt-F11") und dort mit F2 öffnen kann. Eine nähere Beschreibung findet sich im

2 System.__ComObject
(Lesen und lesbar machen von bestimmten LDAP-Attributen)
Bei LDAP-Queries gegen das ActiveDirectory erhält man bei einigen Eigenschaften nicht direkt einen verwertbaren Wert zurück, sondern den auf den ersten Blick ziemlich wertlosen Eintrag "system.__comobject"
$DomRoot=[ADSI]"" #gleichwertig zu [ADSI]"LDAP://DC=testdom,DC=intern"
$DomRoot | select *pwd*, lock*, *time*
maxPwdAge : {System.__ComObject}
minPwdAge : {System.__ComObject}
minPwdLength : {7}
pwdProperties : {1}
pwdHistoryLength : {24}
lockoutDuration : {System.__ComObject}
lockOutObservationWindow : {System.__ComObject}
lockoutThreshold : {0}
creationTime : {System.__ComObject}
von einigen Properties wie minPwdLength erhält man direkt aussagefähige Werte, einige muss man zu interpretieren wissen wie die pwdProperties
Hier jetzt sofort das Skript, das einige dieser Properties meiner Testdomäne bestimmt hat, nicht ohne den Hinweis, dass der entscheidende Teil des Skripts, nämlich die Funktion ConvertADSLargeInteger, von dieser Site stammt: bsonposh.com
$domroot=[ADSI]""
$domroot | select *pwd*,lock*, *time* #oberer Teil der Ausgabe
function ConvertADSLargeInteger([object] $adsLargeInteger)
{
$highPart = $adsLargeInteger.GetType().InvokeMember("HighPart", [System.Reflection.BindingFlags]::GetProperty, $null, $adsLargeInteger, $null)
$lowPart = $adsLargeInteger.GetType().InvokeMember("LowPart", [System.Reflection.BindingFlags]::GetProperty, $null, $adsLargeInteger, $null)
$bytes = [System.BitConverter]::GetBytes($highPart)
$tmp = [System.Byte[]]@(0,0,0,0,0,0,0,0)
[System.Array]::Copy($bytes, 0, $tmp, 4, 4)
$highPart = [System.BitConverter]::ToInt64($tmp, 0)
$bytes = [System.BitConverter]::GetBytes($lowPart)
$lowPart = [System.BitConverter]::ToUInt32($bytes, 0)
return $lowPart + $highPart
# Funktion von bsonposh.com
}
"maxPwdAge: $((ConvertADSLargeInteger $domroot.maxpwdage.value)/-864000000000)"
"minPwdAge: $((ConvertADSLargeInteger $domroot.minpwdage.value)/-864000000000)"
"lockoutduration: $((ConvertADSLargeInteger $domroot.lockoutduration.value)/-864000000000*24*60)"
$ticks=ConvertADSLargeInteger $domroot.creationtime.value
$datum=[DateTime]::FromFileTime($ticks)
"CreationTime: $($datum.datetime)"
maxPwdAge : {System.__ComObject}
minPwdAge : {System.__ComObject}
minPwdLength : {7}
pwdProperties : {1}
pwdHistoryLength : {24}
lockoutDuration : {System.__ComObject}
lockOutObservationWindow : {System.__ComObject}
lockoutThreshold : {0}
creationTime : {System.__ComObject}
maxPwdAge: 42
minPwdAge: 2
lockoutduration: 30
CreationTime: Freitag, 9. Juli 2010 11:49:27
Leider sind nicht alle {System.__Object} Werte LargeIntegerwerte. Beispielsweise ist die Eigenschaft "wellknownproperties" ist vom Typ "ADSTYPE_DN_WITH_BINARY".
MSDN: Binding to Well-Known Objects Using WKGUID
Für die Konvertierung solcher {System.__Object} -Werte muss man eigene Funktionen erstellen. Ich habe zumindest keine gefunden.