You are on page 1of 36

A Windows PowerShell rejtelmei

gy tapasztaltam, hogy nagyon kevesen tudjk, hogy mi is az a PowerShell s mire j, ezrt


gondoltam, hogy nhny egyszer, de azrt hasznos pldn keresztl elmagyarzom a gyakorlati
felhasznlsnak lehetsgeit.
A cikksorozat szlogenje az lehetne: szabaduljunk ki a grafikus cleszkzk fogsgbl, s valstsuk meg
azokat a funkcikat, amelyeket eddig mindenfle internetrl sszevadszott, gyakran beazonosthatatlan
forrsbl szrmaz segdprogrammal oldottunk meg!
Mi az a PowerShell?
A PowerShellt a Microsoft eleinte a hagyomnyos DOS-prompt, a parancssor utdjaknt aposztroflta, de
aztn egyre inkbb egy univerzlis rendszerkezel, feladatautomatizl platformknt lett definilva. Ez azt
jelenti, hogy a PowerShell segtsgvel olyan, a rendszerzemeltetsben felhasznlhat kifejezseket,
kisebb-nagyobb programokat lehet rni, melyekkel a Microsoft egyre tbb szoftvert lehet vezrelni.
Nem felttlenl kell mindenkinek a konzolablakban gpelgetnie mindenfle parancsot. Lesznek persze
ilyenek is (ez a cikksorozat azt prblja bemutatni, hogy ez sem rdngssg, akr otthoni felhasznli is
lehetnek a PowerShellnek), lesznek olyanok is, akik msok szmra ksztenek szkripteket. Aztn lesznek
olyanok is, akik PowerShell-alap eszkzket hasznlnak, s vgl lesznek olyanok, akik a PowerShell
kpessgeit felhasznlva ksztenek rendszergazdk szmra sszetett szoftvereket.
Amikor az Exchange Server 2010 grafikus kezelfelletn kattintgatunk, akkor a httrben PowerShell-
utastsok mennek az Exchange Serverhez, amikor a Windows Server 2008 R2 Active Directory
Administrative Centert hasznljuk, akkor szintn powershelleznk. Azaz maga a Microsoft is egy olyan
platformknt hasznlja a PowerShellt, amellyel rendszergazda eszkzket lehet ltrehozni.
A PowerShell teht egyszerre nagyon sok minden: parancssori eszkz, amellyel begpelt parancsokkal
tudjuk utastani a szmtgpnket, hogy klnbz mveleteket elvgezzen. A PowerShell egy
programnyelv is, minden ehhez szksges jellemzvel: ciklussal, vezrlutastsokkal, opertorokkal,
vltozkkal, adattpusokkal. A PowerShell a rendszergazdk szmra egy olyan eszkz, ami a .NET
keretrendszer profi programozk ltal ltrehozott tbb ezer osztly objektumait s azok szolgltatsait
elrhetv teszi. s vgl szmomra, mint informatikai oktatnak egy olyan, mindenki szmra elrhet
eszkz, amivel mind a Windows opercis rendszerek bels mkdst, mind az objektum-orientltsgot,
mind a programozst nagyon jl meg lehet tantani.

Az els gyakorlat
Mindennek demonstrlsra az els feladat az lenne, hogy kicsit tegyk rendbe a szmtgpre ttlttt
fnykpeinket. A mai digitlis fnykpezgpekben tallhat nagy trolkapacits memriakrtyk mellett
gyakran tbb szz fnykpnk is sszegylik a My Pictures knyvtrban, elg nehz kztk tjkozdni.
Ebben a cikkben addig jutunk el, hogy a kpeinket havi bontsban trakjuk alknyvtrakba.
A Microsoft Windows 7 rkezsvel minden ilyen opercis rendszeren ott van a Windows PowerShell. A
tbbi, de azrt Windows XP-nl nem rgebbi Microsoft opercis rendszert hasznlk pedig ingyen
letlthetik s telepthetik. Nzzk az els lpst, nyissuk meg a PowerShellt, illetve a kezdknek taln
knyelmesebben hasznlhat grafikus szerkeszt felletet, a Windows PowerShell ISE-t!

Ennek a hromosztat ablaknak a fels rszben fogunk dolgozni. A begpelt parancsokat a Run Script
(F5) gombbal tudjuk futtatni, az eredmnyek a kzps ablakrszben jelennek meg. Itt a cikkben
flkvrrel jelzem azt, amit a fels ablakrszbe kell gpelni. Mindig csak annyi legyen a fels rszben,
amennyit n itt jelzek, a korbbi parancsokat mindig trljk ki! Eltr httrsznnel az lthat, ami a
kimeneti ablakrszben jelenik meg. Ahol nagyon sok sor jelenne meg a kimeneten, ott csak az els
nhnyat msoltam ide.

Kezdjnk neki! Felttelezem, hogy a kpek a Pictures knyvtrban tallhatk.
cd .\Pictures
dir
Directory: C:\Users\tibi\Pictures


Mode LastWriteTime Length Name
- - - -
-a- 2009.09.02. 22:58 2525150 P1090919.JPG
-a- 2009.09.02. 22:58 2256418 P1090927.JPG
-a- 2009.09.02. 22:58 2278723 P1090998.JPG
-a- 2009.09.02. 22:59 2499729 P1100022.JPG
-a- 2009.09.02. 22:59 2526647 P1100042.JPG
-a- 2009.09.02. 22:59 2282924 P1100125.JPG

Ez egyelre mg nem tl izgalmas. Azt hisszk, hogy DOS parancsokat hasznlunk, de ez mr szntiszta
PowerShell, valjban a cd a Set-Location, a dir pedig a Get-ChildItem PowerShell parancsok "lneve". Az
igazi rdekessg ott jn el, ha elkezdnk dolgozni az egyes fjlokkal. Elljrban annyit kell tudni, hogy a
PowerShellben minden objektum, hogy vannak lekrdezhet s esetleg trhat tulajdonsgai,s
meghvhat metdusai. A metdusok olyan fggvnyek, parancsok, amelyek az adott objektummal
kapcsolatban valami rtelmes dolgot hajtanak vgre. A mi kprendezget feladatunk szempontjbl most a
kpfjl azon tulajdonsga rdekes, ami a mdostsnak dtumt tartalmazza. Nzzk, ezt hogyan
rhetjk el egy konkrt fjl esetben:
(dir .\P1090919.JPG).lastwritetime
2009-09-02
A zrjelek kzti rsz egy konkrt fjlt "megragad", majd ennek a fjlnak vesszk a lastwritetime
tulajdonsgt. A "pont" karakterrel lehet hivatkozni az objektumok tulajdonsgaira.
Nekem ebbl az v s a hnap kellene szmokkal kifejezve, szpen egybefzve egy ktjellel, mert ilyen
nev alknyvtrakba szeretnm rendezni a kpeimet. Szerencsre az elz kimenetet nem szvegknt kell
feldolgoznunk (az elg nehz lenne), hanem erre a PowerShell ksz megoldssal ll rendelkezsnkre.
Miutn itt egy dtumrl van sz, elveszem a dtumok kezelst vgz parancsot, a get-date-et s
megadom a megfelel formz kifejezst a Format paramternv utn:
get-date (dir .\P1090919.JPG).lastwritetime -Format "yyyy-MM"
2009. szeptember 2. 22:52:57
Ez a formzs teht veszi a dtumbl az vek szmjegyeit (yyyy), egy ktjelet, majd a hnapok
szmnak kt szmjegyt (MM itt kivtelesen fontos a nagybet, mert kisbetvel a perceket jelljk).

Na, ez mr egy fjlra mkdik, most nzzk az sszes kpfjlra ezt hogyan tudjuk ezt ellltani:
dir *.jpg| ForEach-Object {get-date $_.lastwritetime -format "yyyy-MM"}
2010-02
2009-09
2009-09
2009-09
...
Mi is trtnt itt? A dir-t rtjk, az ebbl kijv fjlobjektumokat tovbbkldjk a "futszalagon" (| jel) tovbbi
feldolgozsra. Ezen feldolgozs keretben minden egyes futszalagon rkez objektumra a Foreach-
Object parancs segtsgvel legenerltatjuk az elbb mr ltott mdszerrel az v-h formtum szmsort.
Az ppen aktulis futszalagon rkez objektumra, jelen esetben fjlra, a $_ jellel tudunk hivatkozni.
Fontos, hogy a ForEach-Object utni kifejezs kapcsos zrjelben van, ennek fontos szerepe van, amire
majd egy kvetkez cikkben trek ki.
Ezutn alaktsuk tovbb a kis programunkat! Ebben a lpsben ellenrizzk, hogy v-h formtum
alknyvtr mr ltezik-e? Ezt a Test-Path PowerShell paranccsal lehet megtenni. Ennek mkdsnek
feldertsre vegynk fel egy alknyvtrt ide, a fnykpek knyvtrba, mondjuk "egyb" nvvel. Ez utn
ellenrizzk, hogy ez mit ad eredmnyl:
Test-Path ".\egyb"
True
Ez egy nem ltez knyvtrra False eredmnyt fog adni. Neknk meg pont ekkor kellene alknyvtrt
ltrehozni, amikor ez a vizsglat hamis eredmnyt ad. Programozsban jl ismert az IF vezrlszerkezet,
mellyel akkor lehet vgrehajtatni valamit, amikor egy felttel igaznak rtkeldik. Neknk hamis eredmnyt
ad a Test-Path, amikor tennivalnk lenne, gy fordtani kell a kirtkels eredmnyn, amit a Test-Path
eredmnynek neglsval tudjuk elrni, amit a PowerShellben a felkiltjellel tudunk jelezni. Mindezzel
egytt az If szerkezet gy nz ki:
If(!negland felttel){vgrehajtand kd}
Knyvtrat a New-Item paranccsal tudunk ltrehozni, a kvetkez formtumban:
New-Item Path hova ItemType Directory
Fjlt tmozgatni a Move-Item paranccsal tudunk, melynek szerkezete a kvetkez:
Move-Item Path Destination clknyvtr
Mg annyit tegynk meg, hogy az alknyvtrnevet tegyk be egy vltozba, hiszen ezt tbbszr is fel
fogjuk hasznlni: az alknyvtr megltnek ellenrzsekor, az esetlegesen ltrehozand j knyvtr
esetben s a kp tmozgatsnak clknyvtraknt. Vltozneveket a PowerShellben egy $ jellel kell
kezdeni. A PowerShellben akr kezetes karaktereket is alkalmazhatunk vltoznevekben.

