tranceman84
Goto Top

VBA - Excel - Computername und Bezeichnung(description) aus Active Directory auslesen. Win2003 Domäne

Ich versuche aus einer Active Directory (Win 2003 Domäne) alle beinhalteten Computer und deren Bezeichnungen, unabhängig vom Container in dennen sie sich befinden, auszulesen.

Habe schon lange im Netz nach pasenden lösungen gesucht, aber leider keine richtige gefunden.
Wie man die Computernamen auslesen kann, habe ich bereits gefunden, aber nicht, wie man die dazugehörige Bezeichnung ausliest.

Die eigentliche Ermittlung des Computernamens steht in einer Funktion.
Die übertragung der Daten nach Excel findet in einem Modul statt.

Den Code beider habe ich euch unten eingefügt.

Hoffe ihr könnt mir helfen, ich bekomme das Auslesen der Bezeichnung einfach nicht integriert in den bestehenden Code.


Eingebundene Bibliotheken:
- VIsual Basic for Applications
- Microsoft Excel 11.0 Object Libary
- OLE Automation
- Microsoft Office 11.0 Object Libary
- Microsoft Forms 2.0 Object Libary
- Microsoft ActiveX Data Objects 2.5 Libary
- Active DS Type Libary
- Microsoft Access 11.0 Object Libary

Funktion:
Public Function AllComputers() As String()
  Dim conn As New Connection
  Dim rs As Recordset
 
  Dim Root As IADs
  Dim Domain As IADs
 
  Dim strBase As String
  Dim strFilter As String
  Dim strDomain As String
 
  Dim strAttr As String
  Dim strDepth As String
  Dim strQuery As String
  Dim strPC() As String
  Dim nElement As Integer
 
  On Error GoTo ErrHandler
 
  ReDim strPC(0) As String
 
  ' Pfad der gegenwärtigen Domäne (LDAP) einholen  
  Set Root = GetObject("LDAP://rootDSE")  
  strDomain = Root.Get("defaultNamingContext")  
  Set Domain = GetObject("LDAP://" & strDomain)  
 
  ' LDAP Base DN setzen  
  strBase = "<" & Domain.ADsPath & ">"  
 
  ' Filter auf die Kategorie Computer setzen  
  strFilter = "(&(objectCategory=Computer))"  
 
  ' Attribut setzen  
  strAttr = "name"  
  ' Suchtiefe setzen  
  strDepth = "subTree"  
 
  ' Abfrage zusammen setzen  
  strQuery = strBase & ";" & strFilter & ";" & strAttr & ";" & ";" & strDepth  
  Debug.Print strQuery
  ' Verbindung öffnen  
  conn.Open "Data Source=Active Directory Provider;Provider=ADsDSOObject"  
 
  ' Query ausführen  
  Set rs = conn.Execute(strQuery)

  Do While Not rs.EOF
    If strPC(0) = "" Then  
      nElement = 0
    Else
      nElement = nElement + 1
    End If

    ' das Array Redimensionieren  
    ReDim Preserve strPC(nElement) As String

    ' Den Computernamen in das Array schreiben  
    strPC(nElement) = rs("name")  
    rs.MoveNext
  Loop
 
  ' Das StringArray zurückgeben  
  AllComputers = strPC
 
  If rs.State <> 0 Then rs.Close
  If conn.State <> 0 Then conn.Close
 
' Error Handling  
ErrHandler:
  On Error Resume Next
  AllComputers = strPC
  Set rs = Nothing
  Set conn = Nothing
  Set Root = Nothing
  Set Domain = Nothing
End Function

Modul:

Private Sub AD_auslesen()
  Dim strA() As String
  Dim i As Long
  Dim i2 As Long 'Zähler Blatt ADtest  
     
  strA = AllComputers
  i2 = 1
    
  If Not strA(0) = "" Then  
    For i = 0 To UBound(strA)

            Sheets("ADtest").Select  
            Cells(i2, 1) = strA(i)
            i2 = i2 + 1

    Next
  End If
End Sub

[Edit Biber] Codeformatierung nachgezogen [/Edit]

Content-Key: 148023

Url: https://administrator.de/contentid/148023

Printed on: April 26, 2024 at 03:04 o'clock

Member: bastla
bastla Jul 30, 2010 at 16:51:47 (UTC)
Goto Top
Hallo tranceman84 und willkommen im Forum!

Es sollte doch genügen, die Zeile 34 auf
 strAttr = "name,description"
