Articles

ForEach és ahol magic methods

ForEach és hol van két gyakran használt fogalom, amelyek már elérhető PowerShell óta Verzió 1 jött ki 2006-ban. A ForEach mind utasításként, mind cmdletként (ForEach-Object) elérhető, lehetővé téve, hogy egy objektumgyűjteményen keresztül iteráljon, és egyszer tegyen lépéseket a gyűjtemény minden egyes objektumára. Ahol már elérhető, mint egy cmdlet (ahol-objektum), amely lehetővé teszi, hogy kiszűrje az elemeket egy gyűjtemény, amely nem felel meg néhány feltétel, olyan állapot, amely lehet értékelni akár a tulajdonságok tárgyak a gyűjtemény vagy a tárgyak maguk, amelyek tartoznak a gyűjtemény. A ForEach képesség, hogy tegyen lépéseket a tételek egy gyűjtemény, és a hol képes szűrni a gyűjtemény olyan funkciók, amelyek nagyon hasznos, és szerepelnek az egyik vagy másik formában a logika mögött sok PowerShell szkriptek, parancsok és modulok, függetlenül attól, hogy milyen változata PowerShell használják. Valójában annyira erősen használják őket, hogy a PowerShell 3.0 és 4.0 verzióiban a teljesítmény, a funkcionalitás és a szintaxis javítására összpontosítottak.

A Windows PowerShell 4.0 kiadásával két új “mágikus” módszert vezettek be olyan gyűjteménytípusokhoz, amelyek új szintaxist biztosítanak a ForEach eléréséhez, és ahol a Windows PowerShell képességei vannak. Ezeket a módszereket találóan nevezik ForEach és hol. Ezeket a módszereket “mágiának” hívom, mert nagyon varázslatosak abban, hogyan működnek PowerShellben. Nem jelennek meg a Get-Tag kimenet, akkor is, ha alkalmazni-Force and request-MemberType minden. Ha dobsz fel a ujjú, ásni a reflexió, megtalálja őket; azonban szükség van egy átfogó keresés, mert privát kiterjesztését módszerek végre egy privát osztály. Mégis, annak ellenére, hogy nem felderíthető nélkül less a takaró alatt, hogy ott vannak, ha szükség van rájuk, ők gyorsabb, mint az idősebb társaik, ők pedig olyan funkciókkal, amelyek nem volt elérhető az idősebb társaik, ezért a “mágikus” olyan érzésem, hogy itt hagyom neked, amikor használja őket a PowerShell. Sajnos ezek a módszerek még ma sem dokumentáltak, majdnem egy évvel a nyilvánosság megjelenése óta, így sokan nem veszik észre az ezekben a módszerekben elérhető hatalmat. Ez a cikk megpróbálja kijavítani, hogy elmagyarázza, hol lehet használni, és hogyan működnek, hogy kihasználhassa ezt a varázslatot a PowerShell használatakor.

egy megjegyzés a PowerShell 3.0-ról

mielőtt belemennék, hogy elmagyarázzam, hogyan működik a ForEach és hol működnek a módszerek, meg kell említenem valamit e két módszer és a PowerShell 3.0 tekintetében. Bár igaz, hogy a ForEach és a Where metódusok csak PowerShell 4.0 és későbbi verziókban voltak elérhetők, a PowerShell 3.0 még mindig nagyon széles körben használják sok környezetben, és ha nem használ PowerShell olyan környezetben, amely szabványosított PowerShell 4.0 vagy újabb, akkor találja magát kívánó Ön tudna kihasználni a szintaxis által biztosított új módszerek használatakor PowerShell 3.0. Úgy éreztem, ez a korlátozás érdemes kezelése, így részeként a TypePx modul, hogy nemrég megjelent a GitHub a PowerShell Forrás Galéria (aka a PowerShellGet nyilvános adattár, jelenleg korlátozott előnézet), nem tartalmazza a ForEach Hol script módszerek, funkcionálisan egyenértékű, hogy a módszereket vezetett be a PowerShell 4.0, így lehet kihasználni az új szintaxis meg működését akkor is, ha a PowerShell 3.0. Van néhány hiányosság ebben a megvalósításban, amelyet később kiemelek ebben a cikkben.

