Seriál Windows PowerShell: Představení PSCX podruhé (část 23.)

Minule jsme se seznámili s modulem PSCX a dnes ukážu, v jakých situacích se může modul hodit. Mimochodem, modul PSCX neuniknul ani oku Scotta Hanselmana.

Předpokládejme, že pracuji na nějakém projektu, je vcelku jedno, na jakém. Potřebuji vygenerovat Lorem ipsum, abych naplnil (HTML) stránku přibližně věrohodným obsahem.

Get-LoremIpsum

Pro daný účel poslouží cmdlet Get-LoremIpsum. Pokud nespecifikujeme délku, výstupem je právě jeden odstavec. Pokud bychom chtěli text přesně dané délky, můžeme specifikovat počet znaků, slov, nebo odstavců.

 PS> Get-LoremIpsum -Character 3
Lor
PS> Get-LoremIpsum -Word 3
Lorem ipsum dolor
PS> Get-LoremIpsum -Paragraph 3
Lorem ipsum dolor sit amet, ...
Duis autem vel eum ...
...

V tuto chvíli sice máme text, ale ještě je potřeba jej někam zkopírovat. Copy & Paste v konzoli je dost nepohodlné. Daleko lepší je použít cmdlet Set-Clipboard. Výsledkem tedy je

 PS> Get-LoremIpsum -p 1 | Set-Clipboard

Invoke-BatchFile

Čas od času je třeba spustit VS command line a z ní pak některý z toolků jako např. fuslogvw. Z prosté command line tool spustit nejde, možná jen proto, že cesta k němu není jen v PATH proměnné prostředí. Na import proměnných prostředí zavoláme cmdlet Invoke-BatchFile s cestou k bat souboru.

Cmdlet jednoduše spustí příslušný bat soubor předaný jako parametr a všechny proměnné prostředí existující po spuštění souboru naimportuje do PowerShell session. Příklad:

 Invoke-BatchFile "${env:VS100COMNTOOLS}..\..\VC\vcvarsall.bat"

S touto myšlenkou přišel Lee Holmes a na jeho původní skript je možné se podívat na poshcode.org. Všimněte si triku s && set a přesměrováním do souboru, odkud se pak proměnné přečtou.

ConvertFrom-Base64, ConvertTo-Base64

Hlavně při práci na webu můžeme potřebovat pracovat s base64. Pak nám pomůžou cmdlety ConvertFrom-Base64, ConvertTo-Base64. Bohužel ale jako vstup neberou prostý string, ale je nutné konvertovat vstup na pole bytů.

 PS> 'abc' | ConvertTo-Base64 # vyhodí chybu, bohužel.. je nutné konvertovat na pole bytů
PS> [byte[]][char[]]'proměnné prostředí.' | ConvertTo-Base64 

Pokud ale použijeme české znaky, dostaneme chybu i tak:

 PS> [byte[]][char[]]'proměnné prostředí.' | ConvertTo-Base64
Cannot convert value "ě" to type "System.Byte". Error: "Value was either too large or too small for an unsigned byte."

Musíme si pomoct jinak:

 [text.encoding]::utf8.getBytes('proměnné prostředí.') | ConvertTo-Base64

Cmdlety byly zamýšleny především pro kódování a dekódování souborů. V helpu můžete najít např. toto použití:

 PS> $b64 = ConvertTo-Base64 Foo.dll -NoLineBreak

Resolve-WindowsError, Resolve-HResult

Řekněme, že už máme nějakou funkční aplikaci a ona najednou začne padat a jediná stopa je číslo chyby. První věc, kterou můžeme udělat před tím, než otevřeme prohlížeč, je spuštění jednoho z cmdletů (podle typu chyby).

Kódy můžeme do commandletů posílat přes pipeline, což nám umožní zpracovat více kódu najednou:

 PS> 1..5 | Resolve-WindowsError

Nesprávná funkce
Systém nemůže nalézt uvedený soubor
Systém nemůže nalézt uvedenou cestu
Systém nemůže otevřít soubor
Přístup byl odepřen

Většina skriptů moc zábavná není, co tak si tedy skripty zpestřit nějakou náhodou hláškou? Náhodné hodnoty se generují pomocí Get-Random:

 PS> 1..5 | % { Get-Random -min 0 -max 1000 } | Resolve-WindowsError
Neplatné atributy objektu zadané do funkce NtCreatePort nebo neplatné atributy portu zadané do funkce NtConnectPort
Unknown error (0x200)
Zařazovací vyrovnávací paměť uživatel/jádro přetekla
{Závažná chyba systému}
Bitová kopie systému %s není správně podepsána.
Soubor byl nahrazen podepsaným souborem.
Systém byl ukončen
Unknown error (0x3a1)
PS> 1..5 | % { Get-Random -min 0 -max 1000 } | Resolve-WindowsError
Unknown error (0x189)
Unknown error (0xf8)
Unknown error (0x210)
Disk je plný
Zadaná vyrovnávací paměť obsahuje samé nuly

Test-Xml, Format-Xml

Při mergování změn do *.*proj souboru se někdy zadaří a výsledkem je nevalidí XML. Před commitem, nebo podobnou operací, kdy se chceme přesvědčit, že XML je validní, může posloužit Test-Xml. Jako parametr lze předat i odkaz na XSD, nebo DTD.

 PS> gci D:\MicroTools\ *.fsproj -recurse | Test-Xml
