Megosztás a következőn keresztül:


a csővezetékekről

Rövid leírás

Parancsok egyesítése folyamatokba a PowerShellben

Hosszú leírás

A pipeline egy parancsok sorozata, amelyeket csővezeték operátorok (|) (ASCII 124) kötnek össze. Minden folyamatüzemeltető elküldi az előző parancs eredményeit a következő parancsnak.

Az első parancs kimenete elküldhető feldolgozásra a második parancs bemeneteként. Ez a kimenet pedig elküldhető egy másik parancsnak. Az eredmény egy összetett parancslánc vagy folyamat, amely egyszerű parancsok sorozatából áll.

Például

Command-1 | Command-2 | Command-3

Ebben a példában az Command-1 által kibocsátott objektumok Command-2lesznek elküldve. Command-2 feldolgozza az objektumokat, és elküldi őket Command-3. Command-3 feldolgozza az objektumokat, és továbbítja őket a folyamatláncban. Mivel nincs több parancs a folyamatban, az eredmények megjelennek a konzolon.

A folyamatokban a parancsok feldolgozása balról jobbra haladva történik. A feldolgozás egyetlen műveletként van kezelve, és a kimenet a létrehozáskor jelenik meg.

Íme egy egyszerű példa. A következő parancs lekéri a Jegyzettömb folyamatot, majd leállítja azt.

Például

Get-Process notepad | Stop-Process

Az első parancs a Get-Process parancsmagot használja a Jegyzettömb folyamatának megfelelő objektum lekéréséhez. Folyamatkezelőt (|) használ a folyamatobjektum Stop-Process parancsmagba való küldéséhez, amely leállítja a Jegyzettömb-folyamatot. Figyelje meg, hogy a Stop-Process parancsnak nincs Név vagy azonosító paramétere a folyamat megadásához, mivel a megadott folyamat az adatfolyamon keresztül kerül beküldésre.

Ez a folyamat példája beolvasja az aktuális könyvtárban lévő szövegfájlokat, csak a 10 000 bájtnál hosszabb fájlokat választja ki, hossz szerint rendezi őket, és megjeleníti az egyes fájlok nevét és hosszát egy táblázatban.

Get-ChildItem -Path *.txt |
  Where-Object {$_.length -gt 10000} |
    Sort-Object -Property length |
      Format-Table -Property name, length

Ez a folyamat négy parancsból áll a megadott sorrendben. Az alábbi ábra az egyes parancsok kimenetét mutatja, ahogy azokat a csővezeték következő parancsához továbbítják.

Get-ChildItem -Path *.txt
| (FileInfo objects for *.txt)
V
Where-Object {$_.length -gt 10000}
| (FileInfo objects for *.txt)
| (      Length > 10000      )
V
Sort-Object -Property Length
| (FileInfo objects for *.txt)
| (      Length > 10000      )
| (     Sorted by length     )
V
Format-Table -Property name, length
| (FileInfo objects for *.txt)
| (      Length > 10000      )
| (     Sorted by length     )
| (   Formatted in a table   )
V

Name                       Length
----                       ------
tmp1.txt                    82920
tmp2.txt                   114000
tmp3.txt                   114000

Adatcsatornák használata

A legtöbb PowerShell-parancsmag a pipeline-ek támogatására lett tervezve. A legtöbb esetben egy Get parancsmag eredményeit továbbíthatja egy másik, azonos főnévvel rendelkező parancsmaghoz. A Get-Service parancsmag kimenetét például a Start-Service vagy Stop-Service parancsmagokra is átirányíthatja.

Ez a példafolyamat elindítja a WMI szolgáltatást a számítógépen:

Get-Service wmi | Start-Service

Egy másik példában a PowerShell-beállításjegyzék-szolgáltatón belüli Get-Item vagy Get-ChildItem kimenetét a New-ItemProperty parancsmagra adhatja. Ez a példa hozzáad egy új beállításjegyzék-bejegyzést, NoOfEmployees, amelynek értéke 8124, a MyCompany beállításkulcshoz.

Get-Item -Path HKLM:\Software\MyCompany |
  New-ItemProperty -Name NoOfEmployees -Value 8124