A ForEach method

ForEach egy olyan módszer, amely lehetővé teszi, hogy gyorsan iteráljon egy objektumgyűjteményen keresztül, és tegyen néhány műveletet az adott gyűjtemény minden objektumán. Ez a módszer gyorsabb teljesítményt nyújt, mint a régebbi társaik (a foreach utasítás, valamint a ForEach-Object cmdlet), valamint egyszerűsíti néhány a leggyakoribb műveleteket, hogy érdemes, hogy a tárgyak a gyűjtemény. Az ezzel a módszerrel előállított objektumokat egy általános típusrendszer-gyűjteményben adják vissza.Gyűjtemények.ObjectModel.Gyűjtemény1.

hat támogatott módon lehet hivatkozni erre a módszerre, és ezek mindegyikét részletesebben az alábbiakban ismertetjük. A ForEach módszer meghívásakor használható támogatott érvek a következők:

  • ForEach(scriptblock expression)
  • ForEach(type convertToType)
  • ForEach(string propertyName)
  • ForEach(string propertyName, object newValue) ForEach(string methodName) ForEach(string methodName, object arguments)

  • ForEach(scriptblock expression, object arguments)

vegye figyelembe, hogy ezek támogatott argumentumok, nem pedig a foreach módszerhez rendelkezésre álló különböző túlterhelések. Bármilyen érv párosítások más, mint ezek vezethet hibák, amelyek nem egyértelműen azonosítani, mi a tényleges probléma.

ForEach(scriptblock kifejezés), valamint ForEach(scriptblock kifejezés, tárgy érvek)

Ha át egy script kifejezés a ForEach módszer, hogy képesek elvégezni ugyanazt a feladatot, hogy egy script, hogy használja a foreach utasítás vagy a ForEach-Object parancsmagot. Továbbá, mint a ForEach-Object cmdlet, a $_ és $PSItem változók egyaránt hivatkoznak az aktuális elem, hogy a feldolgozott. Minden olyan argumentum, amelyet a kezdeti szkriptblokk argumentumán túl ad meg, a szkriptblokk argumentumaként kerül felhasználásra. Ez ugyanúgy működik, mint a-ArgumentList paraméter a ForEach-Object parancsmagon. Íme egy példa, amely bemutatja, hogyan használhatja ezt a szkriptblokk végrehajtásához a gyűjtemény minden elemén:

# Get a set of services$services = Get-Service c*# Display the names and display names of all services in the collection$services.foreach{"$($_.Name) ($($_.DisplayName))"}# Select a property name to expand using a script block argument$services.foreach({param($PropertyName); $_.$PropertyName}, 'DisplayName')

lehet, hogy észrevett valami furcsát ebben a szintaxisban, mert nem zártam be a szkriptblokkot zárójelben. Akkor csomagolja a kerek zárójelben, azonban ez nem kötelező PowerShell 4.0 vagy későbbi, mert a PowerShell elemző fokozta, hogy lehetővé váljon a zárójelben elhagyható, ha te is hivatkozva egy módszer, hogy elfogadja egyetlen script érv. A foreach utasításhoz és a ForEach-Object parancsmaghoz hasonlóan a megadott parancsfájl blokk is az aktuális hatókörben kerül meghívásra. Ez azt jelenti, hogy a Szkriptblokk belsejében végrehajtott változó hozzárendelések továbbra is fennmaradnak, miután a ForEach módszer befejezte a végrehajtást.

ForEach (type convertToType)

egyedi ForEach módszer, akkor át egy típust a ForEach módszer, ha szeretné átalakítani minden elem egy gyűjtemény egy másik típus. Képzelje el például, hogy van egy objektumgyűjteménye, és ezeket az objektumokat karakterlánc-egyenértékűvé szeretné konvertálni. Itt van, hogy nézne ki, mint a ForEach módszer:

# Get a collection of processes$processes = Get-Process# Convert the objects in that collection into their string equivalent$processes.foreach()