zu ergänzen, sodass in der Schleife ab Zeile 47 dann auch etwas in der Art von
strPCDescr(nElement) = rs("description")
(oder wie immer Du die Beschreibung speichern willst) möglich wird ...

Grüße
bastla
Mitglied: 48507
48507 Jul 30, 2010 at 16:54:32 (UTC)
Goto Top
Member: tranceman84
tranceman84 Jul 31, 2010 at 04:32:57 (UTC)
Goto Top
Hallo Bastla,

habe versucht das so einzubinden.
Leider bekomme ich die Variable strPCDescr nicht gefüllt.

Entweder bekommt die Schleife den Wert "" zurück oder es geht direkt in den Error Handler des Programms.

MfG
Tranceman84
Mitglied: 76109
76109 Jul 31, 2010 at 07:25:29 (UTC)
Goto Top
Hallo tranceman84!

Die Zeile 47 -60 könnte man auch durch diese Codezeilen ersetzen:
ReDim strPC(1 To rs.RecordCount) As String

Do Until rs.EOF
    strPC(rs.AbsolutePosition) = rs("name")  
    rs.MoveNext
Loop

Gruß Dieter

[edit] Kommentar geändert [/edit]
Member: bastla
bastla Jul 31, 2010 at 08:11:53 (UTC)
Goto Top
Hallo tranceman84!

Scheint etwas knifflig zu sein - versuch es damit:
Desc = rs("description")  
If Not IsNull(Desc) Then strPCDescr(nElement) = Desc(0)
(ob es hier so geklappt hat, ist mangels Feedback nicht eindeutig festzustellen).

Grüße
bastla
Member: tranceman84
tranceman84 Aug 02, 2010 at 05:43:22 (UTC)
Goto Top
Vielen Dank für den Tipp.
Aber das hat eigentlich nichts mit dem Problem "Bezeichnung auslesen" zu tun oder?
Member: tranceman84
tranceman84 Aug 02, 2010 at 05:47:08 (UTC)
Goto Top
Hi Bastla,

leider wieder ohne Erfolg.

Selbst das Programm, wo du diesen Lösungsansatz gefunden hast ist nicht lauffähig.
Habe ich gerade versucht zu testen.

Ich bin jetzt kein Experte in diesem Gebiet, eher im Gegenteil.
Ich habe fast den Eindruck, dass man die Bezeichnung über die Deklaration "description" ein der englischen Version von Win2003 Server so auslesen kann.
Wir haben die deutsche Variante installiert. Kann es sein, dass die Deklaration eventuell dann anders heisst?

MfG
Tranceman84
Member: bastla
bastla Aug 02, 2010 at 06:14:00 (UTC)
Goto Top
Hallo tranceman84!
Kann es sein, dass die Deklaration eventuell dann anders heisst?
Das zumindest wäre als Fehlerquelle auszuschließen - ansonsten fällt mir aber auch nix mehr ein face-sad (bei mir hat der Ansatz übrigens - als VBScript kurz am Server getestet - funktioniert) ...

Grüße
bastla
Mitglied: 76109
76109 Aug 02, 2010 at 06:41:39 (UTC)
Goto Top
Hallo tranceman84!

Zitat von @tranceman84:
Aber das hat eigentlich nichts mit dem Problem "Bezeichnung auslesen" zu tun oder?
Nö, dass hat es sicherlich nicht. Ein Server steht mir nicht zur Verfügung, insofern kann ich zu dem eigentlichen Problem leider nix beitragen.

Gruß Dieter
Member: tranceman84
tranceman84 Aug 02, 2010 at 06:54:15 (UTC)
Goto Top
Hallo an alle, das Problem habe ich lösen können.
Ich denke es ist nicht die optimalste Lösung, aber auf jedenfall funktioniert sie face-wink

Wenn mein Sub "AD_auslesen" gestartet wird, springt das Programm in die Function "AllComputers".
In der Function werden alle Computernamen der Domäne augelesen, in der der Benutzer angemeldet ist, der das Programm startet.
Das Ergbenis der Function (die komplette Computerübersicht) wird dann an das Sub "AD_auslesen" zurückgegeben, welches dann die Computernamen in Excel schreibt.
Danach wird das Sub "BezeichnungADauslsesen" gestartet, in dem die Eigentlichen Computerbezeichnungen (descriptions) in Verbindung mit den vorher gelesenen Computernamen ausgelesen und nach Excel zurückgegeben werden.

Den Quellcode für das Programm "BezeichnungADauslsesen" habe ich unter folgendem Link gefunden:
http://www.mcseboard.de/windows-server-forum-78/computer-beschreibung-a ...

