Posted in: Základy PowerShellu

Základní zabezpečení PowerShellu

Zabezpečení Powershellu začíná u zabezpečení operačního systému. Powershell je opravdu dvousečnou zbraní (nejlepším hackerským nástrojem i nejlepším přítelem obránců a správců), nicméně jsou určité postupy, které reálně snižují potenciální rizika spojená s přítomností PowerShellu. Nežli si dále povíme něco o zabezpečení PowerShellu jako takového, pojďme se podávat na základy. Doporučené body pro bezpečnou práci:

  1. Nepracuji pod účtem s admin oprávněním
  2. Nezpouštím pozornost z odemčeného PC
  3. Pravidleně instaluji bezpečnostní aktualizace
  4. Nespouštím skripty z internetu, které jsem celé nezkontroloval a nerozumím jim na 100%
  5. Moduly a další SW instaluji vždy z důvěryhodných zdrojů (oficiální stažení z webu vydavatele, ověření kontrolních součtů a vše pouze legálně)
  6. Všechny úlohy spouštím s minimálním nutným oprávněním
  7. Vždy mám na systému aktivní Firewall a zabezpečení
  8. Využívám komplexní hesla
  9. Dodržuji všechny bezpečnostní doporučení výrobce OS i jednotlivých aplikací
  10. Navštěvuji jen důvěryhodné weby a nic nedávám do výjimek bezpečnostních SW
  11. PowerShellu nedávám oprávnění administrátora, pokud není nezbytné
  12. S právy admina nespouštím skripty z internetu

Dalším doporučením je, aby práce vždy probíhala v aktuální verzi PowerShellu, verze 5.1 není problémem, pokud nechybí bezpečnostní aktualizace. Starší verze PowerShellu by měly být z PC odebrány, a pokud je potřebuje nějaký SW, mělo by být jejich spouštění logováno a omezeno na daný SW např. pomocí Applocker.

Execution Policy

V PowerShellu od verze 3 najdeme tzv. Execution Policy, což je nastavení, které říká, jaké skripty je povoleno spouštět. Jde o první obrannou linii PowerShellu. Ve výchozím stavu je na Windows Serveru hodnota RemoteSigned, na systémech Windows 10 je výchozí hodnotou Restricted. Co které nastavení znamená?

  • AllSigned Vyžaduje, aby všechny skripty a konfigurační soubory byly podepsány důvěryhodným vydavatelem, včetně skriptů napsaných v místním počítači.
  • Bypass Spustí jakýkoliv skript bez varování a výzev.
  • Default Nastaví na Windows serveru RemoteSigned a na Windows Restricted
  • RemoteSigned Všechny skripty a konfigurační soubory stažené z internetu musí být podepsány důvěryhodným vydavatelem.
  • Restricted Nenačte konfigurační soubory a nespustí skripty.
  • Undefined Pro obor nejsou nastaveny žádné zásady provádění. Odebere přiřazenou zásadu provádění z oboru, který není nastaven zásadami skupiny. Pokud je zásada provádění ve všech oborech Nedefinovaná, je účinná politika Restricted
  • Unrestricted Počínaje PowerShell 6.0 se jedná o výchozí zásadu provádění pro počítače, které nejsou Windows, a nelze ji změnit. Načte všechny konfigurační soubory a spustí všechny skripty. Pokud spustíte nepodepsaný skript, který byl stažen z internetu, budete před spuštěním vyzváni k povolení.

Jak zjistím aktuálně nastavenou politiku ve svém PowerShelu? Odpovědí je příkaz: 

Get-ExecutionPolicy -List

Jak nastavím Execution policy? Odpovědí je příkaz: 

Set-ExecutionPolicy

Execution policy jde nastavovat granuárně na různé úrovně. Pokud spustíme příkaz Set-ExecutionPolicy nastavujeme pravidla pouze pro daný proces PowerShellu. Pro nastavení pravidel například pro uživatele, počítač, nebo všechny uživatele složí přepínač: -Scope

Pro nastavení pravidel máme následující oblasti:

  • MachinePolicy Pomocí zásad skupiny aplikuje nastavení na všechny uživatele daného PC.
  • UserPolicy Nastavení platí lokálně pro daného uživatele.
  • Process Nastavení platí pouze pro dané okno PowerShellu.
  • CurrentUser Nastavení platí pouze pro daného uživatele (může s ním cestovat)
  • LocalMachine Mění výchozí nastavení pro všechny uživatele na daném PC.

Pokud nechcete, aby se v PowerShellu objevila výzva pro potvrzení nastavení použijte přepínač: -Force Pokud chci nastavit, že v aktuálně spuštěné instanci PowerShellu spustím podepsaný skript, využiji příklad níže.