akkor lehetett volna elvégezni ugyanazt a feladatot typecasting a gyűjtemény egy sor típusú karakterlánc (pl.] $folyamatok), és typecasting a tömb valójában lényegesen gyorsabb, azonban van egy nagyon jó esély akkor nem is veszi észre a különbséget a végrehajtási idő, ha nem dolgozik egy nagyon, nagyon nagy gyűjtemény. Annak ellenére, hogy a különbség, én általában inkább a ForEach módszer szintaxis bizonyos helyzetekben, ha lehetővé teszi, hogy fenntartsák az elegancia, a végrehajtás elkerülésével extra kerek zárójelben a forgatókönyvet írok.

ForEach(string propertyName)

A PowerShell 3.0, majd később, egy második paraméter beállítása volt hozzá, hogy ForEach-Object lehetővé teszi, hogy könnyebben letölteni az érték egy adott tulajdonság egyszerűen halad a tulajdonság neve, mint az egyetlen paraméter értéke ForEach-Object. Ezt a kényelmet a ForEach módszer is kínálta. Itt egy példa, amely bemutatja, hogyan tudod halad át a gyűjtemény, majd vissza, egy tulajdonság, hogy gyűjtemény:

# Get all services whose name starts with "w"$services = Get-Service w*# Return the names of those services$services.foreach('Name')

persze, mivel a 3.0-ás verzió a PowerShell, egyszerűen hivatkozhat $szolgáltatások.Nevét a nevét szolgáltatások, valamint, hogy lesz teljes gyorsabb, mint a ForEach módszer alternatív (bár csak észre, hogy a teljesítmény különbség nagyon nagy gyűjtemények abban a sorrendben, a több száz, több ezer tárgyak); ez azonban csak olyan tulajdonságokra vonatkozik, amelyek nem szerepelnek a gyűjteményben, és ez egy szintaxis, amellyel egyes szkriptek nem elégedettek a parancs implicit jellege miatt. Az új ForEach módszer szintaxisa egy explicit alternatívát kínál, amelynek előnye, hogy egy kicsit öndokumentálóbb is.

ForEach (string propertyName, object newValue)

nem csak lehet letölteni egy tulajdonság egy gyűjtemény tárgyak, beállíthatja a tulajdonság egy gyűjtemény tárgyak is. Ez olyan funkció, amely nem érhető el a többi foreach-ban, kivéve, ha kifejezetten létrehozza a szkriptblokkot. A tulajdonság beállításához egyszerűen adja meg a tulajdonság nevét és a használni kívánt értéket a tulajdonság beállításakor, mint ez:

# Note, this is not a realistic example# This would be used more commonly on configuration data$services = Get-Service c*# Now change the display names of every service to some new value$services.foreach('DisplayName','Hello')

csakúgy, mint az egyenlő operátor használatával elvégzendő feladatok, a PowerShell megpróbálja átalakítani, amit új értékként ad meg a hozzárendelt tulajdonság megfelelő típusává.

ForEach(string methodName) és ForEach (string methodName, object argumentumok)

egy metódus meghívásához egyszerűen adja meg a metódus nevét első argumentumként, majd a metódus argumentumait másodikként, harmadikként, negyedikként stb. érvek. Ha a módszer nem vesz fel semmilyen érvet, akkor egyszerűen adja át a módszer nevét, majd hivatkozni nélkül érvek. Íme egy példa, amely bemutatja, hogyan lehet megölni egy csomó folyamatot, amely egy adott programot futtat:

# Get all processes running Chrome$processes = Get-Process -Name Chrome# Now kill all of those processes$processes.foreach('Kill')

ez Itt egy másik példa, ezúttal egy olyan módszer, érvekkel, miközben bemutatja, hogyan lehet ellenőrizni, hogy a parancsok a következő legjobb gyakorlatok segítségével a megfelelő neveket, az álnevek a leggyakrabban használt paraméterek:

# Get all commands that have a ComputerName parameter$cmds = Get-Command -ParameterName ComputerName# Now show a table making sure the parameter names and aliases are consistent$cmds.foreach('ResolveParameter','ComputerName') | Format-Table Name,Aliases

Mint látható, ezek az eredmények, biztosan van néhány ellentmondás végrehajtásában Számítógépnév paraméterek hogy korrigálni kell.

