about_Pipelines

Kısa açıklama

Komutları PowerShell'de işlem hatlarında birleştirme

Uzun açıklama

İşlem hattı, işlem hattı işleçleri () (|ASCII 124) tarafından bağlanan bir komut dizisidir. Her işlem hattı işleci, önceki komutun sonuçlarını sonraki komuta gönderir.

İlk komutun çıkışı, ikinci komuta giriş olarak işlenmek üzere gönderilebilir. Ve bu çıkış başka bir komuta gönderilebilir. Sonuç, basit komutlardan oluşan karmaşık bir komut zinciri veya işlem hattıdır .

Örneğin,

Command-1 | Command-2 | Command-3

Bu örnekte, yayan Command-1 nesneler adresine Command-2gönderilir. Command-2 nesneleri işler ve öğesine Command-3gönderir. Command-3 nesneleri işler ve işlem hattına gönderir. İşlem hattında başka komut olmadığından sonuçlar konsolda görüntülenir.

İşlem hattında komutlar soldan sağa sırasıyla işlenir. İşleme tek bir işlem olarak işlenir ve çıktı oluşturulurken görüntülenir.

Aşağıda basit bir örnek verilmiştir. Aşağıdaki komut Not Defteri işlemini alır ve durdurur.

Örneğin,

Get-Process notepad | Stop-Process

İlk komut, Not Defteri işlemini temsil eden bir nesne almak için cmdlet'ini kullanır Get-Process . İşlem nesnesini cmdlet'e Stop-Process göndermek için bir işlem hattı işleci (|) kullanır ve bu da Not Defteri işlemini durdurur. Stop-Process Belirtilen işlem işlem hattı üzerinden gönderildiğinden, komutun işlemi belirtmek için bir Name veya ID parametresine sahip olmadığını unutmayın.

Bu işlem hattı örneği, geçerli dizindeki metin dosyalarını alır, yalnızca 10.000 bayttan uzun dosyaları seçer, uzunluklarına göre sıralar ve her dosyanın adını ve uzunluğunu bir tabloda görüntüler.

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

Bu işlem hattı, belirtilen sırada dört komut içerir. Aşağıdaki çizimde, işlem hattındaki bir sonraki komuta geçirilirken her komutun çıkışı gösterilmektedir.

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

İşlem hatlarını kullanma

PowerShell cmdlet'lerinin çoğu işlem hatlarını destekleyecek şekilde tasarlanmıştır. Çoğu durumda, Get cmdlet'inin sonuçlarını aynı adın başka bir cmdlet'ine yöneltebilirsiniz. Örneğin, cmdlet'in çıkışını Get-Service veya Stop-Service cmdlet'lerine Start-Service yöneltebilirsiniz.

Bu örnek işlem hattı bilgisayarda WMI hizmetini başlatır:

Get-Service wmi | Start-Service

Başka bir örnek için PowerShell kayıt defteri sağlayıcısındaki veya Get-ChildItem çıkışını Get-Item cmdlet'ine New-ItemProperty yöneltebilirsiniz. Bu örnek, MyCompany kayıt defteri anahtarına 8124 değerine sahip noOfEmployees adlı yeni bir kayıt defteri girdisi ekler.

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

, , Where-Object, Sort-ObjectGroup-Objectve Measure-Object gibi Get-Memberyardımcı program cmdlet'lerinin çoğu neredeyse yalnızca işlem hatlarında kullanılır. Herhangi bir nesne türünü bu cmdlet'lere yöneltebilirsiniz. Bu örnekte, bilgisayardaki tüm işlemlerin her işlemdeki açık tanıtıcı sayısına göre nasıl sıralanacağını gösterir.

Get-Process | Sort-Object -Property handles

Nesneleri , ve gibi Format-ListExport-CSVFormat-TableExport-ClixmlOut-Filebiçimlendirme, dışarı ve çıkış cmdlet'lerine aktarabilirsiniz.

Bu örnekte, bir işlem nesnesinin Format-List özelliklerinin listesini görüntülemek için cmdlet'in nasıl kullanılacağı gösterilmektedir.

Get-Process winlogon | Format-List -Property *

Ayrıca yerel komutların çıkışını PowerShell cmdlet'lerine de yöneltebilirsiniz. Örneğin:

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

Önemli

Success ve Error akışları, diğer kabukların stdin ve stderr akışlarına benzer. Ancak stdin giriş için PowerShell işlem hattına bağlı değildir. Daha fazla bilgi için bkz . about_Redirection.