Set-ExecutionPolicy AllSigned -Scope Process -Force

Obcházení Execution Policy

Obejít Execution Policy není nic těžkého a nejsou na to zapotřebí žádná oprávnění, člověk může být klidně uživatelem typu host. Níže si popíšeme 3 nejběžnější způsoby obcházení:

  1. Příkaz Set-ExecutionPolicy, kterým nastavím policy na požadovanou hodnotu (nelze provést uvnitř skriptu)
  2. V Průzkumníku kliknout na soubor skriptu pravým tlačítkem myši a zvolit „Run with PowerShell“
  3. Spustit si PowerShell ISE, skript v něm otevřít, celý označit pomocí CTRL+A a zvolit RUN SELECTION

Jak je vidět, tak Execution policy jsou pouze nástrojem, který má zabránit chybám z nepozornosti a nechtěnému spuštění kódu, nikoliv reálnou bezpečnostní technologií.

Constrained Language mode

Jak již bylo zmíněno PowerShell stojí na .NET Frameworku a z toho plyne, že umí volat .NET příkazy. Tato zkutečnost je podstatnou, protože dokáže zjednodušit některé úkony správy, ale zároveň je volání .NET příkazů alfou a omegou většiny škodlivých kódů v PowerShellu. Pro hackery je často samotný PowerShell skvělý pomocník, ale protože je určen pro jiné odvětví, je zároveň limitujícím faktorem útoku. Právě technologie Language mode, má za úkol omezit volání .NET příkazů, čímž eliminuje spouštění řady generických skriptů, které hackeři užívají.

Nastavení

Obrana proti školdivému kódu v PowerShellu je poměrně jednoduchá, stačí užívat Constrained Language mode, který značně omezí možnosti, které útočník má. Toto nastavení umožňuje zakázat volání .NET příkazů, a nastavit i další omezení omezení na vlastní PowerShell.

Zjištění jazykového režimu provedeme příkazem:

$ExecutionContext.SessionState.LanguageMode

Základní nastavení do omezeného režimu provedeme příkazem:

$ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage"

Pokud toto nastavení provádíme příkazy, pak není možné jej z omezeného režimu vrátit zpět na plný režim v rámci stejného okna PowerShellu. Stejně jako u Execution policy zde nejsou zapotřebí žádná správcovská práva. Krom omezeného jazykového režimu existují i další, pojďme se tedy podívat na úplný výčet.

  • Full Language – Režim jazyka FullLanguage umožňuje všechny jazykové prvky v relaci. FullLanguage je výchozí jazykový režim
  • Restricted Language – V jazykovém režimu RestrictedLanguage mohou uživatelé používat příkazy (rutiny, funkce, příkazy CIM a pracovní postupy), ale není dovoleno používat bloky skriptů. Jsou omezeny i proměnné a operátory. Bližší informace: Get-Help about_Language_Modes
  • No Language – V jazykovém režimu NoLanguage mohou uživatelé spouštět příkazy, ale nemohou používat žádné jazykové prvky.
  • Constrained Language – povoluje všechny prvky jazyka PowerShell, ale neumožňuje volání .NET a vybraných systémových rutin.

Na rozdíl od Execution policy lze z pozice správce vynutit nastavení na úrovni počítače, jež pevně stavuje jazykový režim a uživatelé jej nemohou změnit. Toto pevné nastavení se provádí pomocí systémové proměnné __PSLockDownPolicy, což lze udělat příkazem .NET:

[Environment]::SetEnvironmentVariable('__PSLockdownPolicy', '4', 'Machine')

Další alternativou je využití systémového GIU:

Poslední možností, pro správce systémů tou nejlepší, je využití Group Policy, resp. Local Policy.

Blokované soubory z internetu

Soubory konfigurace, skriptů a nápovědy jsou ve výchozím stavu po stažení z internetu blokovány a PowerShell bude explicitně vyžadovat potvrzení, že má takový soubor opravdu spustit i když politiky spuštění povolují. Každý soubor, který je stažen z internetu má o této skutečnosti informující příznak v NTFS (alternativní datový proud Zone.Identifier, který má hodnotu „3“), proto PowerShell zná jeho původ. Tuto informaci neobsahují jen soubory pro PowerShell, ale také ostatní stažené soubory, jako jsou Office, PDF, MSI, EXE apod. Výjimku tvoří soubory stažené v rámci modulu příkazem Install-Module z PowerShell galerie nebo jiného důvěryhodného repozitáře, zde si je PowerShell v rámci procesu instalace odblokuje.

Pro odblokování souborů slouží příkaz Unblock-File, který má povinný parametr -Path, nicméně dokáže pracovat i s pozičním zadáním hodnoty parametru, tudíž bez uvedení jména parametru, jen zadáním jeho hodnoty.