, amely lefedi az összes olyan funkciót, amely jelenleg elérhető a ForEach módszerben. Mint látható, ebben a módszerben nincs sok új funkció, de a szintaxis-fejlesztések, amikor egy egyszerű feladatot végez egy objektumgyűjteményen, szépek, és a ForEach módszer teljesítményének javulása a ForEach-Object csővezeték egyenértékű foreach-állításához képest mindenképpen üdvözlendő javulás. Ezzel a magyarázattal az útból, menjünk tovább a Hol módszerhez.

A hol módszer

hol van olyan módszer, amely lehetővé teszi az objektumok gyűjteményének szűrését. Ez nagyon hasonlít a Where-Object cmdlethez, de a Where módszer is olyan, mint a Select-Object és a Group-Object, számos további funkciót tartalmaz, amelyeket a Where-Object parancsmag önmagában nem támogat. Ez a módszer gyorsabb teljesítményt nyújt, mint ahol-objektum egy egyszerű, elegáns parancs. A ForEach-módszerhez hasonlóan minden olyan objektum, amelyet ezzel a módszerrel állítanak ki, egy általános típusú rendszer gyűjteményében kerül visszaadásra.Gyűjtemények.ObjectModel.Gyűjtemény1.

ennek a módszernek csak egy változata létezik, amely a következőképpen írható le:

Where(scriptblock expression])

amint azt a szögletes zárójelek jelzik, a kifejezés szkriptblokkra van szükség, a mód felsorolása és a numberToReturn integer argumentum opcionális, így ezt a módszert 1, 2 vagy 3 argumentummal hívhatja meg. Ha egy adott argumentumot szeretne használni, akkor az argumentum bal oldalán kell megadnia az összes argumentumot (azaz ha értéket szeretne megadni a numbertorrevurn számára, akkor a mode és a expression értékeit is meg kell adnia).

ahol (scriptblock expression)

a legalapvetőbb meghívása a Where metódus egyszerűen vesz egy script blokk kifejezés, mint egy érv. A szkriptblokk kifejezés egyszer kerül kiértékelésre a feldolgozott gyűjtemény minden egyes objektumára, és ha true értéket ad vissza, az objektum a Where metódussal kerül visszaadásra. Ez a függvény megfelelője a Where-Object cmdlet hívásának, valamint a szkriptblokk átadásának. A Where-Object parancsmaghoz hasonlóan a $_ és $PSItem változók is felhasználhatók a szkriptblokk belsejében feldolgozott aktuális elem hivatkozására.

itt van egy nagyon egyszerű példa, amely bemutatja, hogyan szerezheti be a futó szolgáltatások listáját.

# Get all services$services = Get-Service# Now filter out any services that are not running$services.where{$_.Status -eq 'Running'}

Ez nem kínál új funkciókat, de sokkal gyorsabb teljesítményt nyújt, mint a Where-Object és a szintaxis nagyon könnyen követhető, ezért ezt valóban figyelembe kell vennie a szkripteknél, amikor a változóban tárolt gyűjtemények ügyféloldali szűrését végzi.

hol (scriptblock expression, Wheroperatorselectionmode mode)

amikor elkezdi megnézni a Where metódus opcionális paramétereit, a dolgok sokkal érdekesebbé válnak. A Windows PowerShell 4.0 verziója tartalmaz egy új felsorolást a rendszer típusnevével.Menedzsment.Automatizálás.Holoperatorselectionmode. Vegye figyelembe a típusnév utótagját: “SelectionMode”. Arra használják, hogy hatékony kiválasztási képességek Egy ahol szintaxis. Itt vannak a felsorolásban szereplő értékek, meghatározásaikkal együtt:

