执行两个以分号分隔的PowerShell命令时,我得到了意外的结果。第二个命令的输出更改。如果以相反的顺序运行它们,则看不到第二个命令输出。
在这里,我只是想获得一个时间戳和一个用户属于AD的组列表(单行)。
如果我运行此行,则会得到以下输出:
Get-ADPrincipalGroupMembership username | Select-Object name
name
----
Domain Users
CL-Inventory-Group
...
但是,如果我运行以下命令,此行为将发生变化:
get-date; Get-ADPrincipalGroupMembership username | Select-Object name
Wednesday, April 3, 2019 2:31:35 PM
name : Domain Users
name : CL-Inventory-Group
...
还很陌生,如果我以相反的方式运行,这意味着我在第一个命令后说了get-date,则列出组之后,日期戳永远不会显示。
我不正确地分隔命令吗?
答案 0 :(得分:3)
当Powershell控制台格式化程序看到多种类型的对象时,它将默认为根据第一个元素输出进行输出。对于Date
,它作为列表输出,对于Select-Object
中的自定义对象输出,它是一个表。输出的格式设置取决于对象本身的类型(请参阅帮助About Format.ps1xml)。您可以使用Select-Object
将Format-Table
的输出强制为表格:
get-date; Get-ADPrincipalGroupMembership username | Select-Object name | Format-Table
答案 1 :(得分:3)
tl;博士:
在提示符下(交互地)提交多个;
分隔的命令仍会将其输出发送到单个管道(您可以将每个命令行视为一个隐式脚本文件提交)。
简而言之:在您的情况下,第一个命令输出的自动显示格式也确定了第二个命令的显示格式,因此哪个命令最重要:
get-date; Get-ADPrincipalGroupMembership username | Select-Object name
Format-List
之后的所有输出,都隐式地使用Get-Date
,这解释了Get-ADPrincipalGroupMembership ...
命令输出的每个属性行。如果我执行相反的操作,这意味着我在第一个命令后说了get-date,则列出组之后,日期戳永远不会显示。
Select-Object
类型为[pscustomobject]
的输出实例,由于在这种情况下仅具有1个属性,因此它们被锁定在 tabular 显示中,即隐式使用{{ 1}},具有选定的属性作为唯一列,即此处为Format-Table
。由于Name
输出的[datetime]
类型没有Get-Date
属性,因此Name
的输出实际上是 invisible 。请继续阅读以获取背景信息和完整规则。
PowerShell的默认显示格式已针对相同类型的对象进行了优化,这是典型的情况。
如果管道包含类型的 mix ,则默认情况下产生的特定格式取决于:
有关详细信息,请参见下一节。
您可以使用明确的Get-Date
调用来控制格式;您可以在第二个命令上使用Format-*
来强制以表格形式输出:
Format-Table
注意事项:来自Get-Date; Get-ADPrincipalGroupMembership username | Select name | Format-Table
cmdlet 的输出是格式化说明,而不是原始数据,因此该输出不适合进一步的程序处理 。
在没有显式格式命令(Format-*
,Format-Table
,...)的情况下, PowerShell根据给定的条件自动选择合适的显示格式,对象的类型:
Get-Help about_Format.ps1xml
)Format-List
表示形式。.ToString()
; 5个或更多? -> Format-Table
。注意:原始在这里被宽松地指代:
.IsPrimitive
返回Format-List
的那些类型,即$true
,[Boolean]
,[Byte]
,{{1} },[SByte]
,[Int16]
,[UInt16]
,[Int32]
,[UInt32]
,[Int64]
,[UInt64]
,[IntPtr]
, [UIntPtr]
,[Char]
[Double]
,[Single]
,[decimal]
和[bigint]
如果管道中的所有对象都属于同一类型,则上述按定义适用于所有对象。
相反,如果管道中存在类型的 mix ,则适用以下逻辑:
任何原始类型的实例总是都打印相同的,即表示它们是单个值(不是通过调用其[string]
方法获得的具有属性的对象 );例如[securestring]
或.ToString()
或12
;基本类型与管道中后续对象的格式无关。
管道中的第一个非原始对象:
本身是根据其预定义的格式说明或上述默认规则(基于属性的数量)进行打印的。
锁定所有剩余的非原始对象的格式样式-列表与表格:
3.0
或hi
,那么所有其余非原始对象也将使用。Format-Table
(例如,对于Format-List
,通过预定义格式),则锁定的是Format-Custom
。所有随后的非原始对象都将使用锁定的格式样式。
注意事项:如果锁定了 Get-Date
,则第一个非原始对象 确定属性集显示为表格列,如果它们没有这些属性,则可能会导致后续对象似乎消失 -这些对象仍在输出流中,但是,它们没有显示 -请参见this answer进行演示。
Format-List
的隐式使用会导致异步行为,这可能令人惊讶。参见this answer。 如果锁定的是Format-Table
,则不会丢失任何信息,因为每个对象的属性随后会在其各自的行中分别列出。