pondělí 21. prosince 2009

PowerShell film :) [EN]

I can't resist :) Check this out: http://www.mycitymovie.com/id/eec2cae746bdb67ba2755af688d36ee8/



It's understandable even for non-Czech people. Here is the translation of the beginning of the clip:
  • All mornings are same
  • But some are different ...

and during:

  • It's your world
  • MY CITY - already in your life.

I noticed that sometimes the text is missing during the clip. So if you think there has to be something but it's not, you can run the clip again - click Přehrát znovu at the end.

neděle 20. prosince 2009

PowerGUI – část 1.

Vzhledem k tomu, že jsem v poslední době hodně pracoval s PowerGUI, rozhodl jsem se, že těm z vás, kteří tento editor nepoužívají, jej trochu přiblížím.

PowerGUI se skládá ze dvou částí: Admin konzole (ve stylu MMC) a Script Editor. Dnes se podíváme na konzoli, v příštím díle na editor a v závěrečném díle si ukážeme, jak vytvořit vlastní PowerPack.

PowerGUI je volně dostupný nástroj of firmy Quest Software. S touto firmou jsem se potkal již několikrát a i když nepoužívám žádný z jejich komerčních nástrojů, hojně využívám jejich volně dostupných nástrojů. Alespoň pro pořádek musím zmínit vynikající Active Roles Management Shell for Active Directory – do příchodu Windows 2008 Serveru víceméně jediné PowerShell cmdlety pro správu Active Directory (ani nespočítám kolik mi ušetřily času a nervů) a dále např. online konferenci Quest Connect. Z hlediska PowerShellu je zajímavé, že ve firmě Quest pracují i Dmitry Sotnikov a Kirk Munro – oba PowerShell MVP.

Dost bylo chvály. PowerGUI si můžete stáhnout ze stránek PowerGUI.org. Jelikož je PowerGUI grafická nadstavba nad PowerShellem, musíte mít PowerShell nainstalovám (nepředpokládám, že návštěvníci těchto stránek jej nemají). Po instalaci a spuštění se vám objeví podobný obrázek.

powergui

Pod menu a toolbarem je okno rozdělěno na tři části: Navigation Tree, Results/PowerShell Scripts a Actions. V závislosti na vašem vlastním nastavení se toto rozložení může měnit. Vzhled je hodně podoný MMC konzoli ve verzi 3.

V Navigation Tree jsou vidět dostupné instalované PowerPacky (viz dále). Při instalaci si můžete zvolit, které chcete používat. Každý PowerPack obsahuje vnořené nody, kterým jsou přiřazeny určité akce. Například ve větvi Local jsou dostupné akce, které můžete provádět na lokálním PC. Od správy procesů, služeb, sdílených složek přes procházení – a práci se – souborovým systémem, registry, až po brouzdání v WMI. Existují tři základní typy nódů:

  • Adresář – slouží k přehlednějšímu řazení ostatních typů nódů
  • Základní nód – Lze jej použít pro práci s cmdlety dostupnými v aktuální session PowerGUI
  • Script nód – Nejflexibilnější ze všech nódů. Může obsahovat jakýkoli skript, který vrací nějaký objekt. Tento objekt (objekty) pak zobrazí v konzoli. Script nód může být ještě jednoho speciálního typu, takzvaný dynamic. Tento nód je generovaný automaticky za běhu programu. Registry a Drive jsou například oba dynamické.

Pojďme si nyní ukázat trochu praktickou ukázku práce s PowerGUI. Chtěli bychom získat seznam služeb, které jsou právě zastavené a pokud se nám to u některé nelíbí, spustíme ji.

  1. Otevřete konzoli PowerGUI a klikněte na nód Local System a poté Services.
  2. Zobrazí se seznam procesů stejný, jaký byste viděli při otevření snap-inu Services ve Windows. Všimněte si, že panel s akcemi vpravo se změnil (stejně jako v MMC) a jsou dostupné metody, které můžete aplikovat na služby.
  3. Klikněte na položku Filters nad seznamem služeb a definujte si vlastní pravidlo. V našem případě to bude:
    filter
  4. Všechny zastavené služby se objeví ve spodním panelu.
  5. Vyberte službu, kterou chcete spustit a na pravé straně v Action panelu vyberte položku Start a služba bude spuštěna. Zároveń se aktualizuje pohled a vámi vybraná služba zmizí ze seznamu. Najdete ji buď změnou filteru nebo jeho úplným vypnutím pomocí tlačítka Clear All.

PowerPacky

Před chvílí jsem zmiňoval, že existují jakési PowerPacky. Pokud se vrátím k analogii s MMC, tak PowerPack je v PowerGUI to samé jako snap-in v MMC. Jedná se tedy o jakési “rozšíření” pomocí kterého můžete ovládat určité části systému (nebo systémy jako celek).

V průběhu instalace jste si určitě všimli, že můžete přidat např. PowerPack pro práci s Active Directory. Tento PowerPack využívá dříve zmiňovaný Management Shell for AD a cmdlety v něm obsažené jsou PowerPackem spouštěny. Na stránkách PowerGUI jsou dostupné PowerPacky od různých autorů a pokud se vám idea PowerGUI zalíbí, možná na těchto stránkách najdete zrovna ten, který se hodí pro vaši práci. Pokud žádný takový nenajdete, můžete si vytvořit vlastní a poté ho třeba nahrát na web, aby i ostatní mohli těžit z plodů vaší práce. O tvorbě PowerPacku si povíme ve třetí částí této minisérie.

Proč PowerGUI

V konzoli vidím obrovskou výhodu – na jednom místě máte dostupné “všechny” nástroje, které potřebujete. Chcete se podívat, jak vám běží Exchange, IIS nebo třeba VMware server. Nemusíte se přepínat mezi různými konzolemi a potřebné informace máte po ruce. Další výhodou je, že můžete před některými uživateli skrýt určitou funkčnost a tak třeba vaši lidé na helpdesku budou mít možnost pouze na odemykání účtů a nikoli jejich mazání.

Nevýhodou může být považována například rychlost (někdy spíše pomalost) konzole. Musíte myslet na to, že na pozadí běží nějaký příkaz PowerShellu a ten nemusí být vždy nejrychlejší variantou získávání informací. Na druhou stranu – ve svém SMS PowerPacku používám ve většině případů přístup do WMI přes síť a rychlost pro mne není limitujícím faktorem většiny operací.

úterý 1. prosince 2009

PowerPack Challenge 2009

Dnes ráno byly vyhlášeny výsledky letošního ročníku PowerPack Challenge, pořádaného firmou Quest Software.

Letošním vítězem se stal Alan Renouf s jeho Virtu-Al.Net VMware Virtual Infrastructure / vSphere scripts PowerPackem.

Já jsem se svým SMS 2003 PowerPackem dostal hodnocení Honorable Mention a stal se tak šťastným majitelem dárkového certifikátu na Amazon.com.

Po dlouhé odmlce způsobené i tím, že jsem po nocích programoval můj PowerPack se tedy vrátím k častějšímu přispívání na tyto stránky.

sobota 26. září 2009

Přístup na webové stránky

Občas se mi hodí, když mohu pomocí PowerShellu přistoupit na nějakou webovou stránku a stáhnout si ji na disk. Až donedávna jsem používal skript, který jsem vždy měnil podle toho, kde jsem právě byl. V práci jsem vypisoval proxy server a doma jsem jej ze skriptu mazal. Jelikož tento přístup není rozhodně ideální, hledal jsem cestu, jak toto obejít. Jako vždy mi pomohlo MSDN.

Prvním krokem je vytvořit nový objekt založený na třídě WebClient. Poté je potřeba tomuto objektu přiřadit aktuální proxy server (založený na třídě WebProxy). Podrobné informace jsou v komentářích v následujícím kódu.
  1. # nastavit stranku, kterou chceme stahnout
  2. $url = "http://www.powershell.cz"
  3. # vytvorit objekt WebClient
  4. $wc = New-Object System.Net.WebClient
  5. # nastavit defaultni proxy
  6. $proxy = [System.Net.WebProxy]::GetDefaultProxy()
  7. # a pouzit aktualni prihlasovaci udaje
  8. $proxy.UseDefaultCredentials = $true
  9. # pote priradit proxy k objektu WebClient
  10. $wc.proxy = $proxy
  11. # pote stahnout pozadovanou stranku jako text
  12. $wc.DownloadString($url)
Pokud nechcete výpis kódu stránky do konzole, můžete místo metody DownloadString použít DownloadFile.

úterý 15. září 2009

2. díl série o PowerShellu v TechNet Flash zpravodaji

Včera vyšel další díl TechNet Flash zpravodaje. Obsahuje mimojiné druhý díl série o Windows PowerShellu, tentokrát na téma Objekty a roury. Článek je možné nalézt na TechNetu.

Pokud ještě TechNet Flash neodebíráte, můžete to napravit.

čtvrtek 10. září 2009

PowerShell v2 pro Win XP a W2K3

A je to tady! PowerShell v2 pro Win XP a 2003 Server (obě verze zatím jako RC) je zde. Stahovat lze z MS Connect.

Huráááá :)

středa 9. září 2009

Anketa: Novinky v PowerShellu

