tuxhunt3r
Goto Top

VBS - Auslesen aller Gruppen einer OU samt Unter-OUs mit einigen Bedingungen

Hallo ans Forum

Ich habe ein kleines Problem bei einem VBScript, welches ich für den Betrieb schreiben sollte. Hier der Code:

Const ADS_SCOPE_SUBTREE = 10
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,samAccountName FROM 'LDAP://ou=Tralala,dc=beispiel,dc=ch' WHERE objectCategory='group'"    
Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst

Do Until objRecordSet.EOF
	if Instr(objRecordSet.Fields("samAccountName").Value, "D-") > 0 Then  
		Gruppenname=objRecordSet.Fields("samAccountName").Value  
		UserCounter = 0
		' Mitglieder zählen  
		Set objGroup = GetObject(objRecordSet.Fields("AdsPath").Value)  
		objGroup.GetInfo
 		arrMemberOf = objGroup.GetEx("member")  
		For Each strMember in arrMemberOf
			UserCounter = UserCounter + 1
		Next
		if UserCounter < 2 Then
			'Owner auslesen  
			Owner = GetOwner(objRecordSet.Fields("AdsPath").Value)  
			wscript.echo Gruppenname & ";" & Owner  
		End if
		
		
	End if
Loop

'********************************************************************************************  
' Funktionen:  

Function GetOwner(adsPath)
	Set objGroup = GetObject(adsPath)
	Set objNtSecurityDescriptor = objGroup.Get("ntSecurityDescriptor")  
	GetOwner = objNtSecurityDescriptor.Owner
End Function

Dieses Script soll folgendes machen:
Es soll rekursiv alle Unter-OUs von ou=Tralala,dc=beispiel,dc=ch' abgrasen und von jeder Gruppe, die mit "D-" beginnt und weniger als 2 Mitglieder hat, den Namen, die Anzahl Mitglieder und den Owner auslesen. Wenn ich das Script mit CScript in der CMD-Shell starte, kommt zwar keine Fehlermeldung, allerdings sieht die Ausgabe dann so aus:

D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1
D-Gruppe1;Beispiel\User1

Es wird also dieselbe Gruppe mit demselben Owner unendlich mal angezeigt (so scheint es mir zumindest, ich habs nach einer Minute abgebrochen). Kann mir das einer erklären, rsp. eine Lösung anbieten? Ich werde daraus nicht schlau...


Grüsse aus der Schweiz
TuXHunT3R

Content-Key: 116957

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

Printed on: April 23, 2024 at 18:04 o'clock

Mitglied: 76109
76109 May 27, 2009 at 14:59:57 (UTC)
Goto Top
Hallo TuXHunt3R,

am Ende Deiner Loop-Schleife fehlt ein <objRecordSet.MoveNext>

Gruß Dieter
Member: bastla
bastla May 27, 2009 at 15:12:19 (UTC)
Goto Top
Hallo TuXHunt3R und didi1954!

Das eigentliche Problem sollte schon gelöst sein, daher nur noch zwei Anmerkungen:

Wenn der Gruppenname mit "D-" beginnen soll, wäre die genauere Abfrage
If UCase(Left(objRecordSet.Fields("samAccountName").Value, 2)) = "D-" Then

Die Anzahl der Gruppenmitglieder sollte sich etwas direkter auch mit
UserCounter = UBound(objGroup.GetEx("member")) + 1
bestimmen lassen (mit einem On Error Resume Next davor für den Fall, dass die Gruppe keine Mitglieder hat) ...

Grüße
bastla
Member: TuXHunt3R
TuXHunt3R May 27, 2009 at 18:44:20 (UTC)
Goto Top
am Ende Deiner Loop-Schleife fehlt ein <objRecordSet.MoveNext>

Mein Gott, bin ich dämlich....... Ich habe sicher eine Stunde nach dem Fehler gesucht und übersehe so einen besch** MoveNext. Herzlichen Dank jedenfalls.

Wenn der Gruppenname mit "D-" beginnen soll, wäre die genauere Abfrage
Danke für den Hinweis, aber die Gross/Kleinschreibung ist egal.


mit einem On Error Resume Next davor für den Fall, dass die Gruppe keine Mitglieder hat
Guter Tipp, ich werde aber sehen, dass ich das irgendwie anders abfangen kann, z.B. mit einer weiteren Iteration.