Számos segédprogram-cmdletet, például Get-Member, Where-Object, Sort-Object, Group-Objectés Measure-Object szinte kizárólag csővezetékekben használnak. Ezekhez a parancsmagokhoz bármilyen objektumtípust be lehet csövezni. Ez a példa bemutatja, hogyan rendezheti a számítógépen lévő összes folyamatot az egyes folyamatokban megnyitott fogópontok száma alapján.

Get-Process | Sort-Object -Property handles

Az objektumokat a formázási, exportálási és kimeneti parancsmagokhoz, például Format-List, Format-Table, Export-Clixml, Export-CSVés Out-Filecsövezheti.

Ez a példa bemutatja, hogyan jelenítheti meg a folyamatobjektum tulajdonságainak listáját a Format-List parancsmaggal.

Get-Process winlogon | Format-List -Property *

A natív parancsok kimenetét a PowerShell-parancsmagokra is átirányíthatja. Például:

PS> ipconfig.exe | Select-String -Pattern 'IPv4'

   IPv4 Address. . . . . . . . . . . : 172.24.80.1
   IPv4 Address. . . . . . . . . . . : 192.168.1.45
   IPv4 Address. . . . . . . . . . . : 100.64.108.37

Fontos

A siker és hiba streamjei hasonlóak a többi shell stdin és stderr folyamaihoz. Az stdin azonban nincs csatlakoztatva a PowerShell-folyamathoz bemenet céljából. További információért lásd about_Redirection.

Egy kis gyakorlással azt tapasztalhatja, hogy az egyszerű parancsok folyamatokba való kombinálása időt és gépelést takarít meg, és hatékonyabbá teszi a szkriptek használatát.

Hogyan működnek a csővezetékek

Ez a szakasz bemutatja, hogyan vannak a bemeneti objektumok a parancsmag paramétereihez kötve, és hogyan dolgozhatók fel a folyamat végrehajtása során.

Folyamatbemenet elfogadása

A pipelining támogatásához a fogadó parancsmagnak rendelkeznie kell egy olyan paraméterrel, amely elfogadja a folyamatbemenetet. Használja a Get-Help parancsot a Teljes vagy Paraméter beállítással annak meghatározásához, hogy a parancsmag mely paraméterei fogadják el a folyamatbemenetet.

Például annak meghatározásához, hogy a Start-Service parancsmag melyik paramétere fogadja a folyamatbemenetet, írja be a következőt:

Get-Help Start-Service -Full

vagy

Get-Help Start-Service -Parameter *

A Start-Service parancsmag súgója azt mutatja, hogy csak a InputObject és Name paraméterek fogadják el a folyamatbemenetet.

-InputObject <ServiceController[]>
Specifies ServiceController objects representing the services to be started.
Enter a variable that contains the objects, or type a command or expression
that gets the objects.

Required?                    true
Position?                    0
Default value                None
Accept pipeline input?       True (ByValue)
Accept wildcard characters?  false

-Name <String[]>
Specifies the service names for the service to be started.

The parameter name is optional. You can use Name or its alias, ServiceName,
or you can omit the parameter name.

Required?                    true
Position?                    0
Default value                None
Accept pipeline input?       True (ByPropertyName, ByValue)
Accept wildcard characters?  false

Amikor objektumokat küld a pipelinen keresztül a Start-Service, a PowerShell megpróbálja az objektumokat az InputObject és Name paraméterekhez társítani.

Folyamatbemenet elfogadásának módszerei

A parancsmagok paraméterei kétféleképpen fogadhatják el a folyamatbemenetet:

  • ByValue: A paraméter olyan értékeket fogad el, amelyek megfelelnek a várt .NET-típusnak, vagy amelyek átalakíthatók erre a típusra.

    A például a Name paramétere Start-Service fogadja a folyamatbemenetet értékként. Sztringobjektumokat vagy sztringekké konvertálható objektumokat is elfogad.

  • ByPropertyName: A paraméter csak akkor fogadja el a bemenetet, ha a bemeneti objektumnak ugyanaz a tulajdonsága, mint a paraméternek.

    A Start-Service Név paramétere például elfogadhatja azokat az objektumokat, amelyek Name tulajdonságot rendelkeznek. Egy objektum tulajdonságainak listázásához irányítsa a Get-Member-ra.

Egyes paraméterek érték vagy tulajdonságnév alapján is elfogadhatnak objektumokat, így egyszerűbben lehet bemenetet felvenni a folyamatból.