Následující příkaz odblokuje všechny soubory umístěné v adresáři C:\Users\Public\Dokuments:

Get-ChildItem C:\Users\Public\Dokuments\*.* | Unblock-File

Výše zmíněný příkaz odblokuje všechny soubory, tedy i soubory Office, pdf či instalátory. Jeho užití tedy může leckdy ušetřit i klikání na Povolit úpravy v sadě Office na souborech stažených z Moodlu nebo SISu. Více o tomto příkazu v jeho dokumentaci.

Posted in: Základy PowerShellu

Exporty

PowerShell, respektive jeho moduly, umí opravdu rozličné množství exportů a výpisů, ale zde mi jde o export výstupu libovolného příkazu, nikoliv například certifikátu. Nejjednodušší možností je přesměrování konzole do souboru, což se provede příkazem out-file. Například seznam běžících procesů do souboru procesy.txt na ploše uložím takto:

get-process | Out-File $env:USERPROFILE\Desktop\procesy.txt

Lepší je využít export o nějakého dále zpracovatelného formátu, jako je CSV nebo XML.

Export do CSV

K exportu výstupu do CSV slouží příkaz Export-CSV, modifikací příkladu výše pro výstupní formát CSV je následující příkaz:

get-process | Export-Csv $env:USERPROFILE\Desktop\procesy.csv -Encoding UTF8 -Delimiter ";" -NoTypeInformation

Pojďme si to rozebrat. CSV jako výchozí oddělovač využívá čárku, ale v českém jazykovém prostředí se běžně využívá středník, aby se správně uložila desetinná čísla. Parametr Delimiter umí nastavit, právě znak, který je oddělovačem, pokud parametr nevyužijeme, bude SCV využívat čárku jako oddělovač. Dalším parametrem je Encoding, který udává, jaké kódování se užije, bez uvedení přebírá výchozí kódování OS, doporučuji využívat UFT-8, protože je dobře přenosné mezi aplikacemi i systémy. Posledním je důležitý parametr NoTypeInformation, který do výstupu nezapíše na první řádek informace o typu objektu (TypeName). Pokud tento parametr zapomeneme, na první řádek se zapíše typ objektu, v našem příkladu by to bylo: System.Diagnostics.Process Tento řádek pak ztěžuje zpracování souboru dále např. v Excelu, kdy musí být při importu odebrán. Kde naopak je dobré jej mít, je následné zpracování pomocí PowerShellu.

Export do XML

Zde je situace dost podobná jako v případě CSV. Náš příklad s procesy by vypadal následovně:

Get-Process | Export-Clixml -Path $env:USERPROFILE\Desktop\procesy.xml -Encoding Unicode

Export do JSON

Dnes velmi populární datový formát JSON má rovněž v PowerShellu podporu. Bohužel zde není přímý příkaz exportu, ale postup je takový, že výstup se zkonvertuje pomocí příkazu ConvertTo-Json do objektu, který je vnitřně JSON a ten se uloží do souboru pomocí Out-File. Náš příklad s procesy by tedy vypadal následovně:

Get-Process | ConvertTo-Json | Out-File -FilePath $env:USERPROFILE\Desktop\procesy.json

Konverze do HTLM

Jedním z dobrý „exportů“ větších tabulek a dlouhých výpisů může být HTML, které je dobře čitelné po zobrazení v prohlížeči a rovněž prezentovatelné další lidem. I zde využíváme, podobně jako u JSON, konverzi a následné uložení do souboru. Pokud bychom využili samotné ConvertTo-HTML, dostaneme výstup, který je vidět na následujícím obrázku.

Náš příklad by pro uložení v podobě tabulky webové stránky vypadal následovně:

Get-Process | ConvertTo-Html | Out-File $env:USERPROFILE\Desktop\procesy.html

Možností pro ConvertTo je ještě o něco více a využívají se běžně uvnitř samotného kódu skriptů, ale již ne jako export v rozšířeném formátu. O těchto možnostech zase někdy jindy.

Posted in: Základy PowerShellu

Runas v PowerShellu

Určitě jste se octli v situaci, kdy je potřeba spustit něco jako jiný uživatel. V GUI je to jednoduché, stačí kontextové menu, ale má to háček, na PC se načte v minimální podobě profil daného uživatele, jak na to bez toho? Řešením je PowerShell nebo cmd, kdy v CMD místo proměnné zadáte username přímo do příkazu runas.

$ucet = Read-Host -promt "Zadej login"
Runas /noprofile /user:$ucet "powershell.exe"

Z PowerShellu pak už pod daným uživatelem spustíte cokoliv. Když bych chtěl napsat runas korektně PowerShellově, tak by to vypadalo takto:

Start-Process powershell.exe -Credential (Get-Credential) 

