Centrum skryptów - Active Directory

Jak uzyskać listę kont użytkowników utworzonych danego dnia lub w danym okresie?

Udostępnij na: Facebook

Skrypciarze odpowiadają na Wasze pytania

Cześć Skrypciarze!

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.

Jak uzyskać listę kont użytkowników utworzonych danego dnia lub w danym okresie?

Cześć Skrypciarze! Pytanie

Cześć, Skrypciarze! Jak zastosować kwerendę dla Active Directory dotyczącą listy kont użytkowników utworzonych w danym dniu lub danym okresie?

-- PG

Cześć Skrypciarze! Odpowiedź

Cześć, PG. Być może nawet nie zdajecie sobie z tego sprawy, ale sierpień to dla Skrypciarzy i ich rubryki bardzo sprzyjający miesiąc: w końcu dzisiejszy artykuł oznacza początek czwartego roku istnienia rubryki Cześć Skrypciarze! Nasz pierwszy w ogóle artykuł ukazał się 2 sierpnia 2004 i od tamtej pory każdego roboczego dnia tygodnia pojawia się nowy. Ile to już razem artykułów? Sami policzcie. A tak na serio, to naprawdę musicie sobie to sami policzyć, my zgubiliśmy się jakoś rok temu po pojawieniu się pięćsetnego artykułu.

I tu pojawia się pewna kwestia. Można by się spodziewać, że po napisaniu tylu artykułów mamy wiele niesamowitych historii do opowiedzenia. Jak się jednak okazuje, nie mamy żadnych. Ale za to mamy skrypt tworzący listę wszystkich kont użytkowników utworzonych w danym dniu lub okresie:

On Error Resume Next



Const ADS_SCOPE_SUBTREE = 2



dtmCreationDate1 = "20070701000000.0Z"

dtmCreationDate2 = "20070731000000.0Z"



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 Name, whenCreated FROM 'LDAP://dc=fabrikam,dc=com' WHERE objectClass='user' "  & _

        "AND whenCreated>='" & dtmCreationDate1 & "' AND whenCreated<='" & dtmCreationDate2 & "'" 

Set objRecordSet = objCommand.Execute



objRecordSet.MoveFirst



Do Until objRecordSet.EOF

    Wscript.Echo objRecordSet.Fields("Name").Value, objRecordSet.Fields("whenCreated").Value

    objRecordSet.MoveNext

Loop

Zdajemy sobie sprawę z tego, że wielu naszych wiernych czytelników może się obawiać, że po czterech latach rubryka Cześć Skrypciarze! Mogła odbiec od swojego pierwotnego charakteru (co jest nawet wysoce prawdopodobne, biorąc po uwagę fakt, że nikt z nas tak naprawdę nie pamięta, jakie były początkowe założenia). Ale Skrypciarze gwarantują jedno: nie ma się czym martwić. Chcecie dowodu? Konsekwentnie od 3 lat w naszych artykułach umieszczamy następujące wyjaśnienie:

Nie będziemy szczegółowo omawiać przeszukiwania katalogu Active Direktory; to wykracza poza zakres dzisiejszego artykułu. Ale nie martwcie się: nie pozostawimy was bez pomocy, zastanawiających się jak działają skrypty wyszukiwania. Jeżeli potrzebujecie (lub po prostu chcecie) uzyskać więcej informacji na temat zasad działania skryptów wyszukiwania Active Direktory, zajrzyjcie do artykułów z serii Tales from the Script (j.ang.).

Widzicie? Nic się nie zmienia – może jesteśmy zbyt leniwi na zmiany.

Ale za to opowiemy dzisiaj o kwerendzie SQL, zastosowanej w celu pobrania kolekcji wszystkich kont użytkowników utworzonych w okresie pomiędzy dwoma datami (w tym przypadku od 1 lipca 2007 r. do 31 lipca 2007 r.) Zanim to jednak zrobimy, spójrzmy na poniższe dwa wiersze kodu:

dtmCreationDate1 = "20070701000000.0Z"

dtmCreationDate2 = "20070731000000.0Z"

Możecie wierzyć lub nie, te dwa wiersze kodu przypisują naszą datę początkową (1 lipca 2007 r.) oraz datę końcową (31 lipca 2007 r.) do zmiennych dtmCreationDate1 oraz dtmCreationDate2. Oczywiście, nie wyglądają one jak daty, a to z powodu formatu daty i czasu („czas znormalizowany”) wymaganego podczas przeszukiwania katalogu Active Direktory. Zaufajcie nam, wartość 20070701000000.0Z może zostać posegmentowana w poniższy sposób:

  • 2007 reprezentuje rok
  • 07 reprezentuje miesiąc (lipiec) w formacie dwucyfrowym.
  • 01 reprezentuje dzień (pierwszy), także w formacie dwucyfrowym.
  • 000000 reprezentuje odpowiednio godziny, minuty i sekundy, wszystko w formacie dwucyfrowym, 24-godzinnym.
  • .0Z reprezentuje róznicę czasu pomiędzy czasem lokalnym a czasem Greenwich. Ponieważ katalog Active Directory zachowuje wartości daty i czasu używając czasu Greenwich, podaliśmy tu wartość 0. Gdybyśmy chcieli określić przesunięcie o 8 godzin względem czasu Greenwich, podalibśmy coś w stylu: .0+0800. Osiem godzin wcześniej względem czasu Greenwich wyglądałoby następująco: .0-0800 (zauważmy znak minus).

