2014-02-28 42 views
2

我想寫我的第一個腳本,但我有PowerShell的一些問題。Powershell回聲vs寫主機和不同的輸出

我使用下面的代碼:

$Disk = Get-Disk | Where-Object {$_.Path -match "USBSTOR" -and $_.Size -gt 20Gb -and $_.Size -lt 200Gb -and -not $_.IsBoot } 

我想不通爲什麼

PS C:\> echo $disk 
Number Friendly Name       OperationalStatus     Total Size Partition Style 
------ -------------       -----------------     ---------- --------------- 
1  Imation IronKey Wkspace USB Device  Online         59.63 GB MBR 

PS C:\> write-host $disk 
MSFT_Disk (ObjectId = "\\?\usbstor#disk&ven_imation&prod_ironk...) 

更復雜的是,以下PowerShell腳本:

$Disk = Get-Disk | Where-Object {$_.Path -match "USBSTOR" -and $_.Size -gt 20Gb -and $_.Size -lt 200Gb -and -not $_.IsBoot } 
$WIM = Get-PSDrive -PSProvider FileSystem | Where { Test-Path (join-path $_.Root "\sources\install.wim") } 
echo $Disk 
echo $WIM 
Write-Host $WIM 
Write-Host $Disk 

,然後改變回聲的順序和寫入我得到不同的輸出

有人能解釋這是怎麼回事?

回答

7

在PowerShell中,echo映射到Write-Output而不是寫主機。如果你想輸出某些操作產生的對象,你應該輸出它們而不是試圖Write-Host。通過Write-Host編寫的內容不會將其輸出到輸出流,因此您無法(例如)在隨後的調用或管道中使用它。

你看到那個令人討厭的亂碼輸出與Write-Host,因爲它試圖寫出整個對象,並不明白,你可能會喜歡一個漂亮的表格,並列出清晰的屬性。您需要預留Write-Host,因爲當您需要向用戶傳達一些您不介意被使用的簡單信息時,即使此時可能會有更好的替代方案,如Write-DebugWrite-Verbose

更多信息here

你總是可以通過調用HelpGet-Help小命令檢查這樣的映射:

PS C:\> help echo 

NAME 
    Write-Output 
+0

這有助於解釋的事情。但你能解釋爲什麼改變回聲的順序很重要嗎? 如果我在命令行上執行最終腳本,它按預期工作(兩個回聲都是表格)。如果我將它放在powershell腳本中,第一個回顯是表格,最後一個回顯是完整對象。如果我切換它們,輸出結果是相同的(表,對象)。 – user3365921

4

Write-Host小命令輸出到主機(即,的powershell或ISE窗口)。它接受一個對象作爲輸入,並簡單地調用該對象的.ToString()方法(或者如果它是一個數組它調用.ToString()或陣列的每個元素。

Write-Output或其別名echo簡單地寫入輸入對象到當前流水線。任何到達管線末端的對象都會從當前函數cmdlet或腳本返回(如果有的話),然後它們可能會繼續沿着其他管線向下。最終,對象可能會到達管道的末端,而不是在函數內部,cmdlet或腳本,看起來它們被輸出到主機,實際發生的情況是,在最外面的管道的末端,所有對象都被髮送到一個額外的隱藏cmdlet:

Out-Default將對象發送給默認格式化程序,然後發送默認輸出cmdlet。這是默認的格式化你的磁盤對象轉換成一堆FormatStartDataGroupStartDataFormatEntryDataGroupEndDataFormatEndData對象(管像Format-Table輸出到Get-Member看這些對象)。最後,格式化對象被髮送到主機以產生格式化輸出。

如果你想有點好玩嘗試重新定義Out-Default所以你可以看到它被稱爲:

PS C:\scripts> function Out-Default { 
>> Write-Verbose "Called Out-Default" -Verbose 
>> $input | Format-Table | Out-Host 
>> } 
>> 
PS C:\scripts> cd mod2 
VERBOSE: Called Out-Default 
PS C:\scripts\mod2> ls 
VERBOSE: Called Out-Default 


    Directory: C:\scripts\mod2 


Mode    LastWriteTime  Length Name 
----    -------------  ------ ---- 
-a---  29/12/2013  11:00  308 1Var.ps1 
-a---  29/12/2013  11:00  326 2Quotes.ps1 
-a---  29/12/2013  11:00  416 3ObjectMembers.ps1 
-a---  29/12/2013  11:00  665 4Parenthesis.ps1 
-a---  29/12/2013  11:00  392 5If.ps1 
-a---  29/12/2013  11:00  325 6Switch.ps1 
-a---  29/12/2013  11:00  226 7Do_While.ps1 
-a---  29/12/2013  11:00  272 8For_Foreach.ps1 
-a---  29/12/2013  11:00  150 _Startup.ps1