A teljesen sszerakott kis "program" gy nz ki:
cd $HOME\pictures

dir *.jpg | ForEach-Object {
$alknyvtr = get-date $_.lastwritetime -Format "yyyy-MM"
if(! (Test-Path -Path ".\$alknyvtr")) {
New-Item -Path ".\$alknyvtr" -ItemType Directory}
Move-Item -Path $_.pspath -Destination ".\$alknyvtr"
}
Mit is lthatunk itt? Az elejn biztos, ami biztos tlpnk a kpek knyvtrba, nehogy vletlenl msutt
lev kpfjlok kztt garzdlkodjunk. A $HOME vltoz tartalmazza a belpett felhasznl
munkaknyvtrt, felttelezsem szerint ennek Pictures alknyvtrban vannak a kpek. Ezutn a JPG
kiterjeszts fjlokat megragadjuk, rtesszk a futszalagra s bekldjk ket egy ForEach-Object
"gpbe". A gpbe beltunk, a bels felpts a kapcsos zrjelek kztt lthat. A gp belsejben
ltrehozunk egy alknyvtr nev vltozt, ami a gpbe rkez fjl mdostsi idejbl kpzd ktjeles
szmjegyeket tartalmazza. Majd megvizsgljuk, hogy van-e ilyen nev alknyvtr, s ha nincs, akkor
ltrehozzuk azt. Mire a Move-Item-hez rnk, addigra mr biztos van megfelel alknyvtr, gy az ppen
feldolgozs alatt lev kpfjlt t tudjuk oda helyezni.
Mik ebben a programban mg az rdekessgek? Pldul az, hogy a PowerShell a vltozkat az idzjelek
kztt kifejti, gy a ".\$alknyvtr" kifejezs mindig az aktulis alknyvtrnvvel helyettestdik be a . s / jel
utn. Krek mindenkit, hogy a program tesztelst csak olyan fjlokon vgezze, amelyekrl van biztonsgi
msolata, mert flregpelsek esetn esetleg olyan helyre mozgatdnak, ahol nehz megtallni azokat.

A Windows PowerShell rejtelmei - 2. rsz
A Windows PowerShell hasznlatt bemutat cikksorozat msodik rszben szveges llomnyok
feldolgozshoz adunk tippeket.
A cikksorozat els rszben egy egyszer fjlrendszerez pldn keresztl kezdtem bemutatni a
PowerShellt. A cikkhez adott hozzszlsokra reaglva fontosnak tartom hangslyozni, hogy nem akarom
a PowerShellt ms shellekkel szembelltani. Egyrszt azrt nem, mert nem rtek ms shellekhez, gy nem
tartanm ezt korrektnek.
Msrszt egy ilyen sszehasonltsnak annyi rtelme lenne, mint pldul a magyar s az angol nyelv
sszehasonltsnak. Melyik nyelv jobb, szebb, praktikusabb? Ez elg szubjektv dolog, termszetesen a
legtbb ember az anyanyelvt tartja a legjobbnak, legszebbnek, nem utolssorban azrt, mert azt tudja
legjobban, azt tanulta meg legelszr. Msrszt nyilvn Angliban praktikusabb az angol, mint a magyar.
Ugyanez a helyzet a PowerShellel is: a Windows platformon valszn jobb a PowerShell a tbbi shellnl.
Ha csak azt nzzk, hogy szmos Microsoft termk PowerShellel kezelhet, ms shellel nem, akkor
szerintem ez elg egyrtelm.
De trjnk vissza a PowerShellhez! Ebben a pldban mr prblok kevsb szjbargs lenni,
felttelezem immr, hogy az olvask zme azrt valamilyen programozsi ismerettel rendelkezik. A
mostani pldimban mr a knyvemben is alkalmazott jellst hasznlom, azaz itt nem a grafikus
PowerShell ISE felleten dolgozom, hanem a karakteres konzolon. Kicsit mg mdostottam a "gyri"
prompton, a PS C:\> el bebiggyesztettem egy szgletes zrjelek kzti sorszmot, hogy jobban lehessen
hivatkozni ezekre a sorokra.
Nzzk akkor a kvetkez tmakrt, a szvegfjlban trolt adatok feldolgozst! Vegynk egy kpzeletbeli
kerkpros versenyt, amelyen hrom kategriban lehet indulni: frfi, n, ifjsgi, ezek klnbz tvokat
jelentenek. A verseny eredmnyt egy egyszer szveges fjlba rjuk be, legyen a fjl neve bringa.txt:
Nv, Nem, letkor, Tv, Id
Brin Gspr, frfi, 15, 45, 1:34:35
Sos Tibor, frfi, 39, 60, 2:10:34
Fjdalom Csilla, n, 22, 30, 1:21:11
Vegetri Jnos, frfi, 35, 60, 1:59:54
Beld Mrton, frfi, 42, 60, 2:22:10
Jv va, n, 32, 30, 1:12:05
Brill Antal, frfi, 16, 45, 1:54:22
Kerk Pl, frfi, 17, 45, 1:39:54
Hajt Anna, n, 26, 30, 1:19:32
Ezeket az adatokat kellene feldolgozni PowerShell segtsgvel. Ha megfigyeljk a szveget, lthat, hogy
ez valjban egy CSV (comma separated values) adatokat tartalmaz fjl, azaz vesszvel elvlasztott
rtkek tblzata, az els sorban az oszlopok nevei tallhatk. Az ilyen formtum fjlt a PowerShell
nagyon knnyen tudja kezelni:


[4] PS C:\scripts> Import-Csv .\scripts\bringa.txt
| Format-Table

Nv Nem letkor Tv Id
- - - - -
Brin Gspr frfi 15 45 1:34:35
Sos Tibor frfi 39 60 2:10:34
Fjdalom Csilla n 22 30 1:21:11
Vegetri Jnos frfi 35 60 1:59:54
Beld Mrton frfi 42 60 2:22:10
Jv va n 32 30 1:12:05
Brill Antal frfi 16 45 1:54:22
Kerk Pl frfi 17 45 1:39:54
Hajt Anna n 26 30 1:19:32
Lthat, hogy CSV fjlok beolvassra az Import-CSV cmdlet ll rendelkezsnkre. A PowerShell
terminolgiban az "igazi" parancsok neve a cmdlet (ejtsd: kommandlet). Ezek olyan parancsok, amelyeket
a PowerShell sajt infrastruktrja biztost, nem pedig valamilyen kls program. Szigor szablyok
vannak a parancsok elnevezsre, mindannyian ige-ktjel-fnv szerkezetek, radsul a lehetsges
igk is jl behatroltak, gy sok meglepetsre nem kell szmtanunk, radsul elg knnyen kitallhat,
akr egy szmunkra ismeretlen parancsrl is, hogy az mit is csinlhat.
Az Import-CSV pldul beolvassa egy CSV fjl tartalmt s az ottani informcik alapjn ltrehoz specilis
objektumokat olyan tulajdonsgnevekkel, mint ami a fjl els sorban lev elnevezsek. A fenti
kifejezsem vgn n mg tblzatos nzetben krtem az adatokat a Format-Table cmdlet segtsgvel.
Nzzk, hogy a megjelentett sorok tnyleg objektumok, azaz tulajdonsgaik kln-kln megszlthatk:
[6] PS C:\> $versenyzk = Import-Csv .\scripts\bringa.txt
[7] PS C:\> $versenyzk[1].id
2:10:34
Az egyszersg kedvrt az elbb ltott objektum-halmazt betltm egy $versenyzk vltozba [6] s
pldul Sos Tibor ideredmnyt kiolvastam [7]. A $versenyzk tmbjnek egyes elemeire szgletes
zrjelbe rt szmmal kell hivatkozni, az els elem a 0. elem, gy az n adatsorom az 1. elemben van, s
ennek az Id tulajdonsga adta meg az ideredmnyemet.