Paraméterkötés

Amikor egy parancsból egy másik parancsba irányítja az objektumokat, a PowerShell megpróbálja társítani a vezetékes objektumokat a fogadó parancsmag egyik paraméterével.

A PowerShell paraméterkötési összetevője a bemeneti objektumokat a parancsmag paramétereivel társítja az alábbi feltételek szerint:

  • A paraméternek csővezetékről kell fogadnia a bemenetet.
  • A paraméternek el kell fogadnia az elküldött objektum típusát, vagy a várt típusra konvertálható típust.
  • A paraméter nem lett használva a parancsban.

A Start-Service parancsmagnak például számos paramétere van, de csak kettő, Név és InputObject fogadja el a folyamatbemenetet. A Name paraméter sztringeket, a InputObject paraméter pedig szolgáltatásobjektumokat vesz fel. Ezért csövezhet sztringeket, szolgáltatásobjektumokat, valamint olyan objektumokat, amelyek tulajdonságai sztringgé vagy szolgáltatásobjektummá alakíthatók.

A PowerShell a lehető leghatékonyabban kezeli a paraméterkötést. A PowerShell nem javasolható és nem kényszeríthető egy adott paraméterhez való kötésre. A parancs meghiúsul, ha a PowerShell nem tudja kötni a vezetékes objektumokat.

A kötési hibák elhárításával kapcsolatos további információkért lásd a cikk Folyamathibák kivizsgálása című cikket.

Egyszeri feldolgozás

Az objektumok parancshoz való pipálása olyan, mintha a parancs egy paraméterét használva küldi el az objektumokat. Tekintsünk meg egy folyamat példáját. Ebben a példában egy csővezeték használatával jelenítjük meg a szolgáltatásobjektumok tábláját.

Get-Service | Format-Table -Property Name, DependentServices

Funkcionálisan ez olyan, mintha a Format-Table paraméterét használva küldi el az objektumgyűjteményt.

A szolgáltatások gyűjteményét például menthetjük egy olyan változóba, amely az InputObject paraméterrel lett átadva.

$services = Get-Service
Format-Table -InputObject $services -Property Name, DependentServices

Vagy beágyazhatjuk a parancsot az InputObject paraméterbe.

Format-Table -InputObject (Get-Service) -Property Name, DependentServices

Van azonban egy fontos különbség. Ha több objektumot csövez egy parancsba, a PowerShell egyenként küldi el az objektumokat a parancsnak. Parancsparaméter használatakor az objektumok egyetlen tömbobjektumként lesznek elküldve. Ez a kisebb különbség jelentős következményekkel jár.

Folyamat végrehajtásakor a PowerShell automatikusan felsorol minden olyan típust, amely megvalósítja a IEnumerable felületet vagy annak általános megfelelőjét. Az enumerált elemeket a rendszer egyenként küldi el a folyamaton keresztül. A PowerShell System.Data.DataTable típusokat is felsorolja a Rows tulajdonságon keresztül.

Az automatikus számbavétel alól néhány kivétel van.

  • Meg kell hívnia a GetEnumerator() metódust a kivonattáblákhoz, a IDictionary interfészt vagy annak általános megfelelőjét implementáló típusokhoz, valamint System.Xml.XmlNode típusokhoz.
  • A System.String osztály implementálja IEnumerable, a PowerShell azonban nem számba veszi a sztringobjektumokat.

Az alábbi példákban egy tömböt és egy kivonatolót a rendszer a Measure-Object parancsmagba csövez, hogy megszámolja a folyamattól kapott objektumok számát. A tömbnek több tagja van, a kivonatolónak pedig több kulcs-érték párja van. Egyszerre csak a tömb van számba írva.

@(1,2,3) | Measure-Object
Count    : 3
Average  :
Sum      :
Maximum  :
Minimum  :
Property :
@{"One"=1;"Two"=2} | Measure-Object
Count    : 1
Average  :
Sum      :
Maximum  :
Minimum  :
Property :

Hasonlóképpen, ha több folyamatobjektumot is a Get-Process parancsmagból a Get-Member parancsmagba küld, a PowerShell egyenként küldi el az egyes folyamatobjektumokat Get-Member. Get-Member megjeleníti a folyamatobjektumok .NET-osztályát (típusát), valamint azok tulajdonságait és metódusait.

