Es soll schon vorgekommen sein, dass Administratoren eines Netzwerks irgendwann
über den von ihnen verantworteten Maschinen-Park den Überblick verloren haben.
Dann kommen so Fragen wie: "Wo steht noch mal der P4-Rechner der vorletzte Woche
geliefert wurde?", "Bei wieviel Maschinen muss ich denn noch ein paar Speicherriegel
nachrüsten?", "Haben inzwischen alle Rechner 3COM-Netzwerkkarten?". Ist das
Netzwerk etwas größer, dann wird der Ruf nach einer entsprechenden Inventar-Software
für viel Geld recht schnell laut. Wie man mit Windows-Bordmitteln an ein paar
grundlegende Informationen herankommt soll dieser Artikel zeigen.
Ausgangspunkt der Überlegung war die sog. Windows Management Instrumentation-Schnittstelle,
kurz WMI, die Microsoft mit Windows 2000 eingeführt hat. WMI ist die Redmond'sche
COM-Implementierung des Industriestandards WBEM (Web-Based Enterprise Management),
der es sich zum Ziel gesetzt den Zugriff auf Systeminformationen zu vereinheitlichen
und zu vereinfachen. Microsoft bietet dem interessierten Entwickler ein kostenloses
SDK an, dass so nützliche Tools wie den "WMI Object Browser" und das "WMI CIM
Studio" enthält, mit denen man durch die einzelnen WMI-Objekte browsen kann,
um sich einen Überblick zu verschaffen. Die komplette Dokumentation und die
Tools gibt es in der
WMI Platform SDK des MSDN.
Im Prinzip kann man mit WMI einen Rechner vollständig analysieren und administrieren.
Wir konzentrieren uns hier jedoch erstmal auf das automatisierte Auslesen von
ein paar Basis-Informationen. Dabei sollen die IP-Adressen eines kompletten
Subnetzes gescannt werden und die Informationen aller gefundenen Maschinen in
eine Excel-Tabelle eingetragen werden. Aus diesem Grund verwenden wird hier
gleich ein Excel-Arbeitsblatt und schreiben VBA-Code.
Um die Ausgabe des Codes zu strukturieren und gut lesbar zu machen,
geben wir eine Tabellenstruktur vor, in der in den ersten 3 Zeilen Input-Daten
und Schaltflächen abgelegt sind. Ab Zeile 5 beginnt der Datenbereich den der
zu schreibende Code füllen soll:

