Not: Sorudaki komut Start-Process, hedef programın çıktısının doğrudan yakalanmasını önleyen kullanır . Genel olarak, konsol uygulamalarını eşzamanlı olarak yürütmek için kullanmayın Start-Process- yalnızca herhangi bir kabukta olduğu gibi doğrudan çağırın . Bunu yapmak, uygulamayı çağrı konsolunun standart akışlarına bağlı tutar ve çıktısının $output = netdom ...aşağıda açıklandığı gibi basit atamayla yakalanmasını sağlar .
Temel olarak , harici yardımcı programlardan çıktı yakalamak , PowerShell yerel komutlarıyla aynı şekilde çalışır ( harici araçların nasıl yürütüleceği hakkında bir tazeleme isteyebilirsiniz):
$cmdOutput = <command> # captures the command's success stream / stdout
Harici bir program durumunda , programın çıktı satırlarını içeren bir dize dizisi anlamına gelen 1'den fazla çıktı nesnesi üretiyorsa bir nesne dizisi$cmdOutput aldığını unutmayın .
Her zaman tek - potansiyel olarak çok satırlı - bir dize almak istiyorsanız ,<command>
$cmdOutput
$cmdOutput = <command> | Out-String
To yakalama bir değişkene çıktı ve ekrana yazdırmak :
<command> | Tee-Object -Variable cmdOutput # Note how the var name is NOT $-prefixed
Veya, <command>bir cmdlet veya gelişmiş işlevse , ortak parametre
-OutVariable/-ov kullanabilirsiniz :
<command> -OutVariable cmdOutput # cmdlets and advanced functions only
İle unutmayın -OutVariablediğer senaryolarda, aksine $cmdOutputolan her zaman bir koleksiyon sadece bile, bir nesne çıkıştır. Özellikle, dizi benzeri [System.Collections.ArrayList]türün bir örneği döndürülür. Bu tutarsızlığın tartışılması için bu GitHub sorununa
bakın .
Çıktısını yakalamak için birden fazla komutları , kullanıcı ya bir alt-ifade ( $(...)) veya (a komut blok çağrı { ... }ile) &ya da .:
$cmdOutput = $(<command>; ...) # subexpression
$cmdOutput = & {<command>; ...} # script block with & - creates child scope for vars.
$cmdOutput = . {<command>; ...} # script block with . - no child scope
Not olduğu ile önek genel ihtiyaç &(çağrı operatörü) Adını bireysel komuta / yol olduğunu alıntılanan - örneğin $cmdOutput = & 'netdom.exe' ...- se başına dış programlarla ilgili değildir (eşit PowerShell komut dosyaları için de geçerlidir), ama bir sözdizimi gereksinimi : PowerShell varsayılan olarak ifade modunda alıntılanmış bir dize ile başlayan bir ifadeyi ayrıştırırken , komutları (cmdlet'ler, harici programlar, fonksiyonlar, takma adlar) çağırmak için argüman modu gereklidir &.
Arasındaki temel fark, $(...)ve & { ... }/ . { ... }olduğu önceki toplar bellekte tüm giriş , bir bütün olarak dönmeden önce, ikincisi ise akımı tek-tek boru hattı işleme için uygun çıkış.
Yönlendirmeler de temelde aynı şekilde çalışır (ancak aşağıdaki uyarılara bakın):
$cmdOutput = <command> 2>&1 # redirect error stream (2) to success stream (1)
Ancak, harici komutlar için aşağıdakilerin beklendiği gibi çalışması daha olasıdır:
$cmdOutput = cmd /c <command> '2>&1' # Let cmd.exe handle redirection - see below.
Harici programlara özgü hususlar :
Harici programlar , çünkü PowerShell'in tip sistemi dışında çalıştıklarından, sadece başarı akışları (stdout) aracılığıyla dizeleri döndürürler .
Çıktı içeriyorsa 1'den fazla satır bir içine varsayılan bölünme yoluyla, PowerShell dizinin dizeleri . Daha doğrusu, çıktı satırları [System.Object[]]elemanları dizgiler ( [System.String]) olan bir tür dizide saklanır .
Eğer varsa çıkış bir olmak istiyorum tek potansiyel çok satırlı dize , boru içinOut-String :
$cmdOutput = <command> | Out-String
Stderr'ı2>&1 başarı akışının bir parçası olarak yakalamak için stdout'a yönlendirmek uyarılarla birlikte gelir :
Yapmak için 2>&1birleştirme stdout ve stderr kaynağında , let cmd.exeyönlendirmeyi işlemek aşağıdaki deyimleri kullanarak,:
$cmdOutput = cmd /c <command> '2>&1' # *array* of strings (typically)
$cmdOutput = cmd /c <command> '2>&1' | Out-String # single string
cmd /ccmd.exekomut ile çağırır <command>ve <command>bittikten sonra çıkar .
- Yeniden
2>&1yönlendirmenin cmd.exePowerShell tarafından yorumlanmak yerine iletilmesini sağlayan tek tırnak işaretlerini not alın .
Karıştığı unutmayın cmd.exearacı olduğunu onun karakterleri kaçan ve çevre değişkenleri genişletmek için kurallar PowerShell kendi şartlara ek olarak, varsayılan olarak, devreye giriyor; Eğer özel parametresini kullanabilirsiniz + PS v3 içinde --%(sözde durma-ayrıştırma sembolü PowerShell tarafından kalan parametrelerin yorumlanması kapatmak için) için hariç cmd.exegibi tarzı çevre değişken referanslar %PATH%.
Stdout ve stderr'ı bu yaklaşımla kaynağında birleştirdiğiniz için PowerShell'de stdout kaynaklı ve stderr kaynaklı satırları ayırt edemeyeceğinizi unutmayın ; bu ayrıma ihtiyacınız varsa, PowerShell'in kendi 2>&1yönlendirmesini kullanın - aşağıya bakın.
Hangi akışların hangi akıştan geldiğini bilmek için PowerShell 2>&1 yönlendirmesini kullanın :
Standart hataya çıkış olarak tespit edilir hata kayıtları ( [System.Management.Automation.ErrorRecord]böylece,), dize çıkış dizisi içerebilir karışımı içinde dizeleri (a stdout'u çizgisini temsil eden her bir dize) hata kaydı (bir şekilde hataları temsil eden her kaydı) . İstendiği gibi 2>&1, hem dizelerin hem de hata kayıtlarının PowerShell'in başarı çıktı akışı yoluyla alındığını unutmayın ).
Konsolda, hata kayıtları yazdırmak kırmızı ve 1 varsayılan olarak tek üretir çok satırlı bir cmdlet dışı sonlandırma hatası görüntüler edeceğini aynı biçimde, ekran; sonraki hata kayıtları yanı kırmızı yazdırmak, fakat sadece kendi hata yazdırmak mesajı bir üzerine, tek hat .
Çıkarılırken konsola , dizeleri tipik gel ilk neyse ki, ( "aynı anda" stdout / stderr çıkış satırı bir toplu arasından en az) hata kayıtları, ardından çıkış dizisinde, ama ne zaman yakalamak çıktı , olmadan alacağınız aynı çıkış sırasını kullanarak düzgün bir şekilde serpiştirilir2>&1 ; diğer bir deyişle: konsola çıktı alınırken , yakalanan çıktı harici komut tarafından stdout ve stderr satırlarının oluşturulma sırasını GÖSTERMEZ.
Eğer varsa bir bütün çıkış yakalamak tek ile dizeOut-String , PowerShell katacak fazladan satırlar bir hata kaydının dize gösterimi söz konusu lokasyon (gibi ekstra bilgiler içerdiğinden, At line:...) ve kategori ( + CategoryInfo ...); merakla, bu sadece ilk hata kaydı için geçerlidir .
- Bu sorunu gidermek için, geçerli
.ToString()yerine Borulama her çıkış nesnesine yöntemi Out-String:
$cmdOutput = <command> 2>&1 | % { $_.ToString() };
PS v3 + 'da şunları basitleştirebilirsiniz:
$cmdOutput = <command> 2>&1 | % ToString
(Bonus olarak, çıktı yakalanmazsa, konsola yazdırırken bile düzgün aralıklı çıktı üretir.)
Alternatif olarak, hata kayıtları filtrelemek dışarı ile PowerShell hatası akışına gönderebilirsinizWrite-Error (çıkış yakalanan değilse konsola yazdırırken prim olarak, bu bile düzgün serpiştirilmiş çıktı üretir):
$cmdOutput = <command> 2>&1 | ForEach-Object {
if ($_ -is [System.Management.Automation.ErrorRecord]) {
Write-Error $_
} else {
$_
}
}
Start-Process- sadece herhangi bir kabukta olduğu gibi doğrudan çağırın ; zekâ etmeknetdom /verify $pc /domain:hosp.uhhg.org. Bunu yapmak, uygulamayı çağrı konsolunun standart akışlarına bağlı tutar ve çıktısının basit atama ile yakalanmasını sağlar$output = netdom .... Aşağıda verilen cevapların çoğuStart-Processdolaysız olarak doğrudan icra lehine vazgeçmiştir .