Windows PowerShell: Automatyzowanie tworzenia i wyposażania użytkowników, część 3     Windows Server 2008

Windows PowerShell: Automatyzowanie tworzenia i wyposażania użytkowników, część 4 Udostępnij na: Facebook

Autor: Don Jones

Opublikowano: 7 grudnia 2009

Zawartość strony
Decyzje na wejściu  Decyzje na wejściu
Wypełnianie grup  Wypełnianie grup
Dodatkowe atrybuty  Dodatkowe atrybuty
Dalszy rozwój  Dalszy rozwój
Kilka uwag końcowych  Kilka uwag końcowych
Windows PowerShell - Pytania i odpowiedzi  Windows PowerShell - Pytania i odpowiedzi

 

To już ostatni odcinek czteroczęściowego serialu, w którym pokazuję, jak zautomatyzować proces tworzenia i wyposażania kont nowych użytkowników w Active Directory. Do tej pory zademonstrowałem, jak stworzyć nowe konta użytkowników w Active Directory, utworzyć ich foldery domowe i przypisać właściwe uprawnienia do tych folderów. Teraz musimy dodać użytkowników do odpowiednich grup domenowych i zaktualizować kilka atrybutów katalogu.

Przypomnę, że postanowiłem oprzeć konstrukcję skryptu na „funkcji głównej” w celu skoordynowania wszystkich działań, co wyjaśniłem w części pierwszej. Funkcja ta wygląda następująco:

Function Provision {

  PROCESS {

    CreateUser $_

    CreateHomeFolder $_

    AddToGroups $_

    UpdateAttributes $_

  }

}

W części drugiej utworzyłem funkcję podrzędną CreateUser, zaś trzecią poświęciłem funkcji CreateHomeFolder. W tym odcinku zajmę się funkcjami AddToGroups oraz UpdateAttributes.

Decyzje na wejściu

Wszystkie cztery funkcje podrzędne odbierają jako wejście obiekt hashtable, zawierający atrybuty użytkownika. Mój oryginalny przykład pokazany w części pierwszej odczytywał te atrybuty z pliku tekstowego rozdzielanego przecinkami (CSV). W tamtym momencie nie zagłębiałem się zbytnio w to, jak zamierzam zapanować nad przynależnością grupową nowych kont użytkownika. Istnieje wiele metod, którymi można to zrealizować. Na przykład plik CSV mógłby zawierać kolumnę o nazwie Groups, w której mieściłaby się lista nazw grup, jak poniżej:

"Domain Users,Sales,Marketing,East"

Alternatywnie można utworzyć w pliku CSV odrębną kolumnę dla każdej grupy i umieszczać w niej wartość 1, jeśli użytkownik ma należeć do tej grupy, albo 0, jeśli nie. Mogłoby to wyglądać tak:

W moim przykładowym środowisku każdy z wymienionych serwerów zawiera udział administracyjny o nazwie $Homes, zawierający wszystkie foldery domowe. Zakładam też, że administratorzy mają możliwość tworzenia nowych folderów w tym udziale, jak również, że mój skrypt będzie uruchamiany właśnie przez administratora. Na koniec zakładam, że wszystkie serwery wchodzące w zakres działania skryptu znajdują się albo w tej samej domenie, albo w domenach zaufanych, zatem będą ufać kontu administratora użytego do uruchomienia skryptu.

Domain Users,Sales,Marketing,East

1,1,0,0

1,0,1,1

Podejrzewam, że drugie podejście może być łatwiejsze dla osób „mniej technicznych” (na przykład kogoś z działu kadr), gdyż wygląda podobnie do typowej karty kontrolnej. Ponadto jest to coś, co można prosto utworzyć jako tabelę Microsoft Access lub arkusz Microsoft Excel i następnie wyeksportować do pliku CSV. Zatem w dalszej części zamierzam wykorzystać ten drugi wariant.

Co do „dodatkowych atrybutów”, zakładam, że one również pochodzą z dodatkowych kolumn pliku CSV. Jeśli na przykład chciałbym wypełnić atrybut postalCode, powinien być on umieszczony w odpowiedniej kolumnie pliku CSV, zaś funkcja importująca (którą omówiłem w części pierwszej) wczyta tę kolumnę do obiektu hashtable wraz z innymi kolumnami.

Oznacza to, że obiekt hashtable może zawierać coś takiego jak $userinfo['Domain Users'] o wartości 1, jeśli użytkownik ma należeć do tej grupy. Obiekt ten może również zawierać $userinfo['postalCode'] z odpowiednią wartością kodu pocztowego dla każdego nowego użytkownika.

 Do początku strony Do początku strony

Wypełnianie grup

