PowerShell Scripting Games 2010 edzőtábor
Annak érdekében, hogy a magyar versenyzők a nemzetközi porondon is derekasan helytállhassanak, alábbiakban egy kis edző feladatsort állítottam össze. A megoldásokat a feladat melletti linkre kattintva lehet hozzám eljutattni. A legjobb megoldásokat beküldőnek az általa választott Microsoft Press könyvet adjuk ajándékba!
Az általam kitalált "hivatalos" megoldást is majd közzéteszem, illetve ha valaki annál is jobban tud, akkor azt is.
A Scripting Games 2010 versenyről további információk itt: http://blogs.technet.com/heyscriptingguy/archive/tags/2010+Scripting+Games/default.aspx
Természetesen érdemes a korábbi évek versenyfeladatait is átnézni. Sajnos már csak elég hiányosan lelhetők fel ezek az weboldalak, ezeket a lap alján összegyűjtöttem.
De jöjjenek az edző feladatok! (A feladatok megoldásának elküldésekor ellenőrizze, hogy az "Ön adatai" rész ki van-e töltve, és az elküldött adatokat tartalmazó e-mail megérkezik-e a regisztrált e-mail címre. Ha ez nem történik meg, akkor kérem jelezze ezt nekem a soost@iqjb.hu címen!)
- Az elgémberedett tagokat a verseny előtt be kell melegíteni. Egy nagyon egyszerű feladat az első, a PowerShell 2.0 cmdleteket kell összeszámolni. Feladat részletesebben és a beadás...

- Ha már lendületben vagyunk, nem szabad az iramot abbahagyni. Figyeljük az óra ketyegéseit a következő feladatban...

- Nyújtani sem árt az izomkat! Nyúljunk ki a fájlrendszerbe...

- A kitartást is fejleszteni kell! Legjobb erre a számlálgatás...

- Persze versenyezni ésszel kell! Az agyunkat legjobban bonyolultabb számolással tudjuk edzeni...

- Ha már az agytekervények is bemelegedtek, akkor jöjjön a titkosírás megfejtése...

- A következő feladatban már több izomcsoport együttes munkájára van szükség. Erre jó gyakorlat a szövegben való turkálás és összeadás...

- Fokozzuk tovább a terhelést! A sok cmdlet közül válogassuk ki a legsúlyosabbakat...

- Újabb hosszú távú feladat! Az összes cmdletbe ássuk be magunkat és derítsük fel a mélyükön szunnyadó részleteket...

- És a legvégén, levezetésképpen újra mozgassuk át az összes izmunkat! Gyúrjunk, keressünk, számoljunk...