Mám pro vás další anketu. Loni jsem začal s týdenním publikováním novinek v PowerShellu. Ke konci roku jsem s tím přestal, ale vzhledem k tomu, že v současné době začínám pracovat na nové verzi stránek, měl bych dotaz.

Vyhovovalo by vám více okamžité publikování zajímavostí (ve stylu posledních videí) nebo byste radši uvítali týdenní souhrn (ve stylu předchozích Get-PSNews)?

V případě okamžitých novinek bych zřejmě nepublikoval vše, co bych jinak uvedl do týdenního přehledu. Samozřejmě opravdu horké novinky (např. nyní očekávané RC v2 pro XP a 2003 Server) bych publikoval okamžitě.

Dejte mi vědět váš názor. Ať již vyplněním ankety, komentářem pod tímto příspěvkem nebo přes Twitter (@makovec).

Krishna Vutukuri a Remote Sessions

Na Channel 9 jsou dostupná další tři videa o PowerShellu. Tentokrát na téma Remote Sessions. Prezentujícím je (pro mne neznámý) Krishna Vutukuri - PowerShell SDE.

neděle 6. září 2009

James Brundage o PowerShellu

Poslední dobou se roztrhl pytel s nahrávkami o PowerShellu. Po Jeffrey Snoverovi a Bruce Payettovi se můžete podívat na dalšího člena vývojového týmu - hostem na Channel 9 byl tentokrát James Brundage.

Nejprve se věnoval základům PowerShellu:
V druhé sérii mluvil o cmdletech pro práci s objekty (shodou okolností připravuji článek na stejné téma pro jedno z dalších vydání TechNet Flashe).

čtvrtek 3. září 2009

PSv2 Modules

Na TechNet Edge se objevila další tři videa o PowerShellu. Tentokráte s Brucem Payettem v hlavní roli. Bruce se rozpovídal na téma moduly v PowerShellu v2.
  1. PSv2 Modules : An Introduction with Bruce Payette
  2. PSv2 Modules : How to use Them
  3. PSv2 Modules : Write Script and Binary Modules
Je skvělé, že po předchozích sériích s Jeffreym Snoverem a Jamesem Brundagem pokračuje PowerShell tým v šíření osvěty :)

středa 26. srpna 2009

Discussions with the Architect

Dnes ráno jsem si na Twitteru všiml zprávy o nové třídílné sérii na téma PowerShell. Podtitulek -Discussions with the Architect - dává tušit, že hostem je Jeffrey Snover.

Pokud vás téma zajímá, můžete se na videa podívat na následujících stránkách:

úterý 25. srpna 2009

Jak na Active Directory z PowerShellu

Pokud pracujete s Active Directory a chtěli byste se dozvědět více o skriptování AD pomocí PowerShellu, můžete využít akci firmy Quest Software. Kniha Managing Active Directory with Windows PowerShell: TFM® je nyní dostupná zdarma.

Stačí se zaregistrovat na stránkách Questu a kniha vám bude doručena až do schránky (emailové). Autorem knihy je Jeffrey Hicks, což myslím mluví za vše. Já mám knihu delší dobu z poslední podobné akce a i když se mi na ní ne všechno líbí, klady rozhodně převažují.

středa 19. srpna 2009

AD: Přidání uživatelů do skupiny

O práci s Active Directory jsem toho zde zatím moc nepsal. Vzhledem k tomu, že poslední dobou dělám malinko pořádek ve skupinách, příspěvky budou zřejmě častější. Za posledních pár dní jsem narazil na dvě věci, se kterými se můžete potkat.