Alapértelmezett Szűrő a gyűjtemény használata a kifejezés script, legfeljebb számít, ha egy biztosított vagy mulasztást elkövető, hogy minden tárgy a gyűjtemény, ha nem maximális gróf volt, feltéve, hogy a numberToReturn.
First vissza az első n objektumokat, hogy adja át a kifejezés script blokk szűrő, alapértelmezésben csak 1 objektum, ha egy adott szám nem kért numberToReturn.
Last adja vissza az utolsó n objektumokat, amelyek átmennek a kifejezés parancsfájl blokkszűrőjén, csak 1 objektumra alapértelmezve, ha egy adott számot nem kértek a numberToReturn-ben.
SkipUntil Skipuntil
, Amíg Vissza az első N tárgyak gyűjteménye, amíg egy objektum áthalad a kifejezés script szűrő, mulasztó, hogy minden tárgy, ami az első tárgy, amit át, ha nem maximális gróf volt, feltéve, hogy a numberToReturn.
Szét Split egy gyűjtemény a két, elhelyezése tárgyakat, hogy adja át a kifejezést script szűrő az első gyűjtemény legfeljebb számít, ha egy adott numberToReturn, vagy az összes tárgyat, amely át, ha nem maximális száma meghatározott, majd forgalomba, minden más tárgyak, amelyek nem az első gyűjtemény a második gyűjtemény.

mindegyik egyedi értéket kínál az adatgyűjtemények feldolgozásakor, így az alábbiakban megadom az egyes kiválasztási módok további részleteit.

alapértelmezett

nem meglepő, hogy a mode argumentum alapértelmezett értéke “alapértelmezett”. Az alapértelmezett kiválasztási mód ugyanazt a funkciót kínálja, amelyet akkor kap, ha egyáltalán nem ad meg kiválasztási módot. Például írhattuk volna az előző példánk utolsó sorát, mint ez:

# Now filter out any services that are not running$services.where({$_.Status -eq 'Running'},'Default')

ebben a példában az extra argumentum azonban nem szükséges, mert pontosan ugyanazt teszi, mint amit akkor tenne, ha nem adta meg az érvet. Megadhatja a visszatérni kívánt objektumok maximális számát az alapértelmezett kiválasztási mód használata közben a numberToReturn argumentum segítségével, mint ez:

# Get the first 10 services in our collection that are running$services.where({$_.Status -eq 'Running'},'Default',10)

fontos megjegyezni, hogy a pontos funkcionalitás az első kiválasztási mód használatakor is elérhető (amelyről egy pillanat alatt beszélünk), tehát valójában nem praktikus az opcionális paraméterek bármelyikét használni, amikor az alapértelmezett kiválasztási módot használja.

első

ahogy talán kitaláltad, az első kiválasztási mód lehetővé teszi az első objektum(ok) kiválasztását a gyűjteményben, amely átmegy a szkriptblokk kifejezésszűrőn. Ha először használja a numbertorrevurn argumentum értékét, vagy ha először használja a numbertorrevurn argumentum 0 értékét, akkor csak az első objektum kerül visszaadásra, amely átmegy a szűrőn. Opcionálisan megadhatja, hogy hány objektum térjen vissza a számbanvisszatérési argumentum, ebben az esetben sok objektum kerül visszaadásra (feltételezve, hogy sok objektum áthalad a szűrőn).

Íme néhány példa a szolgáltatásgyűjteményünk használatával, amely bemutatja az első kiválasztási módot:

# Get the first service in our collection that is running$services.where({$_.Status -eq 'Running'},'First')# Get the first service in our collection that is running$services.where({$_.Status -eq 'Running'},'First',1)# Get the first 10 services in our collection that are running$services.where({$_.Status -eq 'Running'},'First',10)

vegye figyelembe, hogy ezekben a példákban a második parancs ugyanazokat az eredményeket adja vissza, mint az első parancs, mert egyszerűen kifejezetten átmegy a numberToReturn argumentum alapértelmezett értékében, amikor az első kiválasztási módot használják.

Last

Az utolsó kiválasztási mód ugyanúgy működik, mint az első kiválasztási mód, amely lehetővé teszi az utolsó objektum(ok) kiválasztását a gyűjteményben, amely átmegy a szkriptblokk kifejezésszűrőn. Ha utoljára használja a numbertorrevurn argumentum értékét, vagy ha utoljára használja a numbertorrevurn argumentum 0 értékét, akkor csak az utolsó objektum kerül visszaadásra, amely átmegy a szűrőn. Opcionálisan megadhatja, hogy hány objektum térjen vissza a számbanvisszatérési argumentum, ebben az esetben sok objektum kerül visszaadásra (feltételezve, hogy sok objektum áthalad a szűrőn).