Skoro już wiemy, do czego nam są potrzebne dwie zmienne, możemy skupić się na kwerendzie SQL, dzięki której uzyskamy konta użytkowników utworzone pomiędzy 1 lipca 2007 r. a 31 lipca 2007 r.:

objCommand.CommandText = _

    "SELECT Name, whenCreated FROM 'LDAP://dc=fabrikam,dc=com' WHERE objectClass='user' "  & _

        "AND whenCreated>='" & dtmCreationDate1 & "' AND whenCreated<='" & dtmCreationDate2 & "'" 

Set objRecordSet = objCommand.Execute

Co tutaj robimy? Zgłaszamy zapotrzebowanie na dwie wartości atrybutów (Name oraz whenCreated) z domeny fabrikam.com. Oczywiście nie chcemy tych informacji w odniesieniu do wszystkich obiektów domeny fabrikam.com, a jedynie obiektów spełniających poniższe kryteria:

  • Wartość objectClass to „user”. Co zrobić, gdybyśmy chcieli uzyskać listę kont komputerów utworzonych w lipcu? Żaden problem: wystarczy zmienić „user” na „computer”. A gdybyśmy chcieli uzyskać listę wszystkich kont (niezależnie od wartości objectClass) utworzonych w lipcu? Znowu: żaden problem; w takim przypadku wystarczy w ogóle pominąć klauzulę objectClass=.
  • Wartość atrybutu whenCreated obiektu musi być większa lub równa 1 lipca 2007 r. (reprezentowana przez zmienną dtmCreationDate1).
  • Wartość atrybutu whenCreated obiektu musi być mniejsza lub równa 31 lipca 2007 r. (reprezentowana przez zmienną dtmCreationDate2)

Zgodnie z zasadami logiki (o tak, to może być pierwszy raz od czterech lat, kiedy stosujemy się do zasad logiki) widzimy, że to ogranicza nam uzyskiwane dane do kont użytkowników utworzonych w miesiącu lipcu 2007. A to jest dokładne ten okres o który nam chodzi.

Jeżeli nam nie ufacie, możemy zastosować pętlę Do Until, która będzie działać, dopóki nie dojdziemy do końca naszego zbioru rekordów (czyli uzyskanych danych). Wewnątrz tej pętli wywołujemy echo wartości atrybutów Name oraz whenCreated pierwszego obiektu, a następnie stosujemy metodę MoveNext, przechodzimy dalej i powtarzamy proces dla następnego elementu w zbiorze rekordów:

Do Until objRecordSet.EOF

    Wscript.Echo objRecordSet.Fields("Name").Value, objRecordSet.Fields("whenCreated").Value

    objRecordSet.MoveNext

Co otrzymamy? Coś co wygląda następująco:

Ken Myer 7/31/2007 6:38:40 PM

Pilar Ackerman 7/29/2007 7:22:06 PM

Jonathan Haas 7/26/2007 7:28:42 PM

Gail Erickson 7/24/2007 7:45:14 PM

Carol Phillips 7/17/2007 9:55:16 PM

Kim Abercrombie 7/14/2007 6:11:31 PM

Dylan Miller 7/06/2007 3 :29:44 PM

Uwaga: Zwróćmy uwagę, że pomimo iż musieliśmy zastosować ten dziwny, znormalizowany format czasu w celu określenia wartości atrybutu whenCreated, nie musieliśmy zrobić nic w celu uzyskania rzeczywistych wartości daty i czasu (np. 7/26/2007 7:28:42 PM) wyświetlanych na ekranie. Jak się okazuje, wystarczy użyć formatu znormalizowanego czasu podczas kwerendy katalogu Active Directory; następnie wywołać echo wartości atrybutu whenCreated; wartość jest automatycznie konwertowana na postać, którą jest o wiele łatwiej odczytać.

A co tam, dziś możemy być skrupulatni: nie mamy nic innego do roboty.

I to już wszystko na ten temat, PG: wszystkie konta użytkowników utworzone pomiędzy 1 lipca 2007 r. a 31 lipca 2007 r.. Na koniec dodajmy jeszcze informację, że jesteśmy całkiem dumni z naszej rubryki Cześć Skrypciarze! i jej długowieczności; ośmielamy się zaznaczyć, że tak długo nie trwało publikowanie żadnej innej rubryki w witrynie TechNet. (Głównie dlatego, że nikomu oprócz Skrypciarzy nie chce się publikować niczego w trybie codziennym.) Dlaczego zatem nie robimy żadnej imprezy w celu uczczenia tej okazji? To proste: mieliśmy wielkie przyjęcie z okazji opublikowania historycznego, piećsetnego artykułu. Jak dla Skrypciarzy wystarczy jedna taka impreza na następne cztery lata.

 Do początku strony Do początku strony

Centrum skryptów - Active Directory