A Group-Object cmdlet segítségével egy (vagy több) megadott tulajdonság értéke szerint csoportosíthatunk objektumokat. A csoportokba az azonos tulajdonságértékkel rendelkező objektumok kerülnek.
Készítsünk listát, amely az
„g” betűvel kezdődő cmdleteket csoportosítja ige szerint! A cmdleteket
lekérdező Get-Command
kimenetét a Group-Object-nek
kell megkapnia, paraméterként pedig meg kell adnunk, hogy melyik tulajdonság
értékei szerint akarjuk elvégezni a csoportosítást, ez a Verb
tulajdonság lesz:
PS C:\> get-command g* -commandtype cmdlet | group-object -property verb
Count Name Group
----- ---- -----
145 Get {Get-Acl, Get-Alias, Get-AppLockerFileInfor...
1 Group {Group-Object}
A csoportok és a bennük található elemek száma jól látható, de maga a csoport tagsága ebben a nézetben nem igazán kivehető, ha túl sok az adott csoportban található elem.
Megjegyzés
A csoportokat alaphelyzetben csak maximum 4 elemig jeleníti meg a PowerShell, feltéve, hogy a konzol szélessége ezt megengedi. Ha ennél több elemet is meg akarunk jeleníttetni, akkor a $FormatEnumerationLimit automatikus változó értékét kell átállítani.
Hogy a képernyőszélesség ne legyen korlát, az egészet még táblázatosan formázom tördeléses módon:
[12] PS C:\> $FormatEnumerationLimit = 8
[13] PS C:\> Get-Command g* -CommandType cmdlet | Group-Object -Property verb |
Format-Table -Wrap
Count Name Group
----- ---- -----
46 Get {Get-Acl, Get-Alias, Get-AuthenticodeSignature
, Get-ChildItem, Get-Command, Get-ComputerRest
orePoint, Get-Content, Get-Counter...}
1 Group {Group-Object}
A kimeneten látszik, hogy most az első csoportban 8 elem vált láthatóvá.
Még olyat is lehet csinálni a Group-Object segítségével, hogy egyszerre több szempont szerinti csoportot is létrehozhatunk:
[60] PS C:\> get-process | Group-Object -Property processname, company
Count Name Group
----- ---- -----
3 conhost, Microsoft Cor... {System.Diagnostics.Process (conhost), Syst...
2 csrss, Microsoft Corpo... {System.Diagnostics.Process (csrss), System...
1 dfsrs, Microsoft Corpo... {System.Diagnostics.Process (dfsrs)}
1 dfssvc, Microsoft Corp... {System.Diagnostics.Process (dfssvc)}
1 dns, Microsoft Corpora... {System.Diagnostics.Process (dns)}
1 dwm, Microsoft Corpora... {System.Diagnostics.Process (dwm)}
…
A fenti paranccsal, a processzek neve és gyártójuk alapján, együttesen csoportosítottam a futó folyamatokat. Ez nem igazi kétszintű csoportosítás, hanem képez egy „látszólagos” tulajdonságot, amely a processz nevéből és gyártójából áll, és ezen összetett tulajdonság alapján csoportosít.
Ha nincs szükségünk az egyes elemekre, csak a csoportokra, akkor használhatjuk a ‑NoElement kapcsolót:
[21] PS C:\> get-process | Group-Object -Property company -noelement
Count Name
----- ----
38 Microsoft Corporation
2
2 Sun Microsystems, Inc.
A fenti példában csak a gyártókra voltam kíváncsi és a darabszámokra.
Alaphelyzetben a Group-Object kimenete egy gyűjtemény, nézzük meg, hogy egy-egy eleme ennek hogyan is néz ki:
[70] PS C:\> $csoportok = get-command g* -commandtype cmdlet | group-object -pr
operty verb
[71] PS C:\> $csoportok[0]
Count Name Group
----- ---- -----
46 Get {Get-Acl, Get-Alias, Get-AuthenticodeSignat...
[72] PS C:\> $csoportok[1]
Count Name Group
----- ---- -----
1 Group {Group-Object}
Ebből kinyerhetők az egyes csoportosított elemek a következő módon:
[81] PS C:\> $csoportok[0].group
CommandType Name Definition
----------- ---- ----------
Cmdlet Get-Acl Get-Acl [[-Path] <String[]>...
Cmdlet Get-Alias Get-Alias [[-Name] <String[...
Cmdlet Get-AuthenticodeSignature Get-AuthenticodeSignature [...
Cmdlet Get-ChildItem Get-ChildItem [[-Path] <Str...
Cmdlet Get-Command Get-Command [[-ArgumentList...
…
Ennél egyszerűbb módja is van ennek, ha arra kérjük a Group-Object-et, hogy ne gyűjteményt készítsen nekünk, hanem hashtáblát:
[82] PS C:\> $csoportok = get-command g* -commandtype cmdlet | group-object -pr
operty verb -AsHashTable
[83] PS C:\> $csoportok
Name Value
---- -----
Get {Get-Acl, Get-Alias, Get-AuthenticodeSignatu...
Group {Group-Object}
[84] PS C:\> $csoportok.get
CommandType Name Definition
----------- ---- ----------
Cmdlet Get-Acl Get-Acl [[-Path] <String[]>...
Cmdlet Get-Alias Get-Alias [[-Name] <String[...
Cmdlet Get-AuthenticodeSignature Get-AuthenticodeSignature [...
Cmdlet Get-ChildItem Get-ChildItem [[-Path] <Str...
Cmdlet Get-Command Get-Command [[-ArgumentList...
…
Látható, hogy a –AsHashTable kapcsolóval ezt elérhetjük, így sokkal egyszerűbb az egyes csoportokba sorolt elemeket elérni.
Ezekből a példákból még az is kiderülhetett számunkra, hogy a Group-Object használata előtt nem kell külön sorba rendezni a csővezetéken érkező objektumokat, hogy a csoportok jól kialakuljanak. Emlékezhetünk a format-table cmdlet ‑groupby paraméterére az 1.2.17 Egyszerű formázás fejezetből, ott azt láthattuk, hogy a format-table számára előbb sorba kellett rendezni az objektumokat, hogy jó legyen a csoportosítás. Itt ilyesmire nincs szükség, hiszen a Group-Object halmazokat készít, nem csak megjeleníti a csoportokat.
Hasonlóan a Sort-Object-hez, a Group-Object-el is lehet nem létező tulajdonságok alapján csoportosítani, ha tulajdonságként egy szabályt adunk:
PS C:\> Get-ChildItem C:\PowerShell\ | Group-Object -Property {$_.name.length}
| Sort-Object -Property {[int]$_.Name} -Descending
Count Name Group
----- ---- -----
1 20 {BigEndianUnicode.txt}
2 19 {CheckDynamParam.ps1, test-credential.ps1}
1 18 {BigEndianUTF32.txt}
1 17 {wait-debugger.ps1}
1 16 {CheckNewVars.ps1}
1 14 {runasadmin.ps1}
5 13 {debug-job.ps1, ékezetes1.txt, ékezetes2.tx...
1 12 {BreakAll.ps1}
4 11 {Default.txt, Unicode.txt, Unknown.txt, áll...
1 10 {String.txt}
2 9 {Ascii.txt, UTF32.txt}
5 8 {20150923, Byte.txt, fact.ps1, UTF7.txt...}
2 7 {job.ps1, Oem.txt}
1 6 {Carbon}
Itt a fájlok nevének hossza alapján csoportosítottam a fájlokat. A Group-Object-nél megadott szabályt már alkalmaztam az előző fejezetben. Majd a csoportokat szeretném rendezni a hosszak csökkenő sorrendjében. Sajnos a Name tulajdonság alá került hosszak, bár alapvetően számok voltak, de az eredményben szöveggé alakítja azokat a Group-Object, így a sorba rendezés nem lenne jó. Szerencsére itt is tudjuk alkalmazni a már látott lehetőséget, és inkább rendezzük az egész számmá konvertált Name tulajdonság szerint.