První z nich je zjišťení FSMO rolí. Pokud s AD pracujete častěji určitě znáte příkaz netdom query fsmo. Stejné informace zjistíte pomocí následujících příkazů PowerShellu:
PS C:\> [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest() | fl *RoleOwner

SchemaRoleOwner : server1.domena.net
NamingRoleOwner : server1.domena.net

PS C:\> [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain() | fl *RoleOwner

PdcRoleOwner : server2.sub.domena.net
RidRoleOwner : server2.sub.domena.net
InfrastructureRoleOwner : server2.sub.domena.net

Pro přehlednější výpis si můžete předchozí příkazy zabalit do funkce, ale to už je pouze otázka vkusu (a šetření času).
Druhou věcí, se kterou jsem se potkal, je kopie členů skupiny do jiné skupiny. Opět existuje několik cest, jak to udělat (např. pomocí ds* příkazů), ale v tuto chvíli vidím PowerShell jako lepší řešení. Já se ještě rozhodl zadání trochu upravit, taže výsledkem bylo: Vzít všechny členy skupiny users.all, vybrat pouze účty, které jsou enabled a přidat je do skupiny users.all.new.
Tři úkoly, tři cmdlety, dvě roury.
PS C:\> Get-QADGroupMember 'users.all' | Get-QADUser -Enabled | Add-QADGroupMember 'users.all.new'

Edit: Poté, co jsem se přepl na počítač s nejnovější verzi cmdletů od Questu zjistil jsem, že přidali nový parametr pro Get-QADUser. Správně by tedy mohlo být i toto (celá akce je pak o mnoho rychlejší - na mém počítači 12x):
PS C:\> Get-QADUser -MemberOf 'users.all' -Enabled | Add-QADGroupMember 'users.all.new'

Použité cmdlety nejsou standardní součástí PowerShellu, ale dají se zdarma stáhnout z webu firmy Quest Software.

neděle 9. srpna 2009

PowerShell in Practice - první pohled

Včera jsem si objednal další knihu o PowerShellu - PowerShell in Practice. Knihu vydá (vysvětlím vzápětí) nakladatelství Manning Publications

Budoucí čas jsem použil zcela záměrně, Manning nabízí možnost přístupu k jednotlivým kapitolám knihy ihned po jejich napsání. To přináší výhody jak pro nakladatele, tak pro čtenáře. Autor je v kontaktu se čtenáři a Ti mohou (ale není to pravidlo) ovlivnit obsah knihy (samozřejmě v určitých mezích). Manning tento program nazývá Manning Early Access Program (MEAP). 

Autorem knihy je Richard Siddaway - PowerShell MVP, zakladatel UK PowerShell User Group, blogger.

První varování - kniha není učebnicí PowerShellu! Obsahuje sice kapitoly PowerShell fundamentals a Learning PowerShell, ale na šedesáti stranách nemůžete očekávat zázraky. Jedná se opravdu o velice lehký úvod. V dalších dvou kapitolách je popsána práce s .NET, COM objekty WMI a také skriptování obecně.

Další kapitoly jsou již brány tématicky a věnují se například práci s uživatelskými účty, mailboxy (Exchange 2007), DNS, AD, IIS 7, SQL Server. Nedá mi to, abych knihu nesrovnával s Windows PowerShell Cookbook od Lee Holmese. V Cookbooku je schéma následující: otázka - odpověď. V PowerShell in Practice je dané téma a toto téma je zpracováno do kapitol. Jak už jsem řekl, vzhledem k rozsahu knihy není možné obsáhnout téma do hloubky.

Zatím jsem knihu jen tak prolétl, ale jsem z ní trochu rozpačitý. Na naučení základů PowerShellu jsou lepší jiné a pokud chcete zvládnout PowerShell pro konkrétní produkt, jsou zde popsány základy a na trhu existují i podrobnější knihy (např. pro AD nebo Exchange). na druhou stranu - já si knihu kupoval s tím, že se dozvím právě ty základy ovládání produktů, se kterými nepracuji a to kniha splňuje. Mimoto jsem měl kupón na slevu 37%, takže jsem za zhruba 300 Kč získal další relativně dobrý zdroj névých informací.

Ke knize se ještě vrátím až ji budu mít pročtenou podrobněji.

sobota 8. srpna 2009

Scripting Games 2009 - Event 3

Třetí úkol se jmenoval The shot put.

Divize Advanced
V zadaném vstupním souboru bylo potřeba najít slova (řádky), které obsahují pouze jednu samohlásku (mohla se opakovat), čili ananas je správně, ale ahoj nikoli.
  1. gc './Wordlist_ADV3.txt' |? {(($_.ToCharArray() -match '[aeiouy]'| group)|measure-object).count -eq 1} | out-file result.txt
Použil jsem one-liner, který provádí následující:
  1. načte vstupní soubor
  2. vstupní řádku převede na pole znaků ($_.ToCharArray()). Pokud je v poli znaků pouze jedna samohláska
  3. vypíše vstupní řádku do souboru
Ani v tomto případě se nejednalo o žádnou záludnost. Je dobré vědět, že řetězec znaků lze převést na pole znaků pomocí metody ToCharArray().

Divize Beginners
Vstupní soubor se měl rozdělit na dva a v každém novém souboru měl být jeden odstavec originálního souboru. Ten se měl poté přejmenovat.
  1. (gc s*)[0..4] | Out-File 'First par.txt'
  2. (gc s*)[6..8] | Out-File 'Second par.txt'
  3. ren 'shot put.txt' 'Shot put.old'
V tomto případě jsem nehodlal ztrácet čas a problém jsem vyřešil jako kdyby to bylo ve skutečnosti - bez nějakého ošetřování pomocí tupého kódu.

Získávání informací z WMI

V jednom z předchozích článků jsem slíbil, že se někdy podrobněji podíváme na přístup do WMI pomocí PowerShellu. Ta doba právě nastala :)
O WMI (Windows Management Instrumentation) jste jistě alespoň slyšeli. Pokud ne, určitě vám doporučuji se podívat, k čemu je WMI dobré - můžete začít na Wikipedii nebo na stránkách Microsoftu. Pro potřeby tohoto článku budu předpokládat, že máte alespoň základní představu o tom, k čemu WMI slouží.
Úkol pro všechny následující příklady bude stejný: zjistit všechny běžící procesy s názvem notepad.exe a vypsat jejich ProcessID. Na konci každého příkladu uvedu průměrný čas rychlosti zpracování pro 10 stejných dotazů.
Filtrování pomocí Where-Object
Zrějmě prvním nápadem bude použití standardních příkazů PowerShellu bez nějakého hlubšího zkoumání dalších okolností.
PS C:\> gwmi Win32_Process |? {$_.Name -eq 'notepad.exe'} | select ProcessId
ProcessId
---------
     2072
     5228
Tento postup je přímočarý a pokud potřebujete z WMI "tahat" data pouze příležitostně, bude vám zřejmě stačit. Pokud budete s WMI pracovat častěji (a budete zpracovávat větší množství dat) začne vám za chvíli vadit rychlost (resp. pomalost) zpracování dat. Nevýhodou tohoto přístupu je totiž to, že čtete z WMI všechny procesy a ty pak rourou posíláte cmdletu Where-Object (v mém příkladu zastoupeném jeho aliasem '?' - znak otazník).
Rychlost: 1535 ms
Parametr -Filter
Cmdlet Get-WmiObject má parametr -Filter. Použítím tohoto parametru filtrujete data již na úrovni WMI a dále pracujete pouze s procesy (objekty), které splňují zadané kritérium.
PS C:\> gwmi Win32_Process -filter "name='notepad.exe'" | select ProcessID

ProcessID
---------
     2072
     5228
Rychlost zpracování v tomto případě je 595 ms. Cmdlet Select-Object (resp. jeho alias select) je v tomto případě použit z toho důvodu, že filter nám vrací všechny vlastnosti a my jsme na začátku řekli, že budeme vypisovat pouze ID procesu.
Parametr -Query
Pokud ovládáte jazyk WQL (WMI Query Language) můžete pomocí něj specifikovat dotaz v parametru -Query. Celý příkaz by pak vypadal následovně:
PS C:\> gwmi -Query "SELECT ProcessID FROM Win32_Process WHERE Name='notepad.exe'"

__GENUS : 2
__CLASS : Win32_Process
__SUPERCLASS :
__DYNASTY :
__RELPATH :
__PROPERTY_COUNT : 1
__DERIVATION : {}
__SERVER :
__NAMESPACE :
__PATH :
ProcessId : 2072

__GENUS : 2
__CLASS : Win32_Process
__SUPERCLASS :
__DYNASTY :
__RELPATH :
__PROPERTY_COUNT : 1
__DERIVATION : {}
__SERVER :
__NAMESPACE :
__PATH :
ProcessId : 5228
PowerShell přidal do výpisu ještě několik vlastností, které nás momentálně nezajímají (začínají dvěma podtržítky). Pokud bychom je chtěli odstranit, můžeme opět použít cmdlet Select-Object. Rychlost zpracování byla 573 ms.
Shrnutí
Z předchozích příkladů je vidět, že pokud chcete pracovat s WMI je dobré si rozmyslet, jakým způsobem k němu budete přistupovat. Pokud občas potřebujete okamžitý výsledek z lokálního počítače (a vámi dotazovaná třída nemá tisíce členů), první postup vám možná bude vyhovovat. V případě většího množství dat (případně dotazů na vzdálený počítač) je dobré se naučit používat parametry -Filter nebo -Query.

čtvrtek 6. srpna 2009

Hej, mistře Šelíku!

V posledním vydání TechNet Flash zpravodaje zaujaly mistra Šelíka dvě věci.
  1. Strip jeho kamaráda mistra Skriptíka.
  2. První díl ze série článků o PowerShellu - snad se nám blýská na lepší časy.
Mistr Skriptík tentokrát řešil práci se službami, pojďme se podívat.

Vzhledem k tomu, že služby jsou jednou ze základních komponent, se kterou se administrátor Windows může potkat, má v sobě PowerShell zabudováno hned několik cmdletů pro práci s nimi.

PS C:\> Get-Help *-service | Select name
Name
----
Get-Service
Stop-Service
Start-Service
Suspend-Service
Resume-Service
Restart-Service
Set-Service
New-Service

My se podíváme na Get-Service, Stop-Service a Start-Service. Pro zjištění stavu všech služeb použijeme Get-Service - dostaneme výpis všech služeb včetně jejich aktuálního stavu (výpis jsem notně zkrátil).
PS C:\> Get-Service
Status Name
------ ----
Stopped ADAM_Test
Stopped Alerter
Running ALG
Stopped AppMgmt
Stopped aspnet_state
Running AudioSrv
Running BITS
Running Browser
Running CryptSvc
Running DcomLaunch
Running Dhcp
Running Eventlog
Running EventSystem
Running Spooler

Pro zastavení služby použijeme Stop-Service (spsv) a pro spuštění Start-Service (sasv). V závorkách jsou uvedeny aliasy pro dané cmdlety (pro Get-Service je to gsv).
PS C:\> gsv spooler

Status Name DisplayName
------ ---- -----------
Running Spooler Print Spooler
PS C:\> spsv spooler
PS C:\> gsv spooler

Status Name DisplayName
------ ---- -----------
Stopped Spooler Print Spooler
PS C:\> sasv spooler
PS C:\> gsv spooler

Status Name DisplayName
------ ---- -----------
Running Spooler Print Spooler

Je vidět, že pomocí PowerShellu je práce se službami přímočará a velice jednoduchá.
Pokud je někdo zvídavý a přecijen by chtěl pracovat se službami přes WMI, lze pro zastavení spooleru použít následující příkaz:
PS C:\> (gwmi Win32_Service -filter "name='spooler'").StopService()

__GENUS : 2
__CLASS : __PARAMETERS
__SUPERCLASS :
__DYNASTY : __PARAMETERS
__RELPATH :
__PROPERTY_COUNT : 1
__DERIVATION : {}
__SERVER :
__NAMESPACE :
__PATH :
ReturnValue : 0

Vidíme, že ReturnValue je nula, čili služba byla zastavena úspěšně. Pokud by ReturnValue byla jiná, lze její význam najít na MSDN.
To by bylo pro dnešek vše. Jdu stejně jako mistr Skriptík vyhlížet Windows 7.
Banner mistra Skriptíka je stažen ze stránek TechNet Flash zpravodaje. Děkuji týmu TechNetu za možnost jeho použití pro potřeby tohoto článku.

sobota 1. srpna 2009

Hej, mistře Šelíku!

Po odmlce způsobené pracovní zátěží a poté zaslouženou dovolenou jsme se s mistrem Šelíkem vrátili zpět do práce.

Pro základní práci s procesy lze v PowerShellu použít cmdlet Get-Process (nebo můžete použít alias gps). Při prostém zadání bez parametrů vypíše seznam běžících procesů. Pokud vás zajímá konkrétní proces, stačí uvést jeho jméno.

PS C:\> Get-Process powershell
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
656 14 55592 63296 270 4,29 264 powershell

V případě, že chcete vypsat všechny informace, použijte Format-List
PS C:\> Get-Process powershell | Format-List *
V tomto případě bych se ovšem přikláněl k použítí aliasů

PS C:\> gps powershell | fl *
PS C:\> gps pow* | fl *

přičemž druhý zápis by mohl způsobit "problémy" pokud na vašem počítači poběží proces s názvem např. powercfg.

Jistě jste si všimli, že ve výpisu není nikde vidět vlastník procesu. Je tedy nutné - na radu mistra Skriptíka - použít přístup přes WMI. V PowerShellu je přístup do WMI geniálně jednoduchou záležitostí. Je několik možností, jak cmdlet Get-WmiObject použít. Nyní je nebudu porovnávat, ale beru to jako námět na další článek. Nebudu ani vypisovat výsledek, protože to vždy bude jméno uživatele, který proces spustil. Při práci z příkazové řádky vždy používám pro Get-WmiObject jeho alias gwmi - ušetřím tím přesně $("get-wmiobject".length - "gwmi".length) znaků :)

PS C:\> gwmi win32_process |? {$_.name -eq 'powershell.exe'} | % {$_.GetOwner().User}
PS C:\> (gwmi win32_process |? {$_.name -eq 'powershell.exe'}).GetOwner().User
PS C:\> (gwmi win32_process -filter "name='powershell.exe'").GetOwner().user
PS C:\> (gwmi -query "select * from Win32_Process where name='powershell.exe'").GetOwner().User

Banner mistra Skriptíka je stažen ze stránek TechNet Flash zpravodaje. Děkuji týmu TechNetu za možnost jeho použití pro potřeby tohoto článku.

čtvrtek 25. června 2009

Scripting Games 2009 - Event 2

Úkol číslo dva byl nazván The Long Jump.

