Spis treści

Co to jest PowerShell?

PowerShell jest nową wersją konsoli poleceń w Windows (cmd.exe). Głównym powodem powstania jest automatyzacja zadań administracyjnych w Windows za pomocą poleceń tekstowych i skryptów (a nie narzędzi graficznych). Dostępne polecenia w głównie polecenia tzw. cmdlet, ale można uruchamiać dowolne polecenia konsolowe np. ifconfig, git. Jednak powershell nie jest całkowicie kompatybilny z cmd.exe. Polecenie cmdlet typowo nie zwracają rezultatu jako tekst, ale jako lista obiektów .Net, które mogą być dalej automatycznie przetwarzane bez potrzeby parsowania tekstu. Bogata biblioteka dostępnych komandletów pozwala na zarządzania Active Directory, Exchange, SQL Server oraz produktami innych firm np. VMware PowerShell

Cechy Powershella

  • strumienie/przetwarzanie potokowe (wyjście jednego polecenia jest wejściem dla następnego polecenia)
  • praca głównie na obiektach zamiast na tekście
  • wbudowany system pomocy
  • cmdlet (komandlety) - są to wewnętrzne polecenia Powershella zbudowane na wspólnym silniku .NET Framework (Powershell 5.1 i wcześniejsze) i .NET Core (Powershell 6 i późniejsze). Nie są zbiorem oddzielnych plików wykonywalnych. Cmdlety zazwyczaj pobierają dane wejściowe z obiektów i zwracają obiekty.
  • polecenia w PowerShell mogą być natywnymi plikami wykonywalnymi, cmdletami, funkcjami, skryptami lub aliasami. Każde polecenie, które uruchamiamy, należy do jednego z tych typów. Słowa polecenie i cmdlet są często używane zamiennie, ponieważ cmdlet jest typem polecenia.
  • obsługa bibliotek WMI (Windows Management Instrumentation), CIM (Common Information Model) CIM = WMI = CIM. CIM jest otwartym standardem opracowanym przez Distributed Management Task Force (DMTF), którego najnowsza wersja została wprowadzona w styczniu 2016 roku. CIM zapewnia wspólną definicję informacji o zarządzaniu systemami, sieciami, aplikacjami i usługami, a także umożliwia rozszerzenia dostawców.
  • jest to projekt opensource napisany w języku C#. Kod źródłowy: https://github.com/PowerShell/PowerShell
  • wielkie/małe litery nie są generalnie rozróżniane
  • polecenia często mają wiele form identycznie działających (np. Sort-Object, sort i Sort)

PowerShell nie jest całkowicie zgodny z konsolą cmd.exe ani z terminalem bash.

PowerShell ma co prawda znane polecenia np.: dir, cd, md, pwd, ls, mkdir. Nie są to natywne polecenia, a tylko aliasy do komandletów wykonujących podobne zadania. Te polecenia nie działają identycznie jak ich oryginały. Na przykład w PowerShell nie zadziała:

dir /w ls -al

Aplikacje konsolowe działają tak, jak w cmd.exe np. ping, ifconfig:

ipconfig /all ping localhost -t

WMI jest implementacją CIM firmy Microsoft dla platformy Windows. Dużą wadą poleceń cmdlet WMI jest to, że używają one DCOM do uzyskania dostępu do zdalnych maszyn. DCOM jest technologią przestarzałą, nie jest przyjazny dla zapór sieciowych, może być blokowany przez sprzęt sieciowy, a w razie niepowodzenia wypisuje dziwne błędy.

Komandlety CIM pojawiły się w PowerShell 3.0 jako część nowego API do pracy z klasami CIM, które jest bardziej oparte na standardach.

Podstawowa różnica pomiędzy poleceniami WMI a poleceniami CIM polega na tym, że polecenia CIM wykorzystują WSMAN (WinRM) do łączenia się ze zdalnymi maszynami. W ten sam sposób, w jaki można tworzyć sesje zdalne w PowerShell, można tworzyć sesje CIM i zarządzać nimi za pomocą cmdletów.

Instalacja PowerShell

PowerShell 5.0 jest dołączony do systemu operacyjnego Windows 10 i nie trzeba go instalować.

Preinstalowane wersje PowerShell w wersjach systemu Windows:

Wersja PowerShell System
PowerShell 5.1 Windows 10, Windows Server 2016
PowerShell 5.0 Windows 10
PowerShell 4.0 Windows 8.1, Windows Server 2012R2
PowerShell 3.0 Windows 8, Windows Server 2012
PowerShell 2.0 Windows 7, Windows Server 2008R2
PowerShell 1.0 Windows Server 2008

Sprawdzenie zainstalowanej wersji PowerShell:

Get-Host | Select-Object Version Version ------- 5.1.19041.2673

PowerShell Core 6/7

PowerShell Core 6 i 7 oparte są na nowszej bibliotece .Net Core, która nie jest w pełni zgodna z .Net Framework używanym w poprzednich wersjach. Przez to część komandletów nie jest jest obecna. PowerShell Core jest za to przenośny na Linux i MacOS. Jeśli jednak korzystasz tylko z Windows i PowerShell 5, nie ma w tej chwili powodu do przejścia na kolejną wersję PowerShell Core.

Instrukcja instalacji PowerShell Core 7 .

Konsola PowerShell

Aby uruchomić konsolę PowerShell:

  • wpisujemy w menu Start "PowerShell"
  • klikamy prawym przyciskiem myszy aplikację Windows PowerShell
  • wybieramy opcję Run as administrator (Uruchom jako administrator)

Konsolę możemy uruchomić jako administrator lub użytkownik. Jeśli uruchomimy ją w funkcji administratora powinny działać wszystkie polecenia np. polecenie wyświetlenia zawartości katalogu Get-Content. Nie działa ono w konsoli uruchomionej w funkcji użytkownika.

W konsoli możemy wprowadzać polecenia cmdlet.

Konsola PowerShell ma opcję uzupełniania. Wpisujemy np. Get- klikamy Tab, aby zobaczyć parametry dla polecenia Get.

Parametry wyświetlane są w kolejności alfabetycznej.

Aby wywołać wcześniejsze polecenie naciskamy na klawiaturze strzałkę w górę.

Jeśli wpiszesz kilka poleceń np. dir, ls. Wciśnięcie klawisza funkcyjnego F7 powinno wywołać okienko historii poleceń, z którego możemy wybrać potrzebną nam komendę. Aby komenda ta działała musimy usunąć moduł PSReadLine za pomocą polecenia Remove-Module -Name PSReadLine.

W konsoli możemy używać schowka i opcji kopiowania i wklejania:

  • kopiowanie do schowka - zaznaczamy tekst i naciskamy Ctrl+C lub Enter
  • wklejanie ze schowka - Ctrl+V lub klikamy prawy przycisk myszy RMB

Uruchamianie skryptu Powershell z poziomu konsoli

Polecenia PowerShell mogą być zapisane w pliku (skrypcie) z rozszerzeniem *.ps1. Uruchomienie skryptu wymaga podania pełnej ścieżki lub katalogu bieżącego:

PS C:\> & "C:\Program Files\Scripts\HelloWorld.ps1" PS C:\> & ".\hello.ps1"

Skróty klawiaturowe do zarządzania historią

W konsoli programu PowerShell możemy używać skrótów do zarządzania historią poleceń.

  • (strzałka w górę) — wyświetla poprzednie polecenie
  • (strzałka w dół) — wyświetla następne polecenie
  • F7 — wyświetla historię poleceń
  • Esc — ukrywanie historii, jeśli jest wyświetlona
  • F8 — znajduje polecenie. Najlepiej wpisać co najmniej jeden znak, a następnie nacisnąć klawisz F8
  • F9 — znajdowanie poleceń według identyfikatora historii. Wpisujemy identyfikator historii, a następnie naciskamy klawisz F9. Aby znaleźć identyfikator naciskamy klawisz F7
  • Tab — wyświetla kolejny parametr
  • Shift+Tab — wyświetla poprzedni parametr

Zmiana opcji uruchamiania PowerShell

Domyślnie aplikacja PowerShell otwiera się z uprawnieniami użytkownika. Możemy zmienić domyślne ustawienia i otwierać PowerShell zawsze z uprawnieniami administratora.

Aby to zrobić:

  • wyszukaj w menu Start aplikację PowerShell
  • kliknij na niej prawym przyciskiem myszy i wybierz opcję Open file location (Otwórz lokalizację pliku)
  • kliknij prawym przyciskiem aplikację PowerShell
  • wybierz opcję Properties (Właściwości)
  • w zakładce Shortcut (Skrót) wybierz opcję Advanced (Zaawansowane)
  • zaznacz opcję Run as administrator (Uruchamiaj jako administrator) i kliknij OK.

Po zrobieniu tej zmiany konsola PowerShell będzie się zawsze otwierać z uprawnieniami administratora.

Po otwarciu konsoli z uprawnieniami administratora, nazwa konsoli powinna się wyświetlać Administrator: Windows PowerShell.

Zmiana wyglądu okna konsoli

Wygląd okna konsoli możemy zmodyfikować. Aby to zrobić, klikamy na pasku górnym okna konsoli prawym przyciskiem myszy i wybieramy opcję Properties (Właściwości)

Zakładki okna Properties (Właściwości)

  • Options (Opcje) - zmieniamy na niej np. wielkość kursora
  • Font (Czcionka) - zmieniamy na niej wielkość i rodzaj czcionki
  • Layout (Układ) - zmieniamy na niej rozmiar okna konsoli PowerShell
  • Color (Kolory) - zmieniamy na niej kolory dla:
    • Screen Text - tekst ekranu
    • Screen Background - tło ekranu
    • Popup Text - tekst podręczny
    • Popup Background - tło tekstu podręcznego

PowerShell ISE

PowerShell to przede wszystkim konsola do wykonywania pojedynczych poleceń lub potoku poleceń. Jeśli chcemy przygotować skrypt PowerShell musimy użyć edytora tekstowego np. Notepad, VisualStudio Code

Dostępne jest też narzędzie: Integrated Script Editor (ISE). Jest to zintegrowany edytor i konsola przygotowane specjalnie do tworzenia skryptów PowerShell.

Aby otworzyć ISE wpisz na pasku Start PowerShell i wybierz Windows PowerShell ISE:

W oknie, które się pojawi kliknij ikonę New.

Wówczas otworzy się dokument, w którym można pisać skrypty.

Okno ISE podzielone jest na trzy części:

  • Panel do tworzenia skryptów - zawiera on automatyczne podpowiedzi komend (IntelliSense)

    Podpowiedzi przygotowane są zarówno dla nazw komend jak i dla nazw opcji w komendach.

    W panelu możemy otworzyć jeden lub wiele skryptów. W przykładzie są dwa skrypty.

  • Panel do wyświetlania wyników komend – w części tej mogą też być wpisywane komendy

  • Panel zawierający komendy – możemy w nim wyszukać komendy i je uruchomić

W ISE:

  • nie działa polecenie śledzenia sesji
  • możemy połączyć się z innym komputerem w sieci
  • możemy uruchomić cały skrypt za pomocą klawisza funkcyjnego F5 lub zaznaczyć część skryptu i uruchomić tylko zaznaczoną część za pomocą klawisza funkcyjnego F8
  • uruchomić tylko jedną linijkę skryptu - zaznaczamy ją lub ustawiamy w niej kursor i naciskamy przycisk F8
  • skrót Ctrl+J przywołuje wizard z snippetami kodu

Instalacja Visual Studio Code

  • Instalacja pakietu VSCode z wykorzystaniem winget

    winget install -e --id Microsoft.VisualStudioCode
  • Instalacja rozszerzenia PowerShell

Dostosowanie ustawień do pracy z PowerShell:

  • poprzez skrót Ctrl + , uruchom opcje edycji ustawień
  • wprowadź podstawowe opcje konfiguracyjne (File | Preferences | Settings | Open Settings (JSON) )
{ "editor.quickSuggestionsDelay": 1, "editor.tabCompletion": "on", "files.defaultLanguage": "powershell", "powershell.powerShellAdditionalExePaths": { "PS7": "C:\\Program Files\\PowerShell\\7\\pwsh.exe", "PS5.1": "C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" }, "powershell.powerShellDefaultVersion": "PS7", "powershell.codeFormatting.preset":"Stroustrup", "powershell.startAutomatically": true, "powershell.scriptAnalysis.enable": true, "powershell.integratedConsole.showOnStartup": false, "powershell.integratedConsole.focusConsoleOnExecute": true }
  • Zmiana motywu

Przydatne linki:

Instalacja Windows Terminal

Aplikacja Windows Terminal to nowa konsola w Windows, która ma zastąpić dotychczasową konsolę cmd.

Aby uruchomić naciśnij Start w wpisz wt.

  • Instalacja Windows Terminal poprzez manager pakietów

    winget install Microsoft.WindowsTerminal
  • Dostosowanie ustawień programu

Zadania: Konsola PowerShell, ISE

Aliasy poleceń (komend)

Za pomocą komendy Get-ChildItem możemy wyświetlić zawartość katalogu. To samo możemy zrobić komendami ls lub dir.

W PowerShell komendy ls i dir są to aliasy dla komendy Get-ChildItem.

Polecenie Get-Alias (alias gal) wyświetla listę wszystkich aliasów.

Z listy aliasów możemy wybrać tylko te, które nas interesują. Aby to zrobić do polecenia Get-Alias dopisujemy nazwę aliasu, który chcemy wyszukać np. polecenie Get-Alias dir zwraca poniższą listę:

Wyświetla wszystkie aliasy zaczynające się na literę s:

gal s* CommandType Name Version Source ----------- ---- ------- ------ Alias sajb -> Start-Job Alias sal -> Set-Alias Alias saps -> Start-Process

Odczyt polecenia przypisanego do aliasu Get-ChildItem:

Get-Alias -Definition Get-ChildItem CommandType Name Version Source ----------- ---- ------- ------ Alias dir -> Get-ChildItem Alias gci -> Get-ChildItem Alias ls -> Get-ChildItem

Odczyt polecenia przypisanego do aliasów o nazwie zaczynającej się ciągiem Get-C:

Get-Alias -Definition Get-C* CommandType Name Version Source ----------- ---- ------- ------ Alias cat -> Get-Content Alias dir -> Get-ChildItem Alias gc -> Get-Content

Tworzenie aliasów

Możemy tworzyć własne aliasy za pomocą polecenia Set-Alias np. dla komendy Get-ChildItem utworzymy alias o nazwie ShowItems:

Tworząc alias podajemy nazwę aliasu i nazwę komendy, dla której został on utworzony.

Zdefiniowane tak aliasy zostają usuwane po zamknięciu bieżącej sesji PowerShell.

Alias usuwamy za pomocą polecenia Del alias np. aby usunąć alias "ShowContent" napiszemy

Del alias:ShowContent

Za pomocą komendy Get-Alias -Definition Get-ChildItem wyszukamy aliasy dla polecenia Get-ChildItem

Za pomocą polecenia Sort-Object (alias sort) możemy sortować wyniki np.

Get-Alias | Sort-Object gal | sort

Aliasy są przydatne do szybkiego pisania poleceń. We wdrażanych skryptach produkcyjnych zaleca się stosowanie pełnych nazw poleceń.

Zadania: Aliasy poleceń

System pomocy

Get-Help – wyświetlenie pomocy. PowerShell domyślnie nie instaluje plików pomocy.

Instalacja pomocy

Pliki pomocy możemy zainstalować za pomocą komendy Update-Help. Po wpisaniu komendy Update-Help i zatwierdzeniu klawiszem Enter PowerShell wyświetli komunikat z pytaniem, czy zainstalować pomoc. Wystarczy wpisać Y i ponownie zaakceptować klawiszem Enter aby pomoc została zainstalowana.

Wywołanie polecenia Update-Help nie uaktualni wszystkich modułów dostępnych w systemie, gdyż niektóre moduły mogą nie obsługiwać aktualizacji pomocy.

Aby objąć aktualizacją wszystkie elementy, które obsługują pomoc możemy użyć parametru -Module oraz przełącznika -Force, na przykład:

Update-Help -Module * -Force

Polecenie to zaktualizuje pomoc i wyświetli informację, dla jakich modułów nie udało się zaktualizować pomocy.

Za pomocą polecenia Save-Help możemy zapisać pliki pomocy na dysku np. poleceniem Save-Help -DestinationPath C:\Home\PowerShell zapiszemy je na dysku C:\.

Za pomocą poniższego polecenia możemy zaktualizować pomoc korzystając z plików zapisanych na dysku (np. na komputerze bez połączenia z Internetem):

Update-Help -Force -SourcePath C:\Home\PowerShell

Save-Help i Update-Help ściągają pomoc tylko dla modułów zainstalowanych na lokalnym komputerze.

Przeszukiwanie pomocy

Lista wszystkich poleceń:

Get-Command
CommandType Name Version Source ----------- ---- ------- ------ Alias Add-AppPackage 2.0.1.0 Appx Alias Add-AppPackageVolume 2.0.1.0 Appx Alias Add-AppProvisionedPackage 3.0 Dism Alias Add-ProvisionedAppPackage 3.0 Dism Alias Add-ProvisionedAppxPackage 3.0 Dism Alias Add-ProvisioningPackage 3.0 Provisi...

Liczba dostępnych poleceń:

Get-Command | Measure-Object | select -Property Count
Count ----- 4127

Szukając polecenia po nazwie możemy używać znaku *, który zastępuje dowolny ciąg znaków nazwy.

Wyświetlenie tematów dla istniejących poleceń o nazwie na literę g i mających service w nazwie:

Get-Help g*service*
Name Category Module Synopsis ---- -------- ------ -------- Get-Service Cmdlet Microsoft.PowerShell.M... Gets the servic... Get-WUServiceManager Cmdlet PSWindowsUpdate Get-WUServiceMa... Get-VcsServiceRole Cmdlet VMware.CloudServices Get-VcsServiceR... Get-VcsService Cmdlet VMware.CloudServices Get-VcsService... Get-VIApplianceService Function VMware.PowerCLI.VCenter ... Get-CisService Cmdlet VMware.VimAutomation.C... Get-CisService... Get-VMHostService Cmdlet VMware.VimAutomation.Core Get-VMHostServi...

Listę dostępnych poleceń cmdlet można wyświetlić przez Get-Command np.:

Get-Command *-ds*
Function Stop-DscConfiguration 1.1 PSDesir... Function Update-DscConfiguration 1.1 PSDesir... Cmdlet Invoke-DscResource 1.1 PSDesir... Cmdlet Publish-DscConfiguration 1.1 PSDesir...

Wyświetlanie pomocy

Aby uzyskać pomoc dla np. polecenia Get-Printer wpisujemy Get-Help Get-Printer i naciskamy Enter.

Get-Help Get-Printer
NAME Get-Printer SYNOPSIS Retrieves a list of printers installed on a computer. SYNTAX Get-Printer [[-Name] <String[]>] [-AsJob] [-CimSession <CimSession[]>] [-ComputerNam e <String>] [-Full] [-ThrottleLimit <Int32>] [<CommonParameters>] DESCRIPTION The Get-Printer cmdlet retrieves a list of printers installed on a computer. You can also use Get-Printer to retrieve the properties of a single printer, and then use t hat information as input into other cmdlets.

Jeśli w pomocy chcesz wyświetlić tylko przykłady, użyj opcji -Examples np. Get-Help Get-Printer -Examples wyświetli przykłady z pomocy dla instrukcji Get-Printer.

Get-Help Get-Printer -Examples
NAME Get-Printer SYNOPSIS Retrieves a list of printers installed on a computer. -------------- Example 1: Get a list of printers -------------- Get-Printer This command retrieves a list of printers and printer connections on the local compu ter. ---- Example 2: Get the information for a specific printer ---- Get-Printer -Name "Microsoft XPS Document Writer"

Aby wyświetlić pełną dokumentację polecenia możemy użyć instrukcji:

