č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.