Íme néhány példa a szolgáltatásgyűjteményünk használatával, amely bemutatja az utolsó kiválasztási módot:

# Get the last service in our collection that is running$services.where({$_.Status -eq 'Running'},'Last')# Get the last service in our collection that is running$services.where({$_.Status -eq 'Running'},'Last',1)# Get the last 10 services in our collection that are running$services.where({$_.Status -eq 'Running'},'Last',10)

Is, mint az Első kiválasztási mód példák, a második parancs ezek a példák, ugyanazt az eredményt adja, mint az első parancs, mert egyszerűen kifejezetten halad az alapértelmezett érték a numberToReturn érv, ha az Utolsó kiválasztási mód használata.

SkipUntil

a SkipUntil kiválasztási mód lehetővé teszi a gyűjtemény összes objektumának kihagyását, amíg meg nem találja a szkriptblokk kifejezésszűrőt. Miután megtalálta a szűrőn áthaladó objektumot, a SkipUntil mód vagy visszaadja a gyűjteményben maradt összes objektumot, ha a numberToReturn argumentumhoz nem adtak 0 értéket vagy értéket, vagy visszaadja a gyűjteményben lévő első N fennmaradó objektumokat, ha a numberToReturn argumentumhoz nullánál nagyobb értéket adtak. Mindkét esetben az eredmények tartalmazzák az első objektumot, amely áthaladt a szűrőn.

Íme néhány példa a szolgáltatásgyűjteményünk egy részhalmazát használva a SkipUntil kiválasztási mód műveletben történő megjelenítéséhez:

# Get a collection of services whose name starts with "c"$services = Get-Service c*# Skip all services until we find one with a status of "Running"$services.where({$_.Status -eq 'Running'},'SkipUntil')# Skip all services until we find one with a status of "Running", then# return the first 2$services.where({$_.Status -eq 'Running'},'SkipUntil',2)

ig

A amíg kiválasztási mód biztosítja a SkipUntil kiválasztási mód ellentétes funkcionalitását. Ez lehetővé teszi, hogy vissza tárgyakat a gyűjtemény, amíg meg nem találja az egyik, hogy átmegy a script blokk kifejezés szűrő. Miután megtalálta a szűrőn áthaladó objektumot, a Hol módszer leállítja az objektumok feldolgozását. Ha nem ad meg értéket a numbertorrevurn argumentumhoz, vagy ha 0 értéket ad meg, akkor az Until selection mód visszaadja a gyűjtemény összes objektumát, amely az elsőhöz vezet, amely átmegy a script block expression szűrőn. Ha megadja a szám értékétvisszatérítési argumentum, amely nagyobb, mint 0, A amíg kiválasztási mód legfeljebb az objektumok számát fogja visszaadni, ami azt jelenti, hogy nem talál olyan objektumot, amely átmegy a szkriptblokk kifejezésszűrőn.

Íme néhány példa a szolgáltatásgyűjteményünk egy másik részhalmazát használva, hogy megjelenítse az addigi kiválasztási módot akcióban:

# Get a collection of services whose name starts with "p"$services = Get-Service p*# Return all services until we find one with a status of "Stopped"$services.where({$_.Status -eq 'Stopped'},'Until')# Return the first 2 services unless we find one with a status of# "Stopped" first$services.where({$_.Status -eq 'Stopped'},'Until',2)

Split