Get-Process | Get-Member
TypeName: System.Diagnostics.Process

Name      MemberType     Definition
----      ----------     ----------
Handles   AliasProperty  Handles = Handlecount
Name      AliasProperty  Name = ProcessName
NPM       AliasProperty  NPM = NonpagedSystemMemorySize
...

Megjegyzés:

Get-Member kiküszöböli az ismétlődéseket, így ha az objektumok mind azonos típusúak, csak egy objektumtípust jelenít meg.

Ha azonban a Get-Member paraméterét használja, akkor Get-Member egyetlen egységként fogadja System.Diagnostics.Process objektumokat. Megjeleníti az objektumok tömbjének tulajdonságait. (Figyelje meg a [] típusnév utáni tömbszimbólumot ().)

Például

Get-Member -InputObject (Get-Process)
TypeName: System.Object[]

Name               MemberType    Definition
----               ----------    ----------
Count              AliasProperty Count = Length
Address            Method        System.Object& Address(Int32 )
Clone              Method        System.Object Clone()
...

Előfordulhat, hogy ez az eredmény nem a kívánt eredmény. Miután megértetted, már használhatod. Például minden tömbobjektum rendelkezik Darabszám tulajdonságmal. Ezzel megszámolhatja a számítógépen futó folyamatok számát.

Például

(Get-Process).count

Fontos megjegyezni, hogy a csatornán keresztül küldött objektumok egyesével kerülnek kézbesítésre.

Natív parancsok használata a folyamatban

A PowerShell lehetővé teszi natív külső parancsok hozzáadását a folyamatba. Fontos azonban megjegyezni, hogy a PowerShell folyamata objektumorientált, és nem támogatja a nyers bájtadatokat.

A nyers bájtadatokat kiíró natív program kimenetének pipálása vagy átirányítása .NET-sztringekké alakítja a kimenetet. Ez az átalakítás a nyers adatkimenet sérülését okozhatja.

Áthidaló megoldásként hívja meg a natív parancsokat cmd.exe /c a vagy sh -c és a natív rendszerhéj által biztosított operátorok | használatával>.

Folyamathibák kivizsgálása

Ha a PowerShell nem tudja társítani a vezetékes objektumokat a fogadó parancsmag egyik paraméterével, a parancs meghiúsul.

Az alábbi példában megpróbálunk áthelyezni egy beállításjegyzék-bejegyzést az egyik beállításkulcsból a másikba. A Get-Item parancsmag lekéri a cél elérési útját, amely ezután a Move-ItemProperty parancsmagra lesz továbbítva. A Move-ItemProperty parancs megadja az áthelyezendő beállításjegyzék-bejegyzés aktuális elérési útját és nevét.

Get-Item -Path HKLM:\Software\MyCompany\sales |
Move-ItemProperty -Path HKLM:\Software\MyCompany\design -Name product

A parancs sikertelen, és a PowerShell a következő hibaüzenetet jeleníti meg:

Move-ItemProperty : The input object can't be bound to any parameters for
the command either because the command doesn't take pipeline input or the
input and its properties do not match any of the parameters that take
pipeline input.
At line:1 char:23
+ $a | Move-ItemProperty <<<<  -Path HKLM:\Software\MyCompany\design -Name p

A vizsgálathoz használja a Trace-Command parancsmagot a PowerShell paraméterkötési összetevőjének nyomon követéséhez. Az alábbi példa a paraméterkötést követi nyomon a folyamat végrehajtása közben. A PSHost paraméter megjeleníti a nyomkövetési eredményeket a konzolon, és a FilePath paraméter elküldi a nyomkövetési eredményeket a debug.txt fájlba későbbi hivatkozás céljából.

Trace-Command -Name ParameterBinding -PSHost -FilePath debug.txt -Expression {
  Get-Item -Path HKLM:\Software\MyCompany\sales |
    Move-ItemProperty -Path HKLM:\Software\MyCompany\design -Name product
}

A nyomkövetés eredményei hosszadalmasak, de a Get-Item parancsmaghoz kötött értékeket, majd a névvel ellátott értékeket a Move-ItemProperty parancsmaghoz kötik.

...
BIND NAMED cmd line args [`Move-ItemProperty`]
BIND arg [HKLM:\Software\MyCompany\design] to parameter [Path]
...
BIND arg [product] to parameter [Name]
...
BIND POSITIONAL cmd line args [`Move-ItemProperty`]
...