Zwei Schaltflächen bzw. Funktionen sind für die Steuerung der Liste vorgesehen.
Zum einen "Liste neu erstellen" (Funktion:
GetInventar),
die den kompletten Datenbereich neu aufbaut, und "Leere Zeilen aktualisieren"
(Funktion: RefreshList), die all jene IP-Adressen
noch einmal abfragt, deren Rechner bei einem früheren Lauf nicht verfügbar waren.
Funktion GetInventar
Diese Funktion beinhaltet lediglich die Steuerung über den Datenbereich der
Tabelle. Die eigentlichen Daten werden in der weiter unten im Artikel beschriebenen
Funktion GetWMIInfo ermittelt. Es wird zunächst aus
dem Arbeitsblatt ausgelesen welches Subnetz und welcher IP-Adressbereich bearbeitet
werden soll (Input-Daten in Zelle B1 und D1/D2) und dann wird in einer Schleife
jede der daraus generierten IP-Adressen per WMI angesprochen.
Sub GetInventar()
Dim i As Integer
Dim j As Integer
Dim strSubNetz As String
Dim intRangeF As Integer
Dim intRangeT As Integer
Dim strIP As String
Dim intRow As Integer
Const intStartRow = 5
Application.Cursor = xlWait
'Tabellenbereich leeren
Range("A" & intStartRow & ":Z500").Select
Selection.ClearContents
'SubNetz ermitteln
strSubNetz = Cells(1, 2)
If Len(strSubNetz) = 0 Then
MsgBox "Bitte Subnetz angeben", vbExclamation
Exit Sub
End If
'zu inventarisierenden IP-Bereich ermitteln
intRangeF = CInt(Cells(1, 4).FormulaR1C1)
intRangeT = CInt(Cells(2, 4).FormulaR1C1)
'IP-Bereich überprüfen
If intRangeT < intRangeF Or intRangeF <= 0 Or intRangeT > 255 Then
MsgBox "Der angegebene IP-Bereich ist nicht korrekt!",vbExclamation
Exit Sub
End If
intRow = intStartRow
'Schleife durch IP-Bereich...
For i = 0 To (intRangeT - intRangeF)
Cells(intRow, 1).Select
strIP = strSubNetz & "." & intRangeF + i
'IP-Adresse eintragen
Cells(intRow, 1).FormulaR1C1 = strIP
'WMI-Infos abfragen und eintragen
Call GetWMIInfo(strIP, intRow)
intRow = intRow + 1
ActiveWorkbook.RefreshAll
Next
Application.Cursor = xlDefault
MsgBox "Fertig!", vbInformation
End Sub
Funktion RefreshList
Diese Funktion ist ebenso eine reine Steuerungsfunktion, die jedoch im Gegensatz
zur vorhergehenden Funktion lediglich die noch nicht ermittelten Informationen
im Datenbereich erneut überprüft. Steuerungsmerkmal ist hierbei der Hostname,
d.h. der Rechnername. Ist dieser nicht vorhanden, war der Rechner mit der entsprechenden
IP-Adresse in einem früheren Lauf nicht verfügbar.
Public Sub RefreshList()
Dim i As Integer
Dim strIP As String
Dim intRow As Integer
Const intStartRow = 5
Application.Cursor = xlWait
i = intStartRow
'Alle Zeilen durchlaufen...
Do Until Len(Cells(i, 1).FormulaR1C1) = 0
strIP = Cells(i, 1).FormulaR1C1
'... und prüfen, ob der Hostname eingetragen ist
'Wenn nicht, WMI-Infos abfragen
If Len(Cells(i, 2).FormulaR1C1) = 0 Then
Cells(i, 1).Select
Call GetWMIInfo(strIP, i)
End If
i = i + 1
ActiveWorkbook.RefreshAll
Loop
Application.Cursor = xlDefault
MsgBox "Fertig!", vbInformation
End Sub
Funktion GetWMIInfo
Diese, in beiden Steuerungsfunktionen verwendete Funktion, ist das eigentliche
Arbeitstier der Inventur. Über die beiden Parameter strIP
und intRow wird zum einen festgelegt welche IP-Adresse
angesprochen werden soll und zum anderen in welche Zeile des Arbeitsblatts die
ermittelten Daten eingetragen werden sollen.
Private Sub GetWMIInfo( _
ByVal strIP As String, _
ByVal intRow As Integer)
Dim objWMIService As Object
Dim col As Object
Dim obj As Object
Dim intCol As Integer
On Error Resume Next
'Erste Spalte zur Eintragung festlegen
intCol = 2
'WMIService mit der IP-Adresse initialisieren
Set objWMIService = GetObject("winmgmts:" & _
"{impersonationLevel=impersonate}!\\" & strIP & "\root\cimv2")
'Wenn Computer erreichbar...
If Err = 0 Then
'...WMI-Abfrage auf 'Win32_ComputerSystem' ausführen
Set col = objWMIService.ExecQuery( _
"SELECT * FROM Win32_ComputerSystem")
For Each obj In col
'Hostname ermitteln
Cells(intRow, intCol).FormulaR1C1 = obj.Name
intCol = intCol + 1
'Model ermitteln
Cells(intRow, intCol).FormulaR1C1 = obj.Model
intCol = intCol + 1
'TotalPhysicalMemory ermitteln
Cells(intRow, intCol).FormulaR1C1 = obj.TotalPhysicalMemory
intCol = intCol + 1
'Rolle ermitteln
Select Case obj.DomainRole
Case 0: strRole = "Standalone Workstation"
Case 1: strRole = "Member Workstation"
Case 2: strRole = "Standalone Server"
Case 3: strRole = "Member Server"
Case 4: strRole = "Backup Domain Controller"
Case 5: strRole = "Primary Domain Controller"
End Select
Cells(intRow, intCol).FormulaR1C1 = strRole
intCol = intCol + 1
'Current User ermitteln
Cells(intRow, intCol).FormulaR1C1 = obj.UserName
intCol = intCol + 1
Next
'...WMI-Abfrage auf 'Win32_Processor' ausführen
Set col = objWMIService.ExecQuery("SELECT * FROM Win32_Processor")
For Each obj In col
'Prozessor ermitteln
Cells(intRow, intCol).FormulaR1C1 = Trim$(obj.Name)
intCol = intCol + 1
Next
'...WMI-Abfrage auf 'Win32_NetworkAdapterConfiguration' ausführen
Set col = objWMIService.ExecQuery( _
"SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True")
For Each obj In col
'Netzwerkadapter ermitteln und String kürzen
Cells(intRow, intCol).FormulaR1C1 = _
Replace(obj.Description," - Paketplaner-Miniport", "")
intCol = intCol + 1
'MAC-Adresse ermitteln
Cells(intRow, intCol).FormulaR1C1 = obj.MACAddress
intCol = intCol + 1
Exit For '(da nur der erste Adapter auslesen werden soll)
Next
Else
Err.Clear
End If
End Sub
Abschließend ist noch zu sagen, dass das Timeout bei der Initialisierung
eines WMI-Objekts bei ca. 60 Sekunden liegt, d.h. ein Subnetz mit nur 10 Rechnern
komplett zu scannen dauert sehr lange, da 254 IP-Adressen nicht vergeben sind.
Man sollte daher die Inventarisierung zum einen tagsüber durchführen, wenn die
Chance groß ist, dass viele Rechner an sind und eine Maschine verwenden, die
in diesem Moment nicht weiteres zu tun hat, um sich nicht in der Arbeit zu blockieren,
denn während die Inventarisierung läuft kann man mit Excel nicht weiterarbeiten.
Downloads
Inventar-Test.zip