Nevýhodou zápisu výše je, že se chová jako GUI, tedy dojde k naštení minimální potřebné části profilu uživatele.

Posted in: Windows 10, Windows 11, Windows 8 a 8.1

Úprava času pro zadání hesla do Windows

Jak jistě víte, doba, za kterou musíte stihnout zadat přihlašovací údaje do systému Windows je omezena, takže se vám opět ukáže přihlašovací obrazovka, i když jste velmi pomalými úhozy nepřestali psát a můžete začít znovu. Výchozí nastavení je vyladěno velmi dobře, proto většina lidí tento stav nikdy nezažije, pokud nepřeruší úkon přihlašování se.

Problém jsou lidé, kteří mají různé tělesné postižení, jež jim ztěžuje práci s počítačem a např. psaní na klávesnici je pro ně opravdu velmi náročnou a hodně pomalou činností. Pro tyto lidi je zde primárně Windows Hello, které jim umožní přihlásit se obličejem, otiskem prstu či krátkým pinem, ale co dělat, když z nějakého důvodu není technologie k dispozici?

Pomocí registrového klíče HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI
je možné nastavit v milisekundách dobu pro zadání hesla. Konkrétně pomocí hodnoty IdleTimeOut typu DWORD, kam se zadává čas v milisekundách, po který má být možné vyplňovat přihlašovací údaje.

Posted in: Windows server

Export dat z AD pro tvorbu organizačního diagramu

Dne jen krátký příspěvek v podobě příkazu, který exportuje data připravená pro tvorbu diagramu pracovníků v organizaci pomocí Excelu.

$Path = Read-Host -promt "Zadej cestu k výstupnímu souboru"
Get-ADUser -Filter * -Properties *| Select name, @{n='Manager';e={(Get-ADUser $_.manager).name}}, title, department | Export-Csv $Path -NoTypeInformation -Encoding UTF8 -Force

Alternativa pro zpracování ve Visio:

Import-Module ImportExcel -Force
$Path = Read-Host -promt "Zadej cestu k výstupnímu souboru" 
Get-ADUser -Filter * -Properties *| Select name, @{n='Manager';e={(Get-ADUser $_.manager).name}}, title, department | Export-Excel -Path $Path -Force

Posted in: Základy PowerShellu

Formátování výstupu

Každý výpis v PowerShellu má své váchozí formátování, které je ve většině případů nejlepším pro správné zobrazní výstupu, ale i tak si jej někdy potřebujeme měnit.

Samostatnou částí je v tuto chvíli otevření výstupu v samostatném okně s možností filtrování, vyhledávání a řazení. Tuto možnost získáme příkazem Out-GridView, který umisťujeme za pípu (znak: | ) na konci příkazu. Příklad pro vypsání procesů:

Get-Process | Out-GridView
  1. Format-Table – naformátuje výstup jako tabulku do konzule
  2. Format-Custom – naformátuje dle uživatelem zadané definice
  3. Format-Hex
  4. Format-List – je asi nejčastějším formátem pro podrobné výpisy
  5. Format-SecureBootUEFI – nutné podrobně studovat dokumentaci
  6. Format-Wide – jednosloupcové zobrazení, které se tipicky v konzoli zalamuje na dva sloupce

Jako příklad si ude uveďme výpis procesu iexplorer.exe (aplikace Internet Explorer)

Další informace o formátování výstupu pak nalezneme v dokumentaci. Někdy se za formátování výstupu dá považovat i export např. do JSON, nebo XML, ale o tom, zase někdy příště.

Posted in: Základy PowerShellu

Syntaxe PowerShellu

PowerShell má poměrně jednoduchou a přehlednou základní syntaxi, která je někdy narušena, ale většinově funguje. Základní syntaxí příkazu je:

Sloveso-PodstatnéJméno -parametr hodnota

Příkladem pak může být:

Get-Process -name explorer.exe

Jak jsem již uvedl v základní obecné syntaxi, podstatné jméno nemusí být pouze jedno, ale může jich být více zapsaných jako jedno slovo pomocí Calme zápisu (každé slovo začíná velkým písmenem). Příkladem takového zápisu může být přidání záznamu do DNS:

Add-DnsServerResourceRecordAAAA -Name "host24" -ZoneName "mojedomena.local" 
-AllowUpdateAny -IPv6Address "192.168.1.24" -TimeToLive 01:00:00

Všechna běžně dostupná slovesa (vybrané moduly mohou užívat i další, ale vždy se rozsvítí varování při jejich importu) jsou dostupná následujícím příkazem:

Get-Verb

Úplný seznam uvádím níže:

Verb        Group
----        -----
Add         Common
Clear       Common
Close       Common
Copy        Common
Enter       Common
Exit        Common
Find        Common
Format      Common
Get         Common
Hide        Common
Join        Common
Lock        Common
Move        Common
New         Common
Open        Common
Optimize    Common
Pop         Common
Push        Common
Redo        Common
Remove      Common
Rename      Common
Reset       Common
Resize      Common
Search      Common
Select      Common
Set         Common
Show        Common
Skip        Common
Split       Common
Step        Common
Switch      Common
Undo        Common
Unlock      Common
Watch       Common
Backup      Data
Checkpoint  Data
Compare     Data
Compress    Data
Convert     Data
ConvertFrom Data
ConvertTo   Data
Dismount    Data
Edit        Data
Expand      Data
Export      Data
Group       Data
Import      Data
Initialize  Data
Limit       Data
Merge       Data
Mount       Data
Out         Data
Publish     Data
Restore     Data
Save        Data
Sync        Data
Unpublish   Data
Update      Data
Approve     Lifecycle
Assert      Lifecycle
Complete    Lifecycle
Confirm     Lifecycle
Deny        Lifecycle
Disable     Lifecycle
Enable      Lifecycle
Install     Lifecycle
Invoke      Lifecycle
Register    Lifecycle
Request     Lifecycle
Restart     Lifecycle
Resume      Lifecycle
Start       Lifecycle
Stop        Lifecycle
Submit      Lifecycle
Suspend     Lifecycle
Uninstall   Lifecycle
Unregister  Lifecycle
Wait        Lifecycle
Debug       Diagnostic
Measure     Diagnostic
Ping        Diagnostic
Repair      Diagnostic
Resolve     Diagnostic
Test        Diagnostic
Trace       Diagnostic
Connect     Communications
Disconnect  Communications
Read        Communications
Receive     Communications
Send        Communications
Write       Communications
Block       Security
Grant       Security
Protect     Security
Revoke      Security
Unblock     Security
Unprotect   Security
Use         Other

Sloveso vždy uvádí akci, kterou příkaz provede, proto vím, že příkazy začínající na Get, vždy slouží k nějakému získání dat, hodnot, ale nic nemění. Tato slovesa bychom měli užívat i ve vlastních funkcích a měli bychom se držet zásady, že funkce dělá to, co říká dané sloveso v jejím názvu.

Tato syntaxe je skvělá, protože kód je velmi dobře čitelný i pro úplného začátečníka, nebo člověka, který je daného jazyku neznalý. Její slabinou je zdlouhavost, proto se běžně užívají 2 věci, které zápis zkracují a urychlují:

  • zkratky (aliasy) příkazů
  • zápis pouze malými písmeny

Zápis pouze malými písmeny není žádný problém a mohu jej běžně doporučit užít i ve skriptech (dávkových souborech příkazů). PowerShell se pro interaktivní práci snaží zápis zkrátit tak, aby byl rychlý a efektivní. Aby toho dosáhl, má PowerShell tzv. aliasy, což jsou zkratky jednotlivých příkazů. Krom toho, že PowerShell má vestavěnou sadu Aliasů a každé rozšíření má volitelně sadu Aliasů pro své příkazy, může si uživatel defonovat také další svoje alisy. Seznam dostupných alisů získáme příkazem:

Get-Alias

Aliasy jde pohodlněji hledat pomocí definice (tedy uvedení příkazu, pro který chceme alis), např.:

get-alias -Definition Get-ChildItem

Aliasy mají pro správce systémů ještě jeden význam, snaží se PowerShell příkazy mapovat na CMD nebo BASH příkazy, které správci již dobře znají a běžně využívají. Výše uvedený příklad jsem nevybral náhodnou, pojďme se podívat, jaké jsou alisy pro Get-ChildItem:

get-alias -Definition Get-ChildItem

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

Uvedené alisiy dir (pro Windows svět) a ls (pro Linuxový svět) jsou příkazy, které zná každý správce a sám tento příkaz využívám výhradně v podobě aliasu, byť poměrně často sáhnu po alisu gci. Další takový příklad je alias copy, který je zkratkou pro Copy-Item, případně Linuxáci budou preferovat aplias cp. Velmi často jsou užívané také alisy where a select, o kterých má člověk pocit, že jsou samotnými příkazy, protože málo kdy je vidět Whre-Object a Select-Object.

Pajpa – svislítko

Další běžnou součástí syntaxe v PowerShellu pro práci v terminálu i skriptech je pajpa. Pajpa má význam předání výstupu jednoho příkazu (výstupního objektu) jako vstupu do dalšího příkazu. Počet těchto předání, které zapášeme není nikterak omezen, ale pro přehlednost se využívá relativně nízký počet, obvykle jedno až tři. Příklad pak může být:

get-alias | where Source -eq "Microsoft.PowerShell.Utility" | Out-GridView