Split selection mode egyedi. Ahelyett, hogy visszaküldené a gyűjtemény egy részét, amelyet egy új gyűjteményben kezd el, egy új gyűjteményt ad vissza, amely belsőleg két különálló gyűjteményt tartalmaz. Amit ezek a beágyazott gyűjtemények tartalmaznak, attól függ, hogy hogyan használja az osztott kiválasztási módot. Split lehetővé teszi, hogy osztott gyűjteménye tárgyak két. Alapértelmezés szerint, ha nem ad értéket a numberToReturn érv, vagy ha megadja a 0 érték a numberToReturn érv, Split itt minden tárgy, hogy adja át a script kifejezés szűrő az első beágyazott gyűjtemény, valamint minden egyéb tárgyak (azok, akik nem adja át a script kifejezés szűrő) a második beágyazott gyűjtemény. Ha 0 – nál nagyobb értéket ad meg a numbertorrevurn argumentumhoz, a split az első gyűjtemény méretét a maximális összegre korlátozza, és a gyűjtemény összes többi objektuma, még azok is, amelyek megfelelnek a script block expression szűrőnek, a második gyűjteménybe kerülnek.

Íme néhány példa, amely bemutatja, hogyan osztott kiválasztási mód lehet használni, hogy szét a gyűjtemény tárgyak különböző módokon:

# Get all services$services = Get-Service# Split the services into two groups: Running and not Running$running,$notRunning = $services.Where({$_.Status -eq 'Running'},'Split')# Show the Running services$running# Show the services that are not Running$notRunning# Split the services into the same two groups, but limit the Running group# to a maximum of 10 items$10running,$others = $services.Where({$_.Status -eq 'Running'},'Split',10)# Show the first 10 Running services$10running# Show all other services$others

amint az a példából látható, a Split meglehetősen hatékony kiválasztási mód, amely egyetlen parancshívásban biztosítja a szűrés, a csoportosítás és a kiválasztás keverékét.

Ez a gyűjtemény a kiválasztási módok teszi a hol módszer gyors és elegáns, de ugyanakkor erősebb, mint a Hol-objektum, csoport-objektum és Select-objektum kombinált egyetlen csővezeték. Mi az, amit nem szabad szeretni?

hiányosságok a ForEach, ahol script módszerek TypePx

ahogy már korábban említettük ebben a cikkben, írtam típus kiterjesztések PowerShell 3.0 majd később csomagolta őket egy typepx nevű modulba. TypePx egy script modul, amelyet írt teljesen PowerShell, fut PowerShell 3.0 vagy újabb. Ha a PowerShell 3.0 (csak ha a PowerShell 3.0), TypePx meghatározza ForEach Hol script módszerek, amelyek utánozzák az a viselkedés, az a ForEach Hol módszerek a PowerShell 4.0 majd. Míg a kiterjesztett típusú rendszer PowerShell lehetővé teszi, hogy utánozza ezt a viselkedést, van néhány hiányosság miatt a végrehajtás, hogy a PowerShell, amely befolyásolta, hogy milyen messzire tudtam menni az ilyen típusú kiterjesztések. Ez a szakasz leírja néhány, a különbségek és korlátozások, hogy létezik a ForEach, ahol script módszerek TypePx, hogy érdemes tudni, ha a PowerShell 3.0.

Script blokkok hivatkozni egy script módszer fut a gyermek scope

ellentétben a ForEach, ahol módszerek részeként végrehajtott PowerShell 4.0 vagy újabb, amely a szkriptblokkot az aktuális hatókörben hívja meg, a ForEach, ahol a PowerShell 3.0-ban végrehajtott szkriptmódszerek hivatkoznak a kifejezés szkriptblokkjára egy gyermek hatókörben. Ez egy korlátozás PowerShell, hogy már ott, mivel a kezdetektől (korlátozás, hozzáteszem, hogy azt hiszem, messze a legnagyobb hiányossága PowerShell, mint egy nyelv).

e korlátozás miatt az expression script block belsejében hozzárendelt változók csak a gyermek hatókörében módosulnak. Ennek következményei vannak, ha a kifejezésfájl blokk célja egy változó frissítése abban a hatókörben, amelyben a ForEach-ot vagy a Where-t hívja. Nem valószínű, hogy ez problémát okozna a Where használata közben, mert nem túl gyakori a változók módosítása egy where expression script block-ban, de ForEach script blocks esetén ez problémát jelenthet, ezért ezt szem előtt kell tartania, ha ezeket a kiterjesztéseket használja.

meg kell jegyeznem, hogy szeretném teljesen eltávolítani ezt a korlátozást, és úgy gondolom, hogy képes leszek erre, azonban abban az időben, amikor ezt a cikket írtam, még nem hajtottam végre javítást erre.

