W jaki sposób można uzyskać listę wszystkich wyłączonych kont użytkownika w Active Directory?
Skrypciarze odpowiadają na Wasze pytania
Witamy w rubryce TechNet, w której Skrypciarze z firmy Microsoft odpowiadają na częste pytania dotyczące używania skryptów w administracji systemu. Jeśli macie jakieś pytania z tej dziedziny, zachęcamy do wysłania e-maila na adres: scripter@microsoft.com. Nie możemy zagwarantować odpowiedzi na każde otrzymane pytanie, ale staramy się jak możemy. |
W jaki sposób można uzyskać listę wszystkich wyłączonych kont użytkownika w Active Directory?
Cześć, Skrypciarzu! W jaki sposób można uzyskać listę wszystkich wyłączonych kont użytkownika w Active Directory?
-- Sebastian
Cześć, Sebastianie. Tylko pamiętaj, że sam tego chciałeś. Mamy w zanadrzu skrypt podający listę wyłączonych kont użytkownika w Active Directory; problem w tym, że zawiera on nieco (to niedopowiedzenie) niejasny fragment, a jego wyjaśnienie zajęłoby zbyt dużo miejsca jak na artykuł z tej serii. Jeśli Ci nie szkodzi, możemy kontynuować.
A zresztą: kontynuujmy tak czy siak. W końcu nigdy nie wiadomo, co to będzie, dopóki się nie dojdzie do końca.
Problem polega na tym, że status konta (włączone/wyłączone) stanowi część atrybutu userAccountControl. Jest to atrybut typu maska bitów (bitmask): jeden atrybut grupujący wartości kilku właściwości. W tym przypadku są to następujące właściwości:
- Konto użytkownika jest wyłączone.
- Konto jest obecnie zablokowane.
- Hasło nie jest wymagane.
- Użytkownik nie może zmienić hasła.
- Jest to konto domyślnego typu, odpowiadające przeciętnemu użytkownikowi.
- Po ustawieniu hasło tego konta nie utraci ważności.
- Po ustawieniu, ta flaga wymagać będzie od użytkownika logowania przy użyciu karty inteligentnej.
- Hasło użytkownika utraciło ważność.
Atrybuty maski bitów mogą wprowadzać trochę zamieszania, ale praca z nimi nie jest z reguły szczególnie trudna. Wyjątkiem jest akurat przeszukiwanie Active Directory, czyli właśnie to, co chcemy zrobić. Zazwyczaj do przeszukiwania Active Directory używane jest następujące zapytanie SQL:
Select Name from 'LDAP://dc=fabrikam,dc=com' Where Department = 'Finance'
Zapytanie to zadziała w przypadku większości atrybutów Active Directory; jednak w przypadku atrybutów maski bitów nie jest tak wesoło – nie zadziała ono w ogóle. Dlatego musimy opracować plan B i wysłać zapytanie używając składnie LDAP:
<LDAP://dc=fabrikam,dc=com>;(&(objectCategory=User)" & _
"(userAccountControl:1.2.840.113556.1.4.803:=2));Name;Subtree
Zapewniamy, że nie podoba nam się to równie bardzo, jak i Wam. Ale kiedy zapoznać się bliżej z poszczególnymi elementami, nie wygląda to już tak źle:
- <LDAP://dc=fabrikam,dc=com>. Jest to tylko punkt wyjściowy wyszukiwania: główny katalog domeny fabrikam.com. Nie ma tu nic niezwykłego, może oprócz ostrych nawiasów otaczajacych ścieżkę ADsPath.
- (&(objectCategory=User). Jest to część naszej klauzuli wyszukiwania (warto zwrócić uwagę, że w całym zapytaniu nie pada słowo Where). Część objectCategory=User powinna być oczywista; interesują nas tylko obiekty typu user, czyli użytkownicy. Znak & jest równoważny operatorowi AND klauzuli SQL: oznacza, że łączymy objectCategory=User z jakimś innym elementem.
- (userAccountControl:1.2.840.113556.1.4.803:=2)). To jest właśnie ten jakiś inny element. Wygląda bełkotliwie, ale naprawdę instruuje skrypt, by wyszukiwał obiekty (w naszym przypadku użytkowników) z uaktywnionym drugim bitem atrybutu userAccountControl. Nie będziemy teraz omawiać atrybutów maski bitów; krótkie omówienie znaleźć można w części poświęconej odczytywaniu atrybutów hasła kont użytkowników w przewodniku Microsoft Windows 2000 Scripting Guide. Tymczasem wystarczy nam, jeśli będziemy wiedzieć, że włączony drugi bit oznacza wyłączone konto.
A co z tym 1.2.840.1113556.1.4.803? Otóż jest to reguła łączenia bitów protokołu LDAP i odpowiada operatorowi AND (tak, tak). Innymi słowy, cały ten szaleńczy zapis jest właściwie równoważny temu:
If objUser.userAccountControl AND 2 Then
Jeśli ktoś zna się na maskach bitów, może się w tym rozeznać. Jeśli nie, to też nie kłopot. Skryptów można używać nawet ich nie rozumiejąc.
- Name. Nazwa atrybutu który chcemy wyświetlić.
- Subtree. Zakres poszukiwań; tutaj oznacza, że chcemy przeszukać całe drzewo Active Directory.
Jasne jak przysłowiowy księżyc w nowiu, nie? Nieco więcej informacji znaleźć można w artykule z serii Opowieści-skrypty z kwietnia 2005 (j.ang.), opisującego podstawy przeszukiwania Active Directory, oraz w jego drugiej części (j.ang.). Dla osób bardziej zainteresowanych przeszukiwaniem Active Directory (a to wielce przydatne zainteresowanie) mamy webcast Skrypciarzy (j.ang.).
Aha, racja: na zakończenie mamy kompletny skrypt podający listę wszystkich wyłączonych kont użytkownika w Active Directory. Skoro tylko o to chodziło, trzeba było od razu mówić!
On Error Resume Next
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.CommandText = _
"<LDAP://dc=fabrikam,dc=com>;(&(objectCategory=User)" & _
"(userAccountControl:1.2.840.113556.1.4.803:=2));Name;Subtree"
Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst
Do Until objRecordSet.EOF
Wscript.Echo objRecordSet.Fields("Name").Value
objRecordSet.MoveNext
Loop
Do początku strony