Windows, etc.

PC-Inventur mit Excel und WMI

Alle Rechner im lokalen Netzwerk inventarisieren

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
kick it on dotnet-kicks.de AddThis 0 wikio-Stimme(n) Trackback-Url...

Schlagworte

124 Kommentare bislang...

Dein Kommentar hierzu...


Kommentar-Feed für diesen Beitrag
Gravatare werden unterstützt .:. eMail-Adressen werden nicht veröffentlicht
 

RSS-Feed

Die URL des Standard-Newsfeed von zerbit.de lautet:

http://www.zerbit.de/rssfeed.aspx

Login


 

 

Statistik



kürzlich kommentiert

Artikel 9

  • Datum: 14.02.2005
    Kategorie: Windows, etc.
    Zugriffe: 11.809
    Kommentare: 124
    Trackbacks: 0

Letzte Beiträge

Kategorien

Buttons & More

Blog-Roll

Banner Piraten-Partei