Divize Advanced
Z daného souboru (XLS) bylo potřeba zjistit délky skoků jednotlivých sportovců a na základě výkonů v sezóně určit zda splnili očekávání do nich vkládaná.

  1. $path = "C:\sg2009\LongJump_Adv2.xls"
  2. $xls = New-Object -com Excel.Application
  3. $xls.Visible = $true
  4. $wrkbk = $xls.Workbooks.Open($path)
  5. $format = 23
  6. $wrkbk.SaveAs('C:\sg2009\result.csv',$format)
  7. $wrkbk.Close($true)
  8. $xls.Quit()
  9. $data = Import-Csv C:\sg2009\result.csv
  10. foreach ($row in $data) {
  11. if ($row.'Jump 1' -eq 'x') { $row.'Jump 1' = 0 }
  12. if ($row.'Jump 2' -eq 'x') { $row.'Jump 2' = 0 }
  13. if ($row.'Jump 3' -eq 'x') { $row.'Jump 3' = 0 }
  14. if (([double]$row.'Jump 1' -ge [double]$row.'Jump 2') -and ([double]$row.'Jump 1' -ge [double]$row.'Jump 3')) {
  15. [double]$row.Result = $row.'Jump 1'
  16. }
  17. elseif (([double]$row.'Jump 2' -ge [double]$row.'Jump 1') -and ([double]$row.'Jump 2' -ge [double]$row.'Jump 3')) {
  18. [double]$row.Result = $row.'Jump 2'
  19. }
  20. else {
  21. [double]$row.Result = $row.'Jump 3'
  22. }
  23. if ($row.Result -lt $row.'Season Average') {
  24. $row.'Exceed/Achieve/Under Perform ' = '1.Under Perform'
  25. }
  26. elseif ($row.Result -eq $row.'Season Average') {
  27. $row.'Exceed/Achieve/Under Perform ' = '2.Achieve'
  28. }
  29. else {
  30. $row.'Exceed/Achieve/Under Perform ' = '3.Exceed'
  31. }
  32. }
  33. $data | sort 'Exceed/Achieve/Under Perform ', Result -Descending | `
  34. Export-Csv C:\sg2009\result.csv -Force -NoTypeInformation
Celou úlohu jsem si převedl do PowerShellu tím, že jsem zavolal Excel a použil SaveAs... / CSV. Potom jsem již jen načel data pomocí Import-Csv a porovnal výsledky za sezónu. Výsledek jsem zapsal do potřebného sloupce a poté jen výsledky vyexportoval do nového CSV souboru.

Divize Beginners
Obsahovala jednoduchou úlohu pro dotaz do WMI. V PowerShellu naprosto jednoduchá věc. Celá úloha byla pouze "ztížena" výpisem různých barviček. Tentokrát jsem úkol řešil jako jednoduchou funkci, kdy jsem navíc přidal možnost zadání jména vzdáleného počítače.

  1. function Get-LongJumpResults {
  2. param (
  3. $computer = "localhost"
  4. )
  5. $headerColor = "Green"
  6. $speedColor = "Yellow"
  7. $strengthColor = "Magenta"
  8. $agilityColor = "Cyan"
  9. $data = gwmi Win32_Processor -ComputerName $computer
  10. Write-Host "Strength evaluation for $computer" -ForegroundColor $headerColor
  11. Write-Host "Speed ... $($data.MaxClockSpeed)" -ForegroundColor $speedColor
  12. Write-Host "L2 cache size: $($data.L2CacheSize)" -ForegroundColor $speedColor
  13. Write-Host "L2 cache speed: $($data.L2CacheSpeed)" -ForegroundColor $speedColor
  14. Write-Host "L3 cache size: $($data.L3CacheSize)" -ForegroundColor $speedColor
  15. Write-Host "L3 cache speed: $($data.L3CacheSpeed)" -ForegroundColor $speedColor
  16. Write-Host "Strength ..." -ForegroundColor $strengthColor
  17. Write-Host "Number of Cores: $($data.NumberOfCores)" -ForegroundColor $strengthColor
  18. Write-Host "Number of logical processors: $($data.NumberOfLogicalProcessors)" -ForegroundColor $strengthColor
  19. Write-Host "Name: $(($data.Name).trim())" -ForegroundColor $strengthColor
  20. Write-Host "Agility ..." -ForegroundColor $agilityColor
  21. Write-Host "Address width: $($data.AddressWidth)" -ForegroundColor $agilityColor
  22. } #function Get-LongJumpResults
Opět nic složitého.

pátek 19. června 2009

Audit skupin v Active Directory

Dnes mě na chatu chytil jeden z přátel zabývajících se bezpečností. Líbil se mu report zobrazující lokální administrátory na koncových stanicích a chtěl něco podobného vytvořit pro skupinu Domain Admins. Ptal se mne na možnosti a mou první odpovědí bylo: PowerShell.

První nástřel byl tento:
Get-QADGroupMember 'domain.com/CZ/Domain Admins'

Výstupem příkazu je seznam členů této skupiny. To mělo úspěch a samozřejmě přišla další otázka: "Lze porovnat výsledky proti nějakému danému stavu?" Ano, úkol jak dělaný pro Compare-Object. Celý skript pak vypadal následovně.
  1. function Compare-ADGroup {
  2. param (
  3. [string]$group = 'domain.com/CZ/Domain Admins',
  4. [switch]$snapshot
  5. )
  6. if ($snapshot) {
  7. # save state as snapshot
  8. Get-QADGroupMember $group | `
  9. Select-Object SamAccountName, FirstName, LastName | `
  10. Export-Clixml ./snapshot.xml
  11. }
  12. else {
  13. Get-QADGroupMember $group | `
  14. Select-Object SamAccountName, FirstName, LastName | `
  15. Export-Clixml ./current.xml
  16. # load to variables, sort to prepare for Compare-Object
  17. $s = (Import-Clixml ./snapshot.xml) | Sort-Object SamAccountName
  18. $c = (Import-Clixml ./current.xml) | Sort-Object SamAccountName
  19. # compare objects based on SamAccountName
  20. Compare-Object -ReferenceObject $s -DifferenceObject $c -Property SamAccountName
  21. } # else
  22. } # function Compare-ADGroup
První spuštění musí být s parametrem -Snapshot. Tím se vytvoří referenční soubor se "správnými" daty. Skript by šel ještě vylepšit o kontrolu existence souboru snapshot.xml nebo například o vložení časové značky do souboru current.xml.

středa 10. června 2009

Scripting Games 2009 - Event 1

Určitě vám neuniklo, že byl neoficiálně odstartován další ročník Scripting Games. Nejlepším rozcestníkem je nyní zřejmě stránka PoshCode.org, která zajišťuje prostor pro vkládání hotových skriptů. První úkol má název The 100 meter dash.

Divize Advanced
Úkolem je najít ve vstupním textovém souboru řádky obsahující text a vypsat tři nejkratší. Mé řešení bylo následujcí:

Get-Content "./Personal Information Cards_ADV1.txt" | `
Where-Object {$_ -match "\S"} | `
Sort-Object Length | `
Select-Object -First 3

Celá práce probíhá na jedné řádce.
  1. Načtení souboru.
  2. Vyfiltrování řádek, které obsahují text. Zde vyjádřeno pomocí regulárního výrazu \S - pusť všechno, co není pouze mezera.
  3. Seřaď řádky podle délky.
  4. Vypiš tři nejkratší.
Celý úkol byl relativně jednoduchý, důležité bylo přijít na filtrování prázdných řádek. Někteří použili v druhém kroku funkci trim().

Divize Beginners
Byla na rozdíl od advanced relativně složitá. Vše bylo způsobeno jedním malým "překlepem" kdy ve vstupním souboru byla jedna položka oddělena mezerou místo tabulátorem. Jelikož jsem chtěl mít hotovo rychle, využil jsem letošního pravidla: "Vše, co je dovoleno v reálném světě, je dovoleno i v soutěži." Ručně jsem opravil "chybnou" řádku a skript byl poté již jednoduchý:

Import-Csv '100 Meter Event.txt' -Delimiter "`t" | `
  Sort-Object Time | `
  Select-Object -First 3
  1. Použil jsem cmdlet Import-Csv z PowerShellu verze 2. Ve verzi 2 je totiž u tohoto cmdletu nový parametr, pomocí nějž určíte, jak je soubor oddělen. Výborná věc pro české prostředí, kde je standardním oddělovačem středník.
  2. Výstupem z první roury byly objekty, které jsem seřadil podle času
  3. a pak jen vypsal první tři.
K tomuto úkolu se ještě vrátím a pomocí regulárních výrazů si poradím s problémovou řádkou.

Jelikož jsem u obou řešení používal aliasy, můžete se na mé "opravdové" verze v beginners a advanced divizích podívat přímo na PoshCode.org.

pátek 29. května 2009

Automatizace a Scripting Games

Dnes ráno mne zaujaly na Twitteru dvě zprávy:
  1. Má smysl automatizovat úplně všechno? Připomíná mi to mé poznámky na prezentacích PowerShelu, když říkám, že ne vždy je PowerShell efektivní. Občas prostě není efektivní vůbec nic kromě manuální práce :) Samozřejmě to neplatí při výrobu skriptů pro studijní účely. Přečtěte si původní článek a jestli chcete, nechte mi zde pod článkem komentář.
  2. Summer Scripting Games 2009 - podrobnější informace byly zveřejněny na novém blogu Hey, Scripting Guy! Letos je mottem vzdělání, nikoli soutěž a všechna témata se budou věnovat desetiboji (vzdělávacímu samozřejmě). Cílem je přiblížit průběh více reálnému světu a bude např. možné použít části kódu jiných soutěžících. Zároveň byly potvrzeny čtyři kategorie - VBScript a PowerShell; oba jazyky pro Beginner a Advanced divizi. 