help Get-Service -Full

Aby wyświetlić aktualną i pełną dokumentację w przeglądarce, polecenia możemy użyć instrukcji:

help Get-Service -Online

Aby wyświetlić pełną dokumentację w oddzielnym oknie możemy użyć instrukcji

help Get-Service -ShowWindow

Pole Find można użyc do szybkiego przeskoczenia do szukanego miejsca.

W sekcji Syntax są podane sposoby wywołania polecenia np.

SYNTAX Get-Process [[-Name] <System.String[]>] [-ComputerName <System.String[]>] [-FileVers ionInfo] [-Module] [<CommonParameters>] Get-Process [-ComputerName <System.String[]>] [-FileVersionInfo] -Id <System.Int32[] > [-Module] [<CommonParameters>] Get-Process [-ComputerName <System.String[]>] [-FileVersionInfo] -InputObject <Syste m.Diagnostics.Process[]> [-Module] [<CommonParameters>] Get-Process -Id <System.Int32[]> -IncludeUserName [<CommonParameters>] Get-Process [[-Name] <System.String[]>] -IncludeUserName [<CommonParameters>] Get-Process -IncludeUserName -InputObject <System.Diagnostics.Process[]> [<CommonPar ameters>]
  • kwadratowe nawiasy oznaczają opcjonalny parametr np. [-ComputerName <System.String[]>]
  • typ parametru np.
    • <System.String> - oznacza pojedynczą wartość string (tekst)
    • <System.String[]> - oznacza listę wartości string (tekstów)
    • <System.Int32[]> - oznacza listę liczb całkowitych int32
  • <CommonParameters> - oznacza możliwość użycia tzw. wspólnych parametrów np. -ErrorAction, -Verbose, -WhatIf

Przykładowe użycie, parametr -Name przyjmuje listę nazw procesów:

Get-Process -Name teams, wininit, winlogon

Nazwa samego parametru -Name jest opcjonalna:

Get-Process teams, wininit, winlogon
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName ------- ------ ----- ----- ------ -- -- ----------- 365 22 263960 202964 293,11 12056 1 Teams 1532 59 100440 71204 173,80 14172 1 Teams 295 17 23736 5656 0,50 15140 1 Teams 601 31 106084 43168 72,31 15252 1 Teams 523 23 285372 224760 265,95 16220 1 Teams 268 15 22260 61580 0,08 18104 1 Teams 1273 50 100460 34152 20,30 18556 1 Teams 300 18 16028 19536 19,33 19096 1 Teams 288 17 12064 8044 0,97 20184 1 Teams 170 11 1552 3684 0,08 700 0 wininit 311 14 3256 6004 0,73 944 1 winlogon

Przykładowe użycie, parametr -Id przyjmuje listę numerów procesów:

Get-Process -Id 944, 20184
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName ------- ------ ----- ----- ------ -- -- ----------- 288 17 12064 8044 0,98 20184 1 Teams 311 14 3332 6020 0,73 944 1 winlogon

Przykłady użycia Get-Help:

Get-Help Format-Table -example #Dane o parametrze GroupBy Get-Help Format-Table -Parameter GroupBy #Pomoc w wersji online Get-Help Format-Table -Online #wyświetl wszystkie pliki pomocy Get-Help about_* #pomoc na temat składni poleceń Get-Help about_Command_Syntax #Wyszukaj w pliku pomocy czy wystepuje słowo clixml Get-Help Add-Member -Full | Out-String -Stream | Select-String -Pattern Clixml
help about_aliases # aliasy help about_Common_Parameters # Parametry wspólne

Zadania: System pomocy

Zmienne

Zmienna to nazwane miejsce w komputerze, w którym przechowywana może być wartość. Dzięki zmiennym możemy przechowywać informacje i nimi manipulować.

W PowerShell możemy używać zmiennych w celu przechowywania wartości dowolnego typu np. tekstu, liczb, obiektów i innych.

Nazwy zmiennych w PowerShell poprzedzamy znakiem dolara $.

Przy tworzeniu zmiennej nie trzeba podawać typu danych, które będą w niej przechowywane. Podajemy jedynie nazwę zmiennej i przypisujemy jej wartość. Każda wartość jest konkretnego typu, zmienna przyjmuje taki typ, jakiego jest przechowywana w niej wartość.

$x = 1

Znak = to operator przypisania. W przykładzie przenosi on wartość 1 umieszczoną po prawej stronie w miejsce podane po lewej stronie do zmiennej x.

Zmienna może być użyta wewnątrz wyrażenia w miejsce wartości. Wówczas wartość wzięta ze zmiennej będzie użyta przy obliczaniu wartości wyrażenia.

$x = 1 $y = 2 $z = $x + $y $z

W przykładzie:

  • do zmiennej x przypisujemy wartość 1
  • do zmiennej y przypisujemy wartość 2
  • do zmiennej z przypisujemy wynik dodawania wartości ze zmiennej x i y.
  • wyświetlamy wartość znajdującą się w zmiennej z

Aby zmienić wartość w zmiennej, należy do zmiennej przypisać nową wartość

W przykładzie:

  • do zmiennej x przypisujemy wartość 1
  • wyświetlamy zmienną x
  • do zmiennej x przypisujemy wartość 2
  • wyświetlamy zmienną x

Po ponownym przypisaniu wartości do zmiennej x, pierwsza wartość została skasowana.

Istniejącą zmienną można skasować instrukcją Remove-Variable

PS C:\Windows\system32> $x = 1 PS C:\Windows\system32> $x 1 PS C:\Windows\system32> Remove-Variable -Name x

W przykładzie:

  • tworzymy zmienną x i przypisujemy do niej wartość 1
  • wyświetlamy zmienną x
  • usuwamy zmienną x

Możemy narzucić ograniczenie dla zmiennej, aby np. można było przypisać do niej jedynie wartości określonego typu.

[int]$x = 1

W przykładzie narzucamy ograniczenie dla zmiennej x, aby można było przypisać tylko liczby całkowite.

Jeśli spróbujemy przypisać do zmiennej x tekst, otrzymamy błąd:

Aliasy typów danych w PowerShell

Typ Opis
[int] [Int32] 32-bitowa liczba całkowita ze znakiem
[long] [Int64] 64-bitowa liczba całkowita ze znakiem
[char] [Char] Jeden znak Unicode (obsługa polskich liter)
[string] [String] Łańcuch znaków Unicode (obsługa polskich liter)
[bool] [Boolean] wartość logiczna $true/$false
[byte] [Byte] 8-bitowa liczba całkowita bez znaku (z zakresu 0..255)
[single] [Single] Zmiennoprzecinkowa liczba 32-bitowa
[double] [Double] Zmiennoprzecinkowa liczba 64-bitowa
[decimal] [Decimal] 128-bitowa wartość dziesiętna
[array] Obiekt Tablica (lista wartości)
[hashtable] Obiekt Tablica haszująca (słownik wartości)
[xml] Dokument XML

W PowerShell są też dostępne zmienne specjalne (automatyczne), które tworzone są automatycznie.

Lista zmiennych specjalnych:

Nazwa Zastosowanie
$^ zawiera pierwszy token z ostatniego wiersza wprowadzonego w powłoce
$$ zawiera ostatni token ostatniego wiersza wprowadzonego w powłoce
$_ lub $PSItem bieżący obiekt w potoku - zmienna używana w blokach skryptowych, filtrach, poleceniach Where-Object, ForEach-Object, Switch
$? zawiera status success/fail ostatnio wykonanego wyrażenia
$Args wykorzystywana w funkcjach lub skryptach wymagających parametrów, w których nie został utworzony blok param
$Error zapisuje obiekt błędu w zmiennej $error, jeśli wystąpi błąd
$ExecutionContext zawiera obiekty wykonawcze dostępne dla poleceń cmdlet
$foreach zmienna wyliczeniowa w pętli foreach
$HOME zawiera katalog domowy bieżącego użytkownika (zmienną środowiskową %HOMEDRIVE%\%HOMEPATH%)
$Input dane wejściowe przekierowane do funkcji lub do bloku kodu
$Match tabela skrótów zawierająca elementy znalezione przez operator -match
$MyInvocation zawiera informacje o aktualnie wykonywanym skrypcie lub poleceniu
$PSHome katalog, w którym zainstalowany jest PowerShell
$Host zawiera informacje o aktualnie wykonującym hoście
$LastExitCode zawiera kod wyjściowy ostatnio uruchomionej aplikacji natywnej
$True logiczna wartość TRUE (prawda)
$False logiczna wartość FALSE (fałsz)
$Null reprezentuje pusty obiekt (null)
$This w pliku Types.ps1xml i niektórych instancjach bloków skryptowych reprezentuje bieżący obiekt
$OFS wyjściowy separator pola używany przy konwertowaniu tablicy na łańcuch
$ShellID identyfikator powłoki - wartość ta jest używana przez powłokę do określenia zasady wykonywania i ładowania profili podczas uruchamiania
$StackTrace zawiera szczegółowe informacje stosu śledzenia na temat ostatniego błędu
$PSScriptRoot zawiera folder z którego uruchamiany jest skrypt

Zmienne obiektowe

Wynik komandleta można przypisać do zmiennej.

$proc = Get-Process $proc
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName ------- ------ ----- ----- ------ -- -- ----------- 206 17 2648 6816 7,83 7000 1 adb 136 10 1688 5608 638,39 7588 1 ApMsgFwd 109 8 1136 4808 0,48 7696 1 ApntEx 299 17 3484 13508 14,64 6572 1 Apoint 434 25 14664 29816 4,67 1948 1 ApplicationFrameHost 202 12 7548 12692 118,27 7224 0 audiodg 98 6 1348 4228 0,03 3388 1 bash

Można sprawdzić typ zmiennej:

$proc.GetType()
IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Object[] System.Array

Wartość ze zmiennej może być dalej przetwarzana w potoku:

$proc | Select-Object -First 4 -Property Handles, CPU, ProcessName
Handles CPU ProcessName ------- --- ----------- 206 7,9375 adb 136 645,09375 ApMsgFwd 109 0,484375 ApntEx 299 15,328125 Apoint

Zakres zmiennych

Zmienne znajdują się w określonym zakresie widoczności.

Zakresy zmiennych mają następujące cechy:

  • Zakresy podlegają zagnieżdżaniu. Zakres zewnętrzny to zakres-rodzic.
  • Zmienną widać w jej zakresie oraz zakresach zagnieżdżonych (zakres-dziecko)
  • Możliwe jest zadeklarowanie zmiennych w zakresie zewnętrznym
  • Zmienną można zmienić tylko w zakresie w którym została zadeklarowana (chyba że jawnie określimy inny zakres)

PowerShell obsługuje zakresy:

  • Globalny – ten zakres jest aktywny przy starcie PowerShell. Zmienne i funkcje dostępne po starcie PowerShell znajdują się w globalnym zakresie. Zakres globalny to rodzic dla innych zakresów.

  • Lokalny – bieżący zakres (może być ten sam co globalny zakres)

  • Skryptu – ten zakres jest tworzony przy uruchomieniu skryptu. Dla zmiennych tworzonych w skrypcie, jest to zakres lokalny

Zagnieżdżanie zakresów

Zmienne utworzone w zakresie-rodzicu, są dostępne w zakresie-dziecku (chyba że zmienna zostanie oznaczona jako prywatna).

Aby wyświetlić zmienne z lokalnego zakresu:

Get-Variable -Scope local

Aby wyświetlić zmienne z globalnego zakresu:

Get-Variable -Scope global

Modyfikatory zakresu

Tworząc zmienną lub funkcję możemy określić następujący zakres:

  • global: – globalny
  • local: – lokalny (aktualny i potomne)
  • private: – prywatny (tylko aktualny)
  • script: – zakres skrytpu
  • using: – uzyskuje dostęp do innego zakresu w czasie użycia cmdlet jak: Start-Job lub Invoke-Command.

Utworzenie zmiennej w zakresie lokalnym:

$a = "one"

Zmienna w zakresie globalnym:

$global:a = "one"

Zmienna w zakresie skryptu:

$script:a = "one"

Także funkcje mogą być w określonym zakresie:

function global:Hello { Write-Host "Hello, World" }

Zmienna w zagnieżdżonym zakresie zawsze zasłania zmienną o tej samej nazwie w zakresie wyższego poziomu. Przykład:

#Zmienna globalna $test = "Global" Function Testuje{ #Zmienna lokalna $test = "Local" Write-Host -ForegroundColor Green "Lokalna zmienna $test" Write-Host -ForegroundColor Yellow "Globalna zmienna $($global:test)" } #wywołanie funkcji Testuje

Wynik:

Lokalna zmienna Local Globalna zmienna Global

Referencje

Zadania: Zmienne

Typy danych

Zmienne powłoki PowerShell mogą przechowywać różne typy danych. Powłoka obsługuje wiele typów danych np. wartości logiczne, łańcuchy znaków i liczby całkowite.

Typy danych przechowywane w zmiennej możemy zmieniać. Powłoka PowerShell określa typy danych na podstawie ich wartości.

PS C:\Windows\system32> $a = 1 PS C:\Windows\system32> $a 1 PS C:\Windows\system32> $b = 'kot' PS C:\Windows\system32> $b kot PS C:\Windows\system32> $c = $true PS C:\Windows\system32> $c True PS C:\Windows\system32>

W przykładzie tworzymy zmienną a i przypisujemy do niej kolejno:

  • wartość 1 – zmienna przyjmuje typ danych liczba całkowita (Int32)
  • słowo "kot" – zmienna przyjmuje typ danych łańcuch znaków (String)
  • wartość logiczną "true" – zmienna przyjmuje typ danych logiczny (Boolean)

Po każdym nowym przypisaniu wartości do zmiennej, wyświetlamy zmienną.

Aby sprawdzić aktualny typ zmiennej użyj właściwości GetType():

$a = 1 $b = 'kot' $c = $true $c.GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Boolean System.ValueType

Wartości logiczne

Typ danych logiczny (ang. boolean) przyjmuje tylko dwie wartości:

  • fałsz – wartość 0 lub stała: $false
  • prawda – wartość 1 lub stała: $true
$a = $true [bool]$b = 0

Typy całkowite

Typy danych reprezentujących wartości całkowite (ang. integer) pozwalają na przechowywanie tylko liczb całkowitych i zaokrąglają wszystkie dane dziesiętne do najbliższej liczby całkowitej.

Typy danych całkowitych występują:

  • ze znakiem (ang. signed) — mogą przechowywać liczby całkowite np. UInt32, UInt64
  • bez znaku (ang. unsigned) — mogą przechowywać tylko dodatnie liczby całkowite i zero np. Int32, Int64
[UInt32]$a = 4 [Int64]$a = -477000000 $a.GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Int64 System.ValueType

Typy zmiennoprzecinkowe

Typy zmiennoprzecinkowe (ang. floating-point) to typ Double oraz Float.

Można ich używać do reprezentowania liczb całkowitych, ale najczęściej zmienne zmiennoprzecinkowe są używane do reprezentowania liczb dziesiętnych z częscią ułamkową.

Powłoka PowerShell domyślnie używa typu Double.

$pi = 3.14 $pi.GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Double System.ValueType

Łańcuchy znaków

Ciągi tekstowe (ang. string) pozwalają przechowywać w zmiennej napisy złożone z dowolnych znaków, także wielolinijkowe ciągi tekstu.

Napisy ograniczamy cudzysłowami " bądź apostrofami '. Jeżeli początek napisu oznaczony został cudzysłowem, powinien on zostać zakończony cudzysłowem. Jeśli oznaczony został apostrofem powinien zostać zakończony apostrofem.

$hostname = 'Mambo' $server = "Dell" $server.GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True String System.Object

Zaawansowanie formatowanie poprzez operator -f

"{0:n3}" -f 123.45678 123.457 "{0:d3}" -f [int32]12 012 "{1,10} {0,10} {2,10:x}" -f "First", "Second", 255 # Second First ff "{0:yyyy}" -f (Get-Date) 2022

Formatowanie tekstów: https://ss64.com/ps/syntax-f-operator.html

Obiekty

W powłoce PowerShell wartości każda wartość jest obiektem to znaczny, że posiada jakieś właściwości i metody. Także typy proste (Int32, Boolean) są typami obiektowymi.

Obiekt to pojedyncza instancja określonego szablonu, nazywanego klasą.

Klasa określa rodzaje elementów, które będzie zawierał obiekt:

  • metody (funkcje) obiektu, czyli działania, które można na tym obiekcie wykonać np. obiekt lista może posiadać metodę sort(), która po wywołaniu posortuje zawartość listy
  • właściwości (zmienne) obiektu, czyli zestaw wszystkich informacji o obiekcie. Obiekt lista może mieć np. właściwość length (długość), która przechowuje liczbę elementów listy.
PS C:\Windows\system32> $color = "niebieski" PS C:\Windows\system32> Select-Object -InputObject $color -Property * Length ------ 9 PS C:\Windows\system32>

Zmienne są obiektami i posiadają swoje właściwości.

W przykładzie:

  • tworzymy zmienną $color i przypisujemy do niej wartość "niebieski"
  • za pomocą polecenia Select-Object (wybierz obiekt) i parametru Property (właściwość) wyświetlamy wszystkie właściwości obiektu zmienna $color. Zmienna $color ma tylko jedną właściwość o nazwie Length (długość).

Za pomocą polecenia Get-Member możemy wyświetlić wszystkie metody i właściwości danego obiektu.