Biraz pratik yaparak basit komutları işlem hatlarında birleştirmenin zaman ve yazma tasarrufu sağladığını ve betiğinizi daha verimli hale getirdiğini göreceksiniz.

İşlem hatları nasıl çalışır?

Bu bölümde, giriş nesnelerinin cmdlet parametrelerine nasıl bağlı olduğu ve işlem hattı yürütme sırasında nasıl işlendiği açıklanmaktadır.

İşlem hattı girişini kabul eder

Kanal oluşturmayı desteklemek için, alan cmdlet'in işlem hattı girişini kabul eden bir parametresi olmalıdır. Bir cmdlet'in Get-Help işlem hattı girişini kabul eden parametrelerini belirlemek için Tam veya Parametre seçenekleriyle komutunu kullanın.

Örneğin, cmdlet'in parametrelerinden hangisinin Start-Service işlem hattı girişini kabuldiğini belirlemek için şunu yazın:

Get-Help Start-Service -Full

veya

Get-Help Start-Service -Parameter *

Cmdlet'in Start-Service yardımı, yalnızca InputObject ve Name parametrelerinin işlem hattı girişini kabul ettiğini gösterir.

-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

nesneleri işlem hattı üzerinden adresine Start-Servicegönderdiğinizde, PowerShell nesneleri InputObject ve Name parametreleriyle ilişkilendirmeyi dener.

İşlem hattı girişini kabul etme yöntemleri

Cmdlet'ler parametreleri iki farklı yoldan biriyle işlem hattı girişini kabul edebilir:

  • ByValue: parametresi beklenen .NET türüyle eşleşen veya bu türe dönüştürülebilen değerleri kabul eder.

    Örneğin, Name parametresi Start-Service değere göre işlem hattı girişini kabul eder. Dizelere dönüştürülebilen dize nesnelerini veya nesneleri kabul edebilir.

  • ByPropertyName: Parametresi yalnızca giriş nesnesinin parametresiyle aynı ada sahip bir özelliği olduğunda girişi kabul eder.

    Örneğin, name parametresi Start-Service Name özelliğine sahip nesneleri kabul edebilir. Bir nesnenin özelliklerini listelemek için öğesine yöneltin Get-Member.

Bazı parametreler nesneleri hem değer hem de özellik adına göre kabul ederek işlem hattından giriş almayı kolaylaştırır.

Parametre bağlama

Nesneleri bir komuttan başka bir komuta yönelttiğiniz zaman PowerShell, kanala alınan nesneleri alan cmdlet'in parametresiyle ilişkilendirmeyi dener.

PowerShell'in parametre bağlama bileşeni, giriş nesnelerini aşağıdaki ölçütlere göre cmdlet parametreleriyle ilişkilendirir:

  • parametresi bir işlem hattından girişi kabul etmelidir.
  • parametresi, gönderilen nesnenin türünü veya beklenen türe dönüştürülebilecek bir türü kabul etmelidir.
  • parametresi komutunda kullanılmadı.

Örneğin, Start-Service cmdlet'in birçok parametresi vardır, ancak bunlardan yalnızca ikisi, Name ve InputObject işlem hattı girişini kabul eder. Name parametresi dizeleri, InputObject parametresi ise hizmet nesnelerini alır. Bu nedenle dizelere, hizmet nesnelerine ve dize veya hizmet nesnelerine dönüştürülebilecek özelliklere sahip nesnelere kanal oluşturabilirsiniz.

PowerShell, parametre bağlamayı mümkün olduğunca verimli bir şekilde yönetir. PowerShell'i belirli bir parametreye bağlamaya zorlayamaz veya öneremezsiniz. PowerShell kanallı nesneleri bağlayamazsa komut başarısız olur.

Bağlama hatalarını giderme hakkında daha fazla bilgi için bu makalenin devamında yer alan İşlem Hattı Hatalarını Araştırma bölümüne bakın.

Tek seferde işleme

Nesneleri bir komuta göndermek, komutun bir parametresini kullanarak nesneleri göndermeye benzer. Şimdi bir işlem hattı örneğine bakalım. Bu örnekte, hizmet nesnelerinin tablosunu görüntülemek için bir işlem hattı kullanırız.

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

İşlevsel olarak bu, nesne koleksiyonunu göndermek için inputobject parametresini Format-Table kullanmaya benzer.

Örneğin, hizmet koleksiyonunu InputObject parametresi kullanılarak geçirilen bir değişkene kaydedebiliriz.

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

