Jak důležitá je nápověda u Powershellu? Moc!

Příklad na to, jak důležité informace jsou v nápovědě a na typ objektu vystupujícího z jednoho cmdletu a vstupujícího do druhého cmdletu:
Chceme killnout („zabít“) nějaký proces:

Get-Process | Get-Member
vrátí na první řádce TypeName: System.Diagnostics.Process a následně všechny metody a vlastnosti pro procesy - mezi vlastnostmi je vlastnost Id a Name (tady vidíte, jak důležitý cmdlet ten Get-Member je!).
Nyní si zjistíme, jaký typ vstupního objektu a jaké sady parametrů má cmdlet Stop-Process, který killne process:
get-help -Name Stop-Process –Full
V sekci Inputs je System.Diagnostics.Process (čili typ objektu vystupujícího z cmdletu Get-Process je stejný jako typ objektu vstupujícího do cmdletu Stop-Process). Ještě si v nápovědě zkontrolujeme jaké má cmdlet Stop-Process sady parametrů. Lze vidět, že proces lze předat jeho vlastností Id (ByPropertyName typu Int32) – což je implicitní sada parametrů, vlastním objektem (ByValue) nebo vlastností Name (ByPropertyName typu String).  Čili, když Stop-Process na vstupu nenajde u vstupujícího objektu vlastnost Id, ověří si, zda je objekt typu System.Diagnostics.Process a pokud ne, tak u vstupujícího objektu hledá vlastnost Name. Uvědomte si, že vlastnost Id nebo Name má spousta objektů různých typů! A v případě sady parametrů, která pracuje s ByPropertyName, je jedno o jaký typ objektu jde! V tomto případě je cmdletu Stop-Process jedno, zda se jedná o objekt typu System.Diagnostics.Process  nebo jiný typ objektu! Tady si musíte dát pozor, aby nedošlo k tomu, že do Stop-Process pošlete něco jiného, než jste zamýšleli (a můžete si tak zrušit systémový proces nebo procesy). Proto doporučuji tam, kde jde o hodně používat při testování parametr –WhatIf, který nám řekne co by se stalo, ale vlastní cmdlet nevykoná.
Příklad:
Vybereme z běžících procesů jen ty se jménem iexplore:
Get-Process | ? {$_.Name -eq "iexplore"} | Stop-Process
zde si odpovídají typy objektů a není co řešit.

Máme nějaký cmdlet nebo spíše funkci (může jít o váš vlastní cmdlet, u kterého lze měnit vlastnosti), která má vracet Id nebo Name procesu, který chcete zrušit (v následujícím případě použiji cmdlet, který vrací jména souborů z adresáře - je to pitomé, ale snad názorné):
Get-ChildItem -Path C:\temp | % {$_.BaseName} | Stop-Process
jelikož do Stop-Process nevstupuje v tomto případě typ objektu System.Diagnostics.Process, tak cmdlet Stop -Process nejprve hledá vlastnost Id (tu soubor nemá) a tak hledá vlastnost Name a tu soubor má! Takže můžete killnout úplně jiný proces než jste chtěli, protože v adresáři můžete mít například soubor se jménem lsass.txt (a zrušíte tak proces lsass)!

Takže použijte pro testování:
Get-ChildItem -Path C:\temp | % {$_.BaseName} | Stop-Process –WhatIf

A ověřte si, zda se vám rourou nemůže dostat nesprávná hodnota vlastnosti Id nebo Name.

Posted by Igor Pechanec Saturday, April 20, 2013 8:53:00 PM Categories: Tipy, rady, příklady
Igor Pechanec © 2016-2017, all rights reserved