středa 20. května 2009

Hledání adresářů podle obsahu

Jedna z poznámek na Twitteru mě zavedla ke konzoli PowerShellu. Chtěl jsem si vyzkoušet, jak je jednoduché vyhledat adresáře podle specifického zadání. Konkrétní dotaz zněl: "Chci všechny adresáře začínající písmenem L, které obsahují soubory *.dwg". Dotaz jsem si upravil na "... všechny soubory s příponou PS1, které jsou v adresáři začínajícím na zzz.

Vypadl mi následující one-liner:

ls -i *.ps1 -r | select Directory -u | % {if((Split-Path $_.Directory -le) -like 'zzz*') {$_}}

Lépe je zřejmě čitelný takto:

Get-ChildItem -Include *.ps1 -Recurse | `
Select-Object -Property Directory -Unique |`
ForEach-Object {
if ( (Split-Path $_.Directory -Leaf) -like 'zzz*') { $_ }
}

V první části roury probíhá rekurzivní hledání všech PS1 souborů. Poté vybereme jména všech adresárů a dále hledáme ty, jejichž jméno začíná na zzz. pokud některý podmínku splňuje, tak vypíšeme celou cestu k adresáři.

pondělí 18. května 2009

Scripting Games 2009

Konečně bylo uveřejněno datum letních Scripting Games 2009. Více informací je k nalezení na stránkách Script centra. Vypadá to, že letos se bude soutěžit v PowerShellu a VB Scriptu a Perl tedy zřejmě odpadá. Pokud se chcete dozvědět více, podívejte se na stránky Scripting Games a zapátrejte v archivu.

Letos se na pořádání budou také podílet PowerShellCommunity.org a PoShCode.org.

Profil autora těchto stránek na stránkách Scripting Games (v roce 2007 jsem absolvoval VBS beginners divizi).

čtvrtek 14. května 2009

Hej, mistře Šelíku!

Vítejte zpátky u mistra Šelíka. V posledním TechNet Flash zpravodaji řešil následující problém.

No, dejme tomu - DateDiff je dobrá funkce, ale kdo si má pamatovat, kdy si naposledy měnil heslo. DateDiff (resp. odčítání dvou dat) bych použil v případě, že bych chtěl například zjistit, kolik dní zbývá do Vánoc.

PS C:\> $vanoce = '2009/12/24'
PS C:\> ($vanoce - (get-date)).Days
223

V případě zjištění délky používání hesla je lepší sáhnout přes ADSI na vlastnost PasswordAge.

PS C:\> [ADSI]$user="WinNT://czvm01/administrator,user"
PS C:\> $user.PasswordAge
97399082
PS C:\> ($user.PasswordAge).value/86400
1127,30418981481

První výsledek nám vrátil stáří hesla v sekundách, takže jsme jej přepočítali na dny. Vidíme, že administrátorské heslo na tomto počítači nebylo změněno hodně dlouho :) V případě, že by vás zajímalo stáří hesla pro účet v Active Directory, stačí změnit první řádek na následující variantu:

PS C:\> [ADSI]$user="WinNT://domain.name/administrator,user"

a v proměnné $user budeme mít uložen účet doménového administrátora.

Pokud víte, že informaci o stáří hesla budete využívat častěji, můžete si předchozí kód uložit do skriptu.

function Get-PasswordAge {

param (
[string]$scope = "$env:computername",
[string]$user = "administrator"
)

[ADSI]$ADSIobj="WinNT://$scope/$user,user"
"$user : $([Math]::Round(($ADSIobj.PasswordAge).value/86400))"
}

PS C:\> Get-PasswordAge
1127
PS C:\> Get-PasswordAge -user $env:USERNAME -scope $env:USERDOMAIN
86

Jediným doplněním je závěrečné zaokrouhlení dnů na celá čísla pro lepší přehlednost.

Banner mistra Skriptíka je stažen ze stránek TechNet Flash zpravodaje. Děkuji týmu TechNetu za možnost jeho použití pro potřeby tohoto článku.

úterý 12. května 2009

Update: Hej, mistře Šelíku!

Dnes jsem dostal povolení, že mohu přidávat banner mistra Šelíka do článků na tomto webu (viz např. tento příspěvek).

Banner je součástí českého TechNet Flash zpravodaje, který je dostupný (po registraci) na technetflash.cz. Pokud zpravodaj neodebíráte, mohu vám ho jen doporučit.

Těším se na další setkání s vámi a mistry Skriptíkem a Šelíkem :)

středa 6. května 2009

Windows 7 RC

Jistě nikomu z vás neuniklo, že do světa byla puštěna RC verze Windows 7. Co je ovšem důležité z hlediska PowerShelu, že tím se nám dostává do ruky ve velkém množství kopií PowerShell v2. Já už mám RC stažené a čekám na víkend, abych si s nimi mohl pohrát. Od této chvíle budu více využívat verzi 2 a rád bych přinesl věci, které mne zaujmou.

úterý 5. května 2009

Správa VMware pomocí PowerShellu

V těchto dnech se konečně dostala na trh kniha, na kterou jsem dlouho čekal.

Jedná se o Managing VMware Infrastructure with Windows PowerShell: TFM, kterou napsal Hal Rottenberg. Hal je Microsoft PowerShell MVP a je zároveň VMware vExpert. Obě tato ocenění jej předurčují k tomu, že téma knihy zvládá na té nejvyšší úrovni. Hal je zároveň jedním z moderátorů PowerScripting Podcastu.

Knihu vydalo nakladatelství Sapien Press v edici TFM. Četl jsem z této edice dvě knihy a s oběma jsem byl velice spokojen. Na webu Sapienu jsou ke stažení skripty a zároveň je dostupná ukázková kapitola.

Kniha je již dostupná na Amazonu. V nejbližších dnech si ji budu objednávat :) Pokud se zabýváte správou VMware serveru a chcete vaši práci automatizovat, mohu tuto knihu jen doporučit.

pondělí 4. května 2009

Hlasování - výsledky

Minulý týden doběhlo první hlasování. Otázka byla: "Vadilo by vám, kdyby byl obsah webu v angličtině?" Až do poslední chvíle to vypadalo na remízu, ale pak jeden člověk hlasoval pro Ano. Vzhledem k tomu, že já sám jsem hlasoval pro ne, beru to jako výhru o 15% :)

Rád bych přinášel informace převážně v českém jazyce. Zjistil jsem ovšem, že občas zazní na fóru či Twitteru dotaz, který jsem schopen řešit a rád bych jej publikoval. Proto jsem se již definitivně rozhodl přenést současnou podobu webu na vlastní doménu www.PowerShell.cz a najít providera, který bude schopen nabídnout WordPress jako nástroj pro tvorbu webu. V současné době mám dobré ohlasy na onebit.cz.

Má idea je taková, že PowerShell.cz bude primárně v češtině a v subdoméně en.PowerShell.cz pojede paralelně anglická verze. Mělo by platit, že všechny články, které budou dostupné v angličtině, budou dostupné i v češtině. Opačně to již platit nemusí.

čtvrtek 30. dubna 2009

How to access LN data

Few months ago I started to use PowerShell for access to my Lotus Notes Inbox. It is pretty cool because I don't need to go to LN every time the mail arrives and can see it directly in my dearest Win application:



You see I modified my profile so the number in brackets means how many emails I have in Inbox. Alias she calls my function Show-Email and displays last email (default behaviour). In this article I'd like to show you basic idea. In the next one will show you how to do the work more automatically. Thanks @ye110wbeard for asking on Twitter - it kicks me to finally write the article :)

Whole work with Lotus Notes consists of following steps:
  • Connect to Lotus Notes session
  • Select Database
  • Select View
  • Go thru all documents inside loop
Connect to Lotus Notes Session
As COM is used for connection, New-Object is the way:

PS C:\> $session = New-Object -ComObject Lotus.NotesSession
PS C:\> $session.Initialize()
PS C:\> $session.NotesVersion
Release 6.5.3|September 14, 2004

OK, we are in, let's continue.

Open database and select View
You can connect to database located on the server or to local database. In case of local database, use empty string as first parameter of GetDatabase method.

PS C:\> $db = $session.GetDatabase('','names.nsf')
PS C:\> $db.Title
Moravec's Address Book
PS C:\> $view = $db.GetView('Contacts')
PS C:\> $view.Name
Contacts
PS C:\> $view.AllEntries.Count
215

You can see that I have 215 records in my Address book. I use AllEntries.Count every time I am downloading data from other (big) databases. I simply use the value in Write-Progress cmdlet so can see what's going on.

Grab data
Before you start do read records you have to know the names of items. Who is your best fried now? Of course Get-Member. Or you can go directly to LN database and check the fields manually via Document Properties.

PS C:\> $view.GetFirstDocument().Items | select Name | fw -col 4