Výše uvedený příkaz vypíše aliasy příkazů, které jsou součástí modulu PowerShell Utility. Tento výpis se zobrazí v samostatném okně mřížky, která umožňuje prohledávání, filtrování a řazení výstupu.

Zapisování textu

Text, stejně jako ve většině programovacích jazyků, zadáváme v uvozovkách, ovšem v PowerShellu to není tak jednoduché, jak by se mohlo zdát. Když text zapíšeme do uvozovek (jak je známe v češtině), bude se vyhodnocovat dynamický obsah, viz následující příklad:

Write-Host "Dnes je $datum"
Dnes je 10.06.2023

Na proti tomu, když užiji apostrof (jednoduché uvozovky), dynamický obsah se nevyhodnocuje a budu mít vždy text přesně takový, jako jej mám zapsaný, viz níže:

Write-Host 'Dnes je $datum'
Dnes je $datum

Pokud chci, aby součástí textu byly uvozovky, např. nějaká citace, musím takový text uzavřít do jednoduchých uvozovek a bude platit, že dynamický obsah se nevyhodnocuje, protože české uvozovky jsou v tomto případě znakem textu, nikoliv vymezením textového řetěžce.

Proměnná

Nedílnou součástí psaní skriptů je využívání proměnných. Stejně jako ostatní skriptovací jazyky má i PowerShell dynamicky typované proměnné, tedy proměnné mění svůj datový typ v závislosti na svém obsahu. Jméno proměnné začíná vždy $, takže proměnnou s názvem cislo založíme následovně:

$cislo

Do proměnné se přiřazuje jako ve většině jazyků (alespoň těch, které vychází z C) pomocí symbolu rovnítko, hodnotu 2 tedy do proměnné cislo přiřadíme následovně:

$cislo = 2

Otázkou ovšem zůstává, jakého datového typu proměnná cislo je. K tomu, abychom tuto otázku zodpověděli si musíme uvědomit, že PowerShell je objektový jazyk vycházející z .NET, takže jeho objekty mají nějaké vlastnosti a funkce, ke kterým se dostaneme pomocí tečky. Datový typ naší proměnné zjistíme následovně

$cislo.gettype().name

Výsledkem bude typ Int32, tedy celé číslo. Co se stane, když do proměnné cislo zapíšeme hodnotu slovem?

$cislo = "dva"
$cislo.gettype().name
String

Nabízí se tedy otázka, mohu při psaní skriptu nějak zajistit, že v proměnné bude třeba text a nic jiného? Odpověď je ano, protože PowerShell umí na rozdíl od jiných dynamicky typovaných skriptovacích jazyků zafixovat typ proměnné, pomocí uvedení datového typu v hranatých závorkách před proměnnou, dokazuje to následující příklad.

PS C:\Users\petra> [string]$cislo = 2
PS C:\Users\petra> $cislo.gettype().name
String
PS C:\Users\petra> $cislo = "dva"
PS C:\Users\petra> $cislo.gettype().name
String

A co když není automatická konverze mezi dvěma typy možná?

PS C:\Users\petra> [int]$cislo = 2
PS C:\Users\petra> $cislo.gettype().name
Int32
PS C:\Users\petra> [int]$cislo = "2"
PS C:\Users\petra> $cislo.gettype().name
Int32
PS C:\Users\petra> [int]$cislo = "dva"
Cannot convert value "dva" to type "System.Int32". Error: "Vstupní řetězec nemá správný formát."
At line:1 char:1
+ [int]$cislo = "dva"
+ ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : MetadataError: (:) [], ArgumentTransformationMetadataException
    + FullyQualifiedErrorId : RuntimeException

Jak je vidět, PowerShell vyhodí chybu a hodnotu do proměnné nezapíše. Zároveň však např. číslo zapsané číslicí ve formátu textu pozná a převede jej na číslo.

Proměnná Pajpy

Výchozí proměnná, proměnná pajpy či jinými názvy pojmenovávaný proměnná, která obsahuje objekt, jež je předávám mezi příkazy pomocí pajpy. Tato proměnná je součástí vlastního PowerShellu a má dvoje značení (od verze 3)

  • $_ se obvykle značí a pomocí $_.<vlastnost> se dostanu k vlastnostem objektu, který mi přichází z pajpy
  • $PSItem je plný názve pro tuto proměnnou, kterou nejčastěji zapisujeme jako $_

Další informace o proměnných najdete v dokumentaci PowerShellu a budeme se jim postupně věnovat v dalších článcích tak, jak je budeme potřebovat.

Proměnné prostředí Windows