İsterseniz, komutu InputObject parametresine de ekleyebiliriz.

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

Ancak önemli bir fark vardır. Bir komuta birden çok nesne gönderdiğinizde, PowerShell nesneleri komuta birer birer gönderir. Bir komut parametresi kullandığınızda, nesneler tek bir dizi nesnesi olarak gönderilir. Bu küçük farkın önemli sonuçları vardır.

Bir işlem hattı yürütülürken PowerShell, arabirimini veya genel karşılık gelenini uygulayan IEnumerable herhangi bir türü otomatik olarak numaralandırır. Numaralandırılmış öğeler işlem hattı üzerinden birer birer gönderilir. PowerShell ayrıca özelliği aracılığıyla System.Data.DataTable türlerini numaralandırır.Rows

Otomatik numaralandırmanın birkaç özel durumu vardır.

  • Karma tablolar, arabirimini veya genel karşılık gelenini uygulayan IDictionary türler ve System.Xml.XmlNode türleri için yöntemini çağırmanız GetEnumerator() gerekir.
  • System.String sınıfı uygularIEnumerable, ancak PowerShell dize nesnelerini listelemez.

Aşağıdaki örneklerde bir dizi ve karma tablo, işlem hattından alınan nesne sayısını saymak için cmdlet'ine iletilir Measure-Object . Dizinin birden çok üyesi vardır ve karma tablo birden çok anahtar-değer çifti içerir. Yalnızca dizi bir kerede bir numaralandırılır.

@(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 :

Benzer şekilde, cmdlet'inden Get-Process cmdlet'ine Get-Member birden çok işlem nesnesi gönderirseniz, PowerShell her işlem nesnesini tek tek öğesine Get-Membergönderir. Get-Member işlem nesnelerinin .NET sınıfını (türü) ve bunların özelliklerini ve yöntemlerini görüntüler.

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

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

Not

Get-Member yinelenenleri ortadan kaldırır, bu nedenle nesnelerin tümü aynı türdeyse yalnızca bir nesne türü görüntüler.

Ancak, öğesinin InputObject parametresini Get-MemberGet-Member kullanırsanız system.diagnostics.process nesnelerinin bir dizisini tek bir birim olarak alır. Bir nesne dizisinin özelliklerini görüntüler. (System.Object tür adından sonraki dizi simgesini ([]) not edin.)

Örneğin,

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()
...

Bu sonuç istediğiniz gibi olmayabilir. Ama anladıktan sonra kullanabilirsiniz. Örneğin, tüm dizi nesnelerinin count özelliği vardır. Bunu, bilgisayarda çalışan işlem sayısını saymak için kullanabilirsiniz.

Örneğin,

(Get-Process).count

İşlem hattına gönderilen nesnelerin birer birer teslim edilmesi önemlidir.

İşlem hattında yerel komutları kullanma

PowerShell, işlem hattına yerel dış komutlar eklemenize olanak tanır. Ancak PowerShell'in işlem hattının nesne odaklı olduğunu ve ham bayt verilerini desteklemediğini unutmayın.

Ham bayt verileri veren yerel bir programdan gelen çıkışın borulanması veya yeniden yönlendirilmesi, çıkışı .NET dizelerine dönüştürür. Bu dönüştürme ham veri çıkışının bozulmasına neden olabilir.

Ancak PowerShell 7.4, yerel bir komutun PSNativeCommandPreserveBytePipe stdout akışını bir dosyaya yönlendirirken veya bayt akışı verilerini yerel komutun stdin akışına yönlendirirken bayt akışı verilerini koruyan deneysel özelliği ekledi.

Örneğin, yerel komutu curl kullanarak bir ikili dosya indirebilir ve yeniden yönlendirmeyi kullanarak diske kaydedebilirsiniz.

$uri = 'https://github.com/PowerShell/PowerShell/releases/download/v7.3.4/powershell-7.3.4-linux-arm64.tar.gz'

# native command redirected to a file
curl -s -L $uri > powershell.tar.gz

Bayt akışı verilerini başka bir yerel komutun stdin akışına da aktarabilirsiniz. Aşağıdaki örnekte kullanarak curlsıkıştırılmış bir TAR dosyası indirilir. İndirilen dosya verileri, arşiv içeriğini ayıklamak için komutuna akışla aktarılır tar .

# native command output piped to a native command
curl -s -L $uri | tar -xzvf - -C .

Ayrıca, PowerShell komutunun bayt akışı çıkışını yerel komutun girişine de aktarabilirsiniz. Aşağıdaki örnekler, önceki örnekle aynı TAR dosyasını indirmek için kullanılır Invoke-WebRequest .

# byte stream piped to a native command
(Invoke-WebRequest $uri).Content | tar -xzvf - -C .

# bytes piped to a native command (all at once as byte[])
,(Invoke-WebRequest $uri).Content | tar -xzvf - -C .

Bu özellik, stderr çıkışını stdout'a yeniden yönlendirirken bayt akışı verilerini desteklemez. stderr ve stdout akışlarını birleştirdiğinizde, birleştirilmiş akışlar dize verileri olarak değerlendirilir.

İşlem hattı hatalarını araştırma

PowerShell, kanallı nesneleri alan cmdlet'in parametresiyle ilişkilendiremediğinde komut başarısız olur.

Aşağıdaki örnekte, bir kayıt defteri girdisini bir kayıt defteri anahtarından diğerine taşımaya çalışıyoruz. Get-Item Cmdlet, hedef yolu alır ve ardından cmdlet'ine Move-ItemProperty iletilir. komutu Move-ItemProperty , taşınacak kayıt defteri girişinin geçerli yolunu ve adını belirtir.

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

Komut başarısız olur ve PowerShell aşağıdaki hata iletisini görüntüler:

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

Araştırmak için cmdlet'ini Trace-Command kullanarak PowerShell'in parametre bağlama bileşenini takip edin. Aşağıdaki örnek, işlem hattı yürütülürken parametre bağlamasını izler. PSHost parametresi izleme sonuçlarını konsolunda görüntüler ve FilePath parametresi izleme sonuçlarını daha sonra başvurmak üzere dosyaya debug.txt gönderir.

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
}

