Wenn Sie jemals ein WMI-Skript geschrieben haben, dann haben Sie möglicherweise auch schon das Attribute-werden-als-Array-gespeichert-Problem entdeckt. Und wenn Sie es nicht geschafft haben, das Problem zu lösen - machen Sie sich nichts draus. In der ersten Version des Scriptomatic haben die Scripting Guys die Multi-Value-Attribute einfach vergessen. Der Scriptomatic 1.0 hat einfach nicht immer alle Daten zurückgegeben (ein Problem, das mit Scriptomatic 2.0 behoben wurde).
Sie sind nicht ganz sicher, wovon wir eigentlich reden? Dann sehen Sie sich das folgende simple Skript an. Es gibt die MAC- und IP-Adressen jedes Netzwerkadapters eines Computers zurück:
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery _
("Select * From Win32_NetworkAdapterConfiguration Where IPEnabled = True")
For Each objItem in colItems
Wscript.Echo objItem.MACAddress
Wscript.Echo objItem.IPAddress
NextSieht harmlos aus, oder? Wenn Sie das Skript jedoch ausführen, passiert folgendes:
00:0D:56:F8:1C:3F C:\scripts\x.vbs(9, 5) Microsoft VBScript runtime error: Type mismatch
Wie Sie sehen, fängt das Skript mit der Ausgabe einer MAC-Adresse an. Das ist schon mal ganz gut. Aber dann bricht es mit der Fehlermeldung "Type mismatch" ab. Und zwar genau dann, wenn es die IP-Adresse ausgeben soll. Das ist irgendwie nicht so gut.
Das Problem liegt darin, dass ein Netzwerkadapter mehrere IP-Adressen haben kann. Daher werden diese als Array gespeichert (dies gilt auch für den Fall, dass der Netzwerkadapter gar keine IP-Adressen hat). Da das Attribut IPAddress ein Array ist, können Sie es nicht einfach ausgeben. Stattdessen müssen Sie die einzelnen Werte mit einer For/Each-Schleife durchgehen:
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery _
("Select * From Win32_NetworkAdapterConfiguration Where IPEnabled = True")
For Each objItem in colItems
Wscript.Echo objItem.MACAddress
For Each strAddress in objItem.IPAddress
Wscript.Echo strAddress
Next
NextDie Ausgabe sieht auf einem Computer mit einem Netzwerkadapter zum Beispiel so aus:
00:0D:56:F8:1C:3F 192.168.244.186
Viel besser.
Unter VBScript hätten wir das Problem also gelöst. Aber was, wenn Sie die neue Windows "Monad" Shell verwenden? Gibt es eine genauso einfach Lösung wie eine Schleife unter VBScript?
Um diese Frage zu beantworten, wollen wir uns ein Monad-Skript anschauen, das die IP-Adressen nicht über eine For/Each-Schleife zurückgibt:
$strComputer = "."
$colItems = get-wmiobject -class "Win32_NetworkAdapterConfiguration" -namespace "root\CIMV2" `
-computername $strComputer -filter "IPEnabled = true"
foreach ($objItem in $colItems) {
write-host "MACAddress: " $objItem.MACAddress
write-host "IPAddress: " $objItem.IPAddress
write-host
}Anmerkung: Bei Monad steht das Zeichen ` für einen Zeilenumbruch. Es entspricht dem Unterstrich (_) bei WSH und VBScript.
Die Ausgabe des Skriptes sieht so aus:
00:0D:56:F8:1C:3F 192.168.244.186
Aus der Fehlermeldung können wir klar erkennen, dass ... Moment, das Skript hat funktioniert. Und das ohne Schleife. Wie sich herausstellt, machen Monad Attribute mit Arrays im Gegensatz zu VBScript nichts aus. Monad kümmert sich selbst darum. Und das ist praktischer, als Sie denken. Sicher, es ist nicht besonders schwer, einen Array mit einer Schleife auszugeben. Was aber schwer ist, ist herauszufinden, welche Attribute einen Array speichern und welche nicht. Sehen Sie sich zum Beispiel das folgende Skript an:
On Error Resume Next
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery _
("Select * From Win32_NetworkAdapterConfiguration Where IPEnabled = True")
For Each objItem in colItems
Wscript.Echo objItem.MACAddress
Wscript.Echo objItem.IPAddress
NextDieses Skript gibt für das Attribut IPAddress keine Werte zurück. Das liegt daran, dass die Anweisung On Error Resume Next keine Fehlermeldung ausgibt. Da es keine Fehlermeldung gibt, gehen Sie möglicherweise davon aus, dass das Skript korrekt ausgeführt wurde und der Computer über keine IP-Adresse verfügt. Dies ist möglicherweise nicht korrekt und könnte später zu viel Stress und Arbeit führen (zum Beispiel dann, wenn Sie mehrere Stunden damit verbringen, herauszufinden, warum der Netzwerkadapter keine IP-Adresse hat).
Mit Monad haben Sie dieses Problem nicht. Monad gibt Single-Value- und Multi-Value-Attribute korrekt aus.