Ezzel mr most sok minden el tudunk vgezni, pldul keressk a kategrinknti gyzteseket:
[8] PS C:\> $versenyzk | Group-Object -Property tv | ForEach-Object
{$_.group | Sort-Object -Property id | Select-Object -First 1}
| Format-Table

Nv Nem letkor Tv Id
- - - - -
Brin Gspr frfi 15 45 1:34:35
Vegetri Jnos frfi 35 60 1:59:54
Jv va n 32 30 1:12:05
Mi trtnt itt? Vettem a versenyzi adatokat s rtettem ket a futszalagra. Az els gp, a Group-Object
csoportostotta ezeket, "bedobozolta" a Tv tulajdonsg alapjn, ez adja meg az egyes kategrikat.
Ennek kimenete olyan csoportobjektumok halmaza, melyek Group nev tulajdonsgn keresztl rhetk el
az adott csoportba tartoz versenyzi adatok, azaz a doboz tartalma. Pillantsunk bele, hogy a gpsor ezen
pontjn mi is van a futszalagon, hogyan is nznek ki az gy kpzett dobozok:
[9] PS C:\> $versenyzk | Group-Object -Property tv

Count Name Group
- - -
3 45 {@{Nv=Brin Gspr; Nem=frfi; letkor=15; .
3 60 {@{Nv=Sos Tibor; Nem=frfi; letkor=39; T.
3 30 {@{Nv=Fjdalom Csilla; Nem=n; letkor=22;.
Lthat, hogy hrom doboz kszlt, egy-egy dobozon, azaz csoporton bell az oda tartoz adatok rkezsi
sorrendben vannak, nekem pedig idre kellene rendezni ezeket. gy a [8]-as sorban lthat kifejezsben
veszem a csoport-objektumokat egyesvel a ForEach-Object cmdlettel, s azt adom neki utastsba, hogy
vegye az aktulis csoport elemeit, amelyek teht a Group tulajdonsgon keresztl rhetk el. Ezeket
helyezze egy bels, jabb futszalagra, amin rendezze id szerint az adatokat a Sort-Object cmdlet
segtsgvel, majd egy-egy csoportbl vegye csak az els elemet, azaz a legkisebb ideredmnnyel
rendelkez versenyzt a Select-Object cmdlettel. A legvgn a tblzatos nzetet kiad Format-Table van
ismt.
Fokozzuk ezt! Mi van akkor, ha arra vagyok kvncsi, hogy vajon mi volt a versenyzk tlagsebessge? Ezt
a legelegnsabban gy tudjuk megtudni, ha ezt egy j tulajdonsgknt hozztesszk az egyes versenyzi
adatsorokhoz. s ha mr alaktgatunk, akkor legynk mg preczebbek! Valjban itt az idadatokat
szvegknt olvasta be a PowerShell, ksztsnk ezekbl igazi, id tpus adatokat. Ezt mr a grafikus
szkript-szerkesztben raktam ssze, hogy szebb tagolssal tudjam ide msolni.

Ezeket a formzott, trdelt sorokat egy az egyben ki lehet innen msolni, s be lehet illeszteni kzvetlenl
a PowerShell konzolba, a sortrseket s az tlg sorokat teljesen korrektl kezeli a rendszer:
$versenyzk = @()
Import-Csv c:\scripts\bringa.txt |
ForEach-Object {
$_.Id = [timespan] ($_.id+".0")
$_ | Add-Member -Name tlagsebessg -MemberType NoteProperty -Value `
($_.tv/($_.id.totalhours))
$versenyzk += $_
}
Mi trtnt itt? Elre elksztettem egy $versenyzk nev res tmbt (@() ez a jellse egy res
tmbnek), majd a mr ltott mdon elkezdem beimportlni az adatokat. Minden egyes adatsorra talaktom
az Id tulajdonsgot "igazi" idv, ehhez a [timespan] tpusjellt hasznltam, de mivel ez szmtana mg
tizedmsodpercekre is, ezrt azt mg hozzbiggyesztem a beolvasott adathoz. Ezutn az aktulis elemet
($_) kibvtettem egy jabb tulajdonsggal, aminek neve tlagsebessg, tpusa un. Noteproperty, ami
gyakorlatilag azt jelenti, hogy ez egy statikus adat, rtke pedig a Tv elosztva az elbb kiszmolt Id
rkban kifejezett (totalhours) rtkvel.
Itt mutatkozik meg az idre alakts haszna s a PowerShell tpusossga, mert lthat, hogy milyen
egyszeren lehet ezzel az idtartamok klnbz mrtkegysgekben vett rtkt kpezni. A legvgn az
adott adatsort beraktam a $versenyzk tmb kvetkez elemeknt. Nzzk, hogy tnyleg benne vannak-e
az tlagsebessgek, st, rendezzk mindjrt eszerint cskken sorrendbe:
[26] PS C:\> $versenyzk | Sort-Object -Property tlagsebessg -Descending
| Format-Table nv, tv, id, tlagsebessg

Nv Tv Id tlagsebessg
- - - -
Vegetri Jnos 60 01:59:54 30,02502085070
Brin Gspr 45 01:34:35 28,54625550660
Sos Tibor 60 02:10:34 27,57212152157
Kerk Pl 45 01:39:54 27,0270270270
Beld Mrton 60 02:22:10 25,32239155920
Jv va 30 01:12:05 24,9710982658
Brill Antal 45 01:54:22 23,60827747012
Hajt Anna 30 01:19:32 22,63202011735
Fjdalom Csilla 30 01:21:11 22,17203859577
Hurr! Benne van. A szebb megjelents miatt s most itt csak ngy tulajdonsgot vlasztottam ki a
tblzatba. s mg mindig lehet fokozni! Hogyan lehetne pldul kiszmolni, hogy a versenyzk sszesen
hny kilomtert tekertek, mi volt az tlagos hossz, legkisebb s legnagyobb tv s hny versenyz volt:
[30] PS C:\> $versenyzk | Measure-Object -Sum -Average -Maximum
-Minimum Property tv


Count : 9
Average : 45
Sum : 405
Maximum : 60
Minimum : 30
Property : Tv
Ht ez nem volt tl bonyolult! Miutn ilyen jelleg egyszer statisztikk nagyon gyakoriak, ezrt a
PowerShell alkoti adtak egy beptett cmdletet, a Measure-Object-et, ami megadott tulajdonsgra ezeket
a statisztikai adatokat kiszmolja. Lthat pldul, hogy 9 versenyzm volt, sszesen 405 km-t tekertek s
az tlagtv pont 45 km volt.

A Windows PowerShell rejtelmei - 3. rsz
Harmadik rszhez rkezett a Microsoft Windows parancssort bemutat cikksorozat. Ebben olyan
megoldsi tletek tallhatk, amelyek a rendszergazdk htkznapi zemeltetsi feladataiban is jl
hasznosthatk, pldul objektumok sszehasonltsa vagy adatok letltse az internetrl.
A PowerShellt bemutat cikksorozat harmadik rszben az sszehasonltssal fogok foglalkozni. Korbban
mr volt rla sz, hogy a PowerShellben objektumokkal dolgozunk, radsul ltalban nem is egy-egy
objektummal, hanem egyszerre tbbel, n. objektumgyjtemnyekkel. Az els cikkben sok kpfjl-
objektumot dolgoztam fel, a msodikban sok szvegsor-objektumot. Nagyon sok olyan problma van,
melyek megoldshoz ilyen objektumgyjtemnyek sszehasonltsa rvn juthatunk el. Most egy ilyen
feladatot fogok itt megoldani a PowerShell segtsgvel, lotttippeket rtkelek ki. A kvetkez cikkben mr
olyan pldkat hozok az sszehasonltsokra, melyek a rendszergazdknak jelenthetnek segtsget: kt
egyformnak hitt szmtgp szoftveres klnbsgeit dertem fel.
Letlthet PowerShell-knyv s vetlked
Mieltt belekezdenk a cikk tmjba pr szolglati kzlemnyt engedjenek meg! Az online mdiumok
kzl elsknt a HWSW olvasi rteslhetnek arrl, hogy mr szabadon letlthet a PowerShell 2.0
elmlet s gyakorlat rendszergazdknak cm knyvem a Microsoft Magyarorszg jvoltbl. Msodik hr,
hogy nemsokra indul a Microsoft Scripting Games 2010 vetlkedje, lesz kezd s halad szekci is, gy
brki btran indulhat. Ehhez "edztbort" is szerveztem, tz gyakorl feladatot lehet itt tallni. Ha ezek kzl
megoldanak feladatokat s a megoldsokat eljuttatjk hozzm, akkor rtkelem azokat s majd a
"hivatalos" megoldsokat is kzzteszem. A legtbb, legszebb megoldst bekldnek Microsoft Press
szakknyv a nyeremnye. Biztatok mindenkit, aki rdekldik a PowerShell irnt, hogy vegyen rszt az
edztborban, nzze meg a korbbi vek feladatait s megoldsait s induljon az idei Scripting Games
bajnoksgon, nagyon sokat lehet tanulni s ott jval rtkesebb djak is vrnak a nyertesekre!
Lottzzunk a PowerShell segtsgvel!
Nha veszek lottszelvnyt s ha mr erre vetemedek, akkor nem is egy szmsorral, hanem 3-4-el
jtszom. Viszont a kirtkels nem olyan egyszer, mert a kihzott szmokat szpen egyesvel ssze kell
hasonltani a tippek szmsoraival, ami elg sok sszehasonltgatst ignyel. Hogyan tudna ebben a
PowerShell segteni? Vegynk elszr csak egy tippsort s a tnylegesen hzott szmokat, s hasonltsuk
ssze ezeket az objektumgyjtemnyek sszehasonltsra szolgl Compare-Object cmdlet segtsgvel:


[1] PS C:\> Compare-Object 28,38,55,68,82 10,20,30,40,55

InputObject SideIndicator
- -
10 =>
20 =>
30 =>
40 =>
28 <=
38 <=
68 <=
82 <=

A Compare-Object cmdletnek tadok kt szmsort sszehasonltsra, az els a mlt heti nyertes szmokat
tartalmazza, a msodik a tippemet. A kt szmsor kztt szkz van, ezzel lehet a PowerShellben a
cmdletek paramtereit elvlasztani, mert ahogy az itt is lthat a vessz a tmbelemek
(gyjtemnyelemek) elvlasztsra van fenntartva. Az eredmny "grafikusan" jelzi, hogy mik az eltrsek.
Ezek kztt a szmok kztt csak az 55 kzs, az nem szerepel a listn, a 10 csak a msodik kupacban
van, gy mellette egy "=>" nyl tallhat, a 28 meg csak az els kupacban van, az nyila meg fordtott "<=".
Ez mind szp, de nekem pont az kellene, hogy melyek az egyforma szmok. Szerencsre a Compare-
Object mkdse szablyozhat. Egy jabb paramterrel krhetem, hogy a klnbzsgeket ne mutassa,
egy msikkal meg azt, hogy az egyezsgeket viszont jelentse meg:

[2] PS C:\> Compare-Object 28,38,55,68,82 10,20,30,40,55 -ExcludeDifferent
-IncludeEqual

InputObject SideIndicator
- -
55 ==


Ha csak azt szeretnm ltni, hogy mik az eltallt szmok, arra kicsit kell csak mdostani a fenti kifejezst:

[3] PS C:\> Compare-Object 28,38,55,68,82 10,20,30,40,55
-ExcludeDifferent -IncludeEqual | ForEach-Object {$_.inputobject}
55

Ha meg arra vagyok kvncsi, hogy hny tallatom van, akkor ennek a szmossg tulajdonsgt kell
lekrnem:

[4] PS C:\> (Compare-Object 28,38,55,68,82 10,20,30,40,55
-ExcludeDifferent -IncludeEqual | ForEach-Object {$_.inputobject}).count
[5] PS C:\>

Hopp! Ez nem adott semmit. Azrt, mert itt csak egy tallatom volt. Ha kett lett volna, akkor mkdtt
volna:

[5] PS C:\> (Compare-Object 28,38,55,68,82 10,20,30,68,55
-ExcludeDifferent -IncludeEqual | ForEach-Object {$_.inputobject}).count
2

Vajon mirt? Mert az egsz sszehasonltsnak a kimenete is objektum, csakhogy ez egy tallat esetben
maga az egy darab szm, s a szmnak nincs "count" tulajdonsga. Mg ha tbb tallatom volt, akkor a
kimenet egy gyjtemny, annak mr van "count tulajdonsga. De nem baj, szerencsre van egy olyan
jells a PowerShellben, ami garantlja, hogy mindig gyjtemny legyen a kimenet, mg akkor is, ha csak
egy elem van benne. Ezt egy @() zrjelezssel tudjuk elrni:

[6] PS C:\> @(Compare-Object 28,38,55,68,82 10,20,30,40,55
-ExcludeDifferent -IncludeEqual | ForEach-Object {$_.inputobject}).count
1


s termszetesen ez kt tallatnl is tovbbra is tkletesen mkdik:

[7] PS C:\> @(Compare-Object 28,38,55,68,82 10,20,30,68,55
-ExcludeDifferent -IncludeEqual | ForEach-Object {$_.inputobject}).count
2

Ennek birtokban kszthetnk egy sajt PowerShell cmdlet-szersget, aminek paramterknt tadva kt
szmsort kirja, hogy hny egyez szm van kztk s hogy melyek ezek. Ezt fggvnydefinilssal
oldhatjuk meg. Most ide a grafikus szkriptszerkesztbl van msolva, de egy az egyben bemsolhat a
konzolablakba is s vgs Enter letsvel ltrejn a fggvnydefinci:

function ellenriz-tipp {
param (
[int[]] $hzottak,
[int[]] $tippek)
$tallat = @(
Compare-Object $hzottak $tippek -IncludeEqual -ExcludeDifferent |
ForEach-Object {$_.inputobject})
Write-Host "$tippek : " -NoNewline
if($tallat) {
write-host "Tallat: $($tallat.count), eltallt szmok: $tallat"
}
else {write-host "Nincs tallat"}
}

A fggvny neve az, hogy "ellenriz-tipp". Kt paramtert vr, az els a "hzottak", a msodik a "tippek".
Mindkett egsz szmok gyjtemnye. A fggvny belsejben az elbb kitallt mdon a $tallat vltozba
teszem az eltallt szmokat, majd kirom a kpernyre elszr a tippknt megadott szmokat, majd
aszerint, hogy volt-e tallat, mg mell rom, hogy hny tallat volt s melyek azok. Klnben meg azt rom
ki, hogy "Nincs tallat".

Nzzk, hogyan mkdik ez:

[9] PS C:\> ellenriz-tipp 28,38,55,68,82 10,20,30,40,55
10 20 30 40 55 : Tallat: 1, eltallt szmok: 55
[10] PS C:\> ellenriz-tipp 28,38,55,68,82 10,20,30,68,55
10 20 30 68 55 : Tallat: 2, eltallt szmok: 68 55
[11] PS C:\> ellenriz-tipp 28,38,55,68,82 10,20,30,40,50
10 20 30 40 50 : Nincs tallat

Irny az internet!
Mi van azokkal a jtkfggkkel, akik tbb tucat szmsorral jtszanak? k az egyszersg kedvrt egy
szveges fjlba berhatjk a tippsoraikat s a PowerShell onnan is be tudja olvasni azokat, s
automatikusan kirtkeli az sszes tippsort. De csavarjunk mg egyet a dolgon! n mr a hzott szmokat
is lusta vagyok begpelni, szedje ssze ezeket a PowerShell az internetrl! Sajnos a "hivatalos" lott
oldalon nagyon bonyolultan vannak fent a nyerszmok, de a Teletipp weboldalrl knnyebben le lehet
szedni ezeket. Az ezt elvgz fggvny gy nz ki:

function get-lotto {
$wc = New-Object net.WebClient
$oldal = $wc.DownloadString("http://www.teletipp.hu/")
$keres1 = '5/90\stslott \r\n'
$keres2 = '(\d+\.\sjtkht\s\d{4}\.\d{2}\.\d{2}\.)'
$keres3 = '\r\n'
$keres4 = '(\d{1,2},\d{1,2},\d{1,2},\d{1,2},\d{1,2})'
if($oldal -match ($keres1 + $keres2 + $kerese3 + $keres4))
{
Write-host $Matches[1]
$Matches[2] -split ","
}
}

Ne ijedjen meg senki, nem olyan bonyolult, mint amilyennek ltszik. Ennek a get-lotto fggvnynek nincs is
paramtere. A webes elrs nagyon egyszer, a PowerShell alatt ott a .NET keretrendszer s abban mr
vr rnk egy olyan osztly, ami egyszer webbngszst vgez. Ez az osztly a System.Net.WebClient
nvre hallgat, a PowerShellben nem kell kirni a System eltagot. Ennek az osztlynak egy objektumt
hozom ltre a $wc vltozba a New-Object cmdlet segtsgvel, s ennek a DownloadString metdusval
tltm le a Teletipp oldalt. Ez egy nagy, tbbsoros szveget ad, a weboldal HTML forrskdjt, ebben kell
csak megkeresni az tslott szmait tartalmaz rszt.Hogy hogyan, azt az "igazi" bngsznk forrskd
megjelentjnek segtsgvel tudjuk megalkotni:

A kiemelt rsz kell neknk. Ezt idtll mdon egy regex kifejezs segtsgvel tudjuk megtallni. A keres
kifejezst ngy rszbl, a $keres1 - $keres4-bl raktam ssze, de csak azrt, hogy knyelmesen kifrjen a
kpernyre. A lnyege az, hogy keresem azt a szveget, hogy "5/90 tslott..." ( a szkzt \s-sel, a
sortrst \r\n-nel jelljk regexben). Ezt mg knny megtallni, de ezutn jn egy olyan rsz, ami htrl-
htre ms. Ez szerencsre a regexnek nem okoz gondot! A $keres2-ben azt fogalmazom meg, hogy
keresek legalbb egy szmjegyet (\d+), utna legyen egy szkz, majd az, hogy "jtkht", majd megint
csak 4 s 2 szmjegyekbl, valamint vesszkbl ll dtum. A nyerszmok meg a $keres4 kifejezssel
kereshetk, szintn szmjegyek s vesszk formjban. (Bvebben a knyvemben.)
A nekem kell rszeket, azaz a jtkht adatait s magukat a nyerszmokat zrjelezssel kiemelem, gy
majd a vgs tallatbl ezekre kln is hivatkozhatok. Az $oldal vltozban tallhat HTML forrsban
megkeresem teht az elbb sszerakott keres kifejezssel a nekem rdekes rszt, erre a PowerShellben
a match opertor ll rendelkezsnkre. Ha megtallta a teljes keresett kifejezst, akkor a tallat a
$Matches automatikus vltozba kerl. Ez valjban egy gyjtemny-szersg, ennek [0]-s eleme lenne
a teljes tallat (lsd a kpernykp kiemelt rszt), de ez nekem pont nem kell. Ami kell, az ennek [1]-es
eleme, a jtkht adatai (az els bezrjelezett rsz, azaz a $keres2-re illeszked szveg), amit ki is rok a
konzolra, valamint a [2]-es eleme, maguk a nyerszmok ($keres4-nek megfelel rsz), ez lesz a fggvny
visszatrsi rtke, ezt csak "simn" kiadom. Nzzk, hogyan mkdik ez:

[16] PS C:\> get-lotto
13. jtkht 2010.04.03.
28
38
55
68
82


Most mr csak ssze kell hozni a kt fggvnyt s a fjlba lerakott tippjeimet fel kell olvasni:

[20] PS C:\> $hzs = get-lotto
13. jtkht 2010.04.03.
[21] PS C:\> $hzs
28
38
55
68
82
[22] PS C:\> Get-Content c:\_munka\tippek.txt | ForEach-Object
{ellenriz-tipp $hzs ($_ -split ",")}
11 27 34 53 87 : Nincs tallat
5 10 14 39 70 : Nincs tallat
1 26 42 68 82 : Tallat: 2, eltallt szmok: 68 82

A [20]-as sorban a $hzs vltozba betltm az aktulis nyerszmokat. Amikor kirom a $hzs vltozt
lthat, hogy maga a cmke, azaz hogy "13. jtkht..." nem kerlt bele, mert a fggvnyben az nem
visszatrsi rtk volt, csak kpernyre kirats. Az utols kifejezs a [22]-es sorban remlem mr rthet!
Beolvasom a tippek.txt fjlt, amiben soronknt vesszvel elvlasztva vannak a tippek. Ezekkel a
tippsorokkal meghvom az "ellenriz-tipp" fggvnyemet, aminek els paramtere a $hzs vltoz, amibe
elbb tltttem be a nyerszmokat, msodik paramtert, a tippjeimet meg a szvegfjl aktulis sornak
vesszk mentn trtn feldarabolsa utn kapom (-split opertor). A kimenetben ltszik, hogy kt
tippsoromban nem volt tallat, egy tippsoromban meg kt tallat volt. (Sajnos ezt is csak a plda kedvrt
"hamistottam", valjban nem volt egy tallatom sem.)

A Windows PowerShell rejtelmei - 4. rsz
A Windows PowerShellt bemutat cikksorozat negyedik rszben megmutatom, hogyan tudjk a
rendszergazdk objektumok sszehasonltsval megtallni egy rejtlyesen mkd PC hibit.
gretemhez hven ebben a rszben tovbb folytatom az objektumok sszehasonltst. A rendszergazdk
gyakori problmja, hogy kt ugyanolyannak felttelezett szmtgp mgsem ugyangy viselkedik. Ennek
szmos oka lehet: eltr hardver, eltr szoftveres belltsok, ms fut alkalmazsok, ms teleptett
szolgltatsok, melyek feldertse nem tl egyszer feladat. Ebben a cikkben megmutatom, hogy a
PowerShell ebben is tud neknk segteni, szertegaz jelentseket llthatunk ssze, akr tvoli gpekrl
is, drga rendszerfelgyeleti szoftverek nlkl.
A vizsglat mdszere az lesz, hogy kivlasztok egy referencia-szmtgpet, ami szerintem idelisan
mkdik, s ehhez hasonltom a felttelezetten ugyanolyan, de mgis eltr teljestmnyt nyjt gpet.
Elsknt dertsk fel a kt gpen fut folyamatok kzti klnbsgeket! A fut folyamatokat a Get-Process
cmdlet segtsgvel krdezhetjk le, de ha megadjuk a ComputerName paramtert, nem csak arrl a
gprl, ahol futtatjuk a parancsot, hanem tvoli gprl is. Radsul egyszerre tbb gpnevet adhatunk t
ennek a ComputerName paramternek, gy a kimeneten az sszes rintett gp folyamatait lthatjuk. Most
itt prbaknt csak a "c" betvel kezdd nev folyamatokat trkpezem fel a DC s a Member nev
szmtgpeimen:
[1] PS C:\> Get-Process c* -ComputerName DC, Member

Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
- - - - - - - -
41 6 1616 4208 49 1156 conhost
35 5 1536 4048 47 0,20 2720 conhost
421 11 1768 3532 42 1,84 312 csrss
344 10 1792 3616 42 328 csrss
179 11 1768 6524 110 22,27 360 csrss
144 10 1564 4460 41 368 csrss
Termszetesen ez csak akkor mkdik, ha rendszergazda jogosultsgom van a megfigyelt gpeken. Hogy
azt is lssuk, hogy ez eredmny egyes sorai melyik gprl rkeztek, testre szabom a megjelen tblzatot
a Format-Table cmdlettel, a folyamat neve mellett megjelentem a gp nevt is:


[2] PS C:\> Get-Process c* -ComputerName DC, Member | Format-Table
ProcessName, machinename

ProcessName MachineName
- -
conhost Member
conhost DC
csrss DC
csrss Member
csrss DC
csrss Member
Lthat teht, hogy vegyesen vannak a kt gprl rkezett adatok. Az egyszersg kedvrt mindkt gp
folyamatainak objektumait beteszem egy $all vltozba, majd kpzem az sszehasonltsban rsztvev
kt gp szolgltats-kupact egy-egy MachineName tulajdonsgra val szrssel. Ezt a kt kupacot adom
t az elz cikkben mr ltott Compare-Object-nek a Name paramter alapjn trtn sszehasonltsra:
[3] PS C:\> $all = Get-Process -ComputerName DC, Member
[4] PS C:\> Compare-Object ($all | Where-Object {$_.machinename -eq "DC"})
($all | Where-Object {$_.machinename -eq "Member"}) -Property Name

name SideIndicator
- -
svchost =>
dfsrs <=
dfssvc <=
dns <=
ismserv <=
Microsoft.ActiveDirectory.WebServices <=
ntfrs <=
ScriptEditor <=
vds <=

A vizsglt gpen (Member) teht azok a folyamatok hinyoznak a referenciagphez (DC) kpest, amelyek
neve mellett a "<=" SideIndicator ll, s azok a tbblet folyamatok, melyek mellett a "=>" ll. Krdezheti az
olvas, hogy vajon mirt nem kt kln Get-Process-t hvok meg a kt gpre, s azokat egymssal
hasonltom ssze? A vlasz az, hogy ebbl a formbl kiindulva sokkal knnyebb ezt a vizsglatot
ltalnostani olyan irnyba, hogy a referenciagp mellett ne is egy vizsglt gp legyen, hanem egyszerre
sok, gy egy kifejezssel akr tbb gp elemzst is el tudjuk vgezni.
Bonyolultabb a helyzet a rendszerszolgltatsok sszehasonltsval. Azt, hogy mik a kt gpre teleptett
szolgltatsok kzti eltrsek, az elzek analgijval ugyanilyen mdon fel lehet derteni, csak a Get-
Process cmdlet helyett a Get-Service-t kell hasznlni. Ami kicsit nehezebb, az annak megllaptsa, hogy
melyek azok a szolgltatsok, amelyek ugyan mindkt gpen teleptve vannak, de az egyik gpen el
vannak indtva, mg a msikon nem. Induljunk el itt is mindkt gp sszes szolgltatsnak
sszegyjtsvel:
[11] PS C:\> $all = Get-Service -ComputerName DC, Member
[12] PS C:\> $all

Status Name DisplayName
- - -
Running ADWS Active Directory Web Services
Stopped AeLookupSvc Application Experience
Stopped AeLookupSvc Application Experience
Stopped ALG Application Layer Gateway Service
Stopped ALG Application Layer Gateway Service
...
Ezekbl hagyjuk meg azokat a szolgltatsokat, amelyek mindkt gpen teleptve vannak. Ezt
legegyszerbben a szolgltatsobjektumok nv szerinti csoportostsval s az gy kapott csoportok kzl
a ktelemek kivlogatsval tudjuk megkapni:


[16] PS C:\> $all | Group-Object -Property servicename | where-object
{$_.count -eq 2}

Count Name Group
- - -
2 AeLookupSvc {System.ServiceProcess.ServiceController, S...
2 ALG {System.ServiceProcess.ServiceController, S...
2 AppIDSvc {System.ServiceProcess.ServiceController, S...
2 Appinfo {System.ServiceProcess.ServiceController, S...
2 AppMgmt {System.ServiceProcess.ServiceController, S...
...
Emellett mg azt is meg kell nzni, hogy a ktelem csoportok kzl melyek azok, ahol a csoporton belli
kt szolgltatsobjektum sttusza nem egyforma (group[0] s group[1] tulajdonsgban trolt elem):
[19] PS C:\> $all | Group-Object -Property servicename | where-object
{$_.count -eq 2 and $_.group[0].status -ne $_.group[1].status}

Count Name Group
- - -
2 PolicyAgent {System.ServiceProcess.ServiceController, S...
2 TrkWks {System.ServiceProcess.ServiceController, S...
2 vds {System.ServiceProcess.ServiceController, S...
Ezutn a csoportokat ki kell csomagolni, hogy jra szolgltatsobjektumokat kapjunk, ne pedig
csomagobjektumokat, s ezek kzl ki kell szrni csak a vizsglt gpre vonatkoz adatokat. A
kicsomagolst a Select-Object cmdlet ExpandProperty kapcsolval jelzett zemmdjval tudjuk megtenni:


[18] PS C:\> $all | Group-Object -Property servicename | where-object
{$_.count -eq 2 and $_.group[0].status -ne $_.group[1].status} |
Select-Object -ExpandProperty group | where-object
{$_.machinename -eq "Member"}

Status Name DisplayName
- - -
Running PolicyAgent IPsec Policy Agent
Running TrkWks Distributed Link Tracking Client
Stopped vds Virtual Disk
Ebben a vgeredmnyben pldul az lthat, hogy br mindkt gpen szerepel a PolicyAgent szolgltats,
ez a vizsglt gpemen fut, de a referencia gpemen ez nem fut, hiszen a szrs miatt ott ms kell legyen a
szolgltats llapota. A msik sszehasonltsra igazn j terep a Windowsos szmtgpek WMI
adatbzisa, azaz a Windows Management Instrumentation szolgltats ltal kezelt, a gpek legfontosabb
adatait tartalmaz adatbzisa. Ezen bell is a legalapvetbb informcit a Win32_ComputerSystem osztly
(tbla) tartalmazza, amit PowerShell segtsgvel nagyon egyszeren tudjuk kiolvasni. Nzzk egyelre
egy gpre hogyan is megy ez:
[23] PS C:\> Get-WmiObject -Class Win32_ComputerSystem

Domain : r2.dom
Manufacturer : innotek GmbH
Model : VirtualBox
Name : DC
PrimaryOwnerName : Windows User
TotalPhysicalMemory : 1073274880

Az gy lthat kimenet nem tartalmazza az sszes adatot, minden adat megjelentshez hasznlhatjuk a
Format-List cmdletet a * paramterrel:
[24] PS C:\> Get-WmiObject -Class Win32_ComputerSystem | Format-List *

...
Manufacturer : innotek GmbH
Model : VirtualBox
NameFormat :
NetworkServerModeEnabled : True
NumberOfLogicalProcessors : 1
NumberOfProcessors : 1
OEMLogoBitmap :
OEMStringArray :
PartOfDomain : True
PauseAfterReset : -1
PCSystemType : 2
PrimaryOwnerContact :
PrimaryOwnerName : Windows User
ResetCapability : 1
ResetCount : -1
ResetLimit : -1
Roles : {LM_Workstation, LM_Server, Primary_Domain_C
ontroller, Timesource...}
SupportContactDescription :
SystemStartupDelay :
SystemStartupOptions :
SystemStartupSetting :
SystemType : x64-based PC
TotalPhysicalMemory : 1073274880
...
Ez elg sok tulajdonsgot tett lthatv, gy ersen megvgtam, hogy ne legyen tl hossz. Az opercis
rendszer s a szmtgp legfontosabb adatait lthatjuk. Neknk most nem is nmagban ez a sok
tulajdonsg az rdekes, hanem kt szmtgp ilyen jelleg tulajdonsgai kzti eltrsek. Ezt az
sszehasonltst nem annyira trivilis elvgezni, mert mg objektumok kupacait a Compare-Object
cmdlettel ssze tudjuk hasonltani, addig sajnos tulajdonsgok sszehasonltsra Compare-
ObjectProperty cmdlet nincs. De kszthetnk ilyet! Az alaptlet az, hogy vesszk ezeket a tulajdonsgokat
egyesvel, s egy-egy tulajdonsgnv s rtk prbl j objektumokat ptek ssze. De nzzk ezt
lpsrl-lpsre!
[26] PS C:\> $wmiobj = Get-WmiObject -Class Win32_ComputerSystem
[28] PS C:\> $wmiobj | Get-Member -MemberType properties |
ForEach-Object {"$($_.name) : $($wmiobj.($_.name))"}

AdminPasswordStatus : 3
AutomaticManagedPagefile : True
AutomaticResetBootOption : True
AutomaticResetCapability : True
BootOptionOnLimit :
BootOptionOnWatchDog :
BootROMSupported : True
BootupState : Normal boot
Caption : DC
ChassisBootupState : 2
CreationClassName : Win32_ComputerSystem
...
A fenti lpssorral elszr kpeztem a $wmiobj vltozba a gpem WMI tulajdonsgait, majd ezeknek
vettem a tulajdonsg (property) tpus tagjellemzit a Get-Member cmdlettel. Ezeket a tagjellemzket sorra
kirattam tulajdonsg neve: tulajdonsg rtke formtumban egy Foreach-Object "ciklussal". Mivel nekem
nem az a clom, hogy kirjam ezeket az adatokat, hanem ssze szeretnm hasonltani ezeket egy msik
gp hasonl adataival, ezrt kpezek inkbb egy j, egyedi PSObject tpus objektumot bellk a New-
Object cmdlet segtsgvel. Ez azrt j, mert ezt a fajta objektumot n szabadon felruhzhatom
tulajdonsgokkal:


[30] PS C:\> $wmiobj | Get-Member -MemberType properties | ForEach-Object
{ new-object -TypeName PSObject -Property @{name = $_.name;
DC = $wmiobj.($_.name)}}

name DC
- -
AdminPasswordStatus 3
AutomaticManagedPagefile True
AutomaticResetBootOption True
AutomaticResetCapability True
BootOptionOnLimit
BootOptionOnWatchDog
BootROMSupported True
Ezzel a Property paramter mellett tadott kifejezssel gyakorlatilag oszlopneveket kpeztem az j
objektumom tulajdonsgaival: "name" lett a WMI tulajdonsgok nevei felett, a "DC" pedig az elsknt
vizsglt gp neve, s alatta vannak ennek a gpnek a WMI tulajdonsgrtkei. Ehhez majd hozz lehet
biggyeszteni a msodik gp WMI tulajdonsgrtkeit egy jabb oszlopba, gy az sszehasonlts nagyon
egyszerv vlik. A msodik gp adatainak hozzillesztse az Add-Member cmdlettel lehetsges: egy
egyszer cmke tpus (noteproperty) adatot teszek hozz az objekumomhoz, melynek rtke pont a msik
gp ugyanolyan nev WMI tulajdonsga.
Az eredmnybl azokat a sorokat (objektumokat) kell csak megjelenteni, amelyeknl a kt gpnl
kiolvasott tulajdonsgrtkek nem egyformk, valamint rdemes a WMI bels adatbrzolshoz
szksges mezket is elrejteni. Ez utbbiak neve kt alhzs karakterrel kezddik, gy ez alapjn
szrhetk. A teljes megoldsbl ksztettem egy fggvnyt, ami referencia- s tesztgp nevvel
paramterezhet:


function compare-computersystem ([string] $referencia, [string] $teszt) {
$c1 = Get-WmiObject -Class Win32_ComputerSystem -ComputerName $referencia
$c2 = Get-WmiObject -Class Win32_ComputerSystem -ComputerName $teszt
$ct = $c1 | Get-Member -MemberType Properties |
ForEach-Object {
new-object -typename PSObject -property @{
name = $_.name; $referencia = $c1.($_.name)}}
$ct |
ForEach-Object {
add-member -inputobject $_ -MemberType NoteProperty `
-Name $teszt -Value $c2.($_.name)}
$ct | where-object {
$_.$teszt -ne $_.$referencia -and $_.name -notlike "__*"}
}
A fggvny fejlce utn kt kln vltozba ($c1, $c2) kpzem a gpek WMI adatait. Lthat, hogy ezt is
lehet tvoli mdon meghvni. Ezutn kpzem a korbban mr mutatott tblzat els gp adatait tartalmaz
rszt a $ct vltozba. Majd jra elveszem ezt a vltozt, s minden egyes sorhoz hozzillesztem a
msik gp WMI adatt. A legvgn megszrm az eredmnyt olyan sorokra, ahol eltr a kt gp
tulajdonsgrtke s a tulajdonsg neve nem kt alhzs-karakterrel kezddik. Nzzk, mi lesz az
eredmny, ha ezt meghvom:
[50] PS C:\> compare-computersystem dc member | Format-Table -Wrap

name dc member
- - -
Caption DC MEMBER
DNSHostName dc MEMBER
DomainRole 5 3
Name DC MEMBER
Roles {LM_Workstation, LM_Serve {LM_Workstation, LM_Serve
r, Primary_Domain_Control r, NT, Server_NT}
ler, Timesource...}
TotalPhysicalMemory 1073274880 838393856
A kimenetbl az ltszik, hogy az eltr neveken kvl a szmtgpeim esetleges eltr viselkedst az
eltr szerverszerepek (egyik tartomnyvezrl, a msik tagkiszolgl) s az eltr fizikai memria mrete
okozza. Termszetesen ez csak egy kis demkrnyezet eredmnye, nem lett volna nehz ezt a
klnbsget szabad szemmel is szrevenni, de ugyanezzel a megoldssal akr egy sokgpes
krnyezetben is eredmnyhez jutunk, amit manulisan csak nagyon idignyesen tehetnnk meg.
Mindebbl az ltszik, hogy nhny soros PowerShell-kifejezsekkel sszetett elemzseket vgezhetnk
szmtgp-parkunkban. Miutn ezek a kifejezsek tvolrl is meghvhatk, gy akr az Active Directory
adatbzisban trolt gpnevek alapjn teljes felmrst kszthetnk az eltrsek feldertsre.

A Windows PowerShell rejtelmei - 5. rsz
Egyelre a PowerShell cikksorozat utols rszhez rkeztnk. Ebben a rszben bepillantst adok a
PowerShell kt legfontosabb kt bvtmoduljnak, az Active Directorynak s a Group Policynak a
kpessgeibe.
Csoporttagsgok rekurzv feldertse
Sok olyan feladat addik a rendszergazdk munkja kzben a felhasznlkkal s a szmtgp-
krnyezetk belltsaival kapcsolatban, amelyre a grafikus rendszergazda eszkzk nem adnak
megoldst. Az egyik ilyen egyszer feladat annak szmbavtele, hogy egy felhasznl vajon mely
csoportoknak a tagja? Nem csak egyszeren a kzvetlen tagsg rdekel minket, hanem az ttteles is,
azaz azok a csoportok is, amelyeknek azltal tagja a felhasznl, hogy ezeknek valamely tagcsoportjnak
a tagja.
Ahhoz, hogy az Active Directory-t PowerShell cmdletekkel elrjk, importlni kell az ActiveDirectory modult.
Ehhez telepteni kell a Windows Server 2008 R2-es verzihoz adott Remote Administration Tools csomag
AD DS eszkzei kztt tallhat Active Directory module for Windows PowerShell kpessget:

Ha esetleg maga a tartomnyvezrlnk nem lenne Windows Server 2008 R2 verzij, akkor sincs gond, a
Management Gateway komponenst kell letlteni s telepteni. Ezutn a PowerShell ablakban importljuk
az Active Directory modult:
[1] PS C:\> Import-Module activedirectory
Ezzel szmos j cmdlethez jutunk. De nzzk a megoldand feladatunkat, a csoporttagsg rekurzv
feldertsre a kvetkez fggvnyt lltottam ssze:


function get-ADMemberOfRecursive (
$adobject,
$eddig = (new-object Collections.ArrayList))
{
$ado = Get-ADObject $adobject -Properties memberof
if($ado.memberof){$ado.memberof |
foreach-object {$o = Get-ADObject $_
if($eddig -notcontains $o.distinguishedname){
[Void] $eddig.add(($o.distinguishedname))
get-ADMemberOfRecursive $o $eddig
$o
}
}
}}
A fggvny igazbl egy paramtert vr adobject nven, a msik csak a rekurzv meghvs miatti
esetleges vgtelen ciklusok elkerlst szolglja. Hiszen lehet, hogy a felhasznl tagja A csoportnak, ami
tagja B csoportnak, de B csoport meg tagja A csoportnak. A csoporttagsg feldertse sorn teht szre
kell tudni venni, hogy az A csoportot mr feldertettk, gy azt mg egyszer nem kell vizsglni.
A fggvny trzsben az AD objektumot jra lekrdezem a Get-ADObject cmdlettel, hiszen lehet, hogy a
paramterknt tadott objektum nem tartalmazza a csoporttagsg tulajdonsgot, ennek a kifejezsnek a
kimenete viszont igen. Ha ez az objektum tagja valamilyen csoportnak, akkor minden ilyen csoportra, ha
mg nem vizsgltam, hozzadom a DistinguishadName tulajdonsgt az eddigi csoportok listjhoz s
meghvom erre is a get-ADMemberOfGroup fggvnyt, de mr az eddigi vizsglt csoportok listjval
bvtve. Ezutn a vizsglt csoport objektumt kiadom a kimenetre. Nzzk ennek futst:
[2] PS C:\> get-ADMemberOfRecursive (Get-ADUser vj)

DistinguishedName Name ObjectClass ObjectGUID
- - - -
CN=temp,OU=Dem,... temp group 7cdd95c2-3ee1-4
CN=n,OU=Dem,DC... n group ef75fe02-8168-4
A VJ nev felhasznlm tagja az n nev csoportnak, ami pedig a temp csoportnak a tagja, az n
csoportnak pedig tagja a temp. Ennek ellenre a fggvnyem nem futott vgtelen ciklusba, hanem ezt a kt
csoportot egyszer kiadta a kimenetre. A kvetkez futtatsban a tipikus csoporttagsg pldja lthat. A
soosbence felhasznl tagja a UserGroupnak, ami viszont tagja a ResourceGroupnak:
[3] PS C:\> get-ADMemberOfRecursive (Get-ADUser soosbence)

DistinguishedName Name ObjectClass ObjectGUID
- - - -
CN=ResourceGroup... ResourceGroup group 3542d4c7-f045-4
CN=UserGroup,OU=... UserGroup group 52fe0789-5c76-4

Szervezeti diagram AD informcik alapjn
A kvetkez, orgchart.ps1 szkriptfjl egy kivlasztott felhasznlt a manager tulajdonsga, azaz az
fnkt jelz AD informci alapjn behelyezi a szervezeti hierarchiba:
param ($user)
$user = Get-ADUser -Filter {samaccountname -eq $user} -Properties manager

function get-topmanager ($u, $szint=0) {
if($u.manager) {
$fnk = Get-ADUser $u.manager -Properties manager
if($u.distinguishedname -ne $fnk.distinguishedname){
get-topmanager $fnk ($szint-1)}
}
$u | Add-Member -Member NoteProperty -Name szint -Val $szint -Pass
-force
}

function get-beosztrecursive ($u, $sz = 0){
Get-ADUser -Filter {manager -eq $u} -properties manager |
?{$_.distinguishedname -ne $u.distinguishedname} |
%{if($_){
$_ | Add-Member -Member NoteProperty -Name szint -Val $sz
-Pass -for get-beosztrecursive $_ ($sz+1)}}
}

$tops = @(Get-TopManager $user)
$offset = -$tops[0].szint
$tops | %{$_.szint += $offset}
$beosztottak = get-beosztrecursive $user ($offset+1)
$tops, $beosztottak | %{$_} | ?{$_} | %{
if($_.distinguishedname -eq $user.distinguishedname){$s = "*"}
else{$s=" "} Write-Host ($s + ("|`t")*($_.szint) + "+ " + $_.name)
}
A szkriptben kt segdfggvnyt hasznlok: az egyik a get-topmanager, ami a paramtereknt megadott
felhasznlbl kiindulva vgigszalad a rangltrn, s megadja a feletteseket egszen addig, amg mr
nincs tovbbi fnk, vagy esetleg valaki sajt maga fnke. Minden ilyen fnkhz egy szint tulajdonsgot
is hozzrendelek, hogy tudjam, milyen mlysgben kell majd brzolni a felhasznlmat. A msik
segdfggvny rekurzvan kilistzza az adott felhasznl beosztottjait, azaz nem csak a kzvetleneket,
hanem a beosztottak beosztottjait is, s gy tovbb. Hogy szp formzott lehessen az eredmny, ehhez is
hozzveszem, hogy az adott beosztott hnyadik szint.
Maga a szkript ezek utn nem bonyolult. Elsknt veszem a feletteseket a $tops vltozba. Az els elem,
azaz a top manager szintjnek negltja adja meg, hogy mennyivel eltolva kell majd az egsz hierarchit
megjelentenem, s gyorsan el is tolom a szinteket, hogy a top manager szintje legyen a kiindul 0. Ezutn
veszem rekurzvan a beosztottakat, a szint itt eggyel nagyobbrl indul, mint ahova a felettesek szintjeivel
eljutottam. A vgn az sszes felettest s beosztottat kiratom, az ppen vizsglt felhasznlnl egy *
karakterrel jelzem ezt, egybknt a szintnek megfelel darabszm fggleges vonal s tabultor karaktert
ratok ki, majd egy jelet, majd a felhasznl nevt. Nzzk a kimenetet a Nagy Fnk esetben:
[4] PS C:\> C:\munka\orgchart.ps1 nf
*+ Nagy Fnk
| + Al1 Fnk
| | + Kis1 Fnk
| | + Kis2 Fnk
| | | + Gl Andrs
| | | + Budai Edina
| | | + Dolk Fanni
| + Al2 Fnk
| + Al3 Fnk
| | + Bornai Viktor
| | + Balogh Mria
| | + Budai Andrs
Lthat, hogy a teljes hierarchia lthat. Nzzk csak azt az brt, amiben a Kis2 Fnk nev
felhasznlra vagyok kvncsi:
[5] PS C:\> C:\munka\orgchart.ps1 kis2f
+ Nagy Fnk
| + Al1 Fnk
*| | + Kis2 Fnk
| | | + Gl Andrs
| | | + Budai Edina
| | | + Dolk Fanni
Lthat, hogy itt mr csak az al-ga ltszik teljesen kibontva, a fnkei irnyban csak egy t ltszik.
Group Policy objektumok klnbsgeinek feldertse
A rendszergazdk msik gyakori fejfjsa a Group Policy objektumok kezelse. Ha ksztnk kt GPO-t,
akkor elg nehz az ezekben tallhat belltsokat egyms mellett ttekinteni. Mieltt az ezen a terleten
segteni kpes PowerShell fggvnyt bemutatnm, nzzk elszr is, hogyan kezelhetjk PowerShell
segtsgvel a GPO-kat. Elsknt importlni kell a GroupPolicy modult:
[6] PS C:\> Import-Module grouppolicy
Ez a bvtmny tbbek kztt tartalmaz egy Get-GPOReport cmdletet, amellyel a GPO objektumok
tartalmt tudjuk megnzni. Miutn n nem csak nzegetni, hanem feldolgozni akarom ezeket az adatokat,
ezrt rdemes XML formtum kimenetet krni. Egy konkrt GPO beolvassa gy trtnhet:
[7] PS C:\> $fgpo = [xml] (Get-GPOReport -Name FnkiGpek -ReportType XML)
Ezzel az elll XML formtum kimenetet tnyleges XML adattpusknt tltm be a $fgpo vltozba. Ez
azrt j, mert ennek a vltoznak a tulajdonsgain keresztl frek hozz az adattartalomhoz:
[8] PS C:\> $fgpo

xml GPO
- -
version="1.0" encoding="utf-16" GPO

Ez mg csak a "fejlc", de mehetnk mlyebbre a GPO tulajdonsgon keresztl:
[9] PS C:\> $fgpo.gpo


xsi : http://www.w3.org/2001/XMLSchema-instance
xsd : http://www.w3.org/2001/XMLSchema
xmlns : http://www.microsoft.com/GroupPolicy/Settings
Identifier : Identifier
Name : FnkiGpek
IncludeComments : true
CreatedTime : 2010-05-20T19:47:56
ModifiedTime : 2010-05-20T19:56:59
ReadTime : 2010-05-22T20:40:52.1631171Z
SecurityDescriptor : SecurityDescriptor
FilterDataAvailable : true
Computer : Computer
User : User
Mehetnk tovbb a Computer gban:
[10] PS C:\> $fgpo.gpo.Computer

VersionDirectory VersionSysvol Enabled ExtensionData
- - - -
14 14 true {Security, Publ
s ennek ExtesionData gn tovbb:
[11] PS C:\> $fgpo.gpo.Computer.ExtensionData

Extension Name
- -
Extension Security
Extension Public Key
Extension Registry
Lthat, hogy tbb elklnl rszben troldnak a GPO belltsai. A legtbb belltst ltalban a
Registry gban, azaz a grafikus felleten az Administrative Templates gban talljuk. Menjnk ebbe az
irnyba tovbb s tovbb:
[12] PS C:\> $fgpo.gpo.Computer.ExtensionData[2]

Extension Name
- -
Extension Registry


[13] PS C:\> $fgpo.gpo.Computer.ExtensionData[2].extension

q3 type Policy RegistrySetting
- - - -
http://www.micro... q3:RegistrySettings {Restricts the U... {q3:RegistrySet


[14] PS C:\> $fgpo.gpo.Computer.ExtensionData[2].extension.policy


Name : Restricts the UI language Windows uses for all logged users
State : Enabled
Explain : This is a setting for computers with more than one UI
language installed. If you enable this setting the UI
language of Windows menus and dialogs language for systems
with more than one language is restricted to the specific
language. If the specified language is not installed on the
target computer or the policy is disabled, the language
selection defaults to the language selected by the local
administrator.
Supported : At least Windows Vista
Category : Control Panel/Regional and Language Options
DropDownList : DropDownList
s itt jutottam el a tnyleges belltsokhoz, ahol is a rszletes lerstl kezdve minden hasznos
informcihoz hozzjuthatok. Ez olyan sok, hogy itt a cikkben jelentsen megvgtam. Ennek ismeretben
nzzk, hogy hogyan lehet kt GPO objektumot sszehasonltani a compare-gpos.ps1 szkriptem
segtsgvel:
param ($gpo1, $gpo2, $hive = "User")
function get-registrypolicy ($gpo, $h)
{
(([xml] (Get-GPOReport -name $gpo -ReportType XML -ErrorAction stop
)).GPO.$h.ExtensionData | ?{$_.name -eq "Registry"}).exten
sion.policy
}

$pol1 = get-registrypolicy $gpo1 $hive
$pol2 = get-registrypolicy $gpo2 $hive
if($pol1 -and $pol2) {
Compare-Object $pol1 $pol2 -IncludeEqual -Property name, state
}
elseif($pol1){$pol1 |
select-object name, state, @{n="SideIndicator";e={"<="}}}
else{$pol2 | select-object name, state, @{n="SideIndicator";e={"=>"}}}
A szkript kt GPO nevet vr, illetve, hogy mely gakat hasonltsa ssze (User vagy Computer). A
belsejben definilok egy segdfggvnyt, amely a GPO azon rszeit szedi csak ki, amely a registry, azaz
Administrative Templates gon bell van. Ennek segtsgvel beolvasom mindkt GPO belltsait, majd a
korbbi cikkekben mr ltott Compare-Object cmdlettel sszehasonltom ezeket, de csak akkor, ha mindkt
GPO tartalmaz ezen az gon belltsokat. Ha nem, akkor n emullok hasonl kimenetet, mint amit a
Compare-Object adna, mert a "gyri" cmdlet res objektum sszehasonltst nem tudja megtenni. Hogy
mg ttekinthetbb legyen a kimenet, nzzk rgtn a grafikus rcsban a TitkrniGpek s a
FnkiGpek GPO-k sszehasonltst:
compare-gpos.ps1 TitkrniGpek FnkiGpek Computer | Out-GridView

A fenti rcsban lthatjuk, hogy az els kt bellts mindkt GPO-ban megtallhat, mg a 3-4. csak a
FnkiGpekben, s az 5-6. csak a TitkrniGpekben.
Vgsz
Termszetesen mindhrom kis pldm tovbbfejleszthet, a csoporttagsg rekurzv kifejtsre alapozottan
knnyen fel lehet derteni, hogy vajon egy felhasznlnknak a fjlkiszolgln hol van rsi joga.
Termszetesen nem csak a direkt jogmegadst keressk ilyenkor, hanem hogy valamely csoporttagsga
ltal hol vannak jogai. A szervezeti diagram pldt abba az irnyba lehet tovbbfejleszteni, hogy ne csak
megjelentsben lehessen felhasznlni, hanem a kimenet maga felhasznli objektumok halmaza legyen.
gy egyszeren meg lehetne oldani pldul azt, hogy lltsuk t minden olyan felhasznl csoporttagsgt,
aki Kovcs Bla ltal felgyelt szervezeti egysgben dolgozik.
A Group Policy pldt gy lehetne fokozni, hogy egyrszt ne csak a registry-alap belltsok kztt
vizsgldjon, hanem ms rszekben is. Tovbb hasznos lenne az is, ha egy "etalon" GPO-hoz kpest
valamely GPO-ban azzal ellenttes belltsok vannak, akkor azokat igaztsa az etalonhoz. Szmtalan
ilyen pldt lehetne mg hozni. n prat sszegyjtttem a http://www.iqjb.hu/PSkonzultacio.php oldalra,
ha rdekli a tisztelt olvast ilyen jelleg problmk megoldsa PowerShell segtsgvel, keressen
bizalommal!

http://www.hwsw.hu/hirek/44070/windows-powershell-script-parancssor.html
http://www.hwsw.hu/hirek/44250/powershell-windows-shell-szkript.html
http://www.hwsw.hu/hirek/44338/microsoft-windows-powershell-parancssor.html
http://www.hwsw.hu/hirek/44492/microsoft-windows-powershell-parancssor.html
http://www.hwsw.hu/hirek/44678/microsoft-windows-powershell-active-directory-group-policy-parancssor.html

You might also like