An dieser Stelle möchte ich mich trotzdem nochmal bei allen beteiligten für die schnelle Hilfe bedanken.

MfG
Tranceman84

Hier nochmal der komplett lauffähige Code:
Sub AD_auslesen()
'Auslsesen der Computernamen der AD  
  
  Dim strA() As String
  Dim i As Long
  Dim i2 As Long 'Zähler Blatt ADtest  
     
  strA = AllComputers
  i2 = 1
    
  If Not strA(0) = "" Then  
    For i = 0 To UBound(strA)
        For i3 = 4 To Sheets("Ausnahmen").UsedRange.Rows.Count  
            Sheets("Ausnahmen").Select  
            If strA(i) = Cells(i3, 1) Then GoTo 10
        Next i3
        
        Sheets("ADtest").Select  
        Cells(i2, 1) = strA(i)
        i2 = i2 + 1
10:
    Next
  End If
End Sub

==========================================================

Public Function AllComputers() As String()
  Dim conn As New Connection
  Dim rs As Recordset
 
  Dim Root As IADs
  Dim Domain As IADs
 
  Dim strBase As String
  Dim strFilter As String
  Dim strDomain As String
 
  Dim strAttr As String
  Dim strDepth As String
  Dim strQuery As String
  Dim strPC() As String
  Dim nElement As Integer
 
  On Error GoTo ErrHandler
 
  ReDim strPC(0) As String
 
  ' Pfad der gegenwärtigen Domäne (LDAP) einholen  
  Set Root = GetObject("LDAP://rootDSE")  
  strDomain = Root.Get("defaultNamingContext")  
  Set Domain = GetObject("LDAP://" & strDomain)  
 
  ' LDAP Base DN setzen  
  strBase = "<" & Domain.ADsPath & ">"  
 
  ' Filter auf die Kategorie Computer setzen  
  strFilter = "(&(objectCategory=Computer))"  
 
  ' Attribut setzen  
  strAttr = "name"  
 
  ' Suchtiefe setzen  
  strDepth = "subTree"  
 
  ' Abfrage zusammen setzen  
  strQuery = strBase & ";" & strFilter & ";" & strAttr & ";" & strDepth  
 
  ' Verbindung öffnen  
  conn.Open "Data Source=Active Directory Provider;Provider=ADsDSOObject"  
 
  ' Query ausführen  
  Set rs = conn.Execute(strQuery)
 
  Do While Not rs.EOF
    If strPC(0) = "" Then  
      nElement = 0
    Else
      nElement = nElement + 1
    End If
 
    ' das Array Redimensionieren  
    ReDim Preserve strPC(nElement) As String
 
    ' Den Computernamen in das Array schreiben  
    strPC(nElement) = rs("name")  
    rs.MoveNext
  Loop
 
  ' Das StringArray zurückgeben  
  AllComputers = strPC
 
  If rs.State <> 0 Then rs.Close
  If conn.State <> 0 Then conn.Close
 
' Error Handling  
ErrHandler:
  On Error Resume Next
  AllComputers = strPC
  Set rs = Nothing
  Set conn = Nothing
  Set Root = Nothing
  Set Domain = Nothing
End Function

==========================================================

Sub BezeichnungADauslsesen()
Dim strCN As String 'Computername  

On Error Resume Next

Dim WshShell, Hostname

For i = 1 To Sheets("ADtest").UsedRange.Rows.Count  
    Sheets("ADtest").Select  
    strCN = Cells(i, 1)
    
    Const ADS_SCOPE_SUBTREE = 2
    Set objConnection = CreateObject("ADODB.Connection")  
    Set objCommand = CreateObject("ADODB.Command")  
    objConnection.Provider = "ADsDSOObject"  
    objConnection.Open "Active Directory Provider"  
    Set objCommand.ActiveConnection = objConnection
    objCommand.Properties("Page Size") = 1000  
    objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE  
    objCommand.CommandText = _
       "SELECT ADsPath FROM 'LDAP://DC=satrup,DC=zmg,DC=local' WHERE objectCategory='computer' AND Name='" & strCN & "'"  
    Set objRecordSet = objCommand.Execute
    objRecordSet.MoveFirst
    strADsPath = objRecordSet.Fields("ADsPath").Value  
    
    Set objComputer = GetObject(strADsPath)
    
    objproperty = objComputer.Get("Description")  
    
    Cells(i, 2) = objproperty
        
Next i

End Sub