legtöbb, de nem minden gyűjtemény lesz ForEach és ahol módszerek

a PowerShell 4.0 és később, a ForEach és ahol módszerek varázslatosan elérhetővé minden típusú, hogy végre IEnumerable kivéve String, XmlNode, és típusok, amelyek végre IDictionary. A PowerShellben a kiterjesztett típusú rendszer nem teszi lehetővé kiterjesztések létrehozását interfészekhez, csak típusokhoz. Ez egy kihívás, ha azt szeretnénk, hogy hozzon létre egy széles kiterjesztése, mint a ForEach, ahol. A jelenlegi végrehajtása ezeket a fájlokat a TypePx, a TypePx modul talál minden típus minden szerelvényt töltve az aktuális alkalmazás domain, meg az összes nem-generikus típusok, amelyek meghatározzák IEnumerable de nem IDictionary (kivéve a Húr, XmlNode), plusz minden generikus típusok, amelyek meghatározzák IEnumerable de nem IDictionary a generikus gyűjtemények PSObject, Tárgy, String, Int32, vagy Int64, a ForEach Hol script módszerek jön létre.

Ez számos olyan típusra vonatkozik, amelyek a saját tesztelésemben elegendőek voltak, azonban előfordulhat, hogy olyan típusokba fut be, ahol ezeket a módszereket használni szeretné, és nem állnak rendelkezésre. Ha ez a helyzet, szólj a Githubon keresztül, és meglátom, mit tehetek. Ez egy korlátozás is, amelyet el szeretnék távolítani, de több időre van szükségem ahhoz, hogy megvizsgáljam, hogyan valósíthatom meg az egyenértékű funkcionalitást egy összeállított összeállításban, ahol talán jobban meg tudom határozni, mint a PowerShell 4.0 vagy újabb meghatározása.

A PowerShell szkriptek nem olyan gyorsak, mint a lefordított kód

Ez valószínűleg magától értetődik, de amikor valamit írsz PowerShellben, ami egy értelmezett nyelv, akkor nem fog olyan gyorsan futni, mint ha az egyenértékű logikát olyan nyelven írnád, mint a C#. Ez teljesen így van a ForEach esetében, ahol a script metódusok, amelyek belsőleg ForEach-Object, Where-Object, and pipelining használják a natív ForEach viselkedését, és ahol a módszerek. Ebben az esetben az előnye, hogy ezeket a parancsokat származik az elegáns szintaxis és funkcionalitás nyújtanak, plusz, hogy képes használni ezeket a szkriptek PowerShell 3.0 és 4.0. A teljesítmény előnyei ForEach, ahol csak a PowerShell 4.0 natív végrehajtása.

PowerShell 3.0 igényel zárójelben körül minden módszer paraméterek

említettem a fenti példákban, hogy tudtam, hogy hivatkozhat a módszer egyetlen szó script blokk paraméter csomagolása nélkül, hogy a szó szerinti script blokk további zárójelben. Ez a képesség csak a PowerShell 4-ben létezik.0 vagy újabb fejlesztések miatt, hogy tettek az elemző, hogy a kiadás. A PowerShell 3.0-ban az elemző ezt nem támogatja, ezért mindig zárójelekre van szükség ahhoz, hogy a ForEach, ahol a szkriptmódszerek egyetlen szó szerinti szkriptblokk paraméterrel működjenek ebben a verzióban.

következtetés

amikor elkezdtem utánozni a ForEach viselkedését, és ahol a magic methods a PowerShell 3.0-ban, nem tudtam, hogy mennyi funkcionalitást biztosítanak. Ásni a technikai részletek mögött ezeket a módszereket, hogy tudtam létrehozni a bővítmények akartam TypePx segített feltárni az összes rejtett funkciók ezekben a nagyon erős módszerek, és nagyon boldog vagyok, hogy ossza meg veletek ebben a cikkben. Remélem, hogy ez az információ segít kihasználni ezt a csodálatos új funkciókészletet a PowerShell munkájában, még akkor is, ha még mindig a PowerShell 3.0-t használja. Boldog scripting!