PowerShell w praktyce: Podstawy dla administratora

Kacper Kondraciuk, 24 lutego 2016

Niniejszy artykuł porusza podstawowe zagadnienia z wykorzystania języka skryptowego PowerShell. Przedstawione w dalszej części przykłady mają na celu pokazać początkującym administratorom Windows Server, iż „nie taki diabeł straszny” oraz zachęcić do korzystania z konsoli na co dzień. Wielokrotne powtarzanie monotonnej pracy rodzi potrzebę automatyzacji. Nie zawsze jednak wiadomo, od czego ją zacząć.

Czym jest PowerShell? 

PowerShell w praktyce 1

PowerShell nie jest jedynie interpreterem poleceń, następcą cmd.exe. Jest to język skryptowy, który umożliwia budowanie całych sekwencji poleceń o charakterze tradycyjnych programów.

Uruchamianie środowiska

PowerShell jest domyślnie dodawany do większości współczesnych dystrybucji systemów Windows od wersji licencyjnej Professional w górę. W przypadku braku PowerShell w danej wersji systemu można go w prosty sposób doinstalować. Szczegóły można znaleźć na stronach Microsoftu (https://technet.microsoft.com/pl-pl/library/hh847837.aspx).

PS (PowerShell) znajduje się domyślnie pod ścieżką C:\Windows\System32\WindowsPowerShell\, a zainstalowany tworzy skróty w menu start. Można go także uruchomić wpisując „powershell” w oknie uruchamiania (Win+R).

Podczas tworzenia pierwszych skryptów zalecane jest korzystanie z dołączonego środowiska: Windows PowerShell ISE. Podpowiada ono nazwy oraz składnie zarówno komend jak i zainstalowanych modułów – gotowych do zaimportowania.

PowerShell w praktyce 2

Okno „Windows PowerShell ISE” jest podzielone na część: do edycji treści skryptu i okienko konsoli do testowania.

Pierwsze kroki

Dla administratora najważniejsze są moduły obsługi Active Directory oraz serwera Exchange.

W menu start na kontrolerach domeny zwykle znajdują się oddzielne skróty do uruchamiania gotowych przystawek, np. z Active Directory (AD). Można także w prosty sposób zaimportować taki gotowy moduł do konsoli wpisując polecenie:

Import-Module ActiveDirectory

Do zaimportowania komend niezbędnych do obsługi serwera Exchange należy nawiązać połączenie i rozpocząć sesję z serwerem:

$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://NAZWA_SERWERA_EXCHANGE/powershell
Import-PSSession $session

Pierwszy wiersz w powyższym przykładzie definiuje nawiązanie sesji do zmiennej $session. Należy tutaj odpowiednio określić adres serwera, z którym pragniemy się połączyć. Drugi wiersz powoduje nawiązanie tej sesji.
Ważnym jest, aby użytkownik wpisujący te polecenia w oknie konsoli miał odpowiednie uprawnienia do ich wykonywania.

Przydatne komendy

Zestawienie najważniejszych komend stosowanych w pracy administratora jest kwestią indywidualną.  Komendy przedstawione poniżej są tylko wybranymi przykładami w gąszczu tych, które mogą okazać się przydatne. Mają one na celu jedynie zainspirowanie do poszukiwania tych potrzebnych do własnej pracy.
Każda komenda ma swoją stronę ze szczegółowym opisem na witrynach Microsoftu. Poniżej przedstawiono ich przykładowe zastosowania.

Tworzenie nowego użytkownika domenowego

New-ADUser -SamAccountName Login –Name “Imię” –Surname “Nazwisko” –EmailAdress “adres@mail” –AccountPassword “Hasło” –Patch “ŚcieżkaOU”–Enabled

Powyższy zapis komendy wymaga podania: loginu użytkownika, jego imienia oraz nazwiska, adresu email, hasła jakie ma zostać nadane oraz ścieżki wskazującej gdzie konto ma zostać utworzone. Ponadto, konto jest od razu włączone na czas nieokreślony.
Ścieżkę należy zapisywać w standardowym formacie, np. „OU=Nowi,OU=Pracownicy,DC=Contonso,dc=com”.

  • Przenoszenie obiektu AD do innej Jednostki Organizacyjnej (OU)

Move-ADObject Login -TargetPath „ŚcieżkaOU

Komenda ta jest przydatna w momencie, gdy np. stworzony użytkownik znajduje się nie w tym kontenerze, w którym powinien, a także przy pracach porządkowych w drzewie AD.

  • Zbieranie danych o koncie użytkownika

Get-ADUser login | Select ObjectGUID | ft

Ta komenda wyświetla informacje o użytkowniku. Będzie wyszukiwała jedynie jego GUID, a wynik zostanie przedstawiony w formie tabeli, co jest przydane w celu czytelnego wylistowania większej ilości danych.

  • Usuwanie użytkownika ze wszystkich grup domenowych

Get-ADPrincipalGroupMembership GUID | % {Remove-ADPrincipalGroupMembership GUID -MemberOf $_ -Confirm:$false -ErrorAction SilentlyContinue}

Ta nieco bardziej złożona komenda próbuje usunąć użytkownika ze wszystkich grup (zarówno Distribution jak i Security), do których należy. Oczywiście nie można usunąć go z PrincipalGroup, dlatego też dopisano odpowiedni argument, aby nie wyświetlał się błąd na ekranie. Dodatkowo, nie pyta użytkownika o potwierdzenie każdej z usuwanych grup – wykonuje to sama.

  • Usuwanie skrzynek z serwera Exchange wraz z kontami w AD

Remove-Mailbox alias -Confirm:$false

Powyższej komendy należy używać tylko przy całkowitej pewności wykonywanych działań, gdyż nie  wystąpi zapytanie o potwierdzenie.

  • Ustawianie odpowiedzi automatycznych na skrzynce

$msg=”Treść zwrotki mailowej”
Set-MailboxAutoReplyConfiguration alias -AutoReplyState Enabled -InternalMessage $msg -ExternalMessage $msg

Powyższe wiersze można wprowadzać jeden po drugim. PowerShell zapamięta zdefiniowaną zmienną. Można także wpisywać treść bezpośrednio w cudzysłów, bez korzystania ze zmiennej.
Komenda włącza odpowiedzi automatyczne oraz ustawia dla niego zdefiniowaną treść. Można ustawić oddzielną treść dla wiadomości wewnątrz i na zewnątrz organizacji.

  • Śledzenie wiadomości z logów serwera

Get-TransportServer |Get-MessageTrackinglog -ResultSize Unlimited -Start „data” | where {[string]$recipients -like „fraza„} | Select Timestamp, Sender, {$_Recipients}, MessageSubject, EventID, SourceContext | format-list

Zapis sam znajduje i przeszukuje wszystkie przekaźniki pocztowe. Listuje wszystkie wiadomości wysłane do skrzynek zawierających w nazwie frazę oraz wysłane począwszy od podanej daty (która powinna być zapisana w formacie RRRR-MM-DD GG:MM:SS, np. „2012-07-13 12:00:01”).
Wyświetlane są jedynie niektóre właściwości maila: czas akcji wiadomości, nadawca, odbiorcy, temat wiadomości, ID zdarzenia, szczegóły zdarzenia. Przedstawione są one w formie listy.

Komenda ta, jest szczególnie przydatna w przypadku potrzeby uzyskania informacji o zaginionej wiadomości. Pozwala ona sprawdzić czy wiadomość została wysłana przez użytkownika (lub czy do niego dotarła) oraz zrozumieć przyczynę jej ewentualnego braku.

Obsługa Urzędu Certyfikacji

Jeśli dana organizacja korzysta z Urzędu Certyfikacji (Certification Authority) do podpisywania stron internetowych, czy choćby uwierzytelniania użytkowników, można zautomatyzować pracę związaną z ich obsługą przy użyciu PowerShell.

Sam w sobie PowerShell nie umożliwia wygodnej pracy z Urzędem Certyfikacji (CA), zwłaszcza jeśli oparty jest o starsze wersje Windows Server.
Z pomocą jednak przychodzi zewnętrzny moduł wykonany przez CodePLEX. Można go pobrać ze strony http://pspki.codeplex.com/. Moduł ten jest prosty w instalacji oraz został wydany na licencji Microsoft Public License (Ms-PL). Dodatkowo ma otwarty kod źródłowy, a producent udostępnia szczegółową dokumentację odnośnie jego użycia. Dalej przedstawiono kilka przykładów.

Po zainstalowaniu tego modułu nie tworzą się żadne skróty. Moduł można zaimportować jak każdy inny, nieoparty o sesję (przeciwnie niż w wypadku modułów do obsługi serwera Exchange):

Import-Module PSPKI

Warto zaznaczyć istnienie tej biblioteki komend, nawet jeśli obsługa CA ograniczona będzie do unieważniania certyfikatów.
$filter = 'Request.RequesterName -eq Domena\Login
Get-CertificationAuthority | Get-Issuedrequest -Filter $filter | Revoke-Certificate -Reason „Hold”

Powyższa komenda skutkuje unieważnieniem wszystkich certyfikatów wydawanych w imieniu użytkownika. Dla bezpieczeństwa, certyfikat zostaje wyłączony z opcją przywrócenia go – jedynie podanie parametru „-Reason” jako „Hold” umożliwia późniejsze włączenie certyfikatu.
Co więcej, komenda nie wymaga podawania konkretnego serwera CA. Get-CertificationAuthority przeszuka informacje w każdym zarejestrowanym w organizacji serwerze.

Wprowadzenie do pisania pierwszych skryptów

PowerShell oferuje ogromne możliwości, jednakże nadal trzeba traktować go jedynie jako język skryptowy. Mimo iż pisanie obiektowe z użyciem metod i klas jest dostępne od jakiegoś czasu, nadal jest traktowane jako podejście eksperymentalne

  • Zapisywanie i uruchamianie skryptu

Skrypty można pisać zarówno w ulubionym edytorze tekstu, jak i we wcześniej wspomnianym Windows PowerShell ISE. Ważnym jest, aby nadać mu odpowiednie rozszerzenie, którym domyślnie dla PowerShella jest *.ps1.

Aby uruchomić skrypt, wystarczy podać jego ścieżkę (znajdując się w innej) lub nazwę poprzedzoną przez kropkę i backslash (jeśli plik jest w samej ścieżce) w konsoli PSa lub wcisnąć klawisz F5 w wypadku ISE, np.

PowerShell w praktyce 3
  • Zmienne

PowerShell jest językiem wysokiego poziomu. Zmienne można definiować. Nie jest to jednak niezbędne do ich działania.

$zmienna1 = ‘tekst’
$zmienna2 = 44
$zmienna3 = [int] 7

Wszystkie powyższe zmienne będą działać należycie, mimo iż tylko $zmienna3 ma zadeklarowany typ wartości. Pierwsza z nich przyjmie typ String, podczas gdy dwie pozostałe będą liczbowe. W przypadku $zmienna2 można później zmienić jej typ zapisując do niej dane tekstowe, a do $zmienna1 można analogicznie zapisać potem dane liczbowe.

  • Tablice zmiennych

Przechowywanie większej niż jedna wartość ilości danych w zmiennej może okazać się bardzo przydatne. W tym celu można zastosować tablice, aby odwoływać się do osobnych jej elementów.
Jednakże, aby zmienna działała jako tablica, trzeba ją odpowiednio zadeklarować nadając jej odpowiedni typ.

$zmiennaArray= New-Object string[] 100

W powyższym przykładzie została stworzona tablica o skończonej ilości elementów i o typie String.
Odwoływanie się do poszczególnych elementów polega na wpisaniu w nawiasy kwadratowe indeksu elementu (licząc od zera), np. $zmiennaArray[13].

  • Pętle

Niezbędnym do zastosowania niektórych czynności, zwłaszcza mających na celu automatyzację, jest użycie pętli.
W PowerShellu można korzystać ze standardowych pętli:

Do… While…

$a = 1
DO {
$a
$a++
} While ($a -le 5)

Foreach

$trees = @(„Olcha”,”Jesion”,”Sosna”,”Dąb”,”Świerk”,”Brzoza”)
foreach ($drzewo in $drzewa) {
$drzewo = ” + $drzewo.length
}

FOR

for ($i=0; $i -le 30; $i++)
{
echo “Licznik: ”+$i
}

Pętle można oczywiście zagnieżdżać, lecz o tym więcej będzie w dalszej części.

  • Operacje na plikach

Funkcjonalność skryptów była by dość nikła, gdyby nie było możliwości posiłkowania się plikami.
PowerShell domyślnie umożliwia eksportowanie wyników do plików tekstowych:

$var >> C:\ps_logs\zawartosc_zmiennej.txt

Pozwala także je importować, np. do tablicy:

$lista = New-Object string[] 100
$lista = Get-Content c:\scripts\wartosc_listy.txt

  • Funkcje

Aby zachować przejrzystość w skryptach, jak i wygodę pracy, warto tworzyć funkcje spełniające konkretne role.
Funkcję można zadeklarować w każdym momencie skryptu przed jej wykorzystaniem, lecz dla czystości kodu zalecane jest pisanie ich przed właściwą treścią.

Sposób zadeklarowania nie różni się niczym od tego w pełnoprawnych językach programowania, takich jak C/C++/C#.

Function ListaNazwisk{
$nazwiska[$w] = (Get-ADUser -Identity $login[$v]).Surname
}

Wywołanie jest również podobne.

ListaNazwisk ($nazwiska,$login)

Co najważniejsze, funkcje można wykorzystywać wewnątrz pętli, a także wewnątrz innych funkcji. Dzięki czemu nie trzeba przepisywać tego samego kawałka kodu za każdym jego użyciem lub stosować rekurencje.

Przykładowe skrypty

Na zakończenie przedstawionych zostanie kilka przykładowych skryptów wraz z opisem. Mimo swojej prostoty potrafią zaoszczędzić sporo czasu w porównaniu do ręcznego korzystania z interfejsu graficznego.

  • Usuwanie skrzynek wraz z dowiązanymi kontami AD

$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://NAZWA_SERWERA/powershell

Import-PSSession $session
$lusers = New-Object string[] 200
$lusers = (get-mailbox  -OrganizationalUnit „Ścieżka_do_zablokowanych” -filter ([scriptblock]::create(„whenchanged -lt '$[1]get-date).adddays(-90'”))).alias
$lusers>>C:\ps_logs\usuwane.txt
$licz = ($lusers).count
$licz = $licz-1
for ($w=0; $w -le $licz; $w++)
{ Remove-Mailbox $lusers[$w] -Confirm:$false }

Cel:

Usunięcie wszystkich kont z danego OU, których data modyfikacji jest starsza niż 90 dni. Logowanie usuwanych kont do pliku tekstowego.

Krok po kroku:

nawiązanie połączenia do serwera Exchange;

ładowanie modułu do obsługi komend;

deklaracja tablicy $lusers;

zapisywanie tablicy aliasami skrzynek, których konta znajdują się w zdefiniowanym OU oraz nie były modyfikowane od ponad 90 dni;

zapisywanie aliasów skrzynek do pliku tekstowego;

zliczanie wszystkich aliasów w tablicy $lusers;

operacje arytmetyczne;

start pętli;

usuwanie skrzynek wraz z dopiętymi kontami AD, bez potwierdzenia przez użytkownika;

  • Przykładowe operacje na kontach

$luserN = New-Object string[] 100
$luser = New-Object string[] 100

$masterList = Get-Contentkonta.txt
$count = (Get-Contentkonta.txt | Measure-Object).Count
$j = 0
for ($i=0; $i -le $count; $i++)
{
foreach ($data in $masterList[$i])
{
$luserN[$j] = $data -split ',' -replace '^\s|\s$'
$luser[$j] = (Get-ADUser -identity $luserN[$j]).ObjectGUID
$j++
}
}

Import-Module ActiveDirectory
Import-Module PSPKI
$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://NAZWA_SERWERA/powershell
Import-PSSession $session

Function MailboxRules {
Get-InboxRule -Mailbox $luser[$w] | Remove-InboxRule -Confirm:$false
}

Function MoveUser {
Move-ADObject $luser[$w] -TargetPath „ou=konta_zablokowane,dc=Contonso,dc=com
}

Function DisableUser {
Disable-ADAccount $luser[$w]
}

Function CertRevoke {
$filter = 'Request.RequesterName -eq contonso\’+$luserN[$w]
Get-CertificationAuthority | Get-Issuedrequest -Filter $filter | Revoke-Certificate -Reason „Hold”
}

$countC = $count-1
for ($w=0; $w -le $countC; $w++)
{
DisableUser ($luser)
MoveUser ($luser)
CertRevoke ($luserN)
MailboxRules ($luser)
}

Cel:

Wyłączenie konta użytkownika, przeniesienie go do odpowiedniego kontenera, unieważnienie certyfikatów przez niego generowanych i usunięcie wszystkich reguł jakie miał na skrzynce pocztowej.

Krok po kroku:

zdefiniowanie tablic: jednej z loginami, drugiej z GUIDami obiektów;

wczytanie listy loginów z pliku (loginy w pliku oddzielone jedynie przecinkami);

obliczenie ilości kont do modyfikacji;

ładowanie modułów do obsługi AD, CA oraz Exchengea;

definicja funkcji usuwającej reguły na skrzynce;

definicja funkcji przenoszącej obiekt konta do zdefiniowanego OU;

definicja funkcji wyłączającej konto użytkownika;

definicja funkcji unieważniającej certyfikaty wystawione przez konto;

operacje arytmetyczne;

definicja pętli dla wszystkich elementów w pliku tekstowym;

wywołanie funkcji wewnątrz pętli;

Powyższe komendy i skrypty zostały przygotowane na wersji 5.0 PowerShella. Ich prawidłowe działanie wymaga zainstalowanego PowerShell w wersji minimum 3.0 (dla wykorzystania modułu PSPKI).

Komendy Exchange przygotowano na wersji serwera Exchange 2010. Wszystkie wersje, począwszy od Exchange 2007, na Exchange 2016 kończąc, wspierają wymienione cmdlety i strukturę zapisu skryptów.

Źródła:

  1. Opracowanie własne
  2. Microsoft TechNet
  3. CodePLEX (www.codeplex.com)

Kacper Kondraciuk

References

References
1 get-date).adddays(-90

BLOG

Zobacz inne nasze artykuły

Zarządzanie firmą w czasie pandemii

Zarządzanie firmą w czasie pandemii

Witam, nazywam się Piotr Popławski, jestem Prezesem Zarządu Support Online, spółki zajmującej się outsourcingiem informatycznym. 80-cio osobowy zespół naszej firmy działa prężnie na rynku zarówno Polskim jak i międzynarodowym. Moim hobby jest żeglarstwo, jestem...

FindTime. Jak oszczędzić czas podczas planowania spotkań.

FindTime. Jak oszczędzić czas podczas planowania spotkań.

Za każdym razem, kiedy organizujesz spotkanie z wieloma osobami, stajesz przed wyzwaniem. Jak znaleźć dogodny termin, który pasuje wszystkim uczestnikom? Jeśli zainteresowani są zebrani w jednym miejscu i mają wgląd w swoje kalendarze, zadanie nie musi być trudne. W...