我遇到了PowerShell脚本的问题我失去了"输出到控制台或被重定向的输出。经过大量的工作后,我将其简化为一个容易记录的问题示例。
将以下单行放在脚本(test1.ps1)中,并从基本的PowerShell命令窗口调用它:
Get-WmiObject win32_share | select name, path
您可能会得到两列类似于以下内容的输出:
PS C:\Users\me\temp> ./test1.ps1
name path
---- ----
ADMIN$ C:\Windows
C$ C:\
IPC$
Users C:\Users
但是现在,像这样创建一个两行脚本(test2.ps1),并以相同的方式运行它:
Get-WmiObject win32_share | select name
Get-WmiObject win32_share | select name, path
并观察输出是否被破坏:
PS C:\Users\me\temp> ./test2.ps1
name
----
ADMIN$
C$
IPC$
Users
ADMIN$
C$
IPC$
Users
这两个命令实际上是在运行,但是第二个调用得到了"压缩"进入第一个输出。它失去了第二列,它的标题和间距。
这似乎是"第一个"输出不正确"关闭",因为如果第二行输入另一个选择语句,它似乎并不重要。
顺便说一下,我的原始线条看起来更像是这样:
Get-WmiObject win32_share | select name, path | Write-Output
Get-WmiObject win32_share | select name | Write-Output
因此,在powershell提示符下,我可以使用重定向将输出定向到我想要的地方
PS C:\Users\me\temp\> ./test2.ps1 > ./outfile.txt
如上所述,实际情况比这更完整,但在这一点上,我只是想了解正在发生的事情。
错误?或者我不理解?
答案 0 :(得分:1)
Get-WmiObject win32_share | select name | ft
Get-WmiObject win32_share | select name, path | ft
Get-WmiObject win32_share | ft name
Get-WmiObject win32_share | ft name, path
答案 1 :(得分:1)
link from mjolinor更详细地解释了它,但PowerShell正在尝试将输出组合在一起。来自帖子的重要一行说明:
如果第一个Object有2个属性,即使流中的所有其他对象都有10个属性,您也会获得2列表。
在以下示例中
Get-WmiObject win32_share | select name
Get-WmiObject win32_share | select name, path
当seconds命令运行时,前一个输出没有该属性,因此PowerShell,更具体地说Out-Default
将其丢弃在输出中,以使所有输出同步。
我会更好奇你真正的代码是什么造成了这个问题。与expirat001类似,您可以将输出转换为字符串,这不会发生,因为它们不再是对象。小心这样做,因为你可以这样丢失原始对象。无论哪种方式,数据都不会丢失。只是没有按照你期望的方式展示。
回顾前面的例子,我们可以假装第一行没有路径属性。无论如何从select
调用它只会创建空列但允许显示其他输出。
# In this next command "path" is not a valid property but PowerShell will create the column anyway
Get-WmiObject win32_share | select name, path
Get-WmiObject win32_share | select name, path
这是作弊但您可以将其中一个命令发送到不同的输出流。
Get-WmiObject win32_share | select name
Get-WmiObject win32_share | select name, path | Out-Host
答案 2 :(得分:1)
link from mjolinor确实解释了很多,这里的主要问题是您通过& ./test2.ps1
启动脚本,此命令的输出通过管道输入{{1 }}。反过来,Out-Default
会看到由Out-Default
cmdlet生成的一组PSObject
,并检查第一个对象(这是Select-Object
返回的第一个对象)它看到它只有一个属性“name”,然后从结果对象中格式化一个表,只收集所有属性中的Get-WmiObject win32_share | select name
属性。
要规避,请使用name
或ft
cmdlet将每行的输出转换为Format-Table
s而不是String
s的序列,这样当脚本的时候输出将通过管道输入PSObject
,它将通过未处理的字符串传递字符串。