Spis treści
- Co to jest PowerShell?
- Instalacja PowerShell
- Konsola PowerShell
- PowerShell ISE
- Instalacja Visual Studio Code
- Instalacja Windows Terminal
- Aliasy poleceń (komend)
- System pomocy
- Zmienne
- Typy danych
- Obiekty
- Tablica
Array - Kolekcja
ArrayList - Kolekcja
Hashtable - Operatory
- Polecenia cmdlet
- Parametry poleceń
- Obiekty
- Łączenie poleceń - potoki
- Tworzenie skryptów
- Instrukcje warunkowe
- Pętle
- Obsługa błędów
- Funkcje
- Debugowanie skryptów w ISE
- Moduły
- Dostęp do rejestru Windows
- Usługi zdalne
- Pliki foldery
- Pliki csv
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,sortiSort)
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 -alAplikacje 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:
- https://code.visualstudio.com/docs/languages/powershell
- https://www.techthoughts.info/getting-setup-powershell-development/
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:– globalnylocal:– lokalny (aktualny i potomne)private:– prywatny (tylko aktualny)script:– zakres skrytpuusing:– uzyskuje dostęp do innego zakresu w czasie użycia cmdlet jak:Start-JoblubInvoke-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 parametruProperty(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-Servicepozwala 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:\Userswchodzimy do katalogu Users na dysku C:\
- np. poleceniem
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. poleceniedir 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ówGet-Service- wyświetlenie listy wszystkich usług WindowsGet-Date- sprawdzanie bieżącej daty lub czasu np.Get-Date -DisplayHint TimeGet-Printer- wyświetla listę zainstalowanych drukarekGet-Content- wyświetla zawartość wskazanego plikuExport-Csv- zapisz do pliku na dyskuGet-Service | Export-Csv -Path c:/service.csvImport-Csv- wczytaj plik csv z dyskuImport-Csv C:\service.csvOut-String- tworzy surowy tekst z danych wejściowychGet-Service | Out-String # generuje wartość String Get-Service | Out-String -Stream # generuje wartość Object[] Get-Service | Out-String -Stream | Select-String -Pattern stopOut-File- tworzy i zapisuje surowy tekst do pliku na dysku (domyślne kodowanie UTF-16LE)Get-Service | Out-File c:\services.txt -Encoding utf8Start-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-Hostlubclear– czyści konsolęShow-Command– otwiera okno, w którym po nazwie można znaleźć potrzebne polecenieGet-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-Commandmoż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 siecioweGet-ChildItem– wyświetlenie zawartości kataloguGet-Command– wyświetla listę poleceń wbudowanych w PowerShellGet-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-LogNamewskazujemy, 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 operacjeGet-Counter– pobiera dane licznika wydajności z komputerów lokalnych i zdalnychGet-History– wyświetla historię poleceńGet-WinEvent– pobiera zdarzenia z dzienników zdarzeń i plików dziennika śledzenia zdarzeń na komputerach lokalnych i zdalnychOut-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.
Tutaj usłudzeGet-Service spoolerGet-Serviceprzekazujemy parametrspoolerjako pierwszy parametr. - nazwę – przekazując parametr poprzedzony jego nazwą np.
Tutaj usłudzeGet-Service -Name spoolerGet-Serviceprzekazujemy parametrspoolerjako 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
-Includeumożliwia wyświetlenie tylko wybranych elementów - tych, które zostały w nim wskazane. - Parametr
-Excludeumoż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-Processzwraca listę obiektów typu:System.Diagnostics.ProcessWhere-Objectfiltruje listę, zostawia tylko obiekty o właściwościProcessName="conhost"Select-Objectwybiera tylko właściwośćHandles, w wyniku dostajemy listę wartości typuSystem.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-Servicezwraca obiekt typuSystem.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 minimumLastWriteTime– 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.
- https://www.netspi.com/blog/technical/network-penetration-testing/15-ways-to-bypass-the-powershell-execution-policy/
- https://stackoverflow.com/questions/27753917/how-do-you-successfully-change-execution-policy-and-enable-execution-of-powershe
- https://bestestredteam.com/2019/01/27/powershell-execution-policy-bypass/
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
Ifw przykładzie 1 sprawdzamy, czy wartość 2 jest większa od wartości ze zmiennej$value - w instrukcji
Ifw 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
Ifnie został spełniony - w przykładzie 2 wyświetlony jest tekst "Kod wykonany" oraz tekst
"Wartość jest ok", gdyż warunek w instrukcji
Ifzostał 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
- listujemy wszystkie wartości oddzielając je przecinkami
-
po wyrażeniu
Doumieszczamy 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
Whilez 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 kluczowymDootwieramy 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
Foreachdo 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
$filePathprzypisujemy ścieżkę dostępu do pliku o nazwie "dysks.txt" - w bloku
trywpisujemy polecenieGet-Content, za pomocą którego chcemy wyświetlić zawartość pliku "dysks.txt" - w bloku
catchwpisujemy polecenieWrite-Host, za pomocą którego wyświetlamy tekst "Wystąpił błąd!", jeśli w blokutrypojawi się błąd - w bloku
finallywpisujemy polecenieGet-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-Hostzwraca np. wersję programu jakim się łączymy do PowerShell - polecenie
Write-Hostwyś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:
paramnajpierw definiujemy blok parametrów za pomocą poleceniaParameter()- 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
- https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/new-modulemanifest?view=powershell-7.2
- https://learn.microsoft.com/en-us/powershell/scripting/developer/module/how-to-write-a-powershell-module-manifest?view=powershell-7.2
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:
- pobieramy wartość właściwości Path używając
Get-ItemProperty - dodajemy na końcu
; - użyjemy
Set-ItemPropertyaby 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-ItemPropertyma 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.
- https://learn.microsoft.com/en-us/powershell/scripting/learn/remoting/ssh-remoting-in-powershell-core?view=powershell-7.2
- https://4sysops.com/archives/install-powershell-remoting-over-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-PSSessionNew-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-PSSessioni wyświetlamy listę drukarek poleceniemGet-PrinterEnter-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
- https://www.tutorialspoint.com/powershell/powershell_files_folders.htm
- https://blog.netwrix.com/2018/05/17/powershell-file-management/
- https://community.idera.com/database-tools/powershell/powertips/b/ebookv2/posts/chapter-15-working-with-the-file-system
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