PS C:\Windows\system32> Get-Member -InputObject $color TypeName: System.String Name MemberType Definition ---- ---------- ---------- Clone Method System.Object Clone(), System.Object ICloneabl... CompareTo Method int CompareTo(System.Object value), int Compar... Contains Method bool Contains(string value) CopyTo Method void CopyTo(int sourceIndex, char[] destinatio...

Przykład zawiera tylko kilka wierszy zwróconych przez polecenie. Pozostałe wiersze zostały pominięte.

Przykłady:

$color = "niebieski" $color.ToUpper() $color.StartsWith('nie') $color.length

Tablica Array

Tablica to lista elementów reprezentowana przez pojedynczą zmienną np. lista miesięcy.

Opis w pomocy:

help about_arrays

Definiowanie tablicy

W pierwszym kroku definiujemy zmienną o nazwie $dni i przypisujemy jej tablicę zawierającą nazwy dni tygodnia.

PS C:\Windows\system32> $dni = @('poniedziałek', 'wtorek', 'środa', 'czwartek', 'piątek') PS C:\Windows\system32> $dni poniedziałek wtorek środa czwartek piątek

Znak @, po którym następuje nawias otwierający i zero lub więcej elementów oddzielonych od siebie przecinkami, sygnalizuje powłoce PowerShell, że chcemy utworzyć tablicę.

Odczytywanie elementów tablicy

Aby uzyskać dostęp do wybranego elementu w tablicy, podajemy nazwę tablicy, po której następuje para nawiasów kwadratowych [ ] zawierających indeks elementu, do którego chcesz uzyskać dostęp.

Numerowanie indeksów tablic rozpoczynamy od 0, więc pierwszy element ma indeks 0, drugi element indeks 1 itd. Użycie wartości -1 jako indeksu zwróci ostatni element tablicy.

PS C:\Windows\system32> $dni[0] poniedziałek PS C:\Windows\system32> $dni[1] wtorek PS C:\Windows\system32> $dni[-1] piątek

Aby uzyskać dostęp do wielu elementów w tablicy w tym samym czasie, możemy użyć operatora zakresu .. umieszczonego między dwiema liczbami.

PS C:\Windows\system32> $dni[1..3] wtorek środa czwartek

Można w ten sposób utworzyć tablicę liczb całkowitych:

PS C:\Windows\system32> $numbers = 2..7 PS C:\Windows\system32> $numbers 2 3 4 5 6 7

Modyfikowanie elementów tablicy

Aby zmienić wybrany element tablicy możemy odwołać się do niego za pomocą indeksu i przypisać mu nową wartość.

PS C:\Windows\system32> $dni[4] = 'pt' PS C:\Windows\system32> $dni poniedziałek wtorek środa czwartek pt PS C:\Windows\system32>

Dodawanie elementów do tablicy

Tablica ma stały rozmiar i nie można do niej dodać elementu. Można jednak utworzyć nową tablicę z dotychczasowymi elementami i nowo dodawanym. Nową tablicę tworzymy za pomocą operatora dodawania + i możemy od razu umieścić w tej samej zmiennej.

$dni = $dni + 'sobota' $dni poniedziałek wtorek środa czwartek pt sobota

Drugi sposób z użyciem operatora +=:

$dni += 'sobota' $dni poniedziałek wtorek środa czwartek pt sobota

Do tablicy możemy dodać inną tablicę:

$dni += @('sobota','niedziela') $dni poniedziałek wtorek środa czwartek pt sobota niedziela

Tablice w powłoce PowerShell mają stały rozmiar. Gdy dodajemy element do tablicy, w rzeczywistości tworzymy nową tablicę, składającą się ze starej (interpolowanej) tablicy i nowego elementu. To samo dzieje się, gdy usuwamy dany element z tablicy: powłoka PowerShell niszczy starą tablicę i w jej miejsce tworzy nową.

Kolekcja ArrayList

Kolekcja ArrayList zachowuje się podobnie jak tablica, ale nie mają stałego rozmiaru i mogą być dynamicznie powiększane i pomniejszane.

Definiowanie kolekcji ArrayList odbywa się tak samo jak definiowanie tablic. Jedyną różnicą jest to, że nowa tablica musi być jawnie rzutowana jako typ ArrayList.

$dni = [System.Collections.ArrayList] @('pn', 'wt', 'śr') $dni pn wt śr

Dodawanie i usuwanie elementów w ArrayList

Aby dodawać elementy lub usuwać je z kolekcji ArrayList bez jej niszczenia, używamy jej metod Add() i Remove()

$dni.Add('sobota') 3 $dni pn wt śr sobota

Wyświetlony wynik działania metody to liczba 3, która reprezentuje wartość indeksu nowego elementu kolekcji.

Usuwamy element z ArrayList

$dni.Remove('sobota') $dni pn wt śr

Jeżeli tablica zawiera wiele elementów o tej samej wartości, usunięty zostanie element znajdujący się najbliżej początku kolekcji ArrayList.

Kolekcja Hashtable

Opis w pomocy:

help about_Hash_Tables

Tablica asocjacyjna inaczej nazywana też jako tablica haszująca lub tablica skrótów (ang. hashtable) albo słownik (ang. dictionary)

Tablica haszująca jest strukturą danych podobną do tablicy, ale pracuje się na niej w oparciu o hasła (zwane też kluczami), a nie o indeksy.

W słowniku przechowujemy pary @{ klucz = wartość }.

Klucz (key) nie może się powtórzyć w słowniku Wartość (value) w słowniku nie ma tego ograniczenia co do typu, dowolny typ może być wartością, także lista, inny słownik. Na przykład baza danych zawierająca numery telefoniczne znajomych może być utworzona w następujący sposób:

$kontakty = @{ "Jan" = "938477566" "Jacek" = "938377264" "Janusz" = "947662781" }

Wyświetlamy dane z tablicy haszującej:

$kontakty Name Value ---- ----- Janusz 947662781 Jan 938477566 Jacek 938377264

Odczytywanie elementów z tablic asocjacyjnych

Dostęp do określonego elementu w tablicy haszującej uzyskujemy za pomocą klucza.

$kontakty['Jacek'] 938377264

Dodawanie i modyfikowanie elementów tablicy asocjacyjnej

Aby dodać element do tablicy asocjacyjnej, możemy użyć metody Add() lub utworzyć nowy element, używając nawiasów kwadratowych i znaku równości.

$kontakty.Add("Piotr", "890897678") $kontakty["Zenon"] = "980888765"

Sprawdzenie, czy klucz istnieje w tablicy:

$kontakty.ContainsKey("Zenon")

Wynik:

$kontakty.ContainsKey("Zenon") True

Zmiana elementu w tablicy:

$kontakty["Zenon"] = "666777999"

Zadania: Typy danych

Operatory

Operatory porównania

Przykładowe operatory porównań w PowerShell (case insensitive)

Operator Opis Przykład
-eq = równe (equal) 2 -eq 2 - True, 2 -eq 3 - False
-ne <> nierówne (not equal) $a = 5 ; $a -ne 4
-gt > większe niż (greater than) 30 -gt 10 - True, 5 -gt 10 - False
-ge >= większe lub równe (greater than or equal) $a = 5 ; $a -ge 5
-lt < mniejsze niż (less than) $a = 5 ; $a -lt 5
-le <= mniejsze lub równe (less than or equal) $a = 5 ; $a -le 5
-like podobne do z użyciem symboli wieloznacznych $a = "This is Text" ; $a -like "Text"
-notlike niepodobne do z użyciem symboli wieloznacznych $a = "This is Text" ; $a -notlike "Text"
-match podobne do z użyciem wyrażeń regularnych $a = "This is Text" ; $a -match "Text"
-notmatch niepodobne do z użyciem wyrażeń regularnych $a = "This is Text" ; $a -not-match "Text$"

Dozwolone symbole wieloznaczności (-like i -notlike):

Symbol Opis
* zastępuje zero, jeden lub więcej znaków np. Get-Service -Name dh*
? zastępuje jeden znak np. Get-Process -Name vm??
[abc123] zastępuje jeden z podanych znaków
[a-d] zastępuje jeden z zakresu podanych znaków

Przykład:

Get-Process -Name vm?? Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName ------- ------ ----- ----- ------ -- -- ----------- 724 28 69196 24956 4080 0 vmms 791 74 16632 8708 41432 0 vmwp 776 22 16652 12108 51128 0 vmwp

Dozwolone znaki wyrażeń regularnych (-match i -notmatch):

Znak Opis
wartość dopasowuje znaki (wartość) w porównywanym wyrażeniu
. dopasowuje pojedynczy dowolny znak
[abc] dopasowuje jeden z podanych znaków
[a-d] dopasowuje jeden z zakresu podanych znaków
^ dopasowuje początek wyrażenia
$ dopasowuje koniec wyrażenia

Operatory porównań mają dwie wersje:

  • z rozróżnianiem wielkości liter (ang. case sensitive)
  • bez rozróżniania wielkości liter (ang. case insensitive).
Operator Opis Przykład
-ceq = równe (equal cs) 'ABC' -ceq 'abc' # False
-ieq = równe (equal ci) 'ABC' -ieq 'abc' # True
-cne <> nierówne (not equal cs) 'ABC' -cne 'abc' # True
-ine <> nierówne (not equal ci) 'ABC' -ine 'abc' # False
-cgt > większe niż (greater than cs)
-igt > większe niż (greater than ci)
-cge >= większe lub równe (greater than or equal cs)
-ige >= większe lub równe (greater than or equal ci)
-clt < mniejsze niż (less than cs)
-ilt < mniejsze niż (less than ci)
-cle <= mniejsze lub równe (less than or equal cs)
-ile <= mniejsze lub równe (less than or equal ci)
-clike podobne do z użyciem symboli wieloznacznych cs 'abc' -clike 'aB*' # False
-ilike podobne do z użyciem symboli wieloznacznych ci 'abc' -ilike 'aB*' # True
-cnotlike niepodobne do z użyciem symboli wieloznacznych cs
-inotlike niepodobne do z użyciem symboli wieloznacznych ci
-cmatch podobne do z użyciem wyrażeń regularnych cs
-imatch podobne do z użyciem wyrażeń regularnych ci
-cnotmatch niepodobne do z użyciem wyrażeń regularnych cs
-inotmatch niepodobne do z użyciem wyrażeń regularnych ci

Porównania zawartości tablic

-contains i -in – operatory sprawdzają kolekcję pod kątem szukanej wartości. Gdy znalezione zostanie dopasowanie zwracana jest wartość $true. Działają tak samo, różnią się tylko składnią.

$array = 1..6 if ( $array -contains 3 ) { Write-Output("found") }
$array = 1..6 if ( 3 -in $array ) { Write-Output("found") }

Operator -is

-is – operator, za pomocą którego możemy sprawdzić, czy wartość jest określonego typu np. czy jest tekstowa:

$value = "Kot Filemon" if ( $value -is [string] ) { Write-Output("tekstowa") }

Operatory logiczne

Operatory logiczne służą do odwracania lub łączenia innych wyrażeń.

-not – zmienia wyrażenie z $false na $true lub z $true na $false.

W przykładzie wykonujemy akcję, gdy Test-Path ma wartość $false.

if ( -not ( Test-Path -Path $path ) )

Zamiennie z -not możemy używać operatora !

if ( -not $value ){} if ( !$value ){}

-and – za pomocą operatora -and możemy łączyć wyrażenia.

Obie strony wyrażenia muszą być prawdziwe, aby całe wyrażenie było prawdziwe.

if ( $age -gt 13 -and $age -lt 55 )

W tym przykładzie $wiek musi wynosić najmniej 13 lat dla lewej strony i mniej niż 55 dla prawej strony żeby wyrażenie było prawdziwe.

-or – pozwala na określenie dwóch lub więcej wyrażeń i zwraca $prawda dla całego wyrażenia, jeśli chociaż jedno z wyrażeń wchodzących w jego skład jest prawdziwe.

if ( $age -le 13 -or $age -ge 55 )

W tym przykładzie $wiek musi wynosić najmniej 13 lat dla lewej strony lub mniej niż 55 dla prawej strony żeby wyrażenie było prawdziwe.

Operatory znakowe

Operatory znakowe umożliwiają:

  • wyszukaj wszystkie pliki i katalogi we wskazanym katalogu: Get-ChildItem C:\Windows\*
  • wyszukaj wszystkie pliki i katalogi o określonym rozszerzeniu: Get-ChildItem C:\Windows\*.log
  • wyszukiwanie z podanych znaków np. polecenie Get-ChildItem C:\Windows\[ac]* wyszuka wszystkie pliki zaczynające się na literę "a" lub zaczynające się na literę "c"
  • wyszukiwanie z zakresu znaków np. polecenie Get-ChildItem C:\Windows\[f-i]* wyszuka wszystkie pliki zaczynające na literę z zakresu od "f" do "i"

Przykłady:

Get-ChildItem C:\Windows\*.txt Get-ChildItem C:\Windows\System32\*.dll

Jednostki ilości danych

  • 1 bit x 8 – bajt (B)
  • 1 bajt x 1024 – kilobajt (kB)
  • 1 kB x 1024 – megabajt (MB)
  • 1 MB x 1024 – gigabajt (GB)
  • 1 GB x 1024 – terabajt (TB)

Przykład użycia - wyświetlenie plików o rozmiarze powyżej 30kB:

ls | where Length -gt 30kB
Directory: C:\Users\rav Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 2022-06-05 21:10 31315 DE.gif -a---- 2023-01-04 12:56 148739 infographic.pdf -a---- 2022-08-15 13:47 3065691 Laitila_Gamze.pdf -a---- 2023-02-04 10:24 55718 planeta-2.mp3

Zadania: Operatory

Polecenia cmdlet

Polecenia cmdlet są to pliki wykonywalne, które wykorzystują funkcjonalności wbudowane w środowisko PowerShell.

W PowerShell 5.0 mamy do dyspozycji ponad tysiąc poleceń i wraz z dodawaniem nowych funkcjonalności, dodawane są nowe polecenia. Polecenia możemy też tworzyć sami.

Jedno polecenie możemy wpisać w kilku wierszach. Aby zaznaczyć, że kolejny wiersz zawiera ciąg dalszy tego samego polecenia, używamy znaku lewego apostrofu ` (klawisz bezpośrednio pod Esc).

Write-Host -foregroundcolor green "Polecenie możemy umieścić" ` "w wielu wierszach"

Możemy też w jedej linii umieścić kilka poleceń:

cls ; get-process

Budowa poleceń

Polecenia zbudowane są według konwencji czasownik-rzeczownik (ang. verb-noun) np. Get-Help ("otrzymaj-pomoc").

  • Polecenia z czasownikiem Get (ang. weź, pobierz) używane są do wyświetlenia informacji o elemencie umieszczonym po prawej stronie łącznika np. Get-Help (pobierz pomoc)

  • Polecenia z czasownikiem Set (ang. ustal, określ) używane są do ustawienia lub zmiany cech elementu po prawej stronie łącznika np. Set-Service pozwala m.in. na zmianę trybu uruchomieniowego usługi

Nazwy parametrów nie muszą być wpisywane w całości. Wystarczy fragment nazwy parametru, za pomocą którego zidentyfikujemy ten parametr np. zamiast -Name możemy napisać -Na.

Niektóre polecenia umożliwiają jednoczesną pracę z kilkoma obiektami (usługami systemu Windows). Nazwy usług na liście rozdzielamy przecinkami.

W poniższym przykładzie wyświetlamy informacje o usługach: WebClient, Themes, TabletInputService

Get-Service WebClient, Themes, TabletInputService
Status Name DisplayName ------ ---- ----------- Running TabletInputService Touch Keyboard and Handwriting Pane... Running Themes Themes Stopped WebClient WebClient

Przykładowe polecenia PowerShell (cmdlet)

PowerShell nie rozróżnia wielkości liter. Polecenia get-Childitem, Get-childitem i Get-ChildItem zostaną zinterpretowane tak samo.

  • Set-Location (alias: cd) – zmiana bieżącego katalogu
    • np. poleceniem cd c:\ zmieniamy katalog bieżący na katalog główny na dysku C:\
    • Set-Location C:\Users wchodzimy do katalogu Users na dysku C:\
  • Get-ChildItem (alias: dir) – wyświetlenie listy plików w bieżącym katalogu. Aby wyświetlić pliki zaczynające się określoną literą lub zawierające w nazwie określoną literę używamy symbolu wieloznacznego gwiazdki (*) np. polecenie dir h* wyświetli pliki zaczynające się na literę "h".
  • md – tworzenie nowego podkatalogu w bieżącym katalogu

Na przykład:

  • Get-Process - wyświetlenie listy wszystkich działających procesów
  • Get-Service - wyświetlenie listy wszystkich usług Windows
  • Get-Date - sprawdzanie bieżącej daty lub czasu np.
    Get-Date -DisplayHint Time
  • Get-Printer - wyświetla listę zainstalowanych drukarek
  • Get-Content - wyświetla zawartość wskazanego pliku
  • Export-Csv - zapisz do pliku na dysku
    Get-Service | Export-Csv -Path c:/service.csv
  • Import-Csv - wczytaj plik csv z dysku
    Import-Csv C:\service.csv
  • Out-String - tworzy surowy tekst z danych wejściowych
    Get-Service | Out-String # generuje wartość String Get-Service | Out-String -Stream # generuje wartość Object[] Get-Service | Out-String -Stream | Select-String -Pattern stop
  • Out-File - tworzy i zapisuje surowy tekst do pliku na dysku (domyślne kodowanie UTF-16LE)
    Get-Service | Out-File c:\services.txt -Encoding utf8
  • Start-Transcript - uruchamia śledzenie sesji, wszystkie polecenia z bieżącej sesji zostaną zapisane w pliku na wskazanym miejscu na dysku.
  • Stop-Transcript - zakończa śledzenie sesji

Jeśli pojawia się błąd "access denied" brak dostępu, możemy zmienić politykę uruchamiania skryptów za pomocą polecenia Set-ExecutionPolicy Unrestricted. Po zaakceptowaniu polecenia Enter pojawi się ostrzeżenie, które musimy zaakceptować wpisując Y.

Aby wyświetlić zawartość kilku plików z dysku piszemy następujące polecenie:

Get-Content C:\Home\Pliki_PS\Error.txt, C:\Home\Pliki_PS\Path.txt

W poleceniu po przecinku wskazujemy ścieżkę dostępu do plików, które chcemy odczytać.

Pliki Error.txt i Path.txt na dysku

Pliki Error.txt i Path.txt odczytane w konsoli PowerShell

  • Clear-Host lub clear – czyści konsolę
  • Show-Command – otwiera okno, w którym po nazwie można znaleźć potrzebne polecenie
  • Get-Command – wyświetla szczegółowe informacje o każdym dostępnym poleceniu tj. o poleceniach cmdlet, funkcjach, przepływach, aliasach oraz plikach wykonywalnych. Za pomocą Get-Command możemy np.:
    • wyświetlić listę wszystkich poleceń cmdlet zainstalowanych w Windows PowerShell
    • wyszukiwać polecenia używając ich pełnych nazw lub gwiazdki (*) jako symbolu wieloznacznego
  • Get-Disk – wyświetla informację o dyskach w komputerze
  • $PSVersionTable – odwołanie się do zmiennej, za pomocą której możemy sprawdzić wersję PowerShell.

Jeśli chcesz uruchomić PowerShell w innej wersji, należy w poleceniu podać dodatkowo nr wersji np.

powershell -version 2.0

Uruchomienie PowerShell w starszej wersji może wymagać doinstalowania oprogramowania. Przykład poniżej:

Dla wersji 2.0 nie mamy zainstalowanego Frameworka .NET.

  • Get-PSDrive – wyświetlanie listy dysków. Wyświetlane są zarówno dyski znajdujące się na komputerze jak i dyski sieciowe
  • Get-ChildItem – wyświetlenie zawartości katalogu
  • Get-Command – wyświetla listę poleceń wbudowanych w PowerShell
  • Get-Process – zwraca informację o nazwie procesu, ilość zużytej pamięci, ilości zużytego czasu procesora itp.
  • Get-EventLog – wyświetla zdarzenia z dziennika systemu Windows. Za pomocą parametru -LogName wskazujemy, który z dzienników chcemy wyświetlić. Jeśli pracujemy w konsoli PowerShell ISE możemy wyświetlić podpowiedzi nazw dzienników:
  • ForEach-Object – polecenie, za pomocą którego możemy iterować po zbiorze obiektów i wykonywać na nich operacje
  • Get-Counter – pobiera dane licznika wydajności z komputerów lokalnych i zdalnych
  • Get-History – wyświetla historię poleceń
  • Get-WinEvent – pobiera zdarzenia z dzienników zdarzeń i plików dziennika śledzenia zdarzeń na komputerach lokalnych i zdalnych
  • Out-File – wysyła dane wyjściowe polecenia do pliku tekstowego (kodowanie UTF-16LE)
  • Exit – wyjście z konsoli (zamknięcie konsoli)

Znak --% w PowerShell

Jak w konsoli używać znaku wyjścia, aby nie interpretować znaków specjalnych, tj chcemy aby polecenie interpretowane było jakbyśmy wpisywali je w cmd.exe.

#Przeszukaj wszystkie pliki pomocy, i znajdź gdzie jest użyta sekwencja --% Get-Help about_* | ForEach-Object {Get-Help $_.Name -Full | Out-String -Stream | Select-String -SimpleMatch "--%"} #Błędnie wykonane polecenia, PowerShell interpretuje znaki () icacls C:\Home\Powershell\icacls /grant PC\USER:(CI)(OI)F #Znak --% powoduje ze PowerShell wykona polecenie jakby było wpisane w cmd.exe icacls --% C:\Home\Powershell\icacls\ /grant PC\USER:(CI)(OI)F

Zadania: Polecenia

Parametry poleceń

Do poleceń możemy przekazywać parametry np. polecenie Get-Service zwraca obiekty, które reprezentują usługi na komputerze. Jeśli polecenie Get-Service uruchomimy bez podania parametrów, zwrócone zostaną wszystkie usługi znajdujące się na lokalnym komputerze.

Komendę Get-Service można uruchomić z trzema różnymi zestawami parametrów:

Zestawy parametrów różnią się między sobą ilością oraz kolejnością parametrów.

Polecenie przyjmuje jako parametr nazwę lub ciąg nazw określających nazwę usług, których stan chcemy wyświetlić rozdzielonych przecinkami. Nazwy usług mogą być poprzedzone parametrem -Name. Parametr -Name jest opcjonalny. Każdy opcjonalny parametr znajduje się w nawiasie kwadratowym.

Parametr -ComputerName umożliwia nam wyświetlenie usług na innym komputerze. Po parametrze -ComputerName podajemy nazwę sieciową komputera, na którym chcemy wyświetlić usługi.

Parametry możemy przekazywać przez:

  • pozycję – przekazując parametry jako pierwszy, drugi, trzeci itd. oddzielone przecinkami np.
    Get-Service spooler
    Tutaj usłudze Get-Service przekazujemy parametr spooler jako pierwszy parametr.
  • nazwę – przekazując parametr poprzedzony jego nazwą np.
    Get-Service -Name spooler
    Tutaj usłudze Get-Service przekazujemy parametr spooler jako parametr on nazwie Name.

Bufor wydruku (ang. Print Spooler) to oprogramowanie, które jest wbudowane w system operacyjny Windows. Przechowuje ono tymczasowo zadania drukowania w pamięci komputera dopóki drukarka nie będzie gotowa do ich wydrukowania.

spooler w PowerShell wyświetla informacje o stanie usługi drukowania.

Rodzaje parametrów

Rodzaje parametrów polecenia cmdlet mogą być:

  • nazwanymi – wymagają wpisania nazwy parametru i argumentu podczas wywoływania polecenia cmdlet
  • pozycyjnymi – wymagają tylko wpisania argumentów we względnej kolejności. System następnie mapuje pierwszy nienazwany argument na pierwszy parametr pozycyjny, drugi argument na drugi parametr pozycyjny itd.
  • wymaganymi – muszą być koniecznie podane
  • opcjonalnymi – mogą być pominięte
  • przełącznikami – wartość włącz/wyłącz

Każde polecenie ma wbudowaną informację o tym, jak bardzo zmienia ustawienia systemu Windows. Jeśli polecenie nie wpływa na funkcjonowanie systemu, zostanie wykonane bez wyświetlania użytkownikowi dodatkowych pytań z żądaniem potwierdzenia wykonania.

Przełączniki

Większość poleceń obsługuje parametry przełącznika, za pomocą których możemy sterować wykonywaniem polecenia. Przykładowe parametry to:

  • -WhatIf
  • -Confirm
  • -Verbose
  • -Debug
  • -ErrorAction

Parametr -WhatIf

Parametr powoduje, że polecenie nie jest wykonywane, wyświetlana jest informacja, co by się stało, gdyby polecenie zostało wykonane.

Zadanie: Otwieramy aplikację Notatnik (ang. Notepad).

Wykonamy po kolei poniższe polecenia:

  • wyszukujemy ID procesu aplikacji Notatnik:

    Get-Process not*
    Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName ------- ------ ----- ----- ------ -- -- ----------- 255 13 3016 14496 0,20 2200 1 notepad
  • uruchamiamy polecenie zatrzymania procesu z parametrem -WhatIf:

    Stop-Process -Id 2200 -WhatIf

Parametr -Confirm

Parametr wyświetla żądanie potwierdzenia wykonania polecenia.

Uruchamiamy polecenie zatrzymania procesu z parametrem -Confirm:

Stop-Process -Id 2200 -Confirm

W odpowiedzi na pytanie, czy wykonać polecenie wpisujemy literę N żeby nie zatrzymywać procesu.

Parametr -Verbose

Polecenie zostanie wykonane i wyświetlony zostanie opis wykonanego polecenia.

Uruchamiamy polecenie zatrzymania procesu z parametrem -Verbose:

Stop-Process -Id 2200 -Verbose

Proces został zatrzymany

Parametr -Debug

Wyświetla informacje dotyczące debugowania. Przed wykonaniem polecenia potwierdzamy, czy chcemy je wykonać.

Ponownie otwieramy notatnik i wyszukujemy Id jego procesu:

Get-Process not*

Uruchamiamy polecenie zatrzymania procesu z parametrem -Debug:

Stop-Process -Id 560 -Debug

W odpowiedzi na pytanie wpisujemy literę N żeby nie zatrzymywać procesu

Parametr -ErrorAction

Określa, jakie działanie ma zostać wykonane, gdy pojawi się błąd. Dostępne są opcje:

  • Continue (kontynuuj) – wyświetla komunikat o błędzie i kontynuuje wykonywanie polecenia
  • Ignore (ignoruj) – pomija komunikat o błędzie i kontynuuje wykonywanie polecenia
  • Inquire (pytaj) – wyświetla komunikat o błędzie i monituje o potwierdzenie przed kontynuowaniem wykonywania
  • SilentlyContinue (kontynuuj bez powiadamiania) – pomija komunikat o błędzie i kontynuuje wykonywanie polecenia
  • Stop (zatrzymaj) – wyświetla komunikat o błędzie i zatrzymuje wykonywanie polecenia

Poniżej w przykładzie chcemy zamknąć proces o ID 100560, który nie istnieje.

Stop-Process -Id 560 -ErrorAction Ignore

Parametr -Recurse

Rekurencja to termin używany do opisania procedury, którą można powtórzyć np. możemy wyświetlić listę plików z katalogu i zawartych w nim podkatalogów.

Parametry -Include i -Exclude

  • Parametr -Include umożliwia wyświetlenie tylko wybranych elementów - tych, które zostały w nim wskazane.
  • Parametr -Exclude umożliwia wyświetlenie wszystkich elementów, z wyjątkiem tych, które zostały w nim wskazane.

Zadania: Parametry poleceń

Obiekty

W Powershell wartości zwracane z komandletów to obiekty, a nie tekst. Jeśli jest zwracany tekst to ma on postać obiektu String.

Obiekty można przekonwertować na tekst poleceniem Out-String:

$x = Get-Process | Out-String -Stream

Tekst możemy przeszukiwać poleceniem grep:

$x = $x | Select-String -SimpleMatch "conhost" $x

Wycięcie znaków od 3 do 7:

$x | ForEach-Object {($_.tostring()).substring(3,4)}

Cały ciąg poleceń w jednym bloku:

Get-Process | Out-String -Stream | Select-String -SimpleMatch "conhost" | ForEach-Object {($_.tostring()).substring(3,4)}

Ta sama operacja jeśli działamy na dostępnych obiektach:

Get-Process | Where-Object ProcessName -eq conhost | Select-Object -ExpandProperty Handles

Opis działania:

  • Get-Process zwraca listę obiektów typu: System.Diagnostics.Process
  • Where-Object filtruje listę, zostawia tylko obiekty o właściwości ProcessName="conhost"
  • Select-Object wybiera tylko właściwość Handles, w wyniku dostajemy listę wartości typu System.Int32

Inspekcję typu zwracanej wartości można wyświetlić przez Get-Member:

Get-Process | Get-Member
TypeName: System.Diagnostics.Process Name MemberType Definition ---- ---------- ---------- Handles AliasProperty Handles = Handlecount Name AliasProperty Name = ProcessName

Praca z obiektami

# zapisanie obiektu do zmiennej $usluga = Get-Service XblGameSave # jakie obiekt ma metody Get-Member -InputObject $usluga -MemberType Method # jakie obiekt ma właściwości Get-Member -InputObject $usluga -MemberType Properties $usluga.Start() #Start usługi przez metode $usluga.Stop() #Zatrzymanie usługi poprzez metode

Jak w stringu wyświetlić poprawnie zmienne obiektu.

$xx = Get-Service | Select-Object -First 1 #Niepoprawne osadzenie zmiennej w obiekcie stringa "usługa o nazwie $xx.Name"

Wynik (niepoprawny):

usługa o nazwie System.ServiceProcess.ServiceController.Name
#Poprawne osadzenie poprzez łączenie stringów i obiektu znakiem + "usługa o nazwie " + $xx.Name #Poprawne osadzenie poprzez konstrukcje $() "usługa o nazwie $($xx.Name)"

Wynik (poprawny):

usługa o nazwie AarSvc_95323

Łączenie poleceń - potoki

Dokumentacja dotycząca potoków:

help about_pipelines

Aby pobrać informacje z jednego polecenia cmdlet i przekazać je do innego, używamy potoku (ang. pipe) reprezentowanego znakiem |.

Pojedyncze polecenie np. Get-Service może przekazać wynik do kolejnego polecenia do np. Out-File.

Out-File - polecenie, które otrzymany wynik zapisze w pliku tekstowym.

Get-Service | Out-File C:\Home\PowerShell\uslugi2.txt -Encoding utf8
Get-Content C:\Home\PowerShell\uslugi2.txt

Out-GridView - polecenie, które wyświetli wynik w oddzielnym oknie.

Get-Service | Out-GridView

W oknie tym możemy filtrować polecenia.

W PowerShell widoczny na ekranie tekst to tekstowa reprezentacja obiektów, na których pracują wszystkie polecenia.

Polecenie Get-Member umożliwia znalezienie, jakie obiekty, właściwości i metody są dostępne dla poleceń.

Wynik dowolnego polecenia cmdlet możemy przekierować do polecenia Get-Member, aby zbadać właściwości i metody zwracanego obiektu.

Komenda poprzedzająca Get-Member wykonuje się i przesyła wynik do Get-Member, który wyświetla informacje o typie zwracanych danych.

Wynik polecenia Get-Service | Get-Member to np.:

  • informacja, z jakim obiektem mamy do czynienia. W przykładzie Get-Service zwraca obiekt typu System.ServiceProcess.ServiceController

  • informacja o aliasach

  • informacja o właściwościach obiektu

  • informacja o metodach obiektu

Wyjście jednej komendy może zwracać obiekty różnych typów, które różnią się np. właściwościami i metodami.

Get-ChildItem C:\Home\PowerShell | Get-Member
  • Format-List – przekształcenie wyjścia polecenia na listę
  • Format-Wide – umożliwia wybranie tylko jednej właściwości dla wyświetlanych elementów. Domyślnie wyświetla informacje w dwóch kolumnach. Ilość kolumn możemy określić
  • Measure-Object – służy do mierzenia np. zliczanie, wyliczanie sumy, średniej, maksimum i minimum
  • LastWriteTime – pobiera lub ustawia datę i godzinę ostatniego zapisu bieżącego pliku lub katalogu

W przykładzie wyświetlamy datę i godzinę modyfikacji katalogu C:\Home\PowerShell

Get-ChildItem C:\Home\PowerShell | Measure-Object -Property LastWriteTime -Maximum

Sortowanie w potoku

Sort-Object jest to polecenie, za pomocą którego możemy uporządkować dane zwracane przez poprzednie polecenia w potoku.

Listę usług generowanych przez polecenie Get-Service przekazujemy do polecenia Sort-Object, które posortuje ją ze względu na przekazaną właściwość. W przykładzie sortujemy według nazwy:

Get-Service | Sort-Object -Property Name

lub

Get-Service | Sort Name

Możemy sortować według jednej lub większej ilości kolumn. Kolumny wymieniamy na liście po przecinku. W przykładzie najpierw posortujemy informacje według statusu a następnie w ramach tego samego statusu alfabetycznie według nazwy.

Get-Service | Sort Status, Name

Status przechowywany jest jako liczba, dlatego po posortowaniu danych według statusu, status może nie być wyświetlany w kolejności alfabetycznej.

Domyślnie informacje sortowane są rosnąco. Aby posortować je malejąco dodajemy przełącznik Descending.

Get-Service | sort Name -Descending

Sortowanie po kilku kolumnach w różnych kierunkach:

Get-Service | Sort-Object @{Expression={$_.CanStop}; Descending=$true}, ` @{Expression={$_.DisplayName}; Descending=$false} | Select-Object Status, Name, DisplayName, CanStop, ServiceType, ServiceName | Out-GridView

Uruchamianie wielu poleceń

Można wpisać wiele poleceń w jednym wierszu. Poszczególne polecenia rozdzielamy średnikami.

Get-Printer - wyświetlamy listę dostępnych drukarek

Get-Printer

Przy użyciu znaku przekierowania > przesyłamy wynik do pliku tekstowego (UTF-16LE). Plik tekstowy zostaje zapisany w katalogu C:\Home\PowerShell

Get-Printer > C:\Home\PowerShell\get_serv.txt

W tym samym wierszu dodajemy polecenie Get-Service i przy użyciu znaku przekierowania z dołączeniem >> przekierowujemy wynik do utworzonego w poprzednim poleceniu pliku tekstowego o nazwie "get_serv.txt".

Get-Printer > C:\Home\PowerShell\get_serv.txt Get-Service >> C:\Home\PowerShell\get_serv.txt

W pliku tekstowym mamy teraz informację o drukarkach oraz informację o usługach.


Potok - wybieranie żądanych wartości - Select-Object

#plik pomocy help Select-Object -Full #Wybierz interesujące cię właściwości/kolumny Get-Process | Select-Object -Property ProcessName, Id, WS #wybierz ostatnie 5 elementów Get-Process | Sort-Object -Property WS | Select-Object -Last 5 #Sortowanie w select "a","b","c","a","a","a" | Select-Object -Unique #zmień nazwy plików i wykorzystaj parmetr -Wait to synchronicznego przetwarzania (po kolei) cd C:\Home\Powershell\Pliki\txt\ Get-ChildItem *.txt | Rename-Item -NewName {$_.BaseName + "-ro.txt"} -PassThru | Select-Object -First 5 -Wait #Wybierz właściwość i zwróć jako string Get-Process | Select-Object -ExpandProperty name

Generowanie kolumny obliczeniowej:

# W przypadku zagnieżdżonych właściwości można selektować po właściwości Get-Process | Select -First 5 | Select-Object -Property ProcessName,{$_.StartTime.DayOfweek}
ProcessName $_.StartTime.DayOfweek ----------- ---------------------- adb Saturday ApMsgFwd Saturday ApntEx Saturday Apoint Saturday ApplicationFrameHost Saturday

Kolumna niestandardowa, konstrukcja z tablicą hash z Label/Expression

Get-Process -Name powers* | Select-Object Handle, @{Label= "WS (MB)"; Exp = {[int]($_.WorkingSet/1MB)}},Id,ProcessName, Path | ft Get-Process firefox | Select-Object -Property ProcessName, @{Label="TotalRunningTime"; Expression={(Get-Date) - $_.StartTime}}

Potok - sortowanie - Sort-Object

#plik pomocy help Sort-Object -Full Get-ChildItem -Path C:\WorkArea\Avendi\Scripts\ | Sort-Object Get-ChildItem -Path C:\WorkArea\Avendi\Scripts\ | Sort-Object -Descending Get-ChildItem -Path C:\WorkArea\Avendi\Scripts\ | Sort-Object -Property Length Get-ChildItem -Path C:\WorkArea\Avendi\Scripts\ | Sort-Object -Property Length, Name #Sortowanie rosnąco po jednej kolumnie, malejąco po drugiej Get-Service | Sort-Object -Property @{Expression = "Status"; Descending = $true}, @{Expression = "DisplayName"; Descending = $false} #Sortowanie na podstawie wyliczanej wartości właściwości Get-ChildItem -Path C:\Home\Powershell\Pliki\txt\ | Sort-Object -Property {$_.CreationTime - $_.LastWriteTime} | Format-Table CreationTime, LastWriteTime, FullName #dodatkowe zadania dla słuchaczy Get-hotfix | sort installedOn | select InstalledOn, InstalledBy, HotfixID; Get-EventLog -LogName System | select -first 50 | sort TimeGenerated, Index | select index, timegenerated, Source

Potok - Formatowanie - upiększanie tego co widzimy – Format-Table -List -Wide

Powershell formatuje dane na podstawie plików xml, np. jeden z nich to $PSHOME\DotNetTypes.format.ps1xml

#plik pomocy help Format-Table -Full Get-Service | Format-Table Get-Service | Format-Table -AutoSize Get-Service | Sort-Object -Property Status | Format-Table -AutoSize -GroupBy Status Get-Service | Format-Table -Property Name, DependentServices #formatowanie z niestandardową kolumną Get-Process notepad | Format-Table ProcessName, @{Label="TotalRunningTime"; Expression={(Get-Date) - $_.StartTime}}
#plik pomocy help Format-List -Full Get-Printer | Select-Object -First 1 | Format-List Get-Printer | Select-Object -First 1 | Format-List * Get-Process | Format-List -Property Name, BasePriority, PriorityClass Get-Process | Format-Wide Get-Process | Format-Wide -Column 4

Pamiętaj formatuj zawsze na końcu, jeśli użyjesz formatowanie w trakcie przetwarzania w potoku otrzymasz dane których raczej się nie spodziewasz:

Get-Process | Out-GridView Get-Printer | Format-Table -AutoSize | ConvertTo-Html | Out-File C:\Home\Powershell\format.html -Encoding utf8 Get-Content C:\Home\Powershell\format.html

Potok – grupowanie – Group-Object

#plik pomocy help Group-Object -Full Get-Service | Group-Object -Property status (Get-ChildItem -Path $PSHOME -Recurse ) | Group-Object -Property extension -NoElement | Sort-Object -Property Count -Descending #Grupuj wedlug wyniku operacji matematycznej - liczby parzyste i nieparzyste 1..20 | Group-Object -Property {$_ % 2}

Potok - Filtrowanie i porównywanie – Where-Object

#plik pomocy help Where-Object -Full Get-Service | Where-Object {$_.Status -eq "Stopped"} Get-Service | Where-Object Status -eq "Running" Get-Service | Where-Object Status -eq "Running" | Sort-Object -Property Name,StartType #Filtrowanie z wyrażeniem regularnym Get-Process | Where-Object {$_.ProcessName -Match "^p.*"} #Wiele warunków w jednym Get-Module -ListAvailable | where { ($_.Name -notlike "Microsoft*" -and $_.Name -notlike "PS*") -and $_.HelpInfoUri }

Potok – zliczanie – Measure-Object

#plik pomocy help Measure-Object -Full Get-ChildItem | Measure-Object #Najstarszy plik Get-ChildItem -Recurse -Path C:\Home\Powershell\ | Measure-Object -Property LastWriteTime -Minimum #najmłodszy plik Get-ChildItem -Recurse -Path C:\Home\Powershell\ | Measure-Object -Property LastWriteTime -Maximum #Suma wszystkich plików i średnia wielkość Get-ChildItem | Measure-Object -Property length -Minimum -Maximum -Sum -Average #zliczanie wyrazów linii, znaków "One", "Two", "Three", "Four" | Set-Content -Path C:\Home\Powershell\tmp.txt Get-Content C:\Home\Powershell\tmp.txt | Measure-Object -Character -Line -Word #Zliczanie i niestandardowa kolumna Get-ChildItem -Recurse -Path C:\Home\Powershell\ | Measure-Object -Property Length -Sum | Select @{Name = "Total Length" ; Expression = {[int]($PSItem.Sum /1MB)}}

Potok – robienie migawek danych – zapisywanie do pliku strukturalnego

Get-Process | Export-Csv -Path C:\Home\Powershell\process_1.txt Get-Process | Export-Clixml -Path C:\Home\Powershell\process_1.xml

Potok – porównywanie obiektów – Compare-Object

#plik pomocy help Compare-Object -Full Get-Service | Export-Csv -Path C:\Home\Powershell\Dane\services.csv & 'C:\Program Files\Notepad++\notepad++.exe' C:\Home\Powershell\Dane\services.csv Get-Service | Export-Clixml -Path C:\Home\Powershell\Dane\services.xml Start-Service -Name XblGameSave Get-Service | Export-Clixml -Path C:\Home\Powershell\Dane\services_2.xml #Zapisanie stanu przed zmianą $Przed = Import-Clixml -Path C:\Home\Powershell\Dane\services.xml; #zapisanie stanu po zmianie $Po = Import-Clixml -Path C:\Home\Dane\services_2.xml #porównanie Compare-Object -ReferenceObject $Przed -DifferenceObject $Po -Property Status,Name

Potok – operacje na wszystkich obiektach – wyliczanie Foreach-Object. Tworzone są obiekty w arbitralnymi właściwościami typu PSCustomObject.

#plik pomocy help ForEach-Object -Full #operacje na kolekcji licz 30000, 56798, 12432 | ForEach-Object -Process {$_/1024} Get-ChildItem $PSHOME | ForEach-Object -Process {if (!$_.PSIsContainer) {$_.Name; $_.Length / 1024; " " }}

Potoki a kolekcje

#Wyliczenie elementów za pomoca foreach Get-Service | ForEach-Object -Process {$_.DisplayName} #wyliczenie elementów skrót od wersji powershell 3.0 (Get-Service).DisplayName

Przekazywanie potoku poprzez wartość albo nazwę właściwości

Przekazywanie poprzez wartość.

Dane dokładniej ich typ np. [string] zwracane z pierwszego polecenia, musi odpowiadać typowi danych którego się spodziewa drugie polecenie. Każde polecenie może obsługiwać tylko jeden typ danych, który będzie skojarzony z jednym parametrem. To znaczy jak Get-Service obsługuje [string] dla parametru NAME przekazywanego przez wartość, to już żaden inny parametr tego nie może. To jest pierwsza metoda jaką podejmuje potok dla poleceń w potoku.

#Potoki przekazywanie poprzez wartość "localhost","127.0.0.1" | Out-File -FilePath C:\Home\Powershell\computers.txt Get-Content C:\Home\Powershell\computers.txt #1. Sprawdzamy że to polecenie zwraca dane typu string Get-Content C:\Home\Powershell\computers.txt | Get-Member # 2. Sprawdzamy jakie dane potrafi obsłużyć get-service , dla typu string i #patrzymy czy mogą być obsłużone z potoku, # okazuje się ze to parametr Name, ale nie o taką sytuacje nam chodzi #poniższe polecenie nie zadziała prawidłowo help Get-Service -Full Get-Content C:\Home\Powershell\computers.txt | Get-Service -WhatIf #sprawdzamy ze typy wyjściowy i wejściowy to service wiec tu przekazanie przez #wartość zadziała Get-Service -Name XblGameSave | select -ExpandProperty name | Start-Service -WhatIf Get-Service | Get-Member help Get-Service -Parameter Name #szukamy innego polecenie, tu jako dane wejściowe typu string ma wartość #Computername, ale także nie obsługuje przekazywania przez wartość Get-CimInstance -ClassName Win32_operatingsystem | select version help Get-CimInstance -Full | Out-String -Stream | Select-String string

Jak potok nie może przypasować obiektów poprzez wartość, próbuje drugiej metody poprzez nazwę właściwości. Takich dopasowanych par parametrów wyjściowych i wejściowych może być więcej, np. Name, ComputerName itp.

#Potoki przekazywanie poprzez Nazwe parametru Get-Service -Name XblGameSave | Get-Member help Get-Process -Parameter Name #pierwsze polecenie i drugie na wyjściu maja zupełne inne typy process i service #przypasowanie poprzez wartość nie zadziała #podejmowana jest próba dopasowanie właściwości o tych samych nazwach. #okazue się ze to parametr Name, zatem nazwy procesów są przekazane jako nazwy #usług do wyświetlenia #oczywiscie wynik jest błędny Get-Service -Name XblGameSave | Stop-Process -WhatIf

Przykład wykorzystania:

#tworzymi plik z aliasami notepad C:\Home\Powershell\Dane\aliasy.csv

Treść pliku aliasy.csv:

Name,Value gdzie,get-location ile,measure-object
#importuje csv i tworze obiekt o właściwościach name i value $aliasy = Import-Csv -Path C:\Home\Powershell\Dane\aliasy.csv -Delimiter ',' $aliasy | Get-Member #Nazwy parametrów name i value odpowiadają parametrom polecenia new-alias. # dopasowanie poprawne, wynik polecenia w potoku ok help New-Alias -Full $aliasy| New-Alias

Jak możemy zatem zmodyfikować dane aby przekazywanie pomiędzy poleceniami w potoku zadziałało? Możemy to zrobić na 3 sposoby:

Poprzez niestandardową kolumnę w potoku z polecenia Select i ustawienie nazwy właściwości na taką, jaka jest oczekiwana w wejściowym poleceniu, dla właściwości przekazanej poprzez nazwę parametru.

#Polecenie get-ciminstance w polu computername oczekuje stringa przekazanego #poprzez nazwany parametr, #w potoku tworzymy nową kolumne computername i przypisujemy linie z pliku #Połaczenie parametrów poprawnie Get-Content C:\Home\Powershell\computers.txt | select @{L="ComputerName" ; Expression = {"$_"}} | Get-CimInstance -ClassName Win32_operatingsystem | select version

Poprzez nawiasy i właściwe przekazanie do parametru oczekiwanych typów

#w nawiasach wskazujemy zawartość typu string, #której oczekuje parametr computername) Get-CimInstance -ClassName Win32_operatingsystem -ComputerName (Get-Content C:\Home\Powershell\computers.txt) | select version

Poprzez wyliczenie i "ręczne" dopasowanie parametrów

#Jawne przypisanie do parametru, tj. w potoku dodajemy foreach i jawnie #przypisujemy do zmiennej computername wartość z pliku tekstowego) Get-Content C:\Home\Powershell\computers.txt | ForEach-Object {Get-CimInstance -ClassName Win32_operatingsystem -ComputerName $_ | select version}

Istnieje jeszcze możliwość wyodrębnienia danych w postaci stringu dla jednej właściwości i przekazania do właściwego parametru.

Plik C:\Home\Powershell\Dane\complist.csv:

Name,Ip localhost,127.0.0.1 wp.pl, 123.23.23.34
# Wczytuje dane do obiektu $compy = import-csv -Path C:\Home\Powershell\Dane\complist.csv -Delimiter ',' # Wyodrębnienie computername jako string Get-Service -Name Appinfo -ComputerName ($compy |select -First 1 | Select-Object -ExpandProperty Name)

Przykładowy skrypt z funkcjami w których przekazujemy w potoku poprzez wartość i nazwę parametru w pliku 2_1_potoki.ps1. Wróć do niego po zapoznaniu z funkcjami.

Polecenia wejścia/ wyjścia

Polecenie Write-Host tak samo jak Format-Table nie może być używane w środku potoku, ponieważ nie przekazuje danych dalej, tylko kieruje je na ekran.

#czytanie z klawiatury Read-Host Read-Host -AsSecureString #wyświetlanie w kolorze Write-Host -ForegroundColor red "terenowy" # Write-Host wypisuje na ekran i nie przekazuje danych dalej w potoku Write-Host "Powershell" | where-object { $_.length -gt 10 } Write-Output "Powershell" | where-object { $_.length -gt 10 } #prosta walidacja danych z klawiatury Read-Host "jak ci na imie" | Where-Object Length -gt 5

Zadania: Łączenie poleceń - potoki

Tworzenie skryptów

Tematy w help:

help ABOUT_EXECUTION_POLICIES powershell.exe -help
#możliwe sceneriusze PowerShell.exe -ExecutionPolicy Bypass -File .runme.ps1 Set-ExecutionPolicy Bypass -Scope Process Set-ExecutionPolicy Unrestricted -Scope CurrentUser -Force

Skrypt to zbiór poleceń, które można wykonać w PowerShell np.

Get-Process notepad | Stop-Process

Polecenia umieszczamy w pliku i są one wykonywane w tej samej kolejności, w jakiej zostały wpisane.

Aby utworzyć skrypt PowerShell, kopiujemy polecenia do pliku tekstowego i zapisujemy go z rozszerzeniem .ps1. Jeśli plik utworzymy w PowerShell ISE, rozszerzenie .ps1 zostanie dodane automatycznie.

Ten typ pliku domyślnie nie jest traktowany jako plik wykonywalny – podwójne kliknięcie pliku powoduje otwarcie go w Notatniku a nie wykonanie.

Włączanie obsługi skryptów

Domyślnie w PowerShell nie możemy wykonywać skryptów, ale za pomocą polecenia Set-ExecutionPolicy możemy włączyć obsługę skryptów.

Poziomy obsługi skryptów:

  • Restricted (Ograniczone) - poziom domyślny, nie są ładowane pliki konfiguracyjne, takie jak profil Windows PowerShell ani uruchamiane żadne inne skrypty
  • AllSigned (Wszystkie podpisane) - wymaga, aby wszystkie skrypty i pliki konfiguracyjne były podpisane przez zaufanego wydawcę, łącznie ze skryptami, które zostały napisane na lokalnym komputerze
  • RemoteSigned (Zdalne podpisane) - wymaga, aby wszystkie skrypty i pliki konfiguracyjne pobierane z Internetu były podpisane przez zaufanego wydawcę.
  • Unrestricted (Nieograniczone) - zezwala na ładowanie wszystkich plików konfiguracyjnych i uruchamianie dowolnych skryptów. Jeśli spróbujemy uruchomić niepodpisany skrypt pobrany z Internetu, pojawi się monit o zezwolenie przed jego uruchomieniem.
  • Bypass (Pomijanie) - nie ma żadnych blokad ani nie są wyświetlane monity i ostrzeżenia.
  • Undefined (Niezdefiniowane) - usuwa aktualnie przypisaną zasadę wykonywania z bieżącego zakresu. Parametr ten nie usuwa ustawień narzuconych przez Zasady grupy.

Jako uzupełnienie sześciu poziomów zasady wykonywania, mamy trzy różne zakresy (ang. scope):

  • Process (Proces) - zasada wykonywania dotyczy tylko bieżącego procesu (sesji) PowerShell
  • CurrentUser (Bieżący użytkownik) - zasada wykonywania dotyczy tylko bieżącego użytkownika
  • LocalMachine (Lokalny komputer) - zasada wykonywania dotyczy wszystkich użytkowników danego komputera. Ustawienie zasady LocalMachine wymaga uprawnień administratora na komputerze lokalnym.

Zasady wykonywania dla wszystkich zakresów możemy wyświetlić za pomocą polecenia:

Get-ExecutionPolicy -List

Uruchamianie skryptów

W aplikacji Powershell ISE w okienku Skrypt możemy otwierać i edytować pliki programu Windows PowerShell.

Typy plików, które można otwierać w konsoli ISE:

  • .ps1 — pliki skryptów
  • .psd1 — pliki danych skryptów
  • .psm1 — pliki modułów skryptów
  • .ps1xml — pliki konfiguracyjne
  • pliki XML
  • pliki tekstowe

Aby otworzyć skrypt, możemy przeciągnąć go do konsoli.

Możemy też wybrać opcję File -> Open, wskazać w oknie dialogowym plik do otwarcia i kliknąć przycisk Open.

Skrypty możemy uruchamiać też w aplikacji wiersza poleceń. Aby to zrobić, w menu Start wpisujemy cmd.

W oknie Wiersza poleceń podajemy:

  • pełną ścieżkę do skryptu i przekazujemy skrypt jako argument dla programu PowerShell.exe.
  • dołączamy parametr -NoExit, aby móc zobaczyć dane wyjściowe skryptu

Komentarze

Komentarze są to bloki kodu lub opisy, które nie są wykonywane przez program.

Za pomocą znaku # tworzymy komentarz jednolinijkowy

$a=3 #przypisanie wartości do zmiennej a

Za pomocą znaku <# ... #> zakomentujemy cały blok kodu.

<# $value = 4 if ( 5 -gt $value ) { "Wartość jest ok" } "Kod wykonany"#>

Skrypty z parametrami

Parametr umożliwia wprowadzenie do skryptu danych wejściowych. Jeśli zachowanie skryptu PowerShell musi się w jakiś sposób zmienić, parametr daje możliwość zrobienia tego bez zmiany kodu bazowego.

Parametry mogą być tworzone dla skryptów i dla funkcji. Są zawsze zawarte w bloku param zdefiniowanym za pomocą słowa kluczowego param, po którym następują otwierające i zamykające nawiasy.

Typy parametrów:

  • statyczne - parametry zawsze dostępne w poleceniu lub funkcji
  • dynamiczne - parametry dostępne tylko w określonych warunkach
  • przełącznika - są to parametry bez wartości parametru. Włączamy je lub wyłączamy

Wewnątrz bloku param znajduje się jeden lub więcej parametrów zdefiniowanych, w najprostszym przypadku, przez pojedynczą zmienną.

param ( $Parameter1 )

Jeśli chcemy, żeby parametr akceptował tylko typ danych wejściowych, których potrzebujemy i obsługiwał inne funkcje w przyszłości, powinniśmy przypisać typ do parametru. W przykładzie parametr akceptuje tylko obiekty typu string.

param ( [Parameter()] [string]$Parameter1 )

Dodatkowe parametry dodajemy oddzielając je przecinkiem.

param ( [Parameter()] [string]$Parameter1, [Parameter()] [string]$Parameter2 ) Write-Host "Parameter 1 value is $Parameter1" Write-Host "Parameter 2 value is $Parameter2"

Zapoznaj się z plikiem about i helpem od powershell.exe, który ma specjalny przełącznik. Przydatne linki tu, tutaj oraz tu. Jak podpisać skrypt, znajdziesz w tym artykule.

Jak podspisać skrypt: https://akademiapowershell.pl/2020/11/podpisywanie-powershell/

Zadania: Tworzenie skryptów

Instrukcje warunkowe

PowerShell zawiera instrukcje do warunkowego wykonywania kodu w skryptach.

Instrukcja If

Instrukcja if pozwala programowi „dokonywać wyboru" na podstawie warunków. Warunki są często tworzone przez porównywanie wartości przy użyciu operatorów porównania.

Aby napisać instrukcję if, rozpoczynamy od słowa kluczowego if, po którym umieszczamy nawias zawierający warunek. Po wyrażeniu warunkowym umieszczamy w nawiasach klamrowych kod bloku.

Powłoka PowerShell wykona ten blok kodu tylko wtedy, gdy wyrażenie ma wartość True. Jeżeli wynikiem wyrażenia if jest False lub wartość pusta, blok kodu jest pomijany.

Przykład 1:

$value = 4 if ($value -gt 2) { "Wartość jest ok" } "Kod wykonany"

Przykład 2:

$value = 4 if ($value -gt 5) { "Wartość jest ok" } "Kod wykonany"

Wyjaśnienie do przykładów:

  • w instrukcji If w przykładzie 1 sprawdzamy, czy wartość 2 jest większa od wartości ze zmiennej $value
  • w instrukcji If w przykładzie 2 sprawdzamy, czy wartość 5 jest większa od wartości ze zmiennej $value
  • w obydwu przykładach w konsoli wyświetlony zostaje kod programu
  • w obydwu przykładach wyświetlony zostaje tekst "Kod wykonany"
  • w przykładzie 1 wyświetlony jest tylko tekst "Kod wykonany". Nie został wyświetlony tekst "Wartość jest ok", gdyż warunek znajdujący się w instrukcji If nie został spełniony
  • w przykładzie 2 wyświetlony jest tekst "Kod wykonany" oraz tekst "Wartość jest ok", gdyż warunek w instrukcji If został spełniony

Klauzla Else

Aby do instrukcji If dodać zachowanie alternatywne, po nawiasie zamykającym blok If podajemy słowo kluczowe Else. Po słowie Else umieszczamy blok kodu w nawiasach klamrowych.

$a = 4 If ($a -eq 5) { '$a równa się 5' } Else { '$a nie równa się 5' }

Klauzula Elseif

Klauzula Elseif umożliwia umieszczenie w programie dodatkowych warunków, które będą sprawdzane przed powrotem do kodu w bloku w klauzuli Else.

$a = 4 If ($a -eq 5) { '$a równa się 5' } ElseIf ($a -eq 3) { '$a równa się 3' } Else { '$a nie równa się 3 ani 5' }

Instrukcja Switch

Instrukcja Switch umożliwia wykonywanie różnych fragmentów kodu na podstawie określonych wartości.

Wewnątrz instrukcji Switch umieszczamy w nawiasach klamrowych bloki kodu powiązane z określonymi wartościami. Na końcu umieszczamy domyślny blok kodu.

Przykład 1

$a = "jabłko" switch ($a) { "jabłko" { "Mam jabłko" } "wiśnia" { "Mam wiśnię" } "jabłko" { "Mam drugie jabłko" } "cytryna" { "Mam cytrynę" } "gruszka" { "Mam gruszkę" } default { "Nie mam tego owocu" } }

Wynik:

Mam jabłko Mam drugie jabłko

W przykładzie słowo "jabłko" spełnia dwa warunki.

Przykład 2

$a = "banan" switch ($a) { "jabłko" { "Mam jabłko" } "wiśnia" { "Mam wiśnię" } "jabłko" { "Mam drugie jabłko" } "cytryna" { "Mam cytrynę" } "gruszka" { "Mam gruszkę" } default { "Nie mam tego owocu" } }

Wynik:

Nie mam tego owocu

Domyślnie wykonywane jest każde dopasowanie wewnątrz wyrażenia Switch.

Jeśli w bloku skryptu nie zostanie znalezione dopasowanie i nie zostało użyte wyrażenie Default, wyrażenie Switch się kończy i wykonywany jest kolejny wiersz kodu następujący po nim.

Instrukcja Break

Po każdym lub po niektórych warunkach możemy umieścić instrukcję Break. Powoduje ona, że instrukcja Switch kończy się, gdy wartość testu spełni warunek.

$a = "jabłko" switch ($a) { "jabłko" { "Mam jabłko";break } "wiśnia" { "Mam wiśnię";break } "jabłko" { "Mam drugie jabłko";break} "cytryna" { "Mam cytrynę";break } "gruszka" { "Mam gruszkę";break } default { "Nie mam tego owocu" } }

Wynik:

Mam jabłko

Obsługa tablic

Wyrażenie Switch potrafi obsłużyć tablicę umieszczoną w zmiennej $a. Dla każdego elementu tablicy wykonane zostanie wyrażenie wewnątrz bloku Switch.

$a = 2,3,5,1,77 Switch ($a) { 1 { '$a = 1' } 2 { '$a = 2' } 3 { '$a = 3' } Default { 'nie można określić wartości $a' } } "Wyrażenie po switch"

Wynik działania:

$a = 2 $a = 3 nie można określić wartości $a $a = 1 nie można określić wartości $a Wyrażenie po switch

Zadania: Instrukcje warunkowe

Pętle

Pętle umożliwiają wielokrotne wykonywanie określonego fragmentu kodu aż do chwili, kiedy warunek zatrzymania pętli ulegnie zmianie.

Warunek zatrzymania pętli może być użyty do wykonania pętli:

  • określoną liczbę razy
  • do chwili zmiany wartości logicznej

Każdy przebieg pętli nazywamy iteracją.

W PowerShell mamy do dyspozycji 5 rodzajów pętli.

Warunek pętli musi zostać umieszczony w nawiasach.

Pętla While

W pętli While komputer sprawdza warunek i wykonuje blok kodu raz po raz, dotąd aż warunek okaże się fałszywy.

W tym przykładzie sprawdzamy wartość zmiennej $x. Jeśli wartość $x jest mniejsza niż 5, zostaną wykonane działania umieszczone w nawiasach klamrowych obramowujących blok skryptowy.

$val=0 while($val -ne 5) { Write-Host $val; $val++ }

Poniższa instrukcja while wyświetla liczby od 1 do 5, jeśli zmienna $val została utworzona i zainicjowana na 0.

$val = 0 while($val -ne 5) { $val++ Write-Host $val }

Inny sposób zapisu polecenia:

$val = 0 while($val -ne 5){$val++; Write-Host $val}

W przykładzie, warunek ( $val nie równa się 5 ) jest prawdziwy, gdy $val jest równa 0,1,2,3,4.

Przy każdym obrocie pętli, $val jest zwiększana o 1 przy użyciu operatora ++. W ostatnim obrocie pętli, gdy wartość $val zostanie ustawiona na 5, warunek staje się fałszywy i pętla kończy działanie.

Pętli While najczęściej używamy, gdy liczba iteracji pętli nie jest z góry określona.

Pętla Do ... While

Pętla Do ... While wykonuje się dotąd aż warunek, który sprawdza jest prawdziwy. Pętla wykona co najmniej jeden obrót.

$val=0 Do {Write-host $val; $val++} while ($a -le 5)
$i = 0 $ary = 1..5 do { $ary[$i] $i++ } while ($i -lt $ary.Length)

W przykładzie:

  • do zmiennej $i przypisujemy wartość 0

  • tworzymy tablicę liczb od 1 do 5 i umieszczamy ją w zmiennej $ary. Tablicę możemy utworzyć na dwa sposoby:

    • listujemy wszystkie wartości oddzielając je przecinkami $ary = 1,2,3,4,5
    • używamy operatora zakresu (range) - podajemy wartość początkową i końcową rozdzielając je dwiema kropkami. Operator zakresu działa tylko dla liczb całkowitych. $ary = 1..5
  • po wyrażeniu Do umieszczamy parę nawiasów klamrowych.

  • Wewnątrz nawiasów będzie blok skryptowy. Zmienna sterująca pętlą jest w tym przykładzie indeksem tabeli. Pierwszy element tablicy w Windows PowerShell ma zawsze indeks równy 0.

    Podczas pierwszego przejścia przez pętlę wartość $i jest równa 0. Tym samym zostanie wyświetlony pierwszy element tablicy $ary. Następnie zmienna $i jest inkrementowana (zwiększana) o jeden. Po bloku skryptowym następuje wyrażenie While z warunkiem pętli. Pętla będzie wykonywana dopóki zmienna $i ma wartość mniejszą niż 5. Po osiągnięciu wartości 5 nastąpi zatrzymanie pętli.

Pętla Do...Until

Pętla Do...Until jest wykonywana do momentu, gdy warunek zostanie spełniony.

$val=0 Do {Write-host $val; $val++} until ($a -gt 5)

Skrypty używające pętli Do...Until są często stosowane do odczytywania pliku tekstowego np. odczytujemy dane, dopóki nie dojdziemy do końca pliku.

Różnica pomiędzy pętlą Do...Until i Do...While polega na tym, że pętla Do...While jest wykonywana, dopóki warunek jest prawdziwy, a Do...Until przerywa działanie, gdy warunek zostanie spełniony (stanie się prawdziwy).

$i = 0 $ary = 1..5 Do { $ary[$i] $i ++ } Until ($i -eq 5)

W przykładzie:

  • inicjujemy zmienną $i z wartością 0
  • tworzymy tablicę zawierającą liczby od 1 do 5, umieszczając ją w zmiennej $ary
  • tworzymy konstrukcję Do (do-until) - po słowie kluczowym Do otwieramy parę nawiasów klamrowych. W ich wnętrzu wykorzystujemy zmienną $i jako indeks tablicy $ary do odczytania wartości zapisanych w kolejnych elementach tablicy. Następnie inkrementujemy (zwiększamy) zmienną $i o jeden.
  • po bloku skryptowym umieszczamy warunek powodujący, że pętla jest wykonywana do momentu, gdy wartość zmiennej $i będzie równa 5.

Pętle Do...While oraz Do...Until zawsze wykonają co najmniej jeden obrót.

Pętla For

Pętli For używamy do wykonania bloku kodu określoną liczbę razy. Polecenia są uruchamiane dopóki określony warunek ma wartość $true.

For ($val=1; $val -lt 5; $val++) {Write-host $val}
For($i = 0; $i -le 5; $i++) { '$i equals ' + $i }

W przykładzie:

  • rozpoczynamy od słowa kluczowego For
  • inicjujemy zmienną odliczającą, określając początkową i końcową wartość
  • używamy składni $i++ do zwiększania zmiennej $i o jeden
  • w bloku skryptowym wpisujemy wartość zmiennej $i

Pętla Foreach

Pętla Foreach przechodzi przez daną listę obiektów, wykonuje te same operacje dla każdego obiektu i kończy działanie po przetworzeniu ostatniego obiektu. Lista obiektów jest zwykle reprezentowana w postaci tablicy.

foreach ($file in get-ChildItem *.txt) {Write-host $file.name}
$ary = 1..5 Foreach ($i in $ary) { $i }

W przykładzie:

  • tworzymy tablicę zawierającą liczby od 1 do 5 i umieszczamy ją w zmiennej $ary
  • wywołujemy wyrażenie Foreach do przechodzenia poprzez elementy tablicy.
  • Wewnątrz bloku skryptowego wypisujemy wartość każdego elementu.

Wyrażenia Foreach możemy użyć interaktywnie bezpośrednio w konsoli:

$ary = 1..5 foreach($i in $ary) { $i }

Przerywanie pętli

W PowerShell pętlę możemy opuścić za pomocą słowa kluczowego Break

$ary = 1..5 ForEach ($i in $ary) { if ($i -eq 3) { break } $i } "Wyrażenie po pętli"

W przykładzie wewnątrz bloku skryptowego używamy wyrażenia If do sprawdzenia wartości zmiennej $i. Jeśli jest ona równa 3, wywołujemy wyrażenie Break i opuszczamy pętlę.

Aby po przerwaniu pętli nie wykonywać reszty skryptu, tylko zakończyć jego działanie, powinniśmy użyć wyrażenia Exit zamiast Break.

$ary = 1..5 ForEach($i in $ary) { if($i -eq 3) { exit } $i } "Wyrażenie po pętli"

Po uruchomieniu skryptu wiersz "Wyrażenie po pętli" nie zostanie wykonane gdyż polecenie exit kończy wykonywanie skryptu.

Za pomocą instrukcji Continue możemy przejść na początek pętli.

$c = 0 While ($c -lt 3) { $c++ if ($c -eq 2) { Continue } Write -Host $c }

Zadania: Pętle

Obsługa błędów

Wyjątek to jedna z technik zgłaszania błędu wykonania programu. Wyjątkiem sygnalizuje się zdarzenie, które występuje w trakcie realizacji programu i uniemożliwia normalny przepływ instrukcji programu.

Gdy skrypt PowerShell napotka sytuację, której nie może obsłużyć, podnosi wyjątek.

Gdy zostanie zgłoszony wyjątek, którego skrypt nie obsługuje, zostanie on przekazany do użytkownika jako błąd (ang. error).

Rodzaje błędów:

  • krytyczne (ang. terminating errors) — błędy, które zatrzymują działanie kodu lub polecenia
  • niekrytyczne (ang. nonterminating errors) — błędy, które nie zatrzymują działania kodu lub polecenia

Obsługa błędów niekrytycznych

W przypadku błędów niekrytycznych mechanizm obsługi błędów polega zazwyczaj na wyświetleniu komunikatu o błędzie i kontynuowaniu działania pozostałej części programu.

W przykładowym skrypcie poniżej mamy dwa polecenia:

  • pierwsze zatrzymuje proces o nazwie "notepad"
  • drugie zatrzymuje proces o nazwie "Teams"
Stop-Process -Name "notepad" Stop-Process -Name "Teams"

Aplikacja Notatnik nie jest uruchomiona, więc nie ma dla niej procesu. W związku z tym pierwsza instrukcja zgłasza wyjątek, a druga się wykonuje.

PS C:\Users\Avendi> Stop-Process -Name "notepad" Stop-Process -Name "Teams" Stop-Process : Cannot find a process with the name "notepad". Verify the process name and call the cmdlet a gain. At line:1 char:1 + Stop-Process -Name "notepad" + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (notepad:String) [Stop-Process], ProcessCommandException + FullyQualifiedErrorId : NoProcessFoundForGivenName,Microsoft.PowerShell.Commands.StopProcessCommand

Aby przekształcić błąd w błąd krytyczny, używamy parametru -ErrorAction. Jest to jeden z tzw. parametrów wspólnych (ang. common parameters), które są dostępne w każdym poleceniu cmdlet powłoki PowerShell.

Parametr -ErrorAction określa, co powłoka PowerShell powinna zrobić, kiedy dane polecenie napotka błąd niekrytyczny.

Opcje parametru -ErrorAction:

  • Continue (kontynuuj) — ustawienie domyślne, wyświetla komunikat o błędzie i kontynuuje wykonywanie polecenia
  • Ignore (ignoruj) — kontynuuje wykonywanie polecenia bez zgłaszania błędu i bez rejestrowania go w zmiennej $Error
  • Inquire (zbadaj) — wyświetla komunikat o błędzie i prosi użytkownika o wybranie sposobu postępowania przed kontynuowaniem
  • SilentlyContinue (cicha kontynuacja) — kontynuuje wykonywanie polecenia bez generowania błędu, ale rejestruje go w zmiennej $Error
  • Stop (zatrzymaj) — wyświetla komunikat o błędzie i zatrzymuje działanie polecenia

W przykładzie niżej plik "dysks.txt" nie istnieje. Po uruchomieniu poleceń obydwa się wykonają. Dla pierwszego polecenia zgłoszony zostanie błąd, a drugie polecenie wyświetli dane z pliku "get_serv.txt"

Get-Content C:\Home\PowerShell\dysks.txt Get-Content C:\Home\PowerShell\get_serv.txt

Jeśli do poleceń dodamy parametr Stop, wykonywanie skryptu zostanie zatrzymane po pierwszym poleceniu:

Get-Content C:\Home\PowerShell\dysks.txt -ErrorAction Stop Get-Content C:\Home\PowerShell\get_serv.txt -ErrorAction Stop

Obsługa błędów krytycznych

Aby zapobiec temu, że wystąpienie błędu krytycznego spowoduje zatrzymanie działania programu, możemy błąd przechwycić i obsłużyć za pomocą konstrukcji Try-Catch-Finally.

Blok Try to sekcja kodu, która monitoruje błędy. Tutaj wykonywany jest kod i jeśli w tym czasie wystąpi błąd powodujący zamknięcie programu, następuje jego przechwycenie przez najbliższy blok Catch. Te dwa bloki są ze sobą powiązane i muszą występować razem.

Ostatni blok (nieobowiązkowy) to Finally, w którym instrukcje zostaną wykonane niezależnie od rezultatów poprzednich bloków.

$filePath = 'C:\Home\PowerShell\dysks.txt' try { Get-Content $filePath } catch { Write-Host "Wystąpił błąd!" } finally { Get-ChildItem -Path C:\Home\PowerShell }

W przykładzie:

  • do zmiennej $filePath przypisujemy ścieżkę dostępu do pliku o nazwie "dysks.txt"
  • w bloku try wpisujemy polecenie Get-Content, za pomocą którego chcemy wyświetlić zawartość pliku "dysks.txt"
  • w bloku catch wpisujemy polecenie Write-Host, za pomocą którego wyświetlamy tekst "Wystąpił błąd!", jeśli w bloku try pojawi się błąd
  • w bloku finally wpisujemy polecenie Get-ChildItem, za pomocą którego wyświetlimy pliki dostępne w katalogu "C:\Home\PowerShell"

Zmienna automatyczna $Error

Zmienna $Error jest to zmienna wbudowana, która przechowuje tablicę wszystkich błędów zwróconych w bieżącej sesji powłoki PowerShell. Błędy są uporządkowane według czasu ich pojawienia się.

Obsługa kodów błędów dla zmiennej $? i $LASTEXITCODE

Zmienna $? zawiera status success/fail ostatnio wykonanego wyrażenia.

Zmienna $LastExitCode zawiera kod wyjściowy ostatnio uruchomionej aplikacji natywnej.

Przykład 1:

ping wp.pl

Polecenie zakończone sukcesem:

Pinging wp.pl [212.77.98.9] with 32 bytes of data: Reply from 212.77.98.9: bytes=32 time=14ms TTL=58 Reply from 212.77.98.9: bytes=32 time=13ms TTL=58 Reply from 212.77.98.9: bytes=32 time=13ms TTL=58 Reply from 212.77.98.9: bytes=32 time=13ms TTL=58 Ping statistics for 212.77.98.9: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), Approximate round trip times in milli-seconds: Minimum = 13ms, Maximum = 14ms, Average = 13ms
$? # True $LASTEXITCODE # 0

Przykład 2:

ping wp.io

Polecenie zakończone błędem:

Pinging wp.io [207.154.217.86] with 32 bytes of data: Request timed out. Request timed out. Request timed out. Request timed out. Ping statistics for 207.154.217.86: Packets: Sent = 4, Received = 0, Lost = 4 (100% loss),
$? # False $LASTEXITCODE # 1

Przykład 3: Polecenie przerwane przez Ctrl+C .

$? # False $LASTEXITCODE # -1

Zmienna $PSItem.Exeption.Message zawiera bieżący błąd.

$log = "C:\Home\Powershell\Dane\logi.txt" $status = $true try { Get-Content C:\Home\Powershell\Dane\aliasy.csv_ -ErrorAction Stop } catch { "[error] [$(Get-Date -Format 'yyyy-MM-dd hh:mm:ss ')] Hej nie mam takiego pliku : $($Error[0])" | Out-File -FilePath $log -Append $status = $false } if($status) { "[succes] [$(Get-Date -Format 'yyyy-MM-dd hh:mm:ss ')] udało siue otworzyc plik" >> $log }

Zadania: Obsługa błędów

Funkcje

Funkcje to bloki kodu, które mogą być wielokrotnie wywoływane. Różnica między funkcją a poleceniem cmdlet polega na sposobie tworzenia każdej z tych konstrukcji.

Polecenia cmdlet nie są napisane w PowerShell tylko w innym języku np. C#. Następnie są kompilowane i udostępniane w programie PowerShell.

Funkcje napisane są w PowerShell.

Za pomocą poniższego polecenia możemy zwrócić wszystkie funkcje aktualnie załadowane do sesji PowerShell lub wewnątrz modułów, które są dostępne dla PowerShell.

Get-Command -CommandType Function

Help dotyczący pisania funkcji:

help about_Functions help about_Functions_Advanced help about_functions_advanced_parameter

Definiowanie funkcji

Aby móc używać własną funkcję, musimy ją zdefiniować. Definicję tworzymy używając słowa kluczowego Function, po którym następuje opisowa nazwa zdefiniowana przez użytkownika, po której następuje zestaw nawiasów klamrowych. Wewnątrz nawiasów klamrowych znajduje się blok skryptu, który ma wykonać PowerShell.

Przykład funkcji:

function Install-MMSoftware { Write-Host 'Program zainstalowany' }

Funkcja wykorzystuje polecenie Write-Host do wyświetlania komunikatu w konsoli.

Po zdefiniowaniu funkcji, używamy jej nazwy, aby wykonać kod znajdujący się w bloku skryptu funkcji.

Host:

  • hostem nazywamy komputer
  • polecenie Get-Host zwraca np. wersję programu jakim się łączymy do PowerShell
  • polecenie Write-Host wyświetla komunikat na hoście (komputerze)

Funkcje są dostępne w PSDrive.

Za pomocą polecenia Get-ChildItem -Path Function:\Get-*Version możemy wyświetlić listę funkcji zawierających w nazwie słowo Version:

Aby usunąć funkcję z bieżącej sesji, musimy usunąć ją z funkcji PSDrive lub zamknąć i ponownie otworzyć program PowerShell. Usunąć funkcję możemy poniższym poleceniem:

Get-ChildItem -Path Function:\Get-MMVersion | Remove-Item

Nazwa funkcji

Nazwa funkcji powinna opisywać, do czego funkcja służy.

Konwencja nazewnictwa funkcji w programie PowerShell to składnia czasownik-rzeczownik.

Aby znaleźć listę "zatwierdzonych" czasowników, użyj polecenia cmdlet Get-Verb.

W nazewnictwie funkcji jest dobrze stosować standardową konwencję PowerShell czasownik-rzeczownik i wybierać czasowniki ze standardowej listy czasowników PowerShell.

Przykład utworzenia funkcji i wywołania funkcji:

function Write-Message { Write-Host "Funkcja uruchomiona.." } Write-Message

Parametry funkcji

Funkcje PowerShell mogą mieć dowolną liczbę parametrów.

Podczas tworzenia własnych funkcji mamy możliwość dołączenia parametrów i decydowania, w jaki sposób one działają. Parametry mogą być obowiązkowe lub opcjonalne oraz mogą akceptować dowolne dane lub akceptować tylko wartości z ograniczonej listy możliwych argumentów.

Tworzenie parametru w funkcji wymaga bloku param, który zawiera wszystkie parametry funkcji.

function Install-Software { [CmdletBinding()] param( [Parameter()] [string] $Version ) Write-Host "Oprogramowanie w wersji $Version zainstalowane" } Install-Software -Version 4 ls function:/Install-Software

Wewnątrz powyższego bloku:

  • param najpierw definiujemy blok parametrów za pomocą polecenia Parameter()
  • typ [string] przed nazwą parametru. Umieszczając typ parametru w nawiasach kwadratowych przed nazwą zmiennej parametru, rzutujemy wartość parametru na określony typ. Rzutowanie parametru na typ nie jest obowiązkowe, ale jest zalecane aby zminimalizować ryzyko wystąpienia błędu.
  • dodajemy parametr $Version - gdy uruchomimy funkcję Install-Software z parametrem Version i przekażesz jej numer wersji, powinniśmy otrzymać poniższy wynik:

Domyślnie parametry są opcjonalne.

Atrybuty parametrów

Atrybuty parametrów możemy kontrolować np. jeśli chcemy aby, przy wywoływaniu funkcji parametr był zawsze podawany, definiujemy go jako Mandatory (obowiązkowy).

function Install-MMSoftware { [CmdletBinding()] param( [Parameter(Mandatory)] [string]$Version ) Write-Host "Oprogramowanie w wersji $Version zainstalowane" }

Po ustawieniu atrybutu Mandatory wykonanie funkcji, do której nie został podany parametr zostanie zatrzymane dotąd, dopóki użytkownik nie wprowadzi parametru.

Aby wywołać funkcję z parametrem piszemy kod:

Install-Software -Version 2

Domyślne wartości parametrów

Możemy zdefiniować domyślną wartość parametru, jeśli np. często przekazujemy do funkcji taki sam parametr.

function Install-MMSoftware { [CmdletBinding()] param( [Parameter()] [string]$Version = 2 ) Write-Host "Oprogramowanie w wersji $Version zainstalowane" } Install-MMSoftware

Posiadanie parametru domyślnego nie uniemożliwia przekazania go. Przekazana wartość zastępuje wartość domyślną.

Walidacja parametrów

Dla parametrów funkcji możemy ustawić walidację, aby wymusić wprowadzanie prawidłowych wartości.

function Install-Software { param( [Parameter(Mandatory)] [ValidateSet('1','2')] [string]$Version, [Parameter(Mandatory, ValueFromPipeline)] [string]$ComputerName ) process { Write-Host "I installed software version $Version on $ComputerName." } } "1", "2", "3" | Install-Software -Version 1 # I installed software version 1 on host1. # I installed software version 1 on host2. # I installed software version 1 on host3. help Install-Software

W przykładzie jako parametry możemy podać tylko wartości 1 lub 2.

Wynik działania:

NAME Install-Software SYNTAX Install-Software [-Version] {1 | 2} [-ComputerName] <string> [<CommonParameters>] ALIASES None REMARKS None

Przygotowanie pliku pomocy dla własnej funkcji

help about_Comment_Based_Help

Zapoznaj się z skryptem 3_3_get-PowershellHelp.ps1 oraz 3_4_get-PowershellHelp.ps1_v2.ps1 w których pokazujemy tworzenie plików pomocy.

Zadania: Funkcje

Debugowanie skryptów w ISE

Aby debugować skrypt w ISE wykonujemy kolejno:

  • Ustawienie punktów przerwania – punkty przerwania to miejsca w kodzie, w których debugger ma się zatrzymać, dzięki czemu można sprawdzić bieżące stany zmiennych.

    Aby ustawić punkt przerwania, kliknij linię kodu, a następnie naciśnij klawisz F9. Linia zmienia kolor na czerwony. Jeśli wiersz nie zmieni koloru na czerwony, oznacza to, że albo nie zapisałeś wcześniej skryptu, albo wiersz nie zawiera kodu wykonywalnego.

  • Uruchomienie skryptu – skrypt będzie działał normalnie, ale po trafieniu w linię punktu przerwania PowerShell ISE zatrzymuje się. Bieżąca linia jest zaznaczona na żółto. Możesz teraz najechać kursorem na zmienne w kodzie, aby zobaczyć ich zawartość, lub wykonać dowolny kod w oknie interaktywnym, na przykład zrzucić zawartość zmiennej — a nawet ją zmienić.

  • Kontynuuj – aby kontynuować tylko następną instrukcję, naciśnij klawisz F10 lub F11. F10 wykonuje następną instrukcję w bieżącym zakresie. F11 wykonuje następną instrukcję, niezależnie od zakresu. Jeśli bieżący wiersz wykona funkcję i naciśniesz F10, cała funkcja zostanie wykonana. Jeśli naciśniesz F11, zostaniesz przeniesiony do pierwszego wiersza tej funkcji.

Moduły

Moduł to zbiór funkcji w pliku tekstowym z rozszerzeniem .psm1.

Instalacja modułu w systemie:

Install-Module PSWindowsUpdate #wyszukaj łatek Get-WUList

Komponenty modułów

Na moduł składa się:

  • folder spełniający rolę kontenera modułu. Folder modułu musi mieć taką samą nazwę jak moduł
  • plik tekstowy z rozszerzeniem .psm1, który zawiera kod modułu
  • manifest modułu w pliku z rozszerzeniem .psd1. Manifest jest plikiem opcjonalnym, który zawiera tablicę asocjacyjną (ang. hashtable) z elementami opisującymi metadane modułu. PowerShell posiada polecenie New-ModuleManifest, które umożliwia wygenerowanie szablonu dla nowego manifestu.

Domyślne lokalizacje modułów

Moduły domyślnie tworzone są w następujących lokalizacjach:

  • Moduły systemowe — prawie wszystkie moduły, które są domyślnie instalowane z powłoką PowerShell, znajdują się w katalogu C:\Windows\System32\WindowsPowerShell\1.0\Modules. Jest to lokalizacja przeznaczona tylko dla wewnętrznych modułów powłoki PowerShell.
  • Moduły wszystkich użytkowników — moduły są również przechowywane w folderze C:\Program Files\Windows PowerShell\Modules. Umieszczamy w nim dowolne moduły, które mają być dostępne dla wszystkich użytkowników korzystających z danego komputera.
  • Moduły bieżącego użytkownika — moduły przechowywane w folderze C:\Users\<NazwaKonta>\Documents\WindowsPowerShell\Modules. W tym folderze są wszystkie utworzone lub pobrane moduły, które są dostępne tylko dla bieżącego użytkownika.

Jeżeli folder modułu znajduje się w jednej z w/w lokalizacji, wtedy podczas importu, powłoka PowerShell automatycznie go znajdzie i zaimportuje.

Wyświetlanie modułów

Moduły zaimportowane czyli dostępne w bieżącej sesji możemy wyświetlić:

Get-Module
ModuleType Version Name ExportedCommands ---------- ------- ---- ---------------- Manifest 3.1.0.0 Microsoft.PowerShell.Management {Add-Computer, Add-Content,... Manifest 3.0.0.0 Microsoft.PowerShell.Security {ConvertFrom-SecureString, ... Manifest 3.1.0.0 Microsoft.PowerShell.Utility {Add-Member, Add-Type, Clea... Manifest 3.0.0.0 Microsoft.WSMan.Management {Connect-WSMan, Disable-WSM... Script 2.0.0 PSReadline {Get-PSReadLineKeyHandler, ...

Poszczególne wiersze wyników działania polecenia Get-Module opisują moduły, które zostały zaimportowane do bieżącej sesji. Wszystkie polecenia zdefiniowane w tych modułach są od razu dostępne po zaimportowaniu modułów.

W kolumnie ExportedCommands wyświetlone są polecenia zawarte w module, których możemy użyć w bieżącej sesji.

Aby zobaczyć moduły, które są zainstalowane, ale nie zostały jeszcze zaimportowane używamy parametru -ListAvailable.

Get-Module -ListAvailable
Directory: C:\Users\rav\Documents\WindowsPowerShell\Modules ModuleType Version Name ExportedCommands ---------- ------- ---- ---------------- Script 21.1.18256 SqlServer {Add-RoleMember, Add-SqlAva... Directory: C:\Program Files\WindowsPowerShell\Modules ModuleType Version Name ExportedCommands ---------- ------- ---- ---------------- Binary 2.7.0 DellBIOSProvider {Set-Dell1stBootdevice, Set... Script 0.0 Install_WW {sum2, fun2} Script 1.0.1 Microsoft.PowerShell.Operation.V... {Get-OperationValidation, I... Script 0.0 my_lib {sum, fun} Binary 1.0.0.1 PackageManagement {Find-Package, Get-Package,... Script 3.4.0 Pester {Describe, Context, It, Sho... Script 1.0.0.1 PowerShellGet {Install-Module, Find-Modul...

Właściwość ExportedCommands wyświetla listę wszystkich dostępnych poleceń, które są eksportowane z modułu.

Get-Module Microsoft.PowerShell.Management | Select-Object -ExpandProperty ExportedCommands Get-Command # zawartość wszystkich modułów Get-Command -Module PSReadline # tylko komndy z modułu PSReadline

Polecenie Get-Command – wyświetla wszystkie komandlety ze wszystkich modułów lub ze wskazanego modułu.

Zainstalowane moduły są umieszczane w katalogu C:\Program Files\WindowsPowerShell\Modules.

Galeria modułów

Galeria powłoki PowerShell (ang. The PowerShell Gallery https://www.powershellgallery.com/) to repozytorium modułów i skryptów powłoki PowerShell, z których mogą korzystać zarejestrowani użytkownicy.

Polecenie Find-Module umożliwia przeszukiwanie galerii powłoki PowerShell.

Find-Module -Name *VMware*

W przykładzie wyszukujemy w galerii moduły do zarządzania infrastrukturą zawierające w nazwie słowo "VMware".

Polecenie Find-Module nie pobiera modułów. Pokazuje jedynie, jakie moduły i skrypty są dostępne w galerii.

Przykład instalcja modułu dla bazy SQLite3:

Find-Module -Name *SQLite* # przeszukaj dostępne w galerii moduły Find-Module -Name PSSQLite | Install-Module # zainstaluj (pobierz z Intenetu) Import-Module PSSQLite # zaimportuj (załaduj do bieżącej sesji) Get-Command -Module PSSQLite | Measure-Object | Select-Object count Get-Command -Module PSSQLite # wylistuj dostępne polecenia

Przykład użycia poleceń z modułu PSSQLite:

Import-Module PSSQLite $Database = "c:\home\PowerShell\Names.SQLite" $Query = "CREATE TABLE NAMES ( Fullname VARCHAR(20) PRIMARY KEY, Surname TEXT, Givenname TEXT, Birthdate DATETIME)" #SQLite will create Names.SQLite for us Invoke-SqliteQuery -Query $Query -DataSource $Database # We have a database, and a table, let's view the table info Invoke-SqliteQuery -DataSource $Database -Query "PRAGMA table_info(NAMES)"

Importowanie modułu

Aby zaimportować moduł, który jest już zainstalowany, używamy polecenia Import-Module

Instalowanie modułu

Moduł instalujemy za pomocą polecenia Install-Module

Find-Module -Name VMware.PowerCLI | Install-Module

W przykładzie wyszukujemy i instalujemy moduł VMare.PowerCLI.

Aby odinstalować moduł używamy polecenia Uninstall-Module

Uninstall-Module -Name VMware.PowerCLI

Tworzenie modułu

Moduły możemy tworzyć w PowerShell ISE. Aby utworzyć moduł:

  • wpisujemy funkcje, które mają być w module
  • zapisujemy plik z rozszerzeniem .psm1 - w przykładzie tworzymy moduł o nazwie Module_MM.psm1.

Moduł umieszczamy w lokalizacji C:\Program Files\WindowsPowerShell\Modules

Nazwa katalogu, w którym zapisujemy moduł musi być taka sama jak nazwa modułu.

Utworzony moduł możemy zaimportować poleceniem Import-Module Module_MM.

Moduł zostanie zaimportowany i wykonany zostanie znajdujący się w nim skrypt.

Wyświetlamy listę modułów poleceniem Get-Module. Utworzony moduł znajduje się na liście.

Dodanie manifestu modułu

Zadania: Moduły

Dostęp do rejestru Windows

Wpisy w rejestrze Windows są zapisane w formie ścieżki do lokalizacji gdzie znajduje się lista z parami klucz-wartość.

Listowanie wpisów rejestru

Ścieżka: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion. Aby odczytać wpisy z tej ścieżki użyjemy polecenia: Get-Item.

Get-Item -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion

Wynik:

    Hive: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows


Name                Property
----                --------
CurrentVersion      ProgramFilesDir          : C:\Program Files
                    CommonFilesDir           : C:\Program Files\Common Files
                    ProgramFilesDir (x86)    : C:\Program Files (x86)
                    CommonFilesDir (x86)     : C:\Program Files (x86)\Common Files
                    CommonW6432Dir           : C:\Program Files\Common Files
                    DevicePath               : C:\Windows\inf
                    MediaPathUnexpanded      : C:\Windows\Media
                    ProgramFilesPath         : C:\Program Files
                    ProgramW6432Dir          : C:\Program Files
                    SM_ConfigureProgramsName : Set Program Access and Defaults
                    SM_GamesName             : Games

Same nazwy można wypisać:

Get-Item -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion | Select-Object -ExpandProperty Property

Wynik:

DevicePath
MediaPathUnexpanded
ProgramFilesDir
CommonFilesDir
ProductId

Aby poprawić czytelność możemy użyć Get-ItemProperty:

Get-ItemProperty -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion
PSPath              : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SO
                      FTWARE\Microsoft\Windows\CurrentVersion
PSParentPath        : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SO
                      FTWARE\Microsoft\Windows
PSChildName         : CurrentVersion
PSDrive             : HKLM
PSProvider          : Microsoft.PowerShell.Core\Registry
DevicePath          : C:\WINDOWS\inf
MediaPathUnexpanded : C:\WINDOWS\Media
ProgramFilesDir     : C:\Program Files
CommonFilesDir      : C:\Program Files\Common Files
ProductId           : 76487-338-1167776-22465
WallPaperDir        : C:\WINDOWS\Web\Wallpaper
MediaPath           : C:\WINDOWS\Media
ProgramFilesPath    : C:\Program Files
PF_AccessoriesName  : Accessories
(default)           :

Specjalne właściwości PowerShell mają prefiks "PS", na przykład: PSPath, PSParentPath, PSChildName i PSProvider.

Aby odwołać się do bieżącej lokalizacji można użyć notacji .

Można użyć Set-Location aby odwołać się najpierw do CurrentVersion określonej ścieżki.

Set-Location -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion

Alternatywnie użyć Set-Location:

Set-Location -Path hklm:\SOFTWARE\Microsoft\Windows\CurrentVersion

Po tym można użyć notacji . bez użycia pełnej ścieżki.

Get-ItemProperty -Path .
...
DevicePath          : C:\WINDOWS\inf
MediaPathUnexpanded : C:\WINDOWS\Media
ProgramFilesDir     : C:\Program Files
...

Adresy działają tak samo jak ścieżki na dysku, można użyć Get-ItemProperty -Path ..\Help i odwołać się do lokalizacji: HKLM:\SOFTWARE\Microsoft\Windows\Help.

Uzyskanie pojedynczego wpisu z rejestru

Jest kilka sposobów na odczytanie pojedynczej wartości.

Przykład odczytnia DevicePath z lokalizacji HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion.

Użyj Get-ItemProperty, ustaw parametery Path i Name.

Get-ItemProperty -Path HKLM:\Software\Microsoft\Windows\CurrentVersion -Name DevicePath
PSPath       : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\Software\
               Microsoft\Windows\CurrentVersion
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\Software\
               Microsoft\Windows
PSChildName  : CurrentVersion
PSDrive      : HKLM
PSProvider   : Microsoft.PowerShell.Core\Registry
DevicePath   : C:\WINDOWS\inf

Polecenie zwraca standardowe właściwości PowerShell oraz dodatkowo DevicePath.

Inny sposób to użycie polecenia Reg.exe:

reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion /v DevicePath

Wynik:

! REG.EXE VERSION 3.0

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion
    DevicePath  REG_EXPAND_SZ   %SystemRoot%\inf

Zapis do pojedynczego wpisu w rejestrze

W przykładzie poniżej:

  1. pobieramy wartość właściwości Path używając Get-ItemProperty
  2. dodajemy na końcu ;
  3. użyjemy Set-ItemProperty aby zapisać wartość do rejestru
$value = Get-ItemProperty -Path HKCU:\Environment -Name Path $newpath = $value.Path += ";C:\src\bin\" Set-ItemProperty -Path HKCU:\Environment -Name Path -Value $newpath

Set-ItemProperty ma parametry Filter, Include i Exclude, ale służą one tylko do filtrowania ścieżek, nie nazw właściwości.

Przykład, gdzie zmieniamy Path i usuwamy dopisek zrobiony w poprzednim przykładzie.

$value = Get-ItemProperty -Path HKCU:\Environment -Name Path $newpath = $value.Path.SubString(0, $value.Path.LastIndexOf(';')) reg add HKCU\Environment /v Path /d $newpath /f

Wynik:

The operation completed successfully.

Tworzenie nowych wpisów

Nowy spis dodamy przez New-ItemProperty. Dodamy wartość zmiennej PowerShell $PSHome, która zawiera ścieżkę instalcyjną PowerShell.

Dodajemy nowy wpis:

New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion -Name PowerShellPath -PropertyType String -Value $PSHome

Wynik zawiera informacje o nowym wpisie:

PSPath         : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion
PSParentPath   : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows
PSChildName    : CurrentVersion
PSDrive        : HKLM
PSProvider     : Microsoft.PowerShell.Core\Registry
PowerShellPath : C:\Program Files\Windows PowerShell\v1.0

Wartość PropertyType musi jedną w poniższej tabeli:

Typ właściwości Opis
Binary Dane binarne
DWord Liczba całkowita bez znaku (UInt32)
QWord Dane binarne o rozmiarze 8 bajtów
String Dowolny tekst
ExpandString Ciąg tekstowy ze zmienną środowiskową dynamicznie rozszerzany
MultiString Tekst wieloliniowy

Można dodać na raz kilka wpisów używając listę jako Path:

New-ItemProperty -Name PowerShellPath -PropertyType String -Value $PSHome ` -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion, ` HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion

Można nadpisać istniejący spis przełącznikiem Force do polecenia New-ItemProperty.

Zmiana nazwy

Aby zmienić wartość we wpisie użyj Rename-ItemProperty:

Rename-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion -Name PowerShellPath -NewName PSHome

Aby wyświetlić zmienioną nazwę dodamy paramtr PassThru.

Rename-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion -Name PowerShellPath -NewName PSHome -passthru

Usuwanie wpisów

Użyjemy Remove-ItemProperty:

Remove-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion -Name PSHome Remove-ItemProperty -Path HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion -Name PowerShellPath

Referencje

Zadania: Rejestr

Usługi zdalne

Usługi zdalne powłoki PowerShell (ang. PowerShell remoting) to mechanizm, który umożliwia użytkownikowi zdalne uruchamianie poleceń w sesji na jednym lub na wielu komputerach jednocześnie.

Sesja (PSSession) to środowisko, w którym PowerShell działa na komputerze zdalnym, na którym wykonywane są polecenia.

PowerShell stosuje protokół komunikacyjny WS-MAN (WebService for Management), technicznie to ruch typu http/https na portach 5985 / 5986. Microsoft zaimplementował to w usłudze WinRM. Dane pomiędzy komputerami przekazywane są w formie obiektów xml tj. obiekty są poddane deserializacji. Uwaga format jak przy wywołaniu Export-Clixml (obiekty mają właściwości, ale nie mają metod).

Możliwy jest inny protokół komunikacyjny SSH.

WinRm działa jako dyspozytor, może kierować ruch do wielu aplikacji. WinRM nasłuchuje na tzw. listener http. Wcześniej usługa Winrm musi mieć zarejestrowane tzw. Endpointy. Na podstawie przekazywanej nazwy punktu od strony klienta, WinRM kiereje ruch do odpowiedniego punktu końcowego.

Możemy w systemie mieć wiele punktów końcowych (w powershell'owym slangu nazywamy je konfiguracjami sesji), zapewniając określone funkcjonalności i uprawnienia. Będą to tzw. dodatkowe endpointy powershell, które pozwalają np. na wykonanie tylko paru poleceń dla wybranego użytkownika.

help ABOUT_REMOTE_REQUIREMENTS Help ABOUT_REMOTE_TROUBLESHOOTING

Połączenie zdalne - WinRM

Od wersji Windows Server 2012, system Windows Server jest instalowany z usługą Windows Remote Management (Zdalne zarządzanie systemem Windows, WinRM).

Usługa ta jest służy do obsługi zdalnych poleceń Windows PowerShell. Jest to mechanizm pracy zdalnej używany przez polecenia cmdlet CIM. Gdy tylko komputer Windows Server zostanie skonfigurowany i uruchomiony, można wykonywać do niego zdalne połączenie i uruchamiać polecenia lub otworzyć interaktywną konsolę Windows PowerShell.

Windows 10, jako system kliencki, domyślnie ma usługę WinRM wyłączoną. Dlatego na początek trzeba wykonać cmdlet, za pomocą którego skonfigurujemy mechanizm zdalny Windows PowerShell na maszynie klienckiej:

Enable-PSRemoting -Force

lub

Enable-PSRemoting -Force -SkipNetworkProfileCheck

Wynik wywołania:

PS C:\WINDOWS\system32> Enable-PSRemoting -Force -SkipNetworkProfileCheck Usługa WinRM już jest skonfigurowana w celu odbierania żądań na tym komputerze. Usługa WinRM została zaktualizowana na potrzeby zdalnego zarządzania. Wyjątek zapory dla usługi WinRM został włączony. WARNING: Waiting for service 'Zdalne zarządzanie systemem Windows (WS-Management) (winrm)' to stop...

Aby sprawdzić, czy możemy połączyć się z innym komputerem używamy polecenia Test-WsMan

Test-WsMan nazwa_komputera

Jeśli polecenie nie zadziała, musimy skonfigurować komputer, z którym chcemy nawiązywać połączenie.

Konfiguracja zdalnego połączenia

W środowisku domenowym w PowerShell na komputerze łączącym się i na docelowym uruchamiamy polecenie Enable-PSRemoting -Force.

-Force wpisujemy, jeśli chcemy uruchomić polecenie z domyślną konfiguracją i nie chcemy czytać i akceptować pojawiających się komunikatów podczas wykonywania się polecenia Enable-PSRemoting.

Polecenie to:

  • uruchamia lub restartuje usługę WinRM.
  • ustawia tryb uruchamiania usługi WinRM na Automatic (Automatyczny)
  • tworzy odbiornik akceptujący żądania z dowolnego adresu IP.
  • włącza wyjątek przychodzący zapory dla ruchu WSMAN
  • tworzy docelowe odbiorniki o nazwie Microsoft.powershell, Microsoft.powershell.workflow
  • tworzy docelowy odbiornik o nazwie Microsoft.powershell32 na komputerach 64-bitowych
  • włącza wszystkie konfiguracje sesji.
  • modyfikuje deskryptor zabezpieczeń wszystkich konfiguracji sesji w celu umożliwienia dostępu zdalnego
  • restartuje usługę WinRM w celu zastosowania zmian.

W środowisku bez domeny, na komputerze z którego się łączymy, musimy dodatkowo zdefiniować zaufane komputery – gwiazdka * oznacza "wszystkie". Zamiast gwiazdki możemy podać nazwę zaufanego hosta lub wymienić kilka po przecinku.

Aby to zrobić wpisujemy polecenie:

Set-Item wsman:\localhost\client\trustedhosts *

Potwierdzamy polecenie wpisując Y i naciskamy Enter.

Następnie testujemy połączenie. Jeśli nie zadziała, restartujemy usługę WinRM na komputerze z którego chcemy się łączyć i komputerze zdalnym poleceniem Restart-Service WinRM.

Jeśli połączenie zadziała, powinniśmy zobaczyć następujący komunikat:

Tworzenie zdalnej sesji Windows PowerShell

Aby skonfigurować pojedynczy komputer zdalny otwieramy zdalną sesję Windows PowerShell za pomocą polecenia Enter-PSSession. Tworzy ono interaktywną sesję zdalną Windows PowerShell z maszyną docelową. W przykładzie łączymy się z komputerem o nazwie Mambo16, na którym użytkownikiem jest Mambo12.

Enter-PSSession -ComputerName Mambo16 -Credential Mambo12

W oknie dialogowym, które się pojawi podajemy hasło.

Po połączeniu się możemy wykonywać polecenia na komputerze o nazwie Mambo16

Za pomocą polecenia Exit-PSSession możemy sesję zamknąć.

Sesje stałe

Jeśli potrzebujemy tworzyć wiele połączeń z systemem zdalnym, powinniśmy użyć polecenia New-PSSession do utworzenia sesji zdalnej.

Polecenie New-PSSession umożliwia zapisanie sesji zdalnej w zmiennej, pozwalając na wchodzenie i wychodzenie z sesji bez jej tworzenia i niszczenia.

W przykładzie:

  • tworzymy nową sesję dla komputera o nazwie Mambo16 oraz dla komputera o nazwie Mambo2 za pomocą poleceń New-PSSession

    New-PSSession -ComputerName Mambo16 -Credential Mambo12 New-PSSession -ComputerName Mambo2 -Credential Mambo12
  • przeglądamy listę aktywnych sesji zdalnych za pomocą polecenia Get-PSSession

  • podłączamy się do sesji na komputerze o nazwie Mambo16 używając id sesji i polecenia Enter-PSSession i wyświetlamy listę drukarek poleceniem Get-Printer

    Enter-PSSession -id 2 Get-Printer
  • opuszczamy sesję na na komputerze Mambo16 za pomocą polecenia Exit_PSSession

Za pomocą polecenia Remove-PSSession -id 2 możemy opuścić sesję o konkretnym ID.

Za każdym razem, gdy polecenie New-PSSession tworzy nową sesję, istnieje ona zarówno na serwerze zdalnym, jak i na komputerze lokalnym. Możemy utworzyć wiele sesji na wielu serwerach jednocześnie. Nieużywane sesje czyścimy za pomocą polecenia Remove-PSSession, które nawiązuje połączenie z komputerem zdalnym, zamyka sesję i usuwa lokalny uchwyt sesji PSSession, jeśli uchwyt został utworzony.

Istniejące sesje możemy rozłączyć za pomocą polecenia Disconnect-PSSession.

Uruchamianie pojedynczego polecenia PowerShell

Komenda Invoke-Command umożliwia zdalne wykonywanie poleceń. Invoke-command tworzy nietrwałe sesje. Poszczególne komendy nie będą mogły przekazywać sobie danych. Jeśli jedna komenda przypisze wartość do zmiennej, kolejne Invoke-Comamnd nie pozwoli nam tej zmiennej rozpoznać.

Invoke-Command najczęściej wykorzystujemy do jednorazowych czynności. Składnia:

Invoke-Command -ComputerName podajemy_nazwe_komputera -scriptblock {wpisujemy_polecenie} -Credential Podajemy_nazwe_uzytkownika

Przełączniki uzupełniane w poleceniu:

  • ComputerName – podajemy nazwę zdalnego komputera, z którym chcemy się połączyć
  • Scriptblock – wpisujemy komendę, którą chcemy wykonać na zdalnym komputerze
  • Credential – podajemy nazwę użytkownika na zdalnym komputerze

Uwierzytelnianie powłoki PowerShell

Domyślnie, jeżeli komputer lokalny i zdalny znajdują się w tej samej domenie i oba mają włączone usługi zdalne powłoki PowerShell, nie ma potrzeby jawnego uwierzytelniania. Ale jeżeli tak nie jest, zdalna sesja musi zostać jakoś uwierzytelniona.

Domena w kontekście sieci:

  • odnosi się do dowolnej grupy użytkowników, stacji roboczych, urządzeń, drukarek, komputerów i serwerów baz danych, które udostępniają różne typy danych za pośrednictwem zasobów sieciowych.
  • posiada kontroler domeny, który zarządza funkcjami domeny i bezpieczeństwem sieci
  • jest używana do zarządzania wszystkimi funkcjami użytkownika, w tym uwierzytelnianiem i dostępem do nazwy użytkownika/hasła oraz współdzielonych zasobów systemowych
  • służy do przypisywania określonych uprawnień do zasobów, takich jak konta użytkowników

Najczęściej używane sposoby uwierzytelniania na komputerach zdalnych wykorzystywane przez powłokę PowerShell:

  • Kerberos – używany w domenie Active Directory
  • CredSSP – uwierzytelnianie CredSSP nie potrzebuje Active Directory

W środowisku Active Directory usługi zdalne powłoki PowerShell korzystają z protokołu Kerberos, za pomocą którego Active Directory przeprowadza wszystkie uwierzytelnienia. Powłoka PowerShell do uwierzytelnienia na komputerze zdalnym używa konta, na które jesteśmy zalogowani lokalnie.

Problem drugiego przeskoku

Problem drugiego przeskoku (ang. double hop problem) pojawia się, gdy uruchamiamy kod w sesji zdalnej, a następnie próbujemy uzyskać dostęp do innych zasobów zdalnych z poziomu tej sesji.

Jeżeli w swojej sieci mamy kontroler domeny o nazwie DC i chcemy wyświetlić pliki znajdujące się w jego katalogu głównym C:\ przy użyciu udziału administracyjnego C$, możemy to zrobić zdalnie z poziomu komputera lokalnego.

Get-ChildItem -Path '\\dc\c$'

Problem pojawia się, gdy utworzymy sesję PSSession do innego komputera i spróbujemy ponownie uruchomić to samo polecenie.

Enter-PSSession -ComputerName Mambo16 Get-ChildItem -Path '\\dc\c$'

Pojawia się wówczas odmowa dostępu (ang. Access denied).

Dzieje się tak, gdyż podczas korzystania z domyślnego uwierzytelniania Kerberos, usługi zdalne powłoki PowerShell nie przekazują tych poświadczeń do innych zasobów sieciowych. PowerShell nie wykonuje przeskoku do kolejnego zasobu sieciowego.

Problem możemy ominąć korzystając z uwierzytelnienia CredSSP. Korzystanie z CredSSP może być problematyczne w kontekście bezpieczeństwa. Poświadczenia przekazane do pierwszego komputera są automatycznie używane dla wszystkich połączeń z tego komputera. Oznacza to, że jeżeli bezpieczeństwo tego komputera zostanie naruszone, to przejęte poświadczenia mogą zostać użyte do łączenia się z innymi komputerami w sieci.

Przed zastosowaniem CredSSP powinniśmy go włączyć zarówno po stronie klienta, jak i na serwerze za pomocą polecenia Enable-WsManCredSSP wykonanego w sesji powłoki PowerShell z poziomu administratora. To polecenie posiada parametr Role, który pozwala określić, czy uwierzytelnianie CredSSP jest włączane po stronie klienta, czy po stronie serwera. Najpierw włączamy CredSSP po stronie klienta.

Enable-WSManCredSSP -Role Client -DelegateComputer Mambo16

Po włączeniu uwierzytelniania CredSSP na kliencie musimy zrobić to samo na serwerze

Invoke-Command -ComputerName Server1 -ScriptBlock { Enable-WSManCredSSP -Role Server }
#wyświetl zarejestrowane endpointy Get-PSSessionConfiguration #PsRemoting – logowanie lokalne jako konto localadm, sesja 1-do-1 $cred = Get-Credential -Message "podaj hasło" Enter-PSSession -ComputerName localhost -Credential $cred #Nowa sesja 1-do-1 wielokrotnego użtrku New-PSSession -ComputerName 127.0.0.1 -Credential $cred #Sesja 1-do-wielu Invoke-command -Session (Get-PSSession -ComputerName 127.0.0.1) #rozłącz sesje Disconnect-psssesion #Deserializacja, obiekt bez metod Invoke-Command -ComputerName localhost -Command {get-service} -Credential $cred | Get-Member #jak sprawdzić parametry sesji Parametry sesji: ls WSMan:\localhost\shell ls WSMan:\localhost\Service\

Niejawna komunikacja zdalna. PowerShell pozwala zaimportować do lokalnej sesji moduł z innej sesji. Np. możemy połączyć się do kontrolera domeny, zaimportować moduł, a następnie zaimportować go na lokalnym komputerze.

$session = new-pssession -comp server-r2 invoke-command -command { import-module activedirectory } -session $session import-pssession -session $session -module activedirectory -prefix rem

W usługach domenowych istnieje problem 2 hopa.

Tworzenie niestandardowych punktów końcowych.

Możemy zdefiniować własną powłokę z ograniczoną listą poleceń, uruchamianą w kontekście wskazanego konta i udostępnioną wybranej grupie w AD. Dla wskazanej grupy musimy ustawić prawo Read i Execute.

#Konfiguracja nowego pliku dla endpointa New-PSSessionConfigurationFile -Path C:\WorkArea\Avendi\PSSC\AzureAd_1.pssc - ModulesToImport AzureAd -SessionType RestrictedRemoteServer -CompanyName "Avendi_1" -Author "Maciej Szuba" -PowerShellVersion '3.0' #rejestracja w usłudze WinRM Register-PSSessionConfiguration -Path C:\WorkArea\Avendi\PSSC\AzureAd_1.pssc - RunAsCredential localadm -ShowSecurityDescriptorUI -Name pomoc #Łaczymy sie Enter-PSSession -Credential $cred -ConfigurationName pomoc -ComputerName localhost

PSProvider – dostawcy / adaptery do różnych magazynów danych.

Zarejestrowany dostawca - to taki "adapter", który daje dostęp do jakiegoś magazyny danych emulowanego jako system plików – dysk.

Get-PSProvider Get-PSDrive #Dostępne polecenia typu *item* Get-Command -Name *item* -CommandType Cmdlet

Filtrowanie

Za pomocą polecenia cmdlet możemy tworzyć nowe obiekty programu PowerShell zawierające właściwości wybrane z obiektów. Do ich utworzenia używamy polecenia Select-Object.

Nowy obiekt, który zawiera tylko właściwości Name i FreeSpace Win32_LogicalDisk WMI

Get-CimInstance -Class Win32_LogicalDisk | Select-Object -Property Name,FreeSpace

Za pomocą Select-Object możemy tworzyć właściwości obliczeniowe np. wyświetlić wolne miejsce na dysku w gigabajtach, a nie w bajtach.

Get-CimInstance -Class Win32_LogicalDisk | Select-Object -Property Name, @{ label='FreeSpace' expression={($_.FreeSpace/1GB).ToString('F2')} }

W PowerShell możemy filtrować obiekty w potoku za pomocą polecenia Where-Object.

Polecenie Where-Object używa specjalnej zmiennej $_ aby odwołać się do obiektu w potoku.

W przykładzie mamy listę cyfr i zwracamy z tej listy tylko cyfry mniejsze od 3:

1,2,3,4 | Where-Object {$_ -lt 3}

Wybieramy tylko uruchomione sterowniki systemowe:

Get-CimInstance -Class Win32_SystemDriver | Where-Object {$_.State -eq 'Running'}

Wybieramy tylko sterowniki systemowe, które są uruchamiane automatycznie:

Get-CimInstance -Class Win32_SystemDriver | Where-Object {$_.State -eq "Running"} | Where-Object {$_.StartMode -eq "Auto"}

Wyświetlamy sterowniki systemowe, które są uruchamiane manualnie i wyświetlamy tylko nazwy Name i DisplayName:

Get-CimInstance -Class Win32_SystemDriver | Where-Object {($_.State -eq 'Running') -and ($_.StartMode -eq 'Manual')} | Format-Table -Property Name,DisplayName

Pliki foldery

Tworzenie plików i katalogów

Utworzenie nowego katalogu

New-Item -Path 'C:\temp\Test Folder' -ItemType Directory

Wynik:

Directory: C:\temp

Mode                LastWriteTime     Length Name                                               
----                -------------     ------ ----                                               
d----          4/3/2018   7:06 PM            Test Folder

Tworzenie pliku:

New-Item -Path 'C:\temp\Test Folder\Test File.txt' -ItemType File

W rezultacie powstaje plik C:\temp\Test Folder\Test File.txt o zerowym rozmiarze.

Możemy utworzyć plik z zawartością zmiennej:

$text = 'Hello World!' | Out-File -FilePath C:\data\text.txt

Jeśli plik już istniał, należy dodać przełącznik -Force który wymusi nadpisanie starej zawartości.

Zapis wyników do pliku csv:

Get-Service | Where-Object {$_.Name -like '*time*'} | select Name, ServiceName, Status | Export-Csv -Path c:\tmp\services.csv

Wynik:

#TYPE Selected.System.ServiceProcess.ServiceController
"Name","ServiceName","Status"
"W32Time","W32Time","Stopped"

Kopiowanie plików i katalogów

Aby zrobić kopię rekursywną katalogu:

Copy-Item 'C:\temp\Test Folder' 'C:\temp\Test Folder1'
Copy-Item 'C:\temp\Test Folder' -Destination 'C:\temp\Test Folder1'

Przekopiowanie jednego pliku:

Copy-Item 'C:\temp\Test Folder\Test File.txt' 'C:\temp\Test Folder1\Test File1.txt'

Przekopiowanie wszystkich tekstowych (*.txt) plików do innego katalogu:

Copy-Item -Filter *.txt -Path 'C:\temp\Test Folder' -Destination 'C:\temp\Test Folder1' -Recurse

Usunięcie katalogu (jeśli nie jest pusty, pojawi się pytanie o potwierdzenie):

Remove-Item 'C:\temp\Test Folder1'

Usunięcie katalogu i jego zawartości bez pytania o potwierdzenie:

Remove-Item 'C:\temp\Test Folder' -Recurse

Przenoszenie katalogów i plików

Przeniesienie pliku lub katalogu do nowej lokalizacji:

Move-Item C:\temp\Test\Test.txt C:\temp\Test1 Move-Item C:\temp\Test C:\temp\Test1

Wyświetl zawartość pliku:

Get-Content C:\temp\Test\test.txt

Sprawdzenie, czy katalog lub plik istnieje:

Test-Path C:\temp\test True
Test-Path C:\temp\test\test.txt True

Wyświetlanie zawartość katalogu

Get-ChildItem -Force C:\temp\test Get-ChildItem -Force C:\temp\test -Recurse
#Sprawdz czy plik istnieje Test-Path C:\WorkArea\ #podziel ścieżkę i wyodrębnij tylko nazwę pliku split-Path C:\WorkArea\kurs_PowerShell\Home.zip -Leaf #Zmien extension dla pliku Get-ChildItem C:\Home\PowerShell\reports *.txt | Rename-Item -NewName {$_.BaseName + "- report.txt"} -PassThru | Select-Object -First 5 -Wait

Zadania: Pliki i foldery

Referencje

Pliki csv

Pliki csv to plik tekstowy z określoną strukturą.

Zawiera wiersze i kolumny (jak tabela SQL). Pierwszy wiersz często zawiera nazwy kolumn.

Przykładowy plik w formacie csv:

Computername,IPaddress,Office,Owner computer1,192.168.0.1,London,JoeSmith computer2,192.168.0.2,London,BobJones computer3,192.168.0.3,Sydney,JohnSutton computer4,192.168.0.4,Warsaw,DavidSouth computer5,192.168.0.5,Sydney,RussellSmith computer6,192.168.0.6,Warsaw,RussellSmith

Odczyt pliku csv możliwy jest poleceniem Get-Content:

cd r:\home\pliki_do_zadan\csv $a = Get-Content -Path ComputersUsers.csv $a.GetType() # tablica linii (stringów) $b = Get-Content -Path ComputersUsers.csv -Raw $b.GetType() # jeden duży string Get-Content -Path ComputersUsers.csv -Raw | Get-Member

Aby rozkodować strukturę csv wykorzystamy Import-Csv:

$c = Import-Csv -Path ComputersUsers.csv $c.GetType() # Object[] $c | Get-Member

Wynik:

Name MemberType Definition ---- ---------- ---------- Equals Method bool Equals(System.Object obj) GetHashCode Method int GetHashCode() GetType Method type GetType() ToString Method string ToString() Computername NoteProperty string Computername=computer1 IPaddress NoteProperty string IPaddress=192.168.0.1 Office NoteProperty string Office=London Owner NoteProperty string Owner=JoeSmith

Wybranie tylko pierwszego wiersza:

$firstCsvRow = Import-Csv -Path ./ComputersUsers.csv | Select-Object -First 1 $firstCsvRow

Wynik:

Computername IPaddress Office Owner ------------ --------- ------ ----- computer1 192.168.0.1 London JoeSmith

Wybranie określonej kolumny:

$firstCsvRow | Select-Object -ExpandProperty 'Office' London

Uzupełnienie nagłówka w pliku csv

Plik ComputersUsersNoHeader.csv:

computer1,192.168.0.1,London,JoeSmith computer2,192.168.0.2,London,BobJones computer3,192.168.0.3,Sydney,JohnSutton computer4,192.168.0.4,Warsaw,DavidSouth computer5,192.168.0.5,Sydney,RussellSmith computer6,192.168.0.6,Warsaw,RussellSmith

Taki plik możemy wczytać dostarczając własne nazwy kolumn:

Import-Csv -Path ./ComputersUsersNoHeader.csv -Header 'Nazwa', 'IPAddress','Dział','Kierownik'

Wynik:

Nazwa IPAddress Dział Kierownik ----- --------- ----- --------- computer1 192.168.0.1 London JoeSmith computer2 192.168.0.2 London BobJones computer3 192.168.0.3 Sydney JohnSutton computer4 192.168.0.4 Warsaw DavidSouth computer5 192.168.0.5 Sydney RussellSmith computer6 192.168.0.6 Warsaw RussellSmith

Określenie separatora

Polecenie Import-Csv przyjmuje że separator pola w csv to przecinek. Jeśli nasz plik csv ma jako separatory średniki, możemy to określić parametrem -Delimiter:

$c = Import-Csv -Path ./ComputersUsersNewDelimeter.csv -Delimiter ';' $c

Filtrowanie wierszy

$c = Import-Csv -Path ComputersUsers.csv | Where-Object { $_.'Office' -eq 'Warsaw' } $c

Wynik:

Computername IPaddress Office Owner ------------ --------- ------ ----- computer4 192.168.0.4 Warsaw DavidSouth computer6 192.168.0.6 Warsaw RussellSmith

Tworzenie plików csv

Za pomocą polecenia Export-Csv możemy tworzyć pliki csv:

Get-Process | Select-Object -Property Name,Company,Description | Export-Csv -Path Procesy.csv -NoTypeInformation

Wynik:

"Name","Company","Description" "Dropbox","Dropbox, Inc.","Dropbox" "dwm",, "explorer","Microsoft Corporation","Windows Explorer" "firefox","Mozilla Corporation","Firefox" ...

Zadania: Pliki csv