Aracılığıyla paylaş


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 dizi komuttır. 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 o çıktı başka bir komuta gönderilebilir. Sonuç, basit komutlardan oluşan karmaşık bir komut zinciri veya işlem hattı.

Mesela

Command-1 | Command-2 | Command-3

Bu örnekte, Command-1 tarafından yayılan nesneler Command-2'e gönderilir. Command-2 nesneleri işler ve 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.

Mesela

Get-Process notepad | Stop-Process

İlk komut, Not Defteri işlemini temsil eden bir nesne almak için Get-Process cmdlet'ini kullanır. İşlem nesnesini not defteri işlemini durduran | cmdlet'ine göndermek için işlem hattı işlecini (Stop-Process) kullanır. belirtilen işlem işlem hattı üzerinden gönderildiğinden, Stop-Process komutunun işlemi belirtmek için Adı veya Kimliği 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, bir Get cmdlet'inin sonuçlarını, aynı isme sahip başka bir cmdlet'e yönlendirebilirsiniz . Örneğin, Get-Service cmdlet'in çıkışını Start-Service veya Stop-Service cmdlet'lere 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 Get-Item veya Get-ChildItem çıkışını New-ItemProperty cmdlet'ine yöneltebilirsiniz. Bu örnek, MyCompany kayıt defteri anahtarına 8124değeriyle NoOfEmployeesyeni bir kayıt defteri girdisi ekler.

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

Get-Member, Where-Object, Sort-Object, Group-Objectve Measure-Object gibi yardı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 örnek, bilgisayardaki tüm süreçlerin, her süreçteki açık tanıtıcı sayısına göre nasıl sıralanabileceğini gösterir.

Get-Process | Sort-Object -Property Handles

nesneleri Format-List, Format-Table, Export-Clixml, Export-Csvve Out-Filegibi biçimlendirme, dışarı ve çıktı cmdlet'lerine aktarabilirsiniz.

Bu örnekte, bir işlem nesnesinin özelliklerinin listesini görüntülemek için Format-List cmdlet'inin 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 stdout 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

İşlem hattı uygulamasını desteklemek için, alıcı cmdlet'in işlem hattı girişini kabul eden bir parametresi olmalıdır. bir cmdlet'in işlem hattı girişini kabul eden parametrelerini belirlemek için Get-Help veya Parametre seçenekleriyle komutunu kullanın.

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

Get-Help Start-Service -Full

veya

Get-Help Start-Service -Parameter *

Start-Service cmdlet'ine yönelik 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

Start-Serviceiçin işlem hattı aracılığıyla nesneleri gönderdiğinizde PowerShell, nesneleri InputObject ve Name parametreleriyle ilişkilendirmeye çalışır.

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

Cmdlet parametreleri iki farklı yöntemden biriyle boru 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, üzerindeki Start-Service parametresi, işlem hattı girişini değer olarak kabul eder. Dizelere dönüştürülebilen dize nesnelerini veya nesneleri kabul edebilir.

  • ByPropertyName: Parametre, yalnızca giriş nesnesinde parametreyle aynı ada sahip bir özellik bulunduğunda girdiyi kabul eder.

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

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'i birçok parametreye sahiptir, ancak bunlardan yalnızca ikisi, Ad ve InputObject, işlem hattı girişini kabul eder. Adı parametresi dizeleri, InputObject parametresi ise hizmet nesnelerini alır. Bu nedenle dizelere, servis nesnelerine ve dize veya servis nesnelerine dönüştürülebilecek özelliklere sahip nesnelere iletim yapabilirsiniz.

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 İşlem Hattı Hatalarını Araştırma bakın.

Tek seferde işleme

Nesneleri bir komuta göndermek, komutun bir parametresini kullanarak nesneleri göndermeye benzer. 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 Format-Table parametresini 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

Veya komutunu InputObject parametresine 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 IEnumerable arabirimini veya bunun genel eşdeğerini uygulayan her türü otomatik olarak listeler. Numaralandırılmış öğeler işlem hattı üzerinden birer birer gönderilir. PowerShell ayrıca System.Data.DataTable türlerini Rows özelliği aracılığıyla numaralandırır.

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

  • Karma tablolar, arabirimini veya onun genel karşılıklarını uygulayan türler ve System.Xml.XmlNode türlerini için yöntemini çağırmanız gerekir.
  • System.String sınıfı IEnumerableuygular, 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 Measure-Object cmdlet'ine iletilir. Dizinin birden çok üyesi vardır ve karma tablo birden çok anahtar-değer çifti içerir. Yalnızca dizi birer birer 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, Get-Process cmdlet'inden Get-Member cmdlet'ine birden çok işlem nesnesi gönderirseniz, PowerShell her işlem nesnesini tek tek 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, parametresindeki Get-Member kullanıldığında, Get-Member, tek bir birim halinde System.Diagnostics.Process nesnelerinin bir dizisini alır. Bir nesne dizisinin özelliklerini görüntüler. (System.Object tür adından sonra dizi simgesini () not edin.)

Mesela

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.

Mesela

(Get-Process).Count

Çok önemli olan, işlem hattına gönderilen nesnelerin birer birer teslim edildiğini unutmamaktır.

İşlem hattında yerel komutları kullanma

PowerShell, işlem hattına yerel dış komutlar eklemenize olanak tanır.

PowerShell 7.4'ten önce ham bayt verileri veren yerel bir programdan gelen çıkışın borulanması veya yeniden yönlendirilmesi, çıkışı .NET dizelerine dönüştürdü. Bu dönüştürme ham veri çıkışının bozulmasına neden oldu.

PowerShell 7.4 veya üzeri sürümlerde PSNativeCommandPreserveBytePipe deneysel özellik temel özelliktir. Bu özellik, yerel bir komutun stdout akışını bir dosyaya yeniden yönlendirirken veya bayt akışı verilerini yerel komutun stdin akışına yönlendirirken bayt akışı verilerini korur.

Örneğin, curl yerel komutunu kullanarak yeniden yönlendirme kullanarak ikili bir dosya indirebilir ve 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 curlkullanarak sıkıştırılmış bir TAR dosyası indirilir. İndirilen dosya verileri, arşiv içeriğini ayıklamak için tar komutuna akışla aktarılır.

# 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 örneklerde, önceki örnekle aynı TAR dosyasını indirmek için Invoke-WebRequest kullanılır.

# 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 çıktısını stdout'e 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'i hedef yolu alır ve ardından Move-ItemProperty cmdlet'ine iletilir. Move-ItemProperty komutu, taşınacak kayıt defteri girdisinin 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 Trace-Command cmdlet'ini 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ı konsolda görüntüler ve FilePath parametresi izleme sonuçlarını daha sonra başvurmak üzere debug.txt dosyasına 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, Get-Item cmdlet'ine bağlı olan değerleri ve ardından Move-ItemProperty cmdlet'ine 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 Move-ItemProperty parametresine 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
...

Get-Help parametresinin ö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 ismine göre' işlem hattı girişi aldığını gösterir. Bu nedenle, kanallı nesnenin Hedefadlı bir özelliği olmalıdır.

Get-Membergelen nesnenin özelliklerini görmek için Get-Item kullanın.

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

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

Yolu parametresi, isme veya değere göre işlem hattı girdisini 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, Move-ItemProperty cmdlet'inde hedefi belirtmeli ve taşımak istediğimiz öğenin Get-Item almak için kullanmalıyız.

Mesela

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 boru hattı karakteri ile boru hatlarının devam etmesini desteklemektedir. 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 bakınız