Seriál Windows Powershell: Moduly – dokončení (část 17.)

V minulé části jsme si vytvořili vlastní modul sloužící ke zjišťování aktuálního kurzu. Dnes si ukážeme, jak tento modul ještě trochu vylepšit.

Manifest

Pokud se podíváme na informace o našem modulu, zjistíme, že toho vlastně až tak moc nevíme:

PS C:\> Get-Module Kurzy | fl *

ExportedCommands : {usd, eur, Get-Kurz}
Name : kurzy
Path : C:\Moduly\Kurzy\kurzy.psm1
Description :
Guid : 00000000-0000-0000-0000-000000000000
ModuleBase : C:\Moduly\Kurzy
PrivateData :
Version : 0.0
ModuleType : Script
AccessMode : ReadWrite
ExportedFunctions : {[eur, eur], [Get-Kurz, Get-Kurz], [usd, usd]}
ExportedCmdlets : {}
NestedModules : {}
RequiredModules : {}
ExportedVariables : {}
ExportedAliases : {[kurz, kurz]}
SessionState : System.Management.Automation.SessionState
OnRemove :
ExportedFormatFiles : {}
ExportedTypeFiles : {}

Pokud bychom takovýto modul získali na internetu, bylo by dobré o něm vědět trochu víc. K tomu účelu slouží právě manifest. Jedná se vlastně o hash tabulku (někdy se do češtiny překládá i jako asociativní pole), která obsahuje dvojice klíč-hodnota (key-value) určující vlastnosti manifestu.

Krátce k hash tabulce: Typickým případem je například dvojice hodnot jméno-věk, kdy k určitému člověku přiřadíme jeho věk, např. David – 33. V PowerShellu bychom tuto dvojici zapsali jako:

$h = @{
David = 33;
Martin = 34;
}

Zde jsme si uložili věk dvou lidí do hash tabulky a pro snazší práci tuto tabulku uložili do proměnné h. Nyní s ní můžeme dále pracovat.

PS C:\> $h

Name Value
---- -----
Martin 34
David 33

PS C:\> $h.GetType().FullName
System.Collections.Hashtable

PS C:\> $h.David
33

Jedna položka manifestu tedy vypadá například takto:

PS C:\Scripts > (Get-Content 'C:\Moduly\Pscx\Pscx.psd1')[2]
Author = 'PowerShell Community Developers'

Zde jsme z manifestu k modulu PSCX přečetli třetí řádek obsahující údaje o autorovi.

Další informace se můžete dozvědět například v osmé části tohoto seriálu nebo v nápovědě (Get-Help about_Hash_Tables). Pojďme ale zpátky k modulům.

Manifest můžete vytvořit několika způsoby (od manuálního zapsání v notepadu až po použití speciálního add-inu). My si vyzkoušíme použití cmdletu New-ModuleManifest.

PS C:\> New-ModuleManifest

cmdlet New-ModuleManifest at command pipeline position 1
Supply values for the following parameters:
Path: c:\Moduly\Kurzy\Kurzy.psd1
NestedModules[0]:
Author: David Moravec
CompanyName: PowerShell.cz
Copyright:
ModuleToProcess:
Description: Zjisteni aktualnich kurzu pro jednotlive meny
TypesToProcess[0]:
FormatsToProcess[0]:
RequiredAssemblies[0]:
FileList[0]:

Vidíte, že některé z parametrů jsem přeskočil a vyplnil jsem pouze cestu k manifestu, jméno autora a popis modulu. PowerShell automaticky vytvořil soubor a uložil jej do námi definované cesty.

Poznámka: Nebudu zde celý soubor vypisovat. Jedná se zhruba o 100 řádek hodnot a komentářů. Pokud se chcete podívat, jak manifest vypadá, spusťte si předchozí cmdlet na vašem počítači. Zároveň si všimněte, že některé hodnoty, které jsem nezadával, si PowerShell doplnil automaticky (např. GUID).

Nyní si můžeme opětovně pustit první příkaz dnešního článku.

PS C:\> Get-Module Kurzy | fl *

ExportedCommands : {}
Name : Kurzy
Path : C:\Moduly\Kurzy\Kurzy.psd1
Description : Zjisteni aktualnich kurzu pro jednotlive meny
Guid : b0ec4496-18da-4e61-a37a-f98fc2b6e74a
ModuleBase : C:\Moduly\Kurzy
PrivateData :
Version : 1.0
ModuleType : Manifest
AccessMode : ReadWrite
ExportedFunctions : {}
ExportedCmdlets : {}
NestedModules : {}
RequiredModules : {}
ExportedVariables : {}
ExportedAliases : {}
SessionState :
OnRemove :
ExportedFormatFiles : {}
ExportedTypeFiles : {}

A ihned vidíme změny. ModuleType se změnil na Manifest (z původního Script) a byly doplněny některé parametry. V manifestu můžeme určovat, jaké funkce či aliasy budeme exportovat, jestli potřebujeme pro běh našeho modulu nějaký jiný modul, jakou verzi PowerShellu potřebujeme, atd. Pro podrobnější zkoumání doporučuji podívat se do vytvořeného manifest souboru a sledovat komentáře.

Všimněte si jedné velké záludnosti! V seznamu exportovaných aliasů/funkcí nevidíme vůbec nic. Je to z toho důvodu, že jsme neuvedli žádnou hodnotu pro parametr ModuleToProcess. Můžeme to napravit ruční editací manifestu a opětovným importem modulu. Pak již bude vše v pořádku.

