Lekce 4 - PowerShell - Profily
V předchozí lekci, PowerShell - Datové typy a práce s objekty, jsme se seznámili s objekty a základními datovými typy.
V dnešní lekci kurzu PowerShell frameworku se seznámíme s profily.
Vytvoření profilu
PowerShell profil není nic jiného než spustitelný skript (s příponou
.ps1
), který je v určité lokaci. Tento skript se spouští před
tím, než se uživateli zpřístupní session daného hosta.
Abychom mohli používat profily, je potřeba mít nastavenou
ExecutionPolicy tak, aby PowerShell mohl spustit .ps1
skript. Toto provedeme příkazem
Set-ExecutionPolicy AllSigned
.
Tato lokace je dána systémovou proměnnou $PROFILE
:
C:\> $PROFILE
C:\Users\vojtech\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
Profily jsou rozděleny do 4 kategorií:
- všichni uživatelé, všichni hosté (All users, all hosts) -
profil aplikovaný na všechny hosty (console, ISE) nezávisle na
přihlášeném uživateli, cestu získáme pomocí
$PROFILE.AllUsersAllHosts
- všichni uživatelé, konkrétní host (All users, current host) -
profil aplikovaný na konkrétní hosty nezávisle na přihlášeném
uživateli, cestu získáme pomocí
$PROFILE.AllUsersCurrentHost
- konkrétní uživatel, všichni hosté (Current user, all hosts) -
profil aplikovaný na všechny hosty pro konkrétního uživatele, cestu
získáme pomocí
$PROFILE.CurrentUserAllHosts
- konkrétní uživatel, konkrétní host (Current user, current
host) - profil aplikovaný na konkrétní hosty pro konkrétního
uživatele, cestu získáme pomocí
$PROFILE.CurrentUserCurrentHost
nebo jen$PROFILE
Proměnná $PROFILE
vrací cestu, v které očekává daný
skript profilu (i v případě, že profilový skript neexistuje).
V našem případě budeme pracovat s variantou Current User, current host tak, abychom neafektovali ostatní hosty, popřípadě uživatele používající náš počítač.
Jak již bylo řečeno, i když $PROFILE
vrátí cestu k
profilu, tato cesta je pouze očekávaná a nemusí existovat. Nejprve si tedy
zjistíme, jestli tento profilový skript existuje, k tomu použijeme příkaz
Test-Path
:
C:\> Test-Path $PROFILE
False
V mém případě již profil existuje, tudíž můj výsledek by byl
True
. Předpokládám ale, že většina uživatelů začínající
s PowerShellem tento profil zatím nemá, proto by tam měla být hodnota
False
. Profil vytvoříme jak jinak, než opět PowerShell
příkazem New-Item
:
C:\> New-Item $PROFILE Directory: C:\Users\vojtech\Documents\WindowsPowerShell Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 8/20/2020 5:49 PM 0 Microsoft.PowerShell_profile.ps1
Po tomto příkazu nám PowerShell vrátí objekt právě vytvořeného souboru. Nyní máme profil vytvořen, ale je to pouze prázdný skript, který nic nedělá a je potřeba jej teprve nakonfigurovat. Nicméně si právě otestujeme ExecutionPolicy tak, že daného hosta (například konzoli) zavřeme a spustíme znovu. Pokud nám vše proběhlo bez chyby, vše máme nachystáno pro konfiguraci našeho profilu.
V případě, že se nám objeví tento error, je potřeba přepnout
ExecutionPolicy na buď Unrestricted
nebo alespoň na
AllSigned
:
. : File C:\Users\vojtech\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1 cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Policies at https:/go.microsoft.com/fwlink/?LinkID=135170. At line:1 char:3 + . 'C:\Users\kasnyvoj\Documents\WindowsPowerShell\Microsoft.PowerShell ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : SecurityError: (:) [], PSSecurityException + FullyQualifiedErrorId : UnauthorizedAccess
Konfigurace profilu
Nyní, když máme profil vytvořen a PowerShell host je schopen tento profilový skript spustit, ukážeme si, co do profilu vlastně dát.
Co do profilu dáme je jen čistě na úvaze uživatele, každopádně zde je několik příkladů, co by v profilu mohlo být a co by určitě nemělo být.
Do profilu nepatří:
- manipulace se systémovými proměnnými jako
$ErrorActionPreference
či$WarningPreference
- REST nebo SOAP cally, popřípadě jiné API cally, které jsou závislé na kvalitní připojení k internetu
- dlouho běžící joby, jako například dotazy do Active Directory
- manipulace s nastavením bezpečnosti PowerShellu, jako například manipulace s ExecutionPolicy
- volání externího skriptu, který vyžaduje elevaci (Spustit jako administrátor)
- profil by neměl obsahovat žádné statické řetězce, pokud to není nutné (například cesty k souborům)
- uměle vynucené pauzování exekuce profilu pomocí příkazu
Start-Sleep
- rekurzivní procházení file systému
- obecně nic, co trvá moc dlouho, protože čím déle trvá exekuce
profilu, tím déle čeká uživatel na zpřístupnění své sessiony
Co naopak do profilu určitě patří:
- customizace promptu (příklad + zdrojový kód níže)
- aliasy, obzvláště pokud používáte externí utility jako například git
- vlastní funkce popřípadě třídy (pokud se jedná o více funkcí, doporučuje se již použít moduly, o těch si povíme v dalších lekcích)
- PsCustom objekty, například pokud chceme mít při startu PowerShell hosta
připraven objekt s informacemi o našem počítači, stačí zkopírovat kód z
předešlé lekce, kde jsme si tvořili
$ComputerInfo
objekt - info pro uživatele, například v případě použití vlastních aliasů vypíšeme tyto aliasy do konzole
- dalším nápadům se určitě meze nekladou, nicméně je potřeba pamatovat na to, čím více kódu se v profilu pouští, tím déle může uživatel čekat na zpřístupnění sessiony, což může mít nežádoucí efekt
PowerShell umí detekovat pomalé profily, load delší než 2 sekundy se považuje za problémový. Pokud PowerShell zjistí pomalý load profilu, informuje nás touto zprávou:
Windows PowerShell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
Try the new cross-platform PowerShell https://aka.ms/pscore6
Loading personal and system profiles took 4575ms.
C:\>
Příklad profilu
Jako příklad profilu dávám k dispozici jeden z mých běžně používaných profilů (používám více profilů, záleží na jakém projektu zrovna pracuji). Co se v tomto profilu nachází (v profilu je pouze nedestruktivní kód):
- 1 alias pro utilitu
git
. Pokud s GITem nepracujete, alias a funkci můžete vynechat popřípadě nahradit dle libosti - 2 vlastní (custom) funkce
- customizace prompt funkce (prompt funkce se spouští vždy při stisknutí tlačítka Enter)
Profil otevřete ve svém oblíbeném IDE či jiném textovém editoru (doporučuji Visual Studio Code s rozšířením pro PowerShell)
PowerShell umí automaticky otevřít soubory podle typu
přípony v programu, který má nastaven jako defaultní pro tyto typy
přípon. Toto nastavení se provádí v nastavení Windows. Z PowerShellu nám
stačí již potom zavolat příkaz Invoke-Item
či jeho alias
ii
s cestou k souboru. Tedy v případě profilu
ii $PROFILE
. Pokud bychom zavolali Invoke-Item
na
cestu složky, tato složka se nám otevře v průzkumníku Windows
Do právě vytvořeného profilu
Microsoft.PowerShell_profile.ps1
vložte následující kód:
function Test-Administrator { $currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent()) $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) } function prompt { $PsVersion = $host.version.ToString() switch (Test-Administrator){ $true { $ID='admin' } default { $ID='user' } } Write-Host "[$PsVersion]" -ForegroundColor Cyan -nonewline Write-Host "[$env:USERNAME~$ID][$PWD]" -ForegroundColor DarkCyan -NoNewline Write-Output ' ' } function Get-GitLog { param ( [switch]$ShowFile, [switch]$PassThru ) switch ($ShowFile){ $true {$Attr = '--stat'} default {$Attr = $null} } switch ($PassThru){ $true { git log --pretty=format:"%C(red)%ce%Creset,%Cblue%h%Creset,%C(bold cyan)%cd%Creset,%C(yellow)%s" | ForEach-Object { $LineArr = $_ -split ',' $Hash = [ordered]@{ Commiter = $LineArr[0] CommitHash = $LineArr[1] CommitDate = $LineArr[2] CommitMessage = $LineArr[3..$LineArr.Length] -join ',' } New-Object psobject -Property $Hash } } default {git log --pretty=format:"%C(red)%ce%Creset committed %Cblue%h%Creset on %C(bold cyan)%cd%Creset with message %C(yellow)%s" $Attr} } } New-Alias -Name 'gil' -Value Get-GitLog
Popis custom funkcí a aliasu:
Test-Administrator
- tato funkce určí, jestli daná sessiona hosta běží jako administrátor či nikolivprompt
- je upravená funkce PowerShellu, pokud tuto funkci z profilu smažete, PowerShell bude automaticky používat defaultní prompt funkciGet-GitLog
- tato funkce vrací log příkazugit
. Pokud s touto utilitou nepracujete, můžete ji z profilu smazat nebo nahradit svou vlastní funkcígil
: alias pro funkciGet-GitLog
Nyní restartujte PowerShell hosta, naše prompt by měla vypadat podobně (prompt je ve skutečnosti kolorizována):
Windows PowerShell
[5.1.18362.752][vojtech~admin][C:\Dev\Repos]
Popis promptu:
[5.1.18362.752]
- verze PowerShell frameworku[vojtech~admin]
nebo[vojtech~user]
- jméno uživatele a identifikátor v jakém režimu je host spuštěn[C:\Dev\Repos]
- složka ve které se právě nacházíme
Pokud pracujeme s git klientem (gitlab, github) a spustíme z daného
repozitáře alias gil
, dostaneme podobný výstup tomuto:
Závěrem jen připomenu, že profil není nic jiného než spustitelný PowerShell skript, pro které musí být povolena exekuce, v opačném případě nás bude daný PowerShell host při každém spuštění vítat errorem.
V další lekci, PowerShell - Moduly, se seznámíme s PowerShell moduly a také si jeden vytvoříme.