Server aus AD auslesen und verarbeiten VBS
Guten Tag an Alle,
ich hab ein Problem mit einem Script und komme nicht weiter:
Folgendes soll gemacht werden:
Aus einem AD sollen alle Server ausgelesen werden - Diese sollen dann einzeln nach den lokalen Administratoren abgefragt werden und in eine SQL-DB geschrieben werden.
Was funktioniert bisher:
-> AD auslesen
-> Lokale Administratoren auslesen
Was funktioniert nicht:
Wenn ein lokaler Admin gefunden wurde, werden alle lokalen Admins(und der Server 1x ) in eine DB geschrieben. Nur geht die Schleife dann nicht zum nächsten PC und fragt dort die lokalen Admins ab sondern läuft weiter mit den lokalen Admins von dem einen PC ab. Sprich ich hab irgendwie ne Schleife drin=> ich will von dem PC jeden lokalen Admin nur 1x haben und dann gehts zum nächsten PC der abgefragt wird.
Ich hoffe ihr könnt mir helfen? Wo hab ich meinen Fehler?
Mein bisheriges Script:
Ergänzung: Im Falle des wir z.B. einen englischen Server haben, und des die Gruppe Administratoren nicht gibt, wird der nächste Server abgefragt. Das Script funktioniert also so lange die Gruppe Administratoren nicht vorhanden ist. Dann wechselt er von Server zu Server. Aber wenn die Gruppe gefunden wird, läuft er in eine Schleife beim eintragen der lokalen Admins in die DB.
Gruß Steve
ich hab ein Problem mit einem Script und komme nicht weiter:
Folgendes soll gemacht werden:
Aus einem AD sollen alle Server ausgelesen werden - Diese sollen dann einzeln nach den lokalen Administratoren abgefragt werden und in eine SQL-DB geschrieben werden.
Was funktioniert bisher:
-> AD auslesen
-> Lokale Administratoren auslesen
Was funktioniert nicht:
Wenn ein lokaler Admin gefunden wurde, werden alle lokalen Admins(und der Server 1x ) in eine DB geschrieben. Nur geht die Schleife dann nicht zum nächsten PC und fragt dort die lokalen Admins ab sondern läuft weiter mit den lokalen Admins von dem einen PC ab. Sprich ich hab irgendwie ne Schleife drin=> ich will von dem PC jeden lokalen Admin nur 1x haben und dann gehts zum nächsten PC der abgefragt wird.
Ich hoffe ihr könnt mir helfen? Wo hab ich meinen Fehler?
Mein bisheriges Script:
Option Explicit
'specified Database - make connection to db and select
Const adOpenStatic = 3
Const adLockOptimistic = 3
Set objConnection = CreateObject("ADODB.Connection")
Set objRecordSet = CreateObject("ADODB.Recordset")
'Oeffnen der Datenbank - Verbindung
objConnection.Open _
"Provider=SQLOLEDB;Data Source=SQL-Server; Initial Catalog=DB; User ID=DB_User; Password=PW"
Dim Computerliste, Computer, Benutzer, objConnection, objConnectionAD, objRecordset, objRecordset1, objCommand1, ID_Host, ID, Computername, Hostname, objRecordSet2, ID_Server, Hostzahl, objCommand, PCName, PC, Name
'Abgefrage Computer
Const ADS_SCOPE_SUBTREE = 2
Hostzahl = 0
Set objConnectionAD = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnectionAD.Provider = "ADsDSOObject"
objConnectionAD.Open "Active Directory Provider"
Set objCOmmand.ActiveConnection = objConnectionAD
objCommand.CommandText = _
"Select Name, Location from 'LDAP://DC=Domäne,DC=Domäne' " _
& "Where objectClass='computer'"
objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst
Do Until objRecordSet.EOF
Computer = objRecordset.Fields("Name").Value
Wscript.Echo "Computer Name: " & Computer
Wscript.Echo "Location: " & objRecordSet.Fields("Location").Value
On Error Resume Next
Wscript.Echo ("In Schleife: ")
Wscript.Echo
Wscript.Echo ("Computer: ") & Computer
For Each Benutzer In GetObject("WinNT://" & Computer & "/Administratoren").Members
Wscript.Echo ("lokale Adminstratoren: ") & Benutzer.name
If Err.Number <> 0 Then
Wscript.Echo("Lokale Admingruppe nicht vorhanden")
Wscript.Echo("Error Anzahl:") &Err.Number
else
'Überprüfung ob Hostname = Computer dann Hostzahl = 1
objRecordSet.Open "SELECT Count(Hostname) as Hostzahl FROM tbl_Hosts WHERE Hostname = ('" & Computer & "')" , objConnection, dOpenStatic, adLockOptimistic
Hostzahl = objRecordset.Fields.Item("Hostzahl")
objRecordSet.close
Wscript.Echo("Hostzahl: ") & Hostzahl
'Wenn Hostzahl 1 ist der Hostname schon in der tbl_Hosts vorhanden
if Hostzahl = 1 THEN
Wscript.Echo("Computer: ") & Computer
Wscript.Echo("Computername: ") & Computername
Wscript.Echo("Error Anzahl:") &Err.Number
'Suchen der HostID und in Variable schreiben
objRecordset.Open "SELECT ID from tbl_Hosts WHERE Hostname = ('" & Computer & "')" , objConnection, adOpenStatic, adLockOptimistic
ID_Server = objRecordset.Fields.Item("ID")
objRecordSet.close
'Ausfueren des INSERTs auf die Tabelle tbl_administratoren
objRecordSet.Open "INSERT tbl_Administratoren (Admin, ID_Host) VALUES ('" & Benutzer.Name & "', '" & ID_Server &"')", objConnection, adOpenStatic, adLockOptimistic
WScript.Echo "Eintrag DB: " & Benutzer.Name & " " & ID_Host
'objRecordset.MoveNext
else
'Eintragen des Hostnamens
objRecordSet.Open "INSERT tbl_Hosts (Hostname) VALUES ('" & Computer & "')", objConnection, adOpenStatic, adLockOptimistic
'Auslesen der Host_ID der Tabelle tbl_Hosts
objRecordSet.Open "SELECT ID FROM tbl_Hosts where Hostname = '" & Computer & "' " , objConnection, adOpenStatic, adLockOptimistic
' geht an das erste Recordset
objRecordset.MoveFirst
ID_Host = objRecordset.Fields.Item("ID")
Wscript.Echo("ID: ") & ID_Host
Wscript.Echo("Error Anzahl:") &Err.Number
objRecordSet.close
'Ausfueren des INSERTs auf die Tabelle tbl_administratoren
objRecordSet.Open "INSERT tbl_Administratoren (Admin, ID_Host) VALUES ('" & Benutzer.Name & "', '" & ID_Host &"')", objConnection, adOpenStatic, adLockOptimistic
WScript.Echo "Eintrag DB: " & Benutzer.Name & " " & ID_Host
objConnectionAD.close
'objConnection.close
'Hostzahl = 0
end if
end if
Next
WScript.Echo
objRecordSet.MoveNext
Loop
objConnection.close
Ergänzung: Im Falle des wir z.B. einen englischen Server haben, und des die Gruppe Administratoren nicht gibt, wird der nächste Server abgefragt. Das Script funktioniert also so lange die Gruppe Administratoren nicht vorhanden ist. Dann wechselt er von Server zu Server. Aber wenn die Gruppe gefunden wird, läuft er in eine Schleife beim eintragen der lokalen Admins in die DB.
Gruß Steve
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 111518
Url: https://administrator.de/contentid/111518
Ausgedruckt am: 26.11.2024 um 05:11 Uhr
17 Kommentare
Neuester Kommentar
Hallo,
1. dein Quellcode ist sehr unübersichtlich. Bitte benutze den code-Tag. Rücke deinen Quellcode ein.
2. Bitte benenne die Recordsets bei Dir eindeutig - das hilft Dir schon mal sehr weiter. Die Zeile fast am Schluss deine Codes "objRecordSet.MoveNext" wird wohl deine gewünschte Reaktion niemals zeigen...
Nimm es uns (wenn ich einfach mal hier für uns alle sprechen darf) nicht übel, aber bitte editier deinen Beitrag oben und beherzige diese wenigen Tipps, da es sonst schwierig ist, die Funktionsweise nachzuvollziehen.
Ich schau es mir dann auch noch einmal danach an - versprochen!
Gruß
Markus
1. dein Quellcode ist sehr unübersichtlich. Bitte benutze den code-Tag. Rücke deinen Quellcode ein.
2. Bitte benenne die Recordsets bei Dir eindeutig - das hilft Dir schon mal sehr weiter. Die Zeile fast am Schluss deine Codes "objRecordSet.MoveNext" wird wohl deine gewünschte Reaktion niemals zeigen...
Nimm es uns (wenn ich einfach mal hier für uns alle sprechen darf) nicht übel, aber bitte editier deinen Beitrag oben und beherzige diese wenigen Tipps, da es sonst schwierig ist, die Funktionsweise nachzuvollziehen.
Ich schau es mir dann auch noch einmal danach an - versprochen!
Gruß
Markus
Moin Moin
Abm besten verwendest Du für DB und AD Zugriff unterschiedliche Objekte.
z.B.:
So wie Du das objrecordset einsetzt kann ich nicht mit sicherheit sagen was es beim movenext überhaupt enhält.
Gruß L.
Recordsets hab ich ja nur 2.
Deklariert hast du 3, benutz aber nur 1.Abm besten verwendest Du für DB und AD Zugriff unterschiedliche Objekte.
z.B.:
Dim objConnectionDB, objRecordsetDB, objCommandDB
Dim objConnectionAD, objRecordsetAD, objCommandAD
....
PS: ohne das objRecordset.MoveNext am Ende geht er erst garnicht zum 2. PC sondern ist dann in der Schleife mit dem ersten PC-Namen
Was ja auch dein Problem ist wenn ich deinen Post richtig verstanden habe.So wie Du das objrecordset einsetzt kann ich nicht mit sicherheit sagen was es beim movenext überhaupt enhält.
Gibt es eine Variable für die Gruppe "lokale Administratoren"? Weil ich hab Geräte die in verschiedenen Sprachen installiert sind. Für UK wär es ja "Administrators" auf deutsch "Administratoren" usw. gibt es dafür eine Variable?
Nicht das ich wüste.Gruß L.
Hallo,
ich habe mal den Anfang von Dir kopiert und die SQL Server Verbindung auskommentiert... Dies packst Du am besten in die unten stehende Funktion... Der Vorteil:
Du behältst den Überblick, wenn Du in Funktionen bzw. Subs unterteilst... naja... und die Variablen kommen sich auch nicht in die Quere... normalerweise ...
Vielleicht bringt Dir das ja weiter... ich hatte nur keine Lust, den gesamten Quelltext neu zu designen... es sollte aber nach diesem Ansatz auf jeden Fall funktionieren:
Gruß
Markus
ich habe mal den Anfang von Dir kopiert und die SQL Server Verbindung auskommentiert... Dies packst Du am besten in die unten stehende Funktion... Der Vorteil:
Du behältst den Überblick, wenn Du in Funktionen bzw. Subs unterteilst... naja... und die Variablen kommen sich auch nicht in die Quere... normalerweise ...
Vielleicht bringt Dir das ja weiter... ich hatte nur keine Lust, den gesamten Quelltext neu zu designen... es sollte aber nach diesem Ansatz auf jeden Fall funktionieren:
Option Explicit
'specified Database - make connection to db and select
Const adOpenStatic = 3
Const adLockOptimistic = 3
Set objConnection = CreateObject("ADODB.Connection")
Set objRecordSet = CreateObject("ADODB.Recordset")
'Oeffnen der Datenbank - Verbindung
'objConnection.Open "Provider=SQLOLEDB;Data Source=SQL-Server; Initial Catalog=DB; User ID=DB_User; Password=PW"
Dim Computerliste, Computer, Benutzer, objConnection, objConnectionAD, objRecordset, objRecordset1, objCommand1, ID_Host, ID, Computername, Hostname, objRecordSet2, ID_Server, Hostzahl, objCommand, PCName, PC, Name
'Abgefrage Computer
Const ADS_SCOPE_SUBTREE = 2
Hostzahl = 0
Set objConnectionAD = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnectionAD.Provider = "ADsDSOObject"
objConnectionAD.Open "Active Directory Provider"
Set objCOmmand.ActiveConnection = objConnectionAD
objCommand.CommandText = "Select Name, Location from 'LDAP://DC=DOMAENE,DC=local' Where objectClass='computer'"
objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst
Do Until objRecordSet.EOF
Computer = objRecordset.Fields("Name").Value
hole_admins(Computer)
objRecordSet.MoveNext
loop
function hole_admins(computername)
wscript.echo computername
For Each Benutzer In GetObject("WinNT://" & Computer & "/Administratoren").Members
if Benutzer.name <> "" then
schreibe_datensatz_in_deine_db(computername,Benutzer.Name)
end if
Next
end function
function schreibe_datensatz_in_deine_db(computername, adminaccount)
'Baue DB Verbindung auf
'Frage deine Tabellen ab...oder bastel hier deine Recordsets und inserts und alles andere rein ;-)
'Prüfe Einträge vorhanden...ggf. schreiben oder auch nicht...
'Blablubb und so weiter...
'Schließe den Recordset
'Baue die DB Verbindung wieder ab
end function
Markus
Hallo,
vergleiche mal Deinen Quellcode mit meinem und Du wirst verstehen, warum meiner funktioniert... Bei Dir sind etliche Fehler enthalten.
Mein Tipp: Prüfe bestimmte Inhalte mit z.B. Wscript.Echo bevor Du Neuen Code einfügst... gliedere mehrfach vorkommende Bereich als Sub oder Function aus... (Auch For Each ist immer seeehr nützlich )
Falls Du Access zur Verfügung hast, programmiere dort und übertrage dann den Code in dein VBS-Script... das dürfte dir viel Zeit ersparen in Zukunft:
Aber trotzdem... dein gedanklicher Ansatz mit der SID ist schon einmal sehr lobenswert. WEITER SO!
Gruß und immer weiter so!
Gruß
Markus
vergleiche mal Deinen Quellcode mit meinem und Du wirst verstehen, warum meiner funktioniert... Bei Dir sind etliche Fehler enthalten.
Mein Tipp: Prüfe bestimmte Inhalte mit z.B. Wscript.Echo bevor Du Neuen Code einfügst... gliedere mehrfach vorkommende Bereich als Sub oder Function aus... (Auch For Each ist immer seeehr nützlich )
Falls Du Access zur Verfügung hast, programmiere dort und übertrage dann den Code in dein VBS-Script... das dürfte dir viel Zeit ersparen in Zukunft:
Aber trotzdem... dein gedanklicher Ansatz mit der SID ist schon einmal sehr lobenswert. WEITER SO!
Function hole_admins(computer)
ergebnis = "Lokale Administratoren auf Computer : " & computer
' Setzen des WMI-Dienstes für den Computer
Set objWMIDienst = GetObject("winmgmts:{impersonationlevel=impersonate}!\\" & computer & "\root\cimv2")
' Abfrage fuer WMI zusammensetzen
strWMIAbfrage = "Select * from Win32_Group Where LocalAccount = True"
' Verbindung WMI und Ausfuehrung Abfrage
Set colGruppen = objWMIDienst.ExecQuery(strWMIAbfrage)
' Setzen assoziierte Sammlung
For Each objGruppe In colGruppen
If objGruppe.SID = "S-1-5-32-544" Then
'wscript.Echo ("Lokale Gruppe ") & objGruppe.Name
For Each Benutzer In GetObject("WinNT://" & computer & "/" & objGruppe.Name).Members
If Benutzer.Name <> "" Then
ergebnis = ergebnis & chr(13) & Benutzer.Name
'schreibe_datensatz_in_deine_db'(computername,Benutzer.Name)
End If
Next
End If
Next
hole_admins = ergebnis
End Function
wscript.echo hole_admins ("DEINRECHNER")
Gruß und immer weiter so!
Gruß
Markus
Hallo Steve,
administrativer Bereich ist ein weites Thema genauso wie es Bücher auf dem Markt gibt
vbs bedeutet nichts anderes wie Visual Basic Script... dementsprechend ist es selbstredend, dass VBA (Visual Basic for Applications) dem sehr nahe liegt und man fast alles 1 zu 1 übernehmen kann.
Und in Access kannst Du wunderbar, anstatt
Ich denke, dass DIr das jetzt schon mal etwas sagt.
Zum Thema Bücher... sofern Du Dich ein wenig mit Programmierung auskennst... ein objektorientiertes Denken mitbringst... und ordentlich Basteltrieb mitbringst, sollte Dir die Hilfe ausreichen. Die MSDN von Microsoft hilft Dir auch weiter... Dazu gibt es zahlreiche Foren und andere Seiten. (z.B. www.vbarchiv.de) und ähnliche. Empfehlen kann ich auch noch "Hey! Scripting Guy" auf den Seiten von Microsoft und wenn Du , so wie es aussieht WMI Abfragen benötigst... mmh.. dann nehme den Scriptomatic mal unter die Lupe...
http://www.microsoft.com/technet/scriptcenter/createit.mspx Natürlich ohne Vollständigkeit... waren nur so spontane Sachen, die mir eingefallen sind.
Meistens sind viele deiner Probleme schon irgendwann einmal programmiert worden.
Wenn Du unbedingt gute Bücher lesen möchtest, kann ich o'Reilly immer empfehlen bzw. kann man sich auch auf die Meinung von amzaon Kunden verlassen.
Allerdings stehen wir hier natürlich immer gerne mit Rat und Tat zur Seite - denn jeder hat mal "klein" angefangen...
Das wichtigste jedoch ist - versuch nicht einfach Quelltext zu kopieren, sondern ihn zu verstehen... Der nächste Schritt ist dann logischerweise, dass Du es auch schreiben kannst
Gruß und noch viel Erfolg!
Markus
administrativer Bereich ist ein weites Thema genauso wie es Bücher auf dem Markt gibt
vbs bedeutet nichts anderes wie Visual Basic Script... dementsprechend ist es selbstredend, dass VBA (Visual Basic for Applications) dem sehr nahe liegt und man fast alles 1 zu 1 übernehmen kann.
Und in Access kannst Du wunderbar, anstatt
"wscript.echo variablenname"
zum Beispiel ein"docmd.runsql("INSERT INTO DeineTabelle VALUES ('" & variablenname & "');")
machen...Ich denke, dass DIr das jetzt schon mal etwas sagt.
Zum Thema Bücher... sofern Du Dich ein wenig mit Programmierung auskennst... ein objektorientiertes Denken mitbringst... und ordentlich Basteltrieb mitbringst, sollte Dir die Hilfe ausreichen. Die MSDN von Microsoft hilft Dir auch weiter... Dazu gibt es zahlreiche Foren und andere Seiten. (z.B. www.vbarchiv.de) und ähnliche. Empfehlen kann ich auch noch "Hey! Scripting Guy" auf den Seiten von Microsoft und wenn Du , so wie es aussieht WMI Abfragen benötigst... mmh.. dann nehme den Scriptomatic mal unter die Lupe...
http://www.microsoft.com/technet/scriptcenter/createit.mspx Natürlich ohne Vollständigkeit... waren nur so spontane Sachen, die mir eingefallen sind.
Meistens sind viele deiner Probleme schon irgendwann einmal programmiert worden.
Wenn Du unbedingt gute Bücher lesen möchtest, kann ich o'Reilly immer empfehlen bzw. kann man sich auch auf die Meinung von amzaon Kunden verlassen.
Allerdings stehen wir hier natürlich immer gerne mit Rat und Tat zur Seite - denn jeder hat mal "klein" angefangen...
Das wichtigste jedoch ist - versuch nicht einfach Quelltext zu kopieren, sondern ihn zu verstehen... Der nächste Schritt ist dann logischerweise, dass Du es auch schreiben kannst
Gruß und noch viel Erfolg!
Markus
Hallo,
probiere das mal aus...
Spätestens beim zurückschreiben auf den Rechner wirst Du Probleme bekommen... aber probiere ruhig erstmal weiter aus...
Gruß
Markus
probiere das mal aus...
Function getFullName(username)
arrayU = Split(username,"/")
arraylen = UBound(arrayU)
getFullName = arrayU(arraylen - 1) & "/" & arrayU(arraylen)
End Function 'getFullName
Function hole_admins(computer)
ergebnis = "Lokale Administratoren auf Computer : " & computer & chr(13)
' Setzen des WMI-Dienstes für den Computer
Set objWMIDienst = GetObject("winmgmts:{impersonationlevel=impersonate}!\\" & computer & "\root\cimv2")
' Abfrage fuer WMI zusammensetzen
strWMIAbfrage = "Select * from Win32_Group Where LocalAccount = True AND SID='S-1-5-32-544'"
' Verbindung WMI und Ausfuehrung Abfrage
Set colGruppen = objWMIDienst.ExecQuery(strWMIAbfrage)
' Setzen assoziierte Sammlung
For Each objGruppe In colGruppen
set oGroup = GetObject("WinNT://" & computer & "/" & objGruppe.Name & ",group")
For Each oMember In oGroup.Members
'wscript.echo oMember.adspath
ergebnis = ergebnis & oMember.Name & vbtab & getFullName(oMember.adspath) & chr(13)
Next
Next
hole_admins = ergebnis
End Function
wscript.echo hole_admins (".")
Spätestens beim zurückschreiben auf den Rechner wirst Du Probleme bekommen... aber probiere ruhig erstmal weiter aus...
Gruß
Markus