Yupii - we are almost done:

PS C:\> $doc = $view.GetFirstDocument()
PS C:\> while ($doc -ne $null) {
$lastname = $doc.GetItemValue("LastName")
$firstname = $doc.GetItemValue("FirstName")
Write-Host "$firstname $lastname"
$doc = $view.GetNextDocument($doc)
}

You will see long list of names if you typed it correctly.

In this article I showed you how to easily connect to any LN database and read data from that db. I use the same technique for reading data from our company structure, converting it to objects and load it to PowerGUI for better work with the data.

Livemeeting: Windows PowerShell – úvod

Včera proběhl on-line seminář s názvem Windows PowerShell - úvod. Pod záštitou firmy Altairis byl přednášejícím Štěpán Bechyňský z Microsoftu.

Celá prezentace byla opravdu úvodem a neměla za cíl provést uživatele do hloubky PowerShellu. Jednotlivé části byly ukazovány i v konzoli PowerShellu, takže posluchači měli možnost vidět příkazy ze slidů naživo. Vzhledem k tomu, že se jednalo (pokud si dobře pamatuji) o první on-line vlaštovku nezbývá než doufat, že se dočkáme dalších pokračování. Prezentace měla některé slabší části, ale z mého pohledu převládlo nadšení, že jsme se konečně dočkali české verze. Ke stažení byl dostupný soubor s prezentací a ukázkovými soubory.

Celá prezentace bude po částech dostupná na MSTV.CZ.

středa 29. dubna 2009

Hej, mistře Šelíku!

V jednom ze starších vydání mistra Skriptíka padl následující dotaz: "V přihlašovacím skritpu potřebuji ověřit existenci souboru. Víš, jak na to?" Odpověď byla následující: "Jedna možnost je použít objekt FileSystem a metodu FileExists."

Pokud chcete řešení v PowerShellu, mohu doporučit přímo cmdlet Test-Path. Více o něm v dřívějším článku.
V případě, že chcete použít .NET, existuje třída System.IO.File a obsahuje metodu Exists. Použití je následující:

PS c:\> [System.IO.File]::Exists("c:\config.sys")
True

úterý 21. dubna 2009

PowerShell presentation

OK guys, it's here. As I promised here are slides and demo files from presentation for my colleagues.
  • Slides - I converted it to PDF and removed all company logos so somewhere it can looks strange.
  • Demo files used during presentation. Based on usage of specific technology there are short examples (VM) or really complex (ACL). Complex doesn't mean thousands of lines - we are in PowerShell :)
When I am doing presentation I use practical examples as much as I can. And I am talking a lot - ask my colleagues :) So sometimes you can feel like "out of the context" when looking only to presentation.

I found out that the most interesting part was setting of ACL. On the other hand I was compelled to slow down presentation when I talked about objects in PowerShell. My admin colleagues never tried any object oriented language so I saw on their faces they are "lost". After that I digressed a bit and tried to desbribed the idea of objects. Now I know that for next presentation (if presented for administrators) I have to redesign the slides.

As a conclusion I can say that it was fun. I felt that they were really interested and for the future I see that some of them can thing about PowerShell as about the tool which saves them a lot of work.

pátek 17. dubna 2009

Hej, mistře Šelíku!

Při pročítání posledního CZ TechNet zpravodaje mě napadlo zpracovat téma z komiksu Hej, mistře Skriptíku! v PowerShellu. TechNet Flash zpravodaj je dostupný na www.technetflash.cz (včetně starších čísel). Rozhodně jej doporučuji všem IT odborníkům.


Tentokrát budeme potřebovat PowerShell v2 (CTP3). Tato verze již obsahuje cmdlety pro práci s Windows Event Logy:

PS C:\Users\beta> Get-Command -noun EventLog | Select-Object Name
Clear-EventLog
Get-EventLog
Limit-EventLog
New-EventLog
Remove-EventLog
Show-EventLog
Write-EventLog

Mrkneme se na Write-EventLog. Ten má čtyři povinné parametry: LogName, Source, EventID, Message. Zkusme tedy něco zapsat do aplikačního logu:

Write-EventLog -LogName Application -source "Windows Error Reporting" -eventID 007 -Message "James Bond is cool!"

Výborně, stále tomu ale něco chybí. Většinou budete chtít zapisovat data z vašich programů. Pokud zkusite zápis ve tvaru:

Write-EventLog -LogName Application -source "Moje Aplikace" -eventID 007 -Message "James Bond is cool!"

PowerShell vám vrátí chybu jejíž část The source was not found vám oznámí, že toto nelze. Je to způsobené tím, že každý zdroj (Source), který zapisuje do Event Logu musí být předem zaregistrován (viz MSDN). Naštěstí exituje v PowerShellu cmdlet New-EventLog, který tuto službu udělá za vás. Následující seznam příkazů již tedy povede ke zdárnému konci (pro registraci zdroje musíte příkaz pustit s právy administrátora):

PS C:\> New-EventLog -LogName Application -Source "Moje Aplikace"
PS C:\> Write-EventLog -LogName Application -source "Moje Aplikace" -eventID 001 -Message "Ale ja jsem jednicka."

pátek 13. března 2009

smsDiagram - Draw your SMS hierarchy with one script

The Story
I am an administrator of big SMS hiearchy. Few times I reported to management how our infrastructure looks like. You know managers - they doesn't understand to objects, pipes and other funny parts of admin life. They are like children - likes pictures and graphs. So it's nice to show them infrastructure drawn in Visio. Till now I created it manually but after we merged few sites together it's not fun anymore (we have about 300 servers).

Maybe you recognized small analogy in the title of this post. When I saw an article written by Alan Renouf I knew that my future is bright. So thanks to Alan to kick me (Virtu-Al(ly) of course :)

The Script
Script itself is not so complicated. The biggest part is related to Visio (I use 2003 version) drawing. But there are some parts you might find useful for your own scripts.

Load hierachy from WMI
  1. $siteCode = (Get-WmiObject -ComputerName $server -Namespace root/sms `
  2. -Class SMS_ProviderLocation -Filter "ProviderForLocalSite='True'").SiteCode
  3. # SMS Namespace path
  4. $SMSWMINamespace = 'root/sms/site_'+$siteCode
  5. # List of children servers from SMS_Site class
  6. $servers = Get-WmiObject -ComputerName $server -Namespace $SMSWMINamespace -Class SMS_Site | `
  7. Select ReportingSiteCode, SiteCode, ServerName, Type | `
  8. Sort ReportingSiteCode, SiteCode
At lines 1-2 we have one-liner which connects to WMI of the site server (specified as parameter of the script) and find sitecode in SMS_ProviderLocation class. Then we connect to the SMS site namespace. We can load all necessary information from that namespace (lines 7-9) and save it in $servers object.

Text representation of SMS hierarchy
If you don't have Visio or just want quick overwiew you have two choices:
  1. Use standard SMS report (Sites by hierarchy with time of last site status update)
  2. Pass parameter $textInfo to smsDiagram script :)
Second option will display your hierarchy in this way:

PS C:\> ./smsDiagram.ps1 -server SMS01 -textInfo
CC0 (P)
  CZ0 (P)
    500
    HU0 (P)
      501
  ZZ0 (P)
    003
    004
    ZZ1 (P)

It's easy and fast - as fast as your connectivity to the site server. (P) means that the displayed server is Primary server.

Voila
And here is the nicest part of the script. It uses standard Visio Network template - Detailed Network Diagram. If you want to show infrastructure as Visio diagram just provide site server name as a parameter. In the diagram you can also see which server is Primary (db icon) and which is Secondary.

PS c:\> smsDiagram.ps1 -server SMS01



Now I have latest SMS hierarchy at my desk and it looks awesome :) Final document is saved in your My Documents folder, name is smsDiagram.vsd.

Notes
I didn't test the script against ConfigMgr. My "test lab" is not active now (to be honest - my NB where I ran it crashed before few days and I haven't time to rebuild it now).
No error codes checking now. Be sure you run the script as admin able to connect to WMI of site server.
Sometimes the Visio diagram is "ugly" - it fully depends on how the Visio handle objects creation. Hopefuly will find some solution but it's not a priority now.
Default text info shows site code. For next version I plan to add switch which tells what do you want to show as server description.
For the future versions of the script I also would like to add some more features - display server roles (MP, CAP, ...), customize output (shape names, connectors).
Source code is available at PoSh Code.

Please let me know if you find it useful or if you find some errors. Any feedback for improvement is welcome.

pondělí 9. března 2009

Looking for HResult

In one of the last Hey, Scripting Guy! article is described how to install updates and check it's result codes. I was really surprised when Scripting guys told me: "We can use calc.exe" - OMG why not use converting directly in PowerShell?

PS C:\> "0x{0:x}" -f [int] -2145124318
0x80240022

When I tried this I start thinking about the function which will do the conversion and shows also description of the result code.

  1. # Name : Get-HResult.ps1
  2. # Author: David "Makovec" Moravec
  3. # Web : http://www.powershell.cz
  4. # Email : powershell.cz@googlemail.com
  5. #
  6. # Description: Finds meaning of HResult
  7. #
  8. # Version: 0.1
  9. # History:
  10. # v0.1 - (add) basic functionality
  11. #
  12. # Usage: Get-HResult -2145124318
  13. #
  14. #################################################################
  15. function Get-HResult {
  16. param (
  17. $HResult,
  18. $url = 'http://technet.microsoft.com/en-us/library/cc720442.aspx'
  19. )
  20. $calc = "0x{0:x}" -f [int]$HResult
  21. $lookFor = $calc+'.*?tr'
  22. $wc = New-Object system.net.webclient
  23. $wc.DownloadString($url) -match $lookFor | Out-Null
  24. $tmp = $matches[0]
  25. $searchString = '(?<ResCode>'+$calc+').*\<p\>(?<ResStr>.+?)\<.*\<p\>(?<Description>.+?)\</p.+'
  26. $tmp -match $searchString | Out-Null
  27. Write-Host "HResult: " $HResult
  28. Write-Host "Result Code: " $matches.ResCode
  29. Write-Host "Result String: " $matches.ResStr
  30. Write-Host "Description: " $matches.Description
  31. } #function

By default script return results for Windows Update Agent and has no checking for errors. It has parameter for providing different URL but I didn't try any. Usage is following:

PS C:\> Get-HResult -2145124351
Result Code: 0x80240001
Result String: WU_E_NO_SERVICE
Description: Windows Update Agent was unable to provide the service.

Source code will be available at PoSh Code when I'll be able to open it, now have troubles with connectivity.

pátek 6. března 2009

Hlasování

Trošku jsem přemýšlel nad obsahem tohoto webu. Vzhledem k tomu, že některé z příspěvků bych rád publikoval "mezinárodně", překládám částečně již existující příspěvky.
Proto bych se rád zeptal, jestli by vám vadilo, kdyby byl obsah webu psán v anglickém jazyce. Děkuji za vaše hlasy.

čtvrtek 26. února 2009

Quest Connect

[Update]: Dmitry Sotnikov potvrdil, že se bude jednat o on-line diskusi na téma PowerShell a PowerGUI.

Podle mailu, který mi dnes přistál v poště, to vypadá, že se blíží další konference Quest Connect. Je naplánována na 11. března 2009.
Zatím to vypadá, že část bude živě a část bude archiv minulé konference. Až budu vědět více, dám vědět.

pátek 23. ledna 2009

Jak najít význam zkratky

Poslední dobou hodně komunikuji s lidmi, kteří tráví [četováním] evidentně hodně času i mimo práci. Používají množství zkratek, ze kterých jsem občas trochu mimo. Jelikož pak většinou nechápu odpovědi typu BFN, ACAB a podobně. Do nynějška jsem vždy použil Google a ne vždy se trefil napoprvé. Rozhodl jsem se vytvořit funkci, která vyhledá význam zkratky na internetu. Po vyzkoušení několika stránek se mi zalíbila (jak z hlediska vrácených odpovědí, tak i z hlediska struktury HTML stránky) stránka Acronyms and Abbreviations na TheFreeDictionary.

Vrácené HTML je ve tvaru, který je vidět na obrázku



Pomocí XPath jsem se dotázal na všechny druhé sloupce a výsledkem je seznam významů. Pro stažení a parsování výsledku hledání jsem použil Invoke-Http a Receive-Http z HttpRest. Použití je jednoduché:


PS C:\> Find-Abbreviation itmu
Inventory Tool for Microsoft Updates

  1. # Name : Find-Abbreviation.ps1
  2. # Author: David "Makovec" Moravec
  3. # Web : http://www.powershell.cz
  4. # Email : powershell.cz@googlemail.com
  5. #
  6. # Description: Finds meaning of given abbreviation
  7. # : Uses HttpRest http://poshcode.org/787
  8. #
  9. # Version: 0.1
  10. # History:
  11. # v0.1 - (add) basic functionality
  12. #
  13. # Usage: Find-Abbreviation fyi
  14. #
  15. #################################################################
  16. function Find-Abbreviation {
  17. $url = "http://acronyms.thefreedictionary.com/$args"
  18. Invoke-Http get $url | Receive-Http Text "//tr[@cat]//td[2]"
  19. }
Skript je ke stažení na PoshCode.

pátek 2. ledna 2009

Operátor formátování - 3. část

V minulém díle jsme skončili ukázkou různých formátů data. Dnes si ukážeme, jak si můžeme vytvořit formát vlastní, pokud nám předdefinované nestačí. Vraťme se k mému oblíbenému ShortDatePattern. Uložíme si aktuální datum a čas do proměnné.

PS C:\> $d = Get-Date
PS C:\> $d

31. prosince 2008 22:32:33

PS C:\> "{0:d}" -f $d
31.12.2008
PS C:\> (Get-Culture).DateTimeFormat

ShortDatePattern : d.M.yyyy

0:d (standardní formát) reprezentuje zobrazení ve tvaru d.M.yyyy (uživatelský formát). V uživatelském formátu je význam znaků následující:
  • d – den ve tvaru 31
  • M – měsíc ve tvaru 12
  • yyyy – rok ve tvaru 2008
  • . – funguje jako oddělovač jednotlivých položek
Když si vyzkoušíte následující dva příklady

PS C:\> "{0:d}" -f $d
31.12.2008
PS C:\> "{0:d.M.yyyy}" -f $d
31.12.2008

dostanete naprosto shodný výsledek. V tomto případě je tedy jednodušší použít standardní formát a ušetřit sedm znaků, než si formát data vytvořit po svém. Pokud ovšem budete chtít například jiný oddělovač dne a měsíce, je dobré znát uživatelské formátování a potřebný výstup si vytvořit.

PS C:\> "{0:~d~ [M] (yyyy)}" -f $d
~31~ [12] (2008)

Jak PowerShell (.NET) pozná, zda d, které jsme zadali, je ShortDatePattern nebo uživatelské zobrazení dne? Existuje jednoduché pravidlo – pokud formátovací řetězec obsahuje více než jeden znak (počítá se i mezera!), je brán jako uživatelský formát, čili

PS C:\> "{0:d}" -f $d
31.12.2008
PS C:\> "{0:d }" -f $d
31

V následující části se podíváme na všechny formátovací řetězce. Pro snažší zapamatování jsem se snažil sdružit je do kategorií.

Den
  • d – zobrazuje den jako číslo ve tvaru 1..31
  • dd – zobrazuje den jako číslo ve tvaru 01..31 (přidává nulu v případě, že pořadové číslo dne je menší než 10).
  • ddd – zobrazuje zkratku dne. Jak je definována můžete zjistit pomocí příkazu (Get-Culture).DateTimeFormat.AbbreviatedDayNames
  • dddd – zobrazuje jméno dne, viz (Get-Culture).DateTimeFormat.DayNames
Ukažme si rovnou nějaké příklady

PS C:\> "{0:d}" -f $d
31.12.2008
PS C:\> "{0:d }" -f $d
31
PS C:\> "{0}" -f $d.day
31
PS C:\> "{0:dd}" -f $d
31
PS C:\> "{0:ddd}" -f $d
st
PS C:\> "{0:dddd}" -f $d
středa
PS C:\> (Get-Culture).DateTimeFormat | fl *DayNames

AbbreviatedDayNames : {ne, po, út, st...}
ShortestDayNames : {ne, po, út, st...}
DayNames : {neděle, pondělí, úterý, středa...}

Měsíc
  • M – měsíc jako číslo ve tvaru 1..12
  • MM – měsíc jako číslo ve tvaru 01..12
  • MMM – zkratka měsíce dle (Get-Culture).DateTimeFormat.AbbreviatedMonthNames – zobrazení je ve tvaru římských číslic
  • MMMM – jméno měsíce v plném tvaru, viz (Get-Culture).DateTimeFormat.MonthNames
PS C:\> "{0:M}" -f $d
31 prosince
PS C:\> "{0:M }" -f $d
12
PS C:\> "{0}" -f $d.Month
12
PS C:\> "{0:MM}" -f $d
12
PS C:\> "{0:MMM}" -f $d
XII
PS C:\> "{0:MMMM}" -f $d
prosinec
PS C:\> (Get-Culture).DateTimeFormat | fl *MonthNames

AbbreviatedMonthNames : {I, II, III, IV...}
MonthNames : {leden, únor, březen, duben...}

Nyní jsem již podruhé použil konstrukci, která se vám možná moc nelíbí. Jde o `0:M ` (s mezerou za znakem M). Z ukázek to není patrné, ale zvídavější povahy dospěly ke (správnému) názoru, že mezera navíc se nám projeví ve výstupním řetězci a občas nám to může vadit. Pojďme si to ověřit.

PS C:\> "{0:M }" -f $d
12
PS C:\> ("{0:M }" -f $d).length
3
PS C:\> Write-Host "|$($a[2])|"
| |

Mezera jak vyšitá :) Jak se tohoto jevu zbavit si ukážeme na konci dnešního článku. Do té doby budeme všechny jednopísmenné formátovací řetězce zapisovat s mezerou za znakem.

Ještě jedna malá odbočka před tím, než budeme pokračovat. V následujících příkladech budu v některých částech od aktuálního data odčítat určitý počet dní, hodin, … Pro Ty, kteří zatím moc nepracovali s třídou DateTime či příkazem Get-Date uvádím malou ukázku (za znaky ### bude vždy následovat komentář k příkazu).

PS C:\> $d | Get-Member Add* ### Zobrazíme všechny metody pracující s přičítáním času


TypeName: System.DateTime

Name MemberType Definition
---- ---------- ----------
Add Method System.DateTime Add(TimeSpan value)
AddDays Method System.DateTime AddDays(Double value)
AddHours Method System.DateTime AddHours(Double value)
AddMilliseconds Method System.DateTime AddMilliseconds(Double value)
AddMinutes Method System.DateTime AddMinutes(Double value)
AddMonths Method System.DateTime AddMonths(Int32 months)
AddSeconds Method System.DateTime AddSeconds(Double value)
AddTicks Method System.DateTime AddTicks(Int64 value)
AddYears Method System.DateTime AddYears(Int32 value)

PS C:\> "{0}" -f $d ### Vypíšeme aktuální stav proměnné d
31.12.2008 22:32:33
PS C:\> "{0}" -f $d.AddDays(1) ### Přičteme jeden den
1.1.2009 22:32:33
PS C:\> "{0}" -f $d.AddHours(2) ### Přičteme dvě hodiny
1.1.2009 0:32:33
PS C:\> ### V následujících příkazech budeme časové jednotky odčítat
PS C:\> "{0}" -f $d.AddDays(-366) ### Odečteme 366 dní (rok 2008 byl přestupný)
31.12.2007 22:32:33
PS C:\> "{0}" -f $d.AddSeconds(-611) ### A co třeba nějaký zapamatovatelný čas
31.12.2008 22:22:22

Důležité je z předchozích příkazů pochopit, že v čase můžeme jít i do minulosti.

Rok
  • y – rok jako max. jedno nebo dvouciferné číslo.
  • yy – rok jako dvouciferné číslo.
  • yyy – zobrazí rok jako minimálně trojciferné číslo. Pokud má rok více než tři významové číslice jsou i ty zobrazeny ve výsledku.
  • yyyy – zobrazí rok jako čtyřciferné číslo. Pokud má rok méně než čtyři čísla je zleva doplněn nulami.
  • yyyyy – zobrazí rok jako pěticiferné číslo. Pokud má rok méně než pět číslel je zleva doplněn nulami.
PS C:\> "{0:y}" -f $d
prosinec 2008
PS C:\> "{0:y }" -f $d
8
PS C:\> "{0:yy}" -f $d
08
PS C:\> "{0:yyy}" -f $d
2008
PS C:\> "{0:yyyy}" -f $d
2008
PS C:\> "{0:yyyyy}" -f $d
02008
PS C:\> "{0:yyy}" -f $d.AddYears(-2000)
008
PS C:\> "{0:yyyyy}" -f $d.AddYears(-2000)
00008

Hodina
  • h – zobrazuje hodinu jako číslo z intervalu 1..12. Jedná se tedy o zobrazení dvanáctihodinového cyklu.
  • hh – zobrazuje hodinu jako číslo z intervalu 01..12.
  • H – zobrazuje hodinu jako číslo z intervalu 0..23. Zobrazuje dvacetičtyřhodinový formát.
  • HH – zobrazuje hodinu jako číslo z intervalu 00..23.
PS C:\> "{0:h}" -f $d
Exception retrieving string: "Input string was not in a correct format."
At line:1 char:11
+ "{0:h}" -f <<<< $d
PS C:\> "{0:h }" -f $d.AddHours(-1)
9
PS C:\> "{0:hh}" -f $d.AddHours(-1)
09
PS C:\> "{0:H }" -f $d.AddHours(-1)
21
PS C:\> "{0:HH}" -f $d.AddHours(-1)
21

V případě znaku h byla vyhozena výjimka z toho důvodu, že pro standardní formátování data neexistuje formátovací řetězec h. Tu samou chybu obdržíte, pokud zkusíte např. znak x.

Minuta
  • m – minuta ve tvaru 0..59
  • mm – minuta ve tvaru 00..59
PS C:\> "{0:m}" -f $d
31 prosince
PS C:\> "{0:m }" -f $d
32
PS C:\> "{0:m }" -f $d.AddMinutes(-30)
2
PS C:\> "{0:mm}" -f $d.AddMinutes(-30)
02
PS C:\> "{0:mm}" -f $d
32

Sekunda
  • s – sekunda ve tvaru 0..59
  • ss – sekunda ve tvaru 00..59
Celá idea už je nyní asi jasná a proto uvedeme pouze jeden příklad.

PS C:\> "{0:ss}" -f $d
33

Při zobrazování času můžeme jít až na úroveň milisekund. Formátovacím řetězcem je znak f (a F). V současné době máme v proměnné d uložen čas, který má v sobě hodnotu 290ms. Pro názornost budeme tedy v následujících příkladech odečítat 200 ms.

PS C:\> "{0:H:mm:s:f}" -f $d.AddMilliseconds(-200)
22:32:33:0
PS C:\> "{0:H:mm:s:F}" -f $d.AddMilliseconds(-200)
22:32:33:
PS C:\> "{0:H:mm:s:ff}" -f $d.AddMilliseconds(-200)
22:32:33:09
PS C:\> "{0:H:mm:s:FF}" -f $d.AddMilliseconds(-200)
22:32:33:09
PS C:\> "{0:H:mm:s:fff}" -f $d.AddMilliseconds(-200)
22:32:33:090
PS C:\> "{0:H:mm:s:FFF}" -f $d.AddMilliseconds(-200)
22:32:33:09

V zobrazení milisekund je tedy vidět malá změna při zobrazování – zobrazujeme vždy hodnoty „zleva“, což ale dává smysl, protože potřebujeme znát významově nejvyšší číslici. V zobrazování můžeme jít až na úroveň sedmi f (fffffff, FFFFFFF), ale z hlediska přesnosti to nemá význam (dle MSDN je přesnost hodin většiny systémů Windows 10-15ms).

„Speciální“ formátovací řetězce
.NET zavádí ještě několik dalších znaků, které můžeme při zobrazení data a času použít.
  • g – zobrazuje éru, čili n. l. pro současný rok
  • K, z – zobrazuje informace o časové zóně
  • t, tt – označení dopoledne/odpoledne dle System.Globalization.DateTimeFormatInfo.AMDesignator a System.Globalization.DateTimeFormatInfo.PMDesignator
  • : / - zastupují separátory času a datumu definované dle System.Globalization.DateTimeFormatInfo.TimeSeparator a System.Globalization.DateTimeFormatInfo.DateSeparator
  • “ ‘ – zobrazí text uvedený v uvozovkách
  • % - zobrazí výsledek formátovacího řetězce braného jako uživatelský formát. Jinými slovy od této doby můžete použít místo znaku mezery za formátovacím řetězcem použít procento před, např. %d.
  • \ - zobrazí znak zapsaný za lomítkem, např. \h
  • jakýkoli jiný znak způsobí vyhození výjimky.
PS C:\> (Get-Culture).DateTimeFormat

AMDesignator : dop.
PMDesignator : odp.
DateSeparator : .
TimeSeparator : :

PS C:\> "{0:d}" -f $d
31.12.2008
PS C:\> "{0:d }" -f $d
31
PS C:\> "{0:%d}" -f $d
31
PS C:\> ("{0:%d}" -f $d).length
2

PS C:\> "{0:%g}" -f $d
n. l.

PS C:\> "{0:d \d 'd'}" -f $d
31 d d

Po předcházejcích ukázkách už zřejmě chápete, proč pomocí “{0:d}” –f $d dostaneme výsledek 31.12.2008. Takže se pojďme podívat na trochu složitější příklad. Ve druhém díle jsme si ukazovali i univerzální setříditelný formát, který se zapisuje pomocí formátovacího řetězce u. Je tvořen následujícím způsobem:

PS C:\> "{0:u}" -f $d
2008-12-31 22:32:33Z
PS C:\> [System.Globalization.DateTimeFormatInfo]::CurrentInfo.UniversalSortableDateTimePattern
yyyy'-'MM'-'dd HH':'mm':'ss'Z'

Zleva doprava jsou postupně zobrazeny tyto údaje: rok ve čtyřčíselném formátu (2008), pomlčka (-), měsíc ve dvouciferném formátu (12), pomlčka (-), den ve dvouciferném formátu (31), mezera, hodiny ve čtyřiadvacetihodinovém dvouciferném formátu (22), minuty dvouciferně (32), sekundy dvouciferně (33), písmeno Z.

PS C:\> "Den: {0:%d}`nMesic: {1:%M}`nRok: {2:yyyy}`nJe tedy {0:%d}. {3} {2:yy}" -f $d, $d, $d, `
>> (Get-Culture).DateTimeFormat.MonthGenitiveNames[$d.Month-1]
>>
Den: 31
Mesic: 12
Rok: 2008
Je tedy 31. prosince 08

V předchozím příkladu jsem použil jednu dosud nezmíněnou vlastnost třídy DateTimeMonthGenitiveNames, výsledek je vidět ve výstupu.

Po pročtení toho dílu byste měli být schopni formátovat datum v jakémkoli tvaru. Jako vždy si můžete stáhnout zdrojové kódy. Nicméně i tak doporučuju si všechny příklady (i vaše vlastní vymyšlené) pěkně natlouct přes klávesnici. Jen tak vám přejdou do krve.