我正在尝试编写我的第一个脚本,但我遇到了一些PowerShell问题。
我使用以下代码:
$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
然后改变回声的顺序并写入我得到不同的输出
有人可以解释发生了什么吗?
答案 0 :(得分:7)
在PowerShell中,echo
映射到Write-Output而不是Write-Host。如果要输出某些操作产生的对象,则应输出它们而不是尝试Write-Host
。通过Write-Host
写入的内容不会进入输出流,因此您不能(例如)在后续调用或管道中使用它。
你看到那个令人讨厌的乱码输出Write-Host
,因为它试图写出整个对象,并且不明白你可能更喜欢一个包含干净列出属性的漂亮表。当您需要向用户传达一些您不介意被消费的简单信息时,您应保留Write-Host
,即使这样,也可能有更好的替代方案,如Write-Debug或Write-Verbose。
更多信息here。
您可以通过使用Help
或Get-Help
调用cmdlet来检查这样的映射:
PS C:\> help echo
NAME
Write-Output
答案 1 :(得分:5)
Write-Host
cmdlet输出到主机(即powershell或ISE窗口)。它接受一个对象作为输入,并简单地调用对象的.ToString()
方法(或者如果它是一个数组,它调用.ToString()
或数组的每个元素。
Write-Output
或其别名echo
只是将输入对象写入当前管道。然后,从当前函数,cmdlet或脚本返回到达管道末端的任何对象(如果有的话)(然后它们可以继续沿着某个其他管道继续)。最终,对象可能会到达不在函数,cmdlet或脚本内部的管道的末尾,并且它们似乎会输出到主机。实际发生的是,在最外层管道的末尾,所有对象都被发送到一个额外的隐藏cmdlet:Out-Default
。
Out-Default
将对象发送到默认格式化程序,然后发送默认输出cmdlet。它是默认的格式化程序,可将您的磁盘对象转换为一堆FormatStartData
,GroupStartData
,FormatEntryData
,GroupEndData
和FormatEndData
个对象(管道输出像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