Laboratorium PowerShell – Zadania praktyczne
Poniżej znajduje się 10 zadań laboratoryjnych z zakresu programowania w PowerShell. Każde zadanie jest zaprojektowane tak,
aby zajmowało około 25-30 minut wykonania. Zadania obejmują różne tematy poznane na wykładzie, od podstaw
tworzenia skryptów, przez pracę ze zmiennymi, tablicami i potokiem obiektowym, aż po zaawansowane
przetwarzanie danych i automatyzację zadań systemowych.
Zadanie 1: Kalkulator średniej ocen studenta
Cel:
Napisz skrypt, który pobierze od użytkownika listę ocen, obliczy średnią arytmetyczną i wyświetli komunikat o wyniku zaliczenia (średnia >= 3.0).
Scenariusz:
Jesteś administratorem systemu na uczelni. Prowadzący poprosił Cię o stworzenie narzędzia do wprowadzania ocen cząstkowych studentów. Skrypt ma działać interaktywnie - użytkownik wprowadza kolejne oceny (liczby od 2 do 6), a gdy skończysz wpisywać, wpisz słowo "koniec". Skrypt następnie oblicza średnią arytmetyczną ze wszystkich wprowadzonych ocen z dokładnością do dwóch miejsc po przecinku. Na końcu wyświetla komunikat informujący czy student zdał egzamin (średnia >= 3.0) czy nie zdał (średnia < 3.0). Skrypt powinien też walidować czy wprowadzone wartości są poprawnymi ocenami.
Wskazówki do wykonania:
- Na początku skryptu zadeklaruj pustą tablicę do przechowywania ocen:
$oceny = @()
- Użyj pętli
while ($true) do tworzenia nieskończonej pętli wczytywania
- Wewnątrz pętli użyj polecenia
Read-Host do pobrania oceny od użytkownika
- Sprawdź czy użytkownik wpisał "koniec":
if ($ocena -eq "koniec") { break }
- Waliduj czy wpisana wartość jest liczbą od 2 do 6 za pomocą
[int]$ocena -ge 2 -and [int]$ocena -le 6
- Użyj instrukcji try/catch do obsługi błędów konwersji liczbowej
- Dodaj ocenę do tablicy:
$oceny += $ocena
- Po zakończeniu pętli oblicz sumę:
$suma = ($oceny | Measure-Object -Sum).Sum
- Oblicz średnią używając dzielenia z precyzją:
[math]::Round($suma / $oceny.Count, 2)
- Zastosuj instrukcję
if do sprawdzenia warunku zaliczenia: if ($srednia -ge 3.0)
- Wyświetl komunikat wynikowy z kolorowaniem tekstu za pomocą
Write-Host -ForegroundColor
- Na końcu wyświetl informację o liczbie wprowadzonych ocen i ich wartościach
- Przetestuj skrypt z różnymi danymi wejściowymi, także z nieprawidłowymi danymi
Zadanie 2: Monitor procesów systemowych
Cel:
Stwórz skrypt, który przeanalizuje uruchomione procesy w systemie i wygeneruje raport z najbardziej zasobochłonnych procesów.
Scenariusz:
Pracujesz w dziale IT. Twoim zadaniem jest monitorowanie wydajności serwera. Napisz skrypt, który pobierze listę wszystkich uruchomionych procesów, posortuje je według zużycia pamięci RAM (malejąco) i wyświetli Top 10 najbardziej zasobożernych procesów. Dla każdego procesu pokaż: nazwę, PID, zużycie pamięci w MB i czas działania. Skrypt powinien też identyfikować procesy zużywające więcej niż 100 MB pamięci i oznaczać je jako "UWAGA". Na końcu skrypt wygeneruj podsumowanie: łączne zużycie pamięci przez wszystkie procesy i liczbę procesów powyżej progu 100 MB.
Wskazówki do wykonania:
- Użyj polecenia
Get-Process do pobrania wszystkich procesów
- Pobierz właściwości: Name, Id, WorkingSet64, CPU - użyj
Select-Object
- Konwertuj pamięć na MB:
($_.WorkingSet64 / 1MB)
- Posortuj procesy:
Sort-Object WorkingSet64 -Descending
- Wybierz pierwsze 10:
Select-Object -First 10
- Użyj pętli
ForEach-Object do przetwarzania każdego procesu
- Sprawdź próg pamięci:
if ($pamiecMB -gt 100)
- Formatuj czas działania używając właściwości StartTime lub TotalProcessorTime
- Użyj
Write-Host z kolorowaniem do oznaczenia procesów UWAGA
- Oblicz sumę pamięci:
($procesy | Measure-Object -Property WorkingSet64 -Sum).Sum
- Konwertuj sumę na GB dla czytelności:
[math]::Round($suma / 1GB, 2)
- Zapisz raport do pliku używając
Set-Content
- Przetestuj skrypt i przeanalizuj wyniki
Zadanie 3: Parser pliku logów systemowych
Cel:
Napisz skrypt, który odczyta plik logów, wyizoluje wpisy błędów i wygeneruje statystyki.
Scenariusz:
Jesteś administratorem systemu po awarii. Musisz przeanalizować plik logów, aby znaleźć przyczynę problemu. Napisz skrypt, który odczyta plik logów (jeśli plik nie istnieje, skrypt najpierw tworzy przykładowy plik z losowymi wpisami), wyszuka linie zawierające słowo "ERROR", a następnie wyświetli statystyki: ile razy wystąpił każdy typ błędu, datę i godzinę pierwszego i ostatniego wystąpienia błędu oraz najczęściej występujący typ błędu z informacją ile razy wystąpił. Skrypt powinien też wyświetlić listę wszystkich unikalnych typów błędów znalezionych w logach. Użyj tablicy mieszającej do zliczania typów błędów.
Wskazówki do wykonania:
- Sprawdź czy plik logów istnieje:
Test-Path $sciezka
- Jeśli nie istnieje - utwórz przykładowy plik z danymi testowymi
- Przykładowy plik powinien zawierać linie w formacie:
[2024-01-15 14:23:45] ERROR DatabaseConnection: Failed to connect
- Odczytaj plik używając
Get-Content -Path $sciezka
- Filtruj linie z ERROR:
Where-Object { $_ -match "ERROR" }
- Użyj wyrażeń regularnych do wyciągnięcia typu błędu:
[regex]::Match($linia, 'ERROR (\w+):').Groups[1].Value
- Zadeklaruj tablicę mieszającą:
$bledy = @{}
- Zliczaj typy błędów:
$bledy[$typ]++
- Znajdź pierwszą i ostatnią datę błędu dla każdego typu
- Iteruj po tablicy mieszającej:
foreach ($klucz in $bledy.Keys)
- Posortuj wyniki:
$bledy.GetEnumerator() | Sort-Object Value -Descending
- Znajdź najczęstszy błąd biorąc pierwszy element posortowanej listy
- Wyświetl podsumowanie z liczbą łącznych błędów
- Przetestuj skrypt na różnych plikach logów
Zadanie 4: Automatyczny kreator kopii zapasowych
Cel:
Stwórz skrypt do tworzenia i przywracania archiwów kopii zapasowych plików.
Scenariusz:
Jesteś administratorem systemu i musisz zapewnić bezpieczeństwo danych. Napisz skrypt, który tworzy archiwum spakowane (zip) z podanych plików lub katalogów, dodając do nazwy pliku archiwum datę i godzinę w formacie yyyy-MM-dd_HH-mm-ss. Skrypt powinien obsługiwać dwa tryby pracy: tryb backup (utworzenie archiwum) i tryb restore (odtworzenie plików z archiwum). W trybie backup skrypt przyjmuje jako argumenty katalog źródłowy i katalog docelowy. W trybie restore skrypt przyjmuje ścieżkę do pliku archiwum i katalog docelowy. Skrypt powinien wyświetlać komunikaty postępu i na końcu informować o sukcesie lub błędzie operacji.
Wskazówki do wykonania:
- Użyj bloku
param() do zdefiniowania parametrów
- Zdefiniuj parametry:
[Parameter(Mandatory=$true)][string]$Tryb
- Sprawdź tryb:
if ($Tryb -eq "backup") { ... }
- Waliduj czy katalog źródłowy istnieje:
Test-Path -Path $Zrodlo -PathType Container
- Generuj nazwę archiwum z datą:
Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
- Użyj polecenia
Compress-Archive do tworzenia archiwum
- W trybie restore użyj polecenia
Expand-Archive
- Sprawdź kody wyjścia:
if ($?)
- Obsługę błędów:
try/catch z Write-Error
- Waliduj ścieżki przed operacjami na plikach
- Użyj
Write-Host do wyświetlania postępu z kolorowaniem
- Na końcu wyświetl ścieżkę do utworzonego archiwum
- Przetestuj działanie w obu trybach
- Sprawdź zawartość utworzonego archiwum używając klasy .NET:
Add-Type -AssemblyName System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::OpenRead($sciezka).Entries.FullName
Zadanie 5: Generator bezpiecznych haseł
Cel:
Napisz skrypt generujący bezpieczne hasła losowe zawierające różne typy znaków.
Scenariusz:
Twoja firma potrzebuje narzędzia do generowania bezpiecznych haseł dla nowych pracowników. Napisz skrypt, który generuje hasło o podanej długości (domyślnie 16 znaków) zawierające wielkie litery (A-Z), małe litery (a-z), cyfry (0-9) i znaki specjalne. Skrypt powinien przyjmować jeden opcjonalny argument określający długość hasła. Po wygenerowaniu hasła skrypt powinien zweryfikować czy hasło zawiera przynajmniej jedną wielką literę, jedną małą literę, jedną cyfrę i jeden znak specjalny - jeśli któryś z tych warunków nie jest spełniony, skrypt generuje hasło ponownie (z max 10 próbami). Hasło powinno być wyświetlane na ekranie w czytelnym formacie z informacją o długości.
Wskazówki do wykonania:
- Przyjmij długość hasła jako parametr:
[int]$Dlugosc = 16
- Sprawdź czy parametr jest poprawny:
if ($Dlugosc -lt 4)
- Zdefiniuj zestawy znaków jako zmienne
- Wielkie litery:
[char[]](65..90)
- Małe litery:
[char[]](97..122)
- Cyfry:
[char[]](48..57)
- Znaki specjalne:
[char[]](33..47 + 58..64 + 91..96 + 123..126)
- Połącz wszystkie znaki:
$wszystkieZnaki = $wielkie + $male + $cyfry + $specjalne
- Użyj klasy
[System.Security.Cryptography.RandomNumberGenerator]
- Lub prostsze rozwiązanie:
Get-Random z tablicy znaków
- W pętli do/while generuj hasło spełniające wymagania
- Sprawdź wielkie:
$haslo -cmatch '[A-Z]'
- Sprawdź małe:
$haslo -cmatch '[a-z]'
- Sprawdź cyfrę:
$haslo -match '[0-9]'
- Sprawdź specjalny:
$haslo -match '[!@#$%^&*()]'
- Wyświetl hasło i jego długość
- Przetestuj skrypt z różnymi długościami
Zadanie 6: Menedżer usług systemowych
Cel:
Stwórz skrypt do zarządzania usługami Windows - wyświetlanie, uruchamianie i zatrzymywanie usług.
Scenariusz:
Jako administrator systemu Windows musisz mieć narzędzie do zarządzania usługami. Napisz skrypt, który potrafi wykonywać trzy akcje: (1) list - wyświetlić wszystkie usługi w stanie Running lub Stopped w czytelnym formacie, (2) start - uruchomić usługę o podanej nazwie, (3) stop - zatrzymać usługę o podanej nazwie. Skrypt powinien przyjmować drugi argument jako nazwę usługi. Dla akcji start/stop skrypt ma sprawdzać czy usługa istnieje i czy nie jest już w wymaganym stanie. Skrypt powinien też wyświetlać komunikaty informujące o postępie operacji. Zabezpiecz przed zatrzymaniem krytycznych usług systemowych.
Wskazówki do wykonania:
- Użyj
Get-Service do pobrania listy usług
- Akcja list: filtruj
Where-Object {$_.Status -eq 'Running'}
- Użyj
Select-Object do wyboru właściwości Name, Status, DisplayName
- Akcja start: użyj
Start-Service -Name $nazwa
- Akcja stop: użyj
Stop-Service -Name $nazwa
- Sprawdź czy usługa istnieje:
Get-Service -Name $nazwa -ErrorAction SilentlyContinue
- Sprawdź czy usługa jest już uruchomiona:
if ($serwis.Status -eq 'Running')
- Lista usług krytycznych:
@("WinDefend", "wuauserv", "BITS")
- Zabezpiecz przed zatrzymaniem usług systemowych
- Użyj
Write-Host z kolorowaniem do komunikatów
- Obsługuj wyjątki:
try/catch z Write-Error
- Przetestuj akcje list, start i stop
Zadanie 7: Konwerter jednostek miar
Cel:
Napisz skrypt do konwersji jednostek długości, temperatury i wagi.
Scenariusz:
Pracujesz w dziale logistyki i potrzebujesz narzędzia do szybkiej konwersji jednostek. Napisz skrypt, który obsługuje konwersje jednostek długości (metry <-> stopy, cale <-> centymetry), temperatury (Celsjusz <-> Fahrenheit, Celsjusz <-> Kelvin, Fahrenheit <-> Kelvin) oraz wagi (kilogramy <-> funty, gramy <-> uncje). Skrypt przyjmuje trzy argumenty: wartość do przeliczenia, jednostkę źródłową i jednostkę docelową. Skrypt powinien walidować argumenty i wyświetlać błąd gdy podano nieprawidłowe dane. Wynik konwersji powinien być wyświetlony w czytelnym formacie z informacją co i jak przeliczono. Uruchom skrypt dla każdego typu konwersji i sprawdź wyniki.
Wskazówki do wykonania:
- Użyj bloku
param() do zdefiniowania parametrów
- Przyjmij argumenty: wartość, z_jednostki, do_jednostki
- Sprawdź liczbę argumentów i wyświetl pomoc
- Sprawdź czy wartość jest liczbą używając
[double]::TryParse()
- Użyj instrukcji
switch do wyboru typu konwersji
- Konwersja długości: 1 m = 3.28084 stóp, 1 cal = 2.54 cm
- konwersja temperatury: F = C * 9/5 + 32, K = C + 273.15
- Konwersja wagi: 1 kg = 2.20462 funta, 1 g = 0.035274 uncji
- Użyj
[math]::Round() do zaokrąglenia wyniku
- Nieobsługiwane kombinacje obsłuż komunikatem błędu
- Wyświetl wynik w formacie:
$wartość $z = $wynik $do
- Przetestuj różne konwersje
Zadanie 8: System logowania zdarzeń
Cel:
Stwórz modułowy system logowania z funkcjami do zapisywania i odczytywania logów.
Scenariusz:
Chcesz stworzyć uniwersalny moduł logowania, który może być używany przez inne skrypty. Napisz moduł PowerShell (plik .psm1) z funkcjami logującymi oraz skrypt demonstracyjny. Moduł powinien zawierać trzy funkcje: Write-LogInfo (informacje), Write-LogWarning (ostrzeżenia), Write-LogError (błędy), które zapisują komunikaty do pliku logu z datą, poziomem ważności i wiadomością. Format wpisu logu: [2024-01-15 14:30:45] [INFO] Komunikat informacyjny. Moduł powinien też zawierać funkcję do odczytywania logów. Skrypt demonstracyjny importuje moduł i wywołuje każdą funkcję z przykładowymi komunikatami.
Wskazówki do wykonania:
- Stwórz plik modułu Logger.psm1
- Zdefiniuj zmienną dla ścieżki pliku logu
- Funkcja Write-LogInfo: zapisz z poziomem INFO
- Funkcja Write-LogWarning: zapisz z poziomem WARNING
- Funkcja Write-LogError: zapisz z poziomem ERROR
- Format daty:
Get-Date -Format "yyyy-MM-dd HH:mm:ss"
- Użyj
Add-Content do dopisywania do pliku
- Funkcja Read-Logs:
Get-Content z opcją -Tail
- Funkcja Clear-Logs:
Set-Content pustą treścią
- Eksportuj funkcje:
Export-ModuleMember
- W głównym skrypcie użyj
Import-Module
- Wywołaj każdą funkcję z przykładowymi komunikatami
- Po uruchomieniu sprawdź zawartość pliku logu
- Opcjonalnie: dodaj kolorowanie komunikatów
Zadanie 9: Masowa zmiana nazw plików
Cel:
Napisz skrypt do masowej transformacji nazw plików według określonego wzorca.
Scenariusz:
Masz katalog z wieloma plikami o różnych nazwach (np. IMG_001.jpg, Photo_002.png, DSC1234.jpeg). Musisz je uporządkować: zmienić wielkość liter na małe, dodać prefix, usunąć spacje lub zamienić określony wzorzec w nazwie na inny. Napisz skrypt, który przyjmuje trzy argumenty: katalog z plikami, tryb transformacji (lowercase/uppercase/prefix/replace) i prefix (opcjonalny) lub tekst do zamiany i tekst zamiany. Skrypt powinien wyświetlać podgląd (dry-run) gdy podano opcję -Preview, lub faktycznie zmieniać nazwy bez tej opcji. Skrypt powinien sprawdzać czy plik o nowej nazwie już istnieje i nie nadpisywać istniejących plików. Uruchom skrypt w trybie podglądu i następnie faktycznie zmień nazwy plików.
Wskazówki do wykonania:
- Użyj bloku
param() z parametrem -Preview
- Sprawdź czy katalog istnieje:
Test-Path
- Pobierz listę plików:
Get-ChildItem -Path $katalog -File
- Obsłuż tryb lowercase:
$nowaNazwa = $pol.ToLower()
- Obsłuż tryb uppercase:
$nowaNazwa = $pol.ToUpper()
- Obsłuż tryb prefix:
$nowaNazwa = "$prefix$pol"
- Obsłuż tryb replace:
$nowaNazwa = $pol -replace $stary, $nowy
- Pomiń katalogi:
if ($_.PSIsContainer) { continue }
- Sprawdź czy nowa nazwa istnieje:
Test-Path $nowaSciezka
- Jeśli istnieje, dodaj sufiks lub pomiń
- Jeśli -Preview, tylko wyświetl plan zmian
- Bez -Preview użyj
Rename-Item
- Użyj zmiennych do zliczania zmienionych i pominiętych
- Na końcu wyświetl podsumowanie
- Przetestuj z różnymi trybami
Zadanie 10: Automatyczny instalator środowiska
Cel:
Stwórz skrypt do automatycznej konfiguracji środowiska pracy i instalacji narzędzi.
Scenariusz:
Dostajesz nowy komputer i musisz szybko skonfigurować środowisko pracy. Napisz skrypt, który zainstaluje i skonfiguruje podstawowe narzędzia. Skrypt powinien zainstalować pakiety: git, curl (jeśli nie zainstalowane), utworzyć strukturę katalogów w $HOME (Projects, Scripts, Downloads), skonfigurować profile PowerShell z podstawowymi aliasami (np. ll=Get-ChildItem), utworzyć automatyczny profil jeśli nie istnieje. Skrypt powinien sprawdzać czy jest uruchomiony jako Administrator - jeśli nie, wyświetlić komunikat ostrzegawczy i kontynuować bez instalacji pakietów systemowych. Na końcu wyświetlić podsumowanie wykonanych operacji.
Wskazówki do wykonania:
- Sprawdź uprawnienia administratora:
[Security.Principal.WindowsPrincipal]
- Użyj
GetCurrentPrincipal() i IsInRole()
- Zdefiniuj listę katalogów do utworzenia
- Utwórz katalogi:
New-Item -ItemType Directory
- Sprawdź czy katalog istnieje:
Test-Path
- Utwórz lub edytuj profil:
$PROFILE
- Dodaj aliasy do profilu:
Set-Alias
- Aliasy: ll, la, gl (Get-Location)
- Sprawdź czy git jest zainstalowany:
git --version
- Użyj
winget do instalacji pakietów (jeśli dostępne)
- Alternatywnie wyświetl instrukcje instalacji
- Użyj
Write-Host z kolorowaniem
- Na końcu wyświetl podsumowanie operacji
- Przetestuj na nowym komputerze