PS C:\> (Get-Module Kurzy).ExportedCommands

Name Value
---- -----
usd usd
eur eur
Get-Kurz Get-Kurz

Pokud editujete manifest ručně, může se vám hodit cmdlet Test-ModuleManifest. Ten provede kontrolu správnosti manifestu a pokud neohlásí chybu je vše v pořádku (alespoň z pohledu manifestu samotného).

PS C:\Scripts > Test-ModuleManifest -Path 'C:\Moduly\Kurzy\Kurzy.psd1'

Test-ModuleManifest : The 'C:\Moduly\Kurzy\Kurzy.psd1' module cannot be imported because its manifest contains one or more members that are not valid. The valid manifest members are ('ModuleToProcess', 'NestedModules', 'GUID', 'Author', 'CompanyName', 'Copyright', 'ModuleVersion', 'Description', 'PowerShellVersion', 'PowerShellHostName', 'PowerShellHostVersion', 'CLRVersion', 'DotNetFrameworkVersion', 'ProcessorArchitecture', 'RequiredModules', 'TypesToProcess', 'FormatsToProcess', 'ScriptsToProcess', 'PrivateData', 'RequiredAssemblies', 'ModuleList', 'FileList', 'FunctionsToExport', 'VariablesToExport', 'AliasesToExport', 'CmdletsToExport'). Remove the members that are not valid ('CompanyNme'), then try to import the module again.
At line:1 char:20
+ Test-ModuleManifest <<<< -Path 'C:\Moduly\Kurzy\Kurzy.psd1'
    + CategoryInfo : InvalidData: ('C:\Moduly\Kurzy.psd1:String) [Test-ModuleManifest], InvalidOperationException
    + FullyQualifiedErrorId : Modules_InvalidManifestMember,Microsoft.PowerShell.Commands.TestModuleManifestCommand

ModuleType Name ExportedCommands
---------- ---- ----------------
Script kurzy {usd, eur, Get-Kurz}

Pokud se pozorně podíváte do chybového výpisu, všimnete si, že zhruba v polovině se objevilo

Remove the members that are not valid ('CompanyNme'), then try to import the module again.

Opravdu – ručně jsem změnil správnou hodnotu CompanyName na špatnou CompanyNme. Po opravě už je manifest otestován správně.

Závěrem

Nakonec bych vám ještě rád ukázal několik zajímavých modulů.

PSCX – PowerShell Community Extensions dostupné na Codeplexu. Jedná se o velice pěknou sadu 87 cmdletů:

PS C:\> gcm -Module pscx -CommandType cmdlet | Format-Wide

Add-PathVariable
Clear-MSMQueue
ConvertFrom-Base64
ConvertTo-Base64
ConvertTo-MacOs9LineEnding
ConvertTo-Metric
ConvertTo-UnixLineEnding
ConvertTo-WindowsLineEnding
Convert-Xml
Disconnect-TerminalSession
Expand-Archive
Export-Bitmap
Format-Byte
Format-Hex
Format-Xml
Get-ADObject
Get-AdoConnection
Get-AdoDataProvider
Get-AlternateDataStream
Get-Clipboard
Get-DhcpServer
Get-DomainController
Get-DriveInfo
Get-EnvironmentBlock
Get-FileTail
Get-FileVersionInfo
Get-ForegroundWindow
Get-Hash
Get-HttpResource
Get-LoremIpsum
Get-MountPoint
Get-MSMQueue
Get-OpticalDriveInfo
Get-PathVariable
Get-PEHeader
Get-Privilege
Get-PSSnapinHelp
Get-ReparsePoint
Get-ShortPath
Get-TabExpansion
Get-TerminalSession
Get-TypeName
Get-Uptime
Import-Bitmap
Invoke-AdoCommand
Invoke-Apartment
Join-String
New-Hardlink
New-Junction
New-MSMQueue
New-Shortcut
New-Symlink
Out-Clipboard
Ping-Host
Pop-EnvironmentBlock
Push-EnvironmentBlock
Read-Archive
Receive-MSMQueue
Remove-AlternateDataStream
Remove-MountPoint
Remove-ReparsePoint
Resolve-Host
Send-MSMQueue
Send-SmtpMail
Set-BitmapSize
Set-Clipboard
Set-FileTime
Set-ForegroundWindow
Set-PathVariable
Set-Privilege
Set-VolumeLabel
Skip-Object
Split-String
Start-TabExpansion
Stop-TerminalSession
Test-AlternateDataStream
Test-Assembly
Test-MSMQueue
Test-Script
Test-UserGroupMembership
Test-Xml
Unblock-File
Write-BZip2
Write-Clipboard
Write-GZip
Write-Tar
Write-Zip

Rozhodně je vyzkoušejte, některé cmdlety jsou hodně povedené.

SQLPSX – SQL Server PowerShell Extensions (opět na Codeplexu) slouží k práci s SQL serverem. Velké plus vidím v integraci s ISE, kde můžete použít například Object Browser.

WPK – jako součást PowerShellPacku, o tomto module jsem již psal v jedné z předchozích částí.

Tímto bychom ukončili naše putování po modulech. Příště se podíváme na procházení logů a jejich filtrování pomocí regulárních výrazů.

- David Moravec