İzlemenin sonuçları uzun olsa da, cmdlet'e Get-Item bağlı olan değerleri ve ardından cmdlet'e Move-ItemProperty bağlı olan adlandırılmış değerleri gösterir.

...
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`]
...

Son olarak, yolu Hedef parametresine Move-ItemProperty bağlama girişiminin başarısız olduğunu gösterir.

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

Hedef parametresinin Get-Help özniteliklerini görüntülemek için cmdlet'ini kullanın.

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

Sonuçlar, Hedef'in yalnızca "özellik adına göre" işlem hattı girişi aldığını gösterir. Bu nedenle, kanallı nesnenin Destination adlı bir özelliği olmalıdır.

öğesinden Get-Itemgelen nesnenin özelliklerini görmek için kullanınGet-Member.

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

Çıktı, öğenin Destination özelliği olmayan bir Microsoft.Win32.RegistryKey nesnesi olduğunu gösterir. Bu, komutun neden başarısız olduğunu açıklar.

Path parametresi, ada veya değere göre işlem hattı girişini kabul eder.

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

Komutu düzeltmek için cmdlet'inde Move-ItemProperty hedefi belirtmemiz ve taşımak istediğimiz öğenin Yolunu almak için kullanmamız Get-Item gerekir.

Örneğin,

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

İç çizgi devamlılığı

Daha önce de açıklandığı gibi işlem hattı, genellikle tek bir satırda yazılan işlem hattı işleçleri ()| tarafından bağlanan bir dizi komuttır. Ancak, okunabilirlik için PowerShell işlem hattını birden çok satıra bölmenize olanak tanır. Kanal işleci satırdaki son belirteç olduğunda PowerShell ayrıştırıcısı, işlem hattının oluşturulmasına devam etmek için bir sonraki satırı geçerli komutla birleştirir.

Örneğin, aşağıdaki tek satırlı işlem hattı:

Command-1 | Command-2 | Command-3

şu şekilde yazılabilir:

Command-1 |
    Command-2 |
    Command-3

Sonraki satırlardaki baştaki boşluklar önemli değildir. Girinti, okunabilirliği artırır.

PowerShell 7, bir satırın başındaki işlem hattı karakteriyle işlem hatlarının devamı için destek ekler. Aşağıdaki örneklerde bu yeni işlevi nasıl kullanabileceğiniz gösterilmektedir.

# 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

Önemli

Kabukta etkileşimli çalışırken, kodu satırın başına işlem hatları ile yapıştırırken yalnızca yapıştırmak için Ctrl+V kullanılır. Yapıştırma işlemlerine sağ tıklayarak satırları birer birer ekleyin. Satır bir işlem hattı karakteriyle bitmeyecek olduğundan PowerShell girişin tamamlandığını kabul eder ve bu satırı girilmiş şekilde yürütür.

Ayrıca bkz.