Végül az látható, hogy az elérési út Cél paraméterhez kötése Move-ItemProperty sikertelen volt.

...
BIND PIPELINE object to parameters: [`Move-ItemProperty`]
PIPELINE object TYPE = [Microsoft.Win32.RegistryKey]
RESTORING pipeline parameter's original values
Parameter [Destination] PIPELINE INPUT ValueFromPipelineByPropertyName NO
COERCION
Parameter [Credential] PIPELINE INPUT ValueFromPipelineByPropertyName NO
COERCION
...

A Get-Help parancsmaggal megtekintheti a Cél paraméter attribútumait.

Get-Help Move-ItemProperty -Parameter Destination

-Destination <String>
    Specifies the path to the destination location.

    Required?                    true
    Position?                    1
    Default value                None
    Accept pipeline input?       True (ByPropertyName)
    Accept wildcard characters?  false

Az eredmények azt mutatják, hogy Cél csak "tulajdonságnév alapján" veszi fel a folyamatbemenetet. Ezért a vezetékes objektumnak rendelkeznie kell egy Célnevű tulajdonságmal.

Használja a Get-Member-t az objektum Get-Item-ből származó tulajdonságainak megtekintéséhez.

Get-Item -Path HKLM:\Software\MyCompany\sales | Get-Member

A kimenet azt mutatja, hogy az elem egy Microsoft.Win32.RegistryKey objektum, amely nem rendelkezik Cél tulajdonságmal. Ez megmagyarázza, hogy miért nem sikerült a parancs.

A Elérési út paraméter név vagy érték alapján fogadja el a folyamatbemenetet.

Get-Help Move-ItemProperty -Parameter Path

-Path <String[]>
    Specifies the path to the current location of the property. Wildcard
    characters are permitted.

    Required?                    true
    Position?                    0
    Default value                None
    Accept pipeline input?       True (ByPropertyName, ByValue)
    Accept wildcard characters?  true

A parancs javításához meg kell adnunk a célhelyet a Move-ItemProperty parancsmagban, és Get-Item kell használnunk az áthelyezni kívánt elem elérési útjának lekéréséhez.

Például

Get-Item -Path HKLM:\Software\MyCompany\design |
Move-ItemProperty -Destination HKLM:\Software\MyCompany\sales -Name product

Belső vonal folytatása

Ahogy már említettem, a folyamat olyan parancsok sorozata, amelyeket a folyamatüzemeltetők (|) kötnek össze, amelyek általában egyetlen sorban vannak megírva. Az olvashatóság érdekében azonban a PowerShell lehetővé teszi a folyamat több sorra való felosztását. Ha egy csővezérlő karakter az utolsó elem a sorban, a PowerShell elemző a következő sort illeszti az aktuális parancshoz a folyamat építésének folytatásához.

Például a következő egysoros feldolgozási lánc:

Command-1 | Command-2 | Command-3

a következő módon írható:

Command-1 |
    Command-2 |
    Command-3

A következő sorok kezdő szóközei nem jelentősek. A behúzás növeli az olvashatóságot.

A PowerShell 7-ben támogatás érkezik a csővezetékek folytatására azáltal, hogy a vonal elején lévő csővezeték karaktert használják. Az alábbi példák bemutatják, hogyan használhatja ezt az új funkciót.

# Wrapping with a pipe at the beginning of a line (no backtick required)
Get-Process | Where-Object CPU | Where-Object Path
    | Get-Item | Where-Object FullName -match "AppData"
    | Sort-Object FullName -Unique

# Wrapping with a pipe on a line by itself
Get-Process | Where-Object CPU | Where-Object Path
    |
    Get-Item | Where-Object FullName -match "AppData"
    |
    Sort-Object FullName -Unique

Fontos

Ha interaktívan dolgozik a rendszerhéjban, a kódot csak akkor illessze be a sor elejére csővezetékekkel, ha a beillesztéshez a Ctrl+V billentyűkombinációt használja. A jobb egérgombbal történő beillesztési műveletek egyenként szúrják be a sorokat. Mivel a sor nem végződik folyamat karakterrel, a PowerShell befejezettnek tekinti a bemenetet, és a megadott módon hajtja végre a sort.

Lásd még