Každý admin ví, že systém Windows má vlastní systémové proměnné. Tyto proměnné jsou v PowerShellu rovněž dostupné, ale jinak, nežli v CMD, nebo dialogu spustit, kde se uzavírají do symbolů procento. V PowerShellu mají zvláštní zápis, kde součástí jména proměnné je env:, viz příklad:

$Env:windir

Objekt

Opravdu velmi zjednodušeně jde říct, že v PowerShellu je objektem vše. Pokud se chci k něčemu chovat jako k objektu, není to nic těžkého.

  • Proměnná rovnou využívá tečkové notace
  • Příkaz zavřu do kulatých závorek a využívám tečkové notace

Přístup k vlastnostem objektu na proměnné jsme tu již viděli, jde o:

$cislo.gettype().name

Tento příklad je malinko zvláštní, protože na objektu proměnné $cislo využíváme metodu a na výstupním objektu této metody pak vlastnost. Jak by to bylo s tím, když chci objektově přistoupit k příkazu?

(Get-Date).AddHours(8)

Výše uvedený příkaz vrátí datum a čas, který bude platný za 8 hodin, přičemž využívá metodu objektu, který je vracen příkazem Get-Date.

Programátoři se ovšem nemusí bát, objekty je možné vytvářet pomocí tříd stejně, jako v jiných objektových jazycích, ale jde již o pokročilou věc, kterou IT profesionálové nejspíš potřebovat nebudou, proto si danou syntaxi najděte v dokumentaci.

Bloky

Již opravdu poslední částí obecné syntaxe jsou bloky, ať jde o funkce, větvení, skriptbloky, či sekce DSC. Všechny bloky uzavíráme do složených závorek, např.

try {New-Item -Path Z:\zaloha -name Dnesek -type "directory"} catch {write-host "Nezdařilo se"}

Posted in: Základy PowerShellu

Nápověda PowerShellu

PowerShell je MS produktem s nejlepší dokumentací. Hodně tomu napomáhá silná komunita, ale také fakt, že PowerShell prochází všemi produkty Microsoftu. Pojďme se tedy podívat, jak pracovat s nápovědou, tedy dokumentací.

Před prvním užitím je dobré nápovědu aktualizovat:

Update-Help -Force

Nyní nám již nic nebrání otevřít si okno nápovědy

Get-Help -ShowWindow

Na tomto místě by se slušelo říct, že PowerShell má dva základní druhy nápovědy:

  1. Nápovědu k příkazům
  2. Tématickou nápovědu

Nápovědu k příkazu spustíme tak, že za příkaz nápovědy dáme příkaz, k němuž hledáme nápovědu. Opět na příkladu, řekněme, že chci zjistit nápovědu k práci s procesy ve Windows:

get-help process

Nyní vidím příkazy pro práci s procesy, např. pro výpis procesů vidím, že slouží příkaz get-process a pokud budu chtít další informace o tomto příkazu zadám si 

get-help get-process -ShowWindow
#nebo prop výpis v konzoli
get-help get-process

Kdo by chtěl v konzoli podrobnou nápovědu, pak využije příkaz:

get-help get-process -Full

Komu se naopak nechce číst celou nápovědu, ale chce vidět jen příklady použití, pak může využít:

get-help get-process -examples

Příklady užití příkazu přikládám z vlastního modulu:

Asi nejzajímavější možností, pokud je k dispozici konektivita, je zobrazení nápovědy online pomocí výchozího webového prohlížeče:

get-help get-process -online

A jak je to s tématickou nápovědou? Inu dost obdobně jako s tou k cmdletům. Základem je opět příkaz get-help, ale másto názvu příkazu nebo odvětví zadávám about_ a tématický okruh. V tomto případě již důrazně doporučuji otevírat nápovědu v samostatném okně. Opět si vše ukažme na příkladu, budou nás zajímat rozšíření PowerShellu, kterým se říká moduly:

get-help about_modules -ShowWindow

Pokud se vám zdá psát get-help zdlouhavé, tak mě také, proto prozradím zkratku, stačí napsat man. Připomíná vám to Bash? Nedivím se, jde o jednu ze zkratek, kterou PowerShell právě z Bashe převzal ;). Případně se dá syntaxe převzít z CMD a lze pro základní nápovědu psát (vždy základní výpis do konzoly):

get-process -?

Tvorba nápovědy

Vlastní skripty, funkce a moduly můžeme rovněž vybavit integrovanou nápovědou. Pro skripty a moduly publikované v PowerShell galerii je povinností nápovědu obsahovat. Pokud využíváme pro psaní PowerShell ISE, tak nám s nápovědou pomohou snipety, ale i bez nich to není nic těžkého, jde vlastně o blokový komentář, který má předepsaný tvar.