True
True
True...

Pro zobrazení XML může posloužit již v minulém díle zmiňovaný Format-Xml.

 PS> gci D:\MicroTools\ *.fsproj -rec | Format-Xml

echoargs

Dostali jsme se až k buildu. V rámci tohoto procesu můžeme volat z nějakého PowerShell skriptu nativní aplikace (např. msbuild). Toto je bohužel oblast, ve které často dochází k chybám. V některých případech je totiž velmi těžké správně doplnit apostrofy a escape sekvence. Důkazem budiž několik z mnoha dotazů na StackOverflow.

Jako příklad si vezměne poslední dotaz:

 PS> echoargs -verb:sync -source:dbfullsql="Data Source=mysource;Integrated
Security=false;User ID=sa;Pwd=sapass!;Database=mydb;" -dest:dbfullsql="Data Sourc
e=.\mydestsource;Integrated Security=false;UserID=sa;Pwd=sapass!;Database=mydb;",
computername=10.10.10.10,username=administrator,password=adminpass

Arg 0 is <-verb:sync>
Arg 1 is <-source:dbfullsql=Data>
Arg 2 is <Source=mysource;Integrated>
Arg 3 is <Security=false;User>
Arg 4 is <ID=sa;Pwd=sapass!;Database=mydb;>
Arg 5 is <-dest:dbfullsql=Data>
Arg 6 is <Source=.\mydestsource;Integrated>
Arg 7 is <Security=false;User>
Arg 8 is <ID=sa;Pwd=sapass!;Database=mydb; computername=10.10.10.10 username=adm...

Command line:
"C:\Users\stej\Documents\WindowsPowerShell\Modules\pscx\Apps\EchoArgs.exe"  -verb:s
ync "-source:"dbfullsql=Data Source=mysource;Integrated Security=false;User ID=sa;P
wd=sapass!;Database=mydb;"" "-dest:"dbfullsql=Data Source=.\mydestsource;Integrated
Security=false;User ID=sa;Pwd=sapass!;Database=mydb;" computername=10.10.10.10 user
name=administrator password=adminpass"

Na samém konci výpisu vidíme command line tak, jak ji vidí systém. Tento výpis je implementován v nejnovější verzi 2.1 Beta1. Dřívější verze obsahovaly pouze výpis argumentů.

Get-FileVersionInfo

Z práce nás vyruší email o spadlém buildu. Prý neprošly testy, protože se nám do binárek připletla assembly se špatnou verzí. V logu vidíme jasně, že nemohl načíst assembly abc.dll. V této chvíli potřebujeme rychle zjistit, jaké verze assembly vlastně v adresářích máme a kde se nachází ta špatná. Najdeme tedy všechny soubory daného jména a pošleme je do Get-FileVersionInfo.

 PS>  gci D:\MicroTools\ *common*dll -rec | Get-FileVersionInfo

ProductVersion  FileVersion   FileName
--------------  -----------   --------
0.5.0.18216     0.5.0.18216   D:\MicroTools\bin\MicroCommon.dll
0.5.0.18216     0.5.0.18216   D:\MicroTools\MicroCommon\obj\Debug\MicroCommon.dll
0.5.0.18216     0.5.0.18216   D:\MicroTools\pub\MicroCommon.dll
0.4.0.32450     0.4.0.32450   D:\MicroTools\old\MicroCommon.dll

Pokud víme, že některá verze na disku nemá co dělat, můžeme ji pak jednoduše smazat takto:

 gci D:\MicroTools\ *common*dll -rec | 
  Get-FileVersionInfo | 
  ? { $_.ProductVersion -match '0\.4' } |
  Remove-Item -path {$_.FileName}

Zde stojí za povšimnutí poslední řádek s Remove-Item; jako argument se totiž předává ne hodnota, ale skriptblock, který se vyhodnotí pro každý objekt z pipeline a naváže se pak na parametr -path. Ve scriptblocku se můžeme odkazovat na proměnnou $_, která obsahuje aktuální prvek v pipeline. Jak je tedy patrné, kód z objektu vráceného cmdletem Get-FileVersionInfo vrátí obsah property FileName a ten se naváže na parametr -path. Jiný (ale ne ekvivalentní) zápis by mohl být tento:

 gci D:\MicroTools\ *common*dll -rec | 
  Get-FileVersionInfo | 
  ? { $_.ProductVersion -match '0\.4' } |
  select -expand filename | 
  Remove-Item

První možnost je přehlednější a kratší. Naposledy o této možnosti psal Jim Christopher.

Help

A v neposlední řadě musím zmínit i příjemnější help. Pro porovnání si můžete zkusit help gc -full s importovaným PSCX a bez. PSCX přidává svou vlastní funkci help, která využívá less.exe. Můžeme se tak pohybovat po helpu šipkou nahoru/dolu a ukončit režim helpu klávesou q. Po opuštění zmizí obsah helpu a ukáže se původní obsah konzole. Příjemné, že?

Dnes jsme si ukázali, co nabízí modul PSCX. Nezapomeňte ovšem, že předvedené příkazy tvoří jen malou část z toho, co modul nabízí. Podívejte se na všechny příkazy, jistě najdete další zajímavé: Get-Command -Module pscx.