Funkcja AddToGroups musi być w stanie zaakceptować każdą możliwą grupę, która może pojawić się w pliku wejściowym. Zamierzam po prostu sprawdzać dla każdej grupy, czy dla danego użytkownika występuje wartość 1, czy 0, i w pierwszym przypadku dodać użytkownika do tej grupy. Ponieważ wartość 0 jest często synonimem logicznego fałszu, podczas gdy cokolwiek różnego od zera (na przykład 1) odpowiada logicznej prawdzie, odpowiednie porównania są bardzo proste. Tak więc funkcja będzie wyglądała tak:

Function AddToGroup {

  Param($userinfo)

  If ($userinfo['Sales']) { Add-QADGroupMember 

    -identity 'DOMAIN\Sales' '

    -member ('DOMAIN\'+$userinfo

     ['samAccountName']) }

  If ($userinfo['East]) { Add-QADGroupMember 

    -identity 'DOMAIN\East' '

    -member ('DOMAIN\'+$userinfo

     ['samAccountName']) }

  If ($userinfo['Marketing]) { Add-

    QADGroupMember 

    -identity 'DOMAIN\Marketing' 

    -member ('DOMAIN\'+$userinfo

     ['samAccountName']) }

}

I tak dalej dla kolejnych grup. Zwróćmy uwagę, że nadal używamy poleceń Quest AD Cmdlets dostępnych w witrynie www.quest.com/powershell.

Cały ten powtarzający się kod wygląda jednak nużąco i nieelegancko. Znacznie ładniej byłoby utworzyć tablicę możliwych nazw grup i następnie przechodzić przez jej wartości. Dzięki temu dodanie lub usunięcie grupy w przyszłości nie będzie wymagało edycji całego kodu – trzeba będzie tylko zmienić zawartość tablicy. Nowa wersja funkcji wygląda więc następująco:

Function AddToGroup {

        Param($userinfo)

        $groups = 'Sales','Marketing','East'

        Foreach ($group in $groups) {

        If ($userinfo[$group]) { 

        Add-QADGroupMember

        -identity 'DOMAIN\'+$group

        -member ('DOMAIN\'+$userinfo

         ['samAccountName']) }

          }

         }

Tak jest znacznie bardziej przejrzyście, a ponadto łatwiejsze będzie wykonywanie poprawek w przyszłości.

 Do początku strony Do początku strony

Dodatkowe atrybuty

Na koniec muszę poradzić sobie z dodatkowymi atrybutami, które chcielibyśmy ustawić dla nowych użytkowników. W istocie zamierzam posłużyć się tą samą techniką, której użyłem przed chwilą: utworzę tablicę możliwych do wykorzystania nazw atrybutów i spowoduję, że skrypt będzie wyliczał tę tablicę. W tym wypadku muszę dopuścić sytuację, w której jeden lub kilka atrybutów dla danego użytkownika jest pustych, jak w poniższym przykładzie:

Function UpdateAttributes {

        Param($userinfo)

        $attribs = 'postalCode','title',

        'physicalDeliveryOfficeName'

        Foreach ($attrib in $attribs) {

        If ($userinfo[$attrib] –ne '') {

        $update = @{$attrib=$userinfo

        ['attrib']}

        Set-QADUser

        -identity 'DOMAIN\'+$userinfo

       ['samAccountName'] 

      -objectAttributes $update

        }

      }

    }

Ponieważ polecenie cmdlet Set-QADUser akceptuje obiekt hashtable dla parametru – objectAttributes, można by pomyśleć, że mógłbym po prostu przekazać go do obiektu $userinfo. Jednak mamy w nim takie rzeczy jak nazwy grup, które nie są nazwami atrybutów Active Directory, zatem taki trik by nie zadziałał. Co więcej, nie chcę przesyłać żadnych pustych atrybutów, zatem potrzebna jest zdolność – co zrobiłem w tej funkcji – przejścia najpierw przez całą listę atrybutów i następnie uaktualnienia jedynie tych, które faktycznie mają wartości w oryginalnym pliku CSV.

 Do początku strony Do początku strony

Dalszy rozwój

Istnieje oczywiście wiele rzeczy, które można zrobić, aby rozbudować ten skrypt. Oto kilka pomysłów, które przychodzą na myśl:

Odpowiedź: Tak. Z jednym tylko, ale istotnym wyjątkiem, pojedyncze i podwójne cudzysłowy zachowują się identycznie. Oznacza to, ze obydwa poniższe polecenia spowodują przypisanie do zmiennej $var łańcucha "Microsoft":

  • Zamiast odczytywania informacji z pliku CSV można pobierać je z bazy danych (na przykład z bazy działu kadr). Wymaga to tylko zastąpienia funkcji importującej, co omówiłem w części pierwszej artykułu.
  • Można wykonać inne działania wyposażające nowe konta użytkowników. Będzie to wymagało dodania nowych funkcji podrzędnych do głównej funkcji Provision. Warto pamiętać, aby każde zasadnicze zadanie miało własną funkcję podrzędną, co zapewni, że całość będzie łatwiejsza do napisania, debugowania i modyfikacji.
  • Można zapisać plik dziennika zawierający wykonywane operacje. W tym celu daje się wykorzystać polecenie Out-File, aby dodawać tekst do pliku dziennika wewnątrz każdej z funkcji podrzędnych.
  • Przy użyciu technik przedstawionych w tej serii można także utworzyć skrypt ponownego wyposażania, który będzie zmieniał przydziały grup, uprawnienia i atrybuty Active Directory dla użytkowników przechodzących na inną pozycję wewnątrz firmy.
$var = 'Microsoft'

$var = "Microsoft"

 Do początku strony Do początku strony

Kilka uwag końcowych

Mam nadzieję, że gotowy skrypt i wszystkie jego podrzędne funkcje okażą się użytecznym punktem startowym do konstruowania własnych skryptów tworzenia i wyposażania użytkowników. Na zakończenie chciałbym dodać kilka komentarzy do niektórych decyzji, które podjąłem podczas jego tworzenia.

Wybrałem użycie obiektów hashtable do przechowywania informacji o użytkownikach zamiast budowy własnego obiektu, gdyż zapewniają one prostszą metodę wyliczania zbiorów właściwości, gdy nie możemy z góry przewidzieć, czym będą te właściwości. Mówiąc inaczej, obiekt hashtable jest łatwiejszy w użyciu, gdy wiemy, że trzeba będzie dodać więcej atrybutów, a jednocześnie możemy się spodziewać, że nie wszystkie zostaną wykorzystane przy każdym uruchomieniu skryptu.

Wybrałem narzędzie Cacls.exe do modyfikowania uprawnień folderu, gdyż, jak wyjaśniłem w części trzeciej, jest to po prostu prostsze niż użycie własnych poleceń powłoki dotyczących ACL. Dodatkowo zastosowanie Cacls.exe pozwoliło mi zademonstrować jedną z metod parametryzowania zewnętrznych narzędzi wiersza polecenia przy użyciu zmiennych powłoki.

Zdecydowałem się na użycie poleceń cmdlet firmy Quest zamiast ADSI, gdyż oferują one coś, co odczuwam jako bardziej naturalne podejście do manipulowania danymi katalogowymi w Windows PowerShell. Korzystanie z narzędzia ADSI może być bardzo męczące, przy czym wymusza ono bardziej proceduralny styl programowania, nie zaś styl zorientowany na polecenia, którego mogłem użyć w tym przykładzie.

Bez względu na to, czy Czytelnik podejmie te same decyzje przy tworzeniu własnych skryptów, mam nadzieję, że uzna te techniki i odmienne podejścia za użyteczne przy rozwiązywaniu niektórych zadań administracyjnych. Zapraszam też do dzielenia się swoimi sugestiami i propozycjami ulepszeń. W mojej witrynie ConcentratedTech.com dostępna jest strona Contact, z której można wysłać do mnie wiadomość. Proszę przy tym zaznaczyć, czy będę mógł wykorzystać te komentarze w przyszłych wydaniach TechNet Magazine.

 Do początku strony Do początku strony

Windows PowerShell - Pytania i odpowiedzi

Pytanie: Jakie produkty firmy Microsoft mogą być zarządzane przy użyciu poleceń cmdlet Windows PowerShell?

Odpowiedź: Obecnie lista obejmuje Exchange Server 2007, System Center Virtual Machine Manager, System Center Operations Manager oraz System Center Data Protection Manager. Ponadto SQL Server 2008 zawiera kilka poleceń cmdlet Windows PowerShell, jakkolwiek sprowadzają się one głównie do umożliwienia wykonania wyrażeń Transact-SQL (Transact-SQL jest natywnym językiem skryptowym w SQL Server).

Nie trzeba jednak ograniczać się do tej listy. Można zarządzać Active Directory, korzystając z darmowego zestawu poleceń cmdlet, udostępnianego przez www.quest.com/powershell . Polecenia cmdlet dla Internet Information Services (IIS) 7.0 są w trakcie projektowania. Istnieją nawet polecenia cmdlet dla produktów innych firm, takich jak VMWare, IBM WebSphere MQ i inne. Można również wykorzystać istniejące narzędzia wiersza polecenia do zarządzania komponentami Windows, takimi jak IIS, DNS, DHCP, Windows Firewall i wiele innych.

O autorze

Don Jones jest współzałożycielem firmy (i witryny) Concentrated Technology, zawierającej blogi na temat Windows PowerShell, SQL Server, App-V i inne.

 Do początku strony Do początku strony

Windows PowerShell: Automatyzowanie tworzenia i wyposażania użytkowników, część 3     Windows Server 2008