Ich lass den Beitrag mal noch offen. Ich werde es morgen im Geschäft ausprobieren, gebe dann Feedback und poste das funktionierende Script.
Member: bastla
bastla May 27, 2009 at 19:07:06 (UTC)
Goto Top
Hallo TuXHunt3R!
... die Gross/Kleinschreibung ist egal.
Dir vielleicht face-wink, aber VBS unterscheidet da sehr wohl.

Das "genauer" bezog sich allerdings mehr auf die Tatsache, dass mit InStr() im gesamten Text gesucht wird, während Left() nur den Anfang des Strings betrachtet ...

Wie sehr Du Dich auf die Richtigkeit der Gruppennamen verlassen kannst bzw willst (und daher die genannten Aspekte tatsächlich nicht zum Tragen kommen sollten), musst Du natürlich selbst entscheiden.

Grüße
bastla
Mitglied: 76109
76109 May 27, 2009 at 20:56:31 (UTC)
Goto Top
Hallo TuXHunt3R und bastla!

Zitat von @TuXHunt3R:
Mein Gott, bin ich dämlich....... Ich habe sicher eine Stunde
nach dem Fehler gesucht und übersehe so einen besch** MoveNext.
Tja, manchmal sieht man den Wald vor lauter Bäumen nichtface-smile
Danke für den Hinweis, aber die Gross/Kleinschreibung ist egal.
Ist nur egal, wenn Du die Option TextCompare angibst (Default=vbBinaryCompare):
if Instr(1, objRecordSet.Fields("samAccountName").Value, "D-", vbTextCompare) > 0  

Gruß Dieter

[Edit] Aufgrund des Hinweises von bastla, die Startposition noch eingefügt, weil diese
bei Angabe der Vergleichsart auch angegeben werden muss (sonst optional).[/Edit]
Member: bastla
bastla May 27, 2009 at 21:27:23 (UTC)
Goto Top
... was allerdings einerseits noch immer nicht nur den Anfang des Strings vergleicht und andererseits nur funktioniert, wenn Du auch eine Startposition angibst:
If InStr(1, objRecordSet.Fields("samAccountName").Value, "D-", vbTextCompare) > 0 Then
Grüße
bastla
Mitglied: 76109
76109 May 27, 2009 at 22:00:28 (UTC)
Goto Top
Hallo bastla!

Zitat von @bastla:
... was allerdings einerseits noch immer nicht nur den Anfang des Strings vergleicht
und andererseits nur funktioniert, wenn Du auch eine Startposition angibst:
Wieso denn? Die Startposition ist optional und wird sie nicht angegeben, dann ist die Startposition das 1. Zeichen

Allerdings hast Du insoweit Recht, dass ein "D-" auch an anderer Stelle im Suchstring gefunden werden könnte. In dem Fall müsste der Vergleich If InStr(...) = 1 Then.... heissen.

Aber von dem abgesehen, würde ich persönlich auch UCase(Left..) verwenden.

Gruß Dieter
Member: bastla
bastla May 27, 2009 at 22:08:23 (UTC)
Goto Top
@76109
Die Startposition ist optional und wird sie nicht angegeben, dann ist die Startposition das 1. Zeichen
... es sei denn, die MS-Doku wäre korrekt: "The start argument is required if compare is specified."

Grüße
bastla
Mitglied: 76109
76109 May 27, 2009 at 22:12:14 (UTC)
Goto Top
Hallo bastla!

Aja, stimmt. Wenn Vergleich angegeben wird, dann muss auch die Startposition angegeben werden.

Werde es oben ändern.

Gruß Dieter
Member: bastla
bastla May 27, 2009 at 22:21:13 (UTC)
Goto Top
Auch ein Test mit
WScript.Echo InStr("Versuch", "U", vbTextCompare)
vs
WScript.Echo InStr(1, "Versuch", "U", vbTextCompare)
spricht dafür, dass der Wert wohl anzugeben ist ...

Grüße
bastla
Mitglied: 76109
76109 May 27, 2009 at 22:29:50 (UTC)
Goto Top
Hallo nochmal,

äh, hab ich doch schon geschrieben oder warst Du wieder zu schnell, während ich meine Antwort noch mal geändert hatte?

Gruß Dieter
Member: bastla
bastla May 27, 2009 at 22:32:02 (UTC)
Goto Top
warst Du wieder zu schnell, während ich meine Antort noch mal geändert hatte?
Ausnahmsweise ... face-wink

Grüße
bastla