Nápověda nemusí obsahovat všechny bloky uvedené na obrázku (může navíc obsahovat .NOTE [informace o autorovi a verzi] apod.), úplný výčet klíčových slov a jejich význam je v dokumentaci. Častěji má nápověda podobu následujícího příkladu:

<#
.Synopsis
   kontrola systémovýh souborů.
.DESCRIPTION
   kontrola systémových souborů nativními nástroji scf a dism
.EXAMPLE
   Check-SystemFiels -scannow
   provede příkaz sfc /scannow
.EXAMPLE
   Check-SystemFiels -scanfile -Path c:\windows\system32\kernel32.dll
   Provede kontrolu integrity a pokusí se o opravu souboru kernel32.dll
#>

Pokud jsou komentáře u definic parametrů, pak výsledná nápověda vypadá následovně:

Synopsis
    kontrola systémovýh souborů.

Description
    kontrola systémových souborů nativními nástroji scf a dism


Parameters
    -path <String>
        Určuje cestu k souboru, který má být verifikován nebo opraven

        Required?                    false
        Position?                    1
        Default value                
        Accept pipeline input?       true (ByPropertyName)
        Accept wildcard characters?  false

    -scannow <SwitchParameter>
        Spustí kontrolu systémových souborů běžícího systému, vede na sfc /scannow

        Required?                    false
        Position?                    named
        Default value                False
        Accept pipeline input?       false
        Accept wildcard characters?  false

    -verifyonly <SwitchParameter>
        Provede kontrolu bez pokusů o opravu poškozeného souboru, vede na sfc /verifyonly

        Required?                    false
        Position?                    named
        Default value                False
        Accept pipeline input?       false
        Accept wildcard characters?  false

    -scanfile <SwitchParameter>
        Nastavuje nástroj sfc do móduz kontroly konkrétního soubooru, vždy kombinován s parametrem Path

        Required?                    false
        Position?                    named
        Default value                False
        Accept pipeline input?       false
        Accept wildcard characters?  false

    -offline <SwitchParameter>
        Říká, že se bude verifikovat jiná, nežli běžící instance systému Windows, kombinuje se s parametry offbootdir a offwindir

        Required?                    false
        Position?                    named
        Default value                False
        Accept pipeline input?       false
        Accept wildcard characters?  false

    -verifyfile <SwitchParameter>
        kontrola souboru

        Required?                    false
        Position?                    named
        Default value                False
        Accept pipeline input?       false
        Accept wildcard characters?  false

    -offbootdir <String>
        U offline kopie systému Windows říká, který disk je její systémový

        Required?                    false
        Position?                    named
        Default value                
        Accept pipeline input?       false
        Accept wildcard characters?  false

    -offwindir <String>
        U offline kopie systému Windows udává její systémový adresář

        Required?                    false
        Position?                    named
        Default value                
        Accept pipeline input?       false
        Accept wildcard characters?  false

    -store <SwitchParameter>
        pomocí nástroje DISM provede sken a následně opravu systémových balíčů běžící kopie systému Windows

        Required?                    false
        Position?                    named
        Default value                False
        Accept pipeline input?       false
        Accept wildcard characters?  false



Syntax
    Check-SystemFiles [[-path] <String>] [-scannow ] [-verifyonly ] [-scanfile ] [-offline ] [-verifyfile ] [-offbootdir <String>] [-offwindir <String>] [-store ] [<CommonParameters>]


Examples
    -------------------------- EXAMPLE 1 --------------------------
    PS C:\>Check-SystemFiels -scannow
    
    provede příkaz sfc /scannow




    -------------------------- EXAMPLE 2 --------------------------
    PS C:\>Check-SystemFiels -verifyonly
    
    provede příkaz sfc /verifyonly - tedy pouze kontrolu bez oprav




    -------------------------- EXAMPLE 3 --------------------------
    PS C:\>Check-SystemFiels -scanfile -Path c:\windows\system32\kernel32.dll
    
    Provede kontrolu integrity a pokusí se o opravu souboru kernel32.dll




    -------------------------- EXAMPLE 4 --------------------------
    PS C:\>Check-SystemFiels -offline -scanfile -Path d:\windows\system32\kernel32.dll -offbootdir d: -offwindir d:\windows
    
    Provede kontrolu integrity a pokusí se o opravu souboru kernel32.dll z offline image na disku d:




    -------------------------- EXAMPLE 5 --------------------------
    PS C:\>Check-SystemFiels -store
    
    Provede kontrolu systému příkazem dism /online /cleanup-image /restorehealth

Jak je vidět, nápovědu je možné (až na klíčová slova definující jednotlivé sekce) psát v mateřském jazyce, ale pro PowerShell galerii je potře mít nápovědu anglicky, teoreticky pak můžete mít značkou jazyka odlišený odstavec mateřském jazyce v každé sekci.

Back to Top