Az edzőtábor résztvevői és eredményeik (2010.04.23 17:00-kori állapot) - a táborozás befejezve:
| Résztvevők-Feladatok |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
| B. Lajos |
OK |
OK |
OK |
OK |
OK |
OK |
OK |
OK |
OK |
OK |
| B. Mihály |
OK |
OK |
OK |
OK |
OK |
OK |
OK |
OK |
OK |
- |
| Csaba |
OK |
OK |
OK |
OK |
OK |
OK |
OK |
OK |
OK |
|
| Ferenc |
OK |
|
|
|
|
|
|
|
|
|
| I. Mihály |
OK |
OK |
OK |
|
|
|
|
|
|
|
| János |
OK |
OK |
OK |
OK |
~ |
|
OK |
- |
- |
- |
| Jgerse |
OK |
OK |
OK |
OK |
OK |
|
- |
|
|
|
| Krisztina |
OK |
OK |
OK |
OK |
~ |
OK |
- |
OK |
|
|
| M. Lajos |
OK |
OK |
OK |
- |
|
|
|
|
|
|
| Zoltán |
OK |
OK |
OK |
OK |
~ |
OK |
- |
OK |
OK |
OK |
| zsoltesz |
OK |
OK |
OK |
OK |
OK |
OK |
OK |
OK |
OK |
OK |
Kérem, hogy akinek az eredménye név nélkül érkezett, az küldje újra, akár e-mailben is nekem el.
Jelmagyarázat:
- OK - jó a megoldás
- ~ - nem pont erre gondoltam, de elfogadom, jó a megoldás
- - - nem jó a megoldás
- üres - nem kaptam megoldást
Az edzőtábor feladatainak megoldása
1. feladat: Hány cmdlet van a bővítmények nélküli PS 2.0-ban?
Elég egyszerű a megoldás, egy dologra kell figyelni, hogy a „sima” get-command nem elég, mert az mindeféle dolgot visszaad, függvényeket és álneveket, így az többet mutat, mint a cmdletek száma. A helyes megoldás tehát:
PS C:> (Get-Command -CommandType cmdlet).count
236
2. feladat: Mennyi 2010.01.01 ketyegésekben (ticks) kifejezett értékének "e" alapú logaritmusa, egészre kerekítve?
Szintén nem nagyon érkezett rossz megoldás, a PowerShell alatt szunynadó .NET keretrendszerből tudjuk kölcsönözni a szükséges matematikai függvényeket:
PS C:> [int][math]::log(([datetime] "2010.01.01").ticks)
41
3. feladat: Közvetlenül a $PSHOME alatti fájlok közül melyiknek a FileVersion tulajdonsága "0.0.0.0"?
Azt hittem, ez komolyabb próbatétel lesz, de nem, a résztvevők nagyon ügyesek voltak:
PS C:> (Get-ChildItem $PSHOME | Where-Object {$_.versioninfo.Fileversion -eq "0.0.0.0"} ).name
CompiledComposition.Microsoft.PowerShell.GPowerShell.dll
4. feladat: Az "about_Windows_PowerShell_2.0" súgóban hány sorban szerepel a "p" betű?
Itt már kicsit szórt a társaság. A jó megodások alapvetően vagy a –match operátorral dolgoztak, vagy – szerintem ez az elegánsabb – a Select-String cmdlettel. A megoldás kulcsa egyébként, hogy a sorok megtalálásához tördelni kellett a súgót soronként:
PS C:> ((Get-Help about_Windows_PowerShell_2.0) -split "\r\n" | Select-String "P").count
177
5. feladat: Ha az "a" lenne az 1, a "b" a 2, stb, akkor a "PowerShell" betűinek szorzata mennyi?
Ennél a feladatnál többen megijedtek a negatív számoktól, így átalakították a PowerShell szót kisbetűssé, de ezt nem kértem. Később pontosítottam a feladatot, de a kisbetűsített megoldásokat is elfogadtam. A megoldásomban látszik, hogy se ciklust nem kell szervezni, se átalakító metódusokat nem kell meghívni, de egyéb átmeneti változókat nem kell képezni. A „programolós” stílust többen nehezen vetették el, de azért a jó eredmény mellett ezeket a megoldásokat is elfogadtam.
PS C:> $k = 1; [int[]][Char[]]"PowerShell" | foreach-object {$k*=$_-96}; $k
37200384000
6. feladat: Mi van ideírva "titkosírással": RydqdskdjOnvdqRgdkk?
Először többen megijedtek, de aztán akik legyőzték az ijedtségüket azoknak nem okozott gondot a megoldás. Megint volt pár „programolós” megközelítés, de a PowerShell segítségével ezt a feladatot nagyon tömören is meg lehet oldani:
PS C:> $ofs=""; [string][char[]]([int[]][char[]]"RydqdskdjOnvdqRgdkk" | ForEach-Object )
SzeretlekPowerShell
7. feladat: A "Literal" szót tartalmazó about help témák fájljainak méreteinek összege mennyi?
Ez a feladat erőser rostálta a társaságot. Itt szintén néhányan case sensitive-en értelmezték a feladatot, de ez nem volt kérés, azért ezeket a megoldásokat is elfogadtam. Balogh Mihály megoldása még az enyémnél is elegánssabb volt, mivel a Select-Stringet használta a Get-Content és –match kombinációja helyett, így az erre alapozott megoldás lett a „hivatalos”. Többen nem a fájl méretét nézték, hanem a help karaketereinek összegét, ami ugyan csak pár bájtos eltérés volt, de ezeket a megoldásokat nem tudtam elfogadni.
A tömör megoldás kulcsa az egymásba ágyazott pipe-ok, azaz a Where-Object-en belül az éppen aktuális elemmel nyitott új cső létrehozása:
PS C:> (Get-ChildItem -Path $PSHOME\en-Us\about_*.txt | Where-object { $_ | select-string "literal"} | Measure-Object -Property length -Sum).sum
34064
8. feladat: A 9 legtöbb paraméterrel rendelkező cmdlet "get-command" által kiolvasható paramétereinek számának összege mennyi?
Ez a feladat már igazán nagy kihívás volt! Egyrészt fontos volt, hogy tényleg a Get-Command által mutatott paraméterekkel dolgozzunk, hiszen a Get-Help a „common parameter”-eket nem ismerteti részletesen.
PS C:> (Get-Command -CommandType cmdlet | Foreach-Object {$_.parameters.keys.count} | Sort-Object -Descending | Select-Object -first 9 | Measure-Object -sum).sum
246
Ennél a feladatnál talán az ellenőrzés volt a legnehezebb, hiszen a hosszú, beágyazott csővezetékbe bem látunk bele. Így érdemes - az ellenőrzést megkönnyítendő - egy kicsit hosszabb megoldási móddal is próbálkozni:
PS C:> Get-Command -CommandType cmdlet | select-object name, @{n="nofparams"; e={$_.parameters.keys.count}} | Sort-Object -property nofparams -Descending | Select-Object -first 9
Name nofparams
---- ---------
New-ModuleManifest 38
Invoke-Command 28
New-PSSessionOption 28
Get-WSManInstance 28
Get-WmiObject 26
Set-WmiInstance 25
Invoke-WmiMethod 25
Register-PSSessionConfiguration 24
Set-WSManInstance 24
Persze ez nem adja még meg az összeget, de legalább látjuk, hogy jól gondolkozik-e?
9. feladat: Az összes cmdlet súgótémáinak példái közül, melyik változó szerepel a legtöbbször?
Itt is két értelmezéssel találkoztam. Az egyik csak a példák kódsoraiban kutakodott, de én nem akartam ennyire mélyre ásni, elég volt csak az Examples-ben keresgélni, kódsorral és magyarázattal együtt. A megoldás kulcsa egy regex kifejezés, ami a mi esetünkben lehetett elég egyszerű is: egy szó szerinti $ jel és legalább egy betűszerűség már jó is volt, hiszen nem nagyon van olyan sztring a súgótémákban, ahol a $ más jelentéskörynezetben szerelne, mint változónév. A help összetett objektum, így benne küzvetlenül nem tudunk „regexelni”, szöveggé kell alakítani.
Többszörös találatot keresünk, így a matches metódus kell nekünk, ennek kimenetének value tulajdonsága tartalmazza a megtalált változónevet. Ezután már csak csoportosítani, sorbarendezni és ez elsőt venni kell.
PS C:> $r = [regex] '\$\w+'
PS C:> Get-Command -CommandType Cmdlet | get-help -Examples | Out-String | ForEach-Object{ $r.matches($_) | %{$_.value}} | Group-Object | Sort-Object count -Descending | Select-Object -First 1 -Property name
Name
----
$s
Ha valaki csak a példák „code” tulajdonságában keresett, akkor a végeremény a $a-volt.
10. feladat: Az about_* help témák közül a leghosszabb és legrövidebb sorainak számának a különbsége mennyi?
Az utolsó feladat volt a legcsűrcsavarossabb természetesen, de ezt is két sorban is meg lehetett oldani.
PS C:> $t = Get-Help about_* | ForEach-Object {(Get-Help $_.name | Out-String | Measure-Object -Line).lines} | Sort-Object -Descending | Select-Object –First 1 -Last 1
PS C:> $t[0]-$t[1]
1371
Itt is inkább az ellenőrzés volt a nehéz, meg az, hogy ne magukban súgófájlokban kotorásszunk, mert a Get-Content és Measure-Object –lines kombinációja nem számolja bele az egymás utáni üres sorokat, márpedig az üres sor is sor! Így érdemes olyan átmeneti megoldást készíteni, amiben látszanak az egyes súgótémák nevei és a sorok száma is:
PS C:> Get-Help about_* | select-object name, @{l="sorok";e={(Get-Help $_.name | Out-String | Measure-Object -Line).lines}} | Sort-Object -property sorok -Descending | Select-Object -First 1 -Last 1
Name sorok
---- -----
about_preference_variables 1408
about_Continue 37
|