在一行中运行两个PowerShell命令时,为什么更改了输出格式? [英] Why is the output format changed when running two PowerShell commands in one line?
问题描述
执行两个以分号分隔的PowerShell命令时,我得到了意外的结果.第二个命令的输出更改.如果以相反的顺序运行它们,则看不到第二个命令输出.
I'm getting unexpected results when executing two PowerShell commands separated by a semicolon. The output of the second command changes. If I run them in reverse order, I don't see the second command output.
在这里,我只是想获得一个时间戳和一个用户属于AD的组列表(单行).
Here I'm simply trying to get a time stamp and a list of groups a user belongs to in AD, as a one-liner.
如果我运行此行,则会得到以下输出:
If I run this line, i get the following output:
Get-ADPrincipalGroupMembership username | Select-Object name
name
----
Domain Users
CL-Inventory-Group
...
但是,如果我运行以下命令,此行为将发生变化:
However if I run the following, this behavior changes:
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,则列出组之后,日期戳永远不会显示.
Stranger yet, If i run the in reverse, meaning i say get-date after the first command, the date stamp never shows up after the groups are listed.
我不正确地分隔命令吗?
Am I improperly separating commands?
推荐答案
tl; dr :
在提示符下(交互地)提交多个;
分隔的命令仍将其输出发送到单个管道(您可以将提交的每个命令行都视为隐式脚本)文件).
Submitting multiple ;
-separated commands at the prompt (interactively) still sends their output to a single pipeline (you can think of each command line submitted as an implicit script file).
简而言之:在您的情况下,第一个命令输出的自动显示格式也确定了第二个命令的显示格式,因此哪个命令最重要
In short: in your case, the first command output's automatic display formatting also determined the display formatting for the 2nd command, so which command comes first matters:
-
获取日期;Get-ADPrincipalGroupMembership用户名|选择对象名称
- 锁定了
Get-Date
之后所有输出的Format-List
隐式使用,这解释了Get-ADPrincipalGroupMembership ...
命令.
- locked in implicit use of
Format-List
for all output followingGet-Date
, which explains the each-property-on-its-own line output from theGet-ADPrincipalGroupMembership ...
command.
如果我执行相反的操作,这意味着我在第一个命令后说了get-date,则列出组之后,日期戳永远不会显示.
If i run the reverse, meaning i say get-date after the first command, the date stamp never shows up after the groups are listed.
- 类型为
-
Select-Object
输出实例,由于在这种情况下它们只有1个属性,因此它们被锁定在表格显示,即隐式使用Format-Table
,,并将所选属性作为唯一列,即此处只是Name
.由于Get-Date
输出的[datetime]
类型没有Name
属性,因此Get-Date
的输出实际上是 invisible . Select-Object
output instances of type[pscustomobject]
, which, due to their having just 1 property in this case, locked in tabular display, i.e., implicit use ofFormat-Table
, with the selected property as the only column, i.e., justName
here. Since the[datetime]
type output byGet-Date
doesn't have aName
property,Get-Date
's output was effectively invisible.- 管道中对象的 order
- 及其默认格式设置行为
[pscustomobject]
的
请继续阅读以获取背景信息和完整规则.
Read on for background information and the complete rules.
PowerShell的默认显示格式已针对相同类型的对象进行了优化,这是典型的情况.
PowerShell's default display formatting is optimized for objects of the same type, as that is the typical case.
如果管道包含类型的 mix ,则默认情况下产生的特定格式取决于:
If a pipeline contains a mix of types, the specific formatting that results by default depends on:
有关详细信息,请参见下一部分.
See the next section for details.
您可以使用显式的 Format-*
调用来控制格式;您可以在第二个命令上使用 Format-Table
强制表格输出:
You can use explicit Format-*
calls to control the formatting; in your case, you can use Format-Table
on your 2nd command to force tabular output:
Get-Date; Get-ADPrincipalGroupMembership username | Select name | Format-Table
注意事项: Format-*
cmdlet 的输出是格式化说明,而不是原始数据,使此输出不适合进行进一步的程序处理 .
Caveat: The output from Format-*
cmdlets are formatting instructions rather than the original data, which makes this output unsuitable for further programmatic processing.
在没有显式格式命令( Format-Table
, Format-List
,...)的情况下, PowerShell自动选择合适的显示格式,基于给定对象的 type :
In the absence of explicit formatting commands (Format-Table
, Format-List
, ...), PowerShell automatically chooses a suitable display format, based on a given object's type:
- If present for a given type, PowerShell uses predefined formatting instructions (see
Get-Help about_Format.ps1xml
) - In their absence:
- If the type is a primitive type (see below): the object's
.ToString()
representation is output. - Otherwise: the format style is chosen based on the following simple rules: 4 or fewer properties? ->
Format-Table
; 5 or more? ->Format-List
.
注意:原始在这里是宽松地指的是:
Note: Primitive is used loosely here to refer to:
- 所有原始CLR类型-
.IsPrimitive
返回$ true
,即
[Boolean]
,[Byte]
,[SByte]
,[Int16]
,[UInt16]
,[Int32]
,[UInt32]
,[Int64]
,[UInt64]
,[IntPtr]
,[UIntPtr]
,[Char]
,[Double]
,[Single]
- 类型
[decimal]
,[bigint]
,[string]
和[securestring]
- 任何其他无属性类型.
- all primitive CLR types - those for which
.IsPrimitive
returns$true
, namely[Boolean]
,[Byte]
,[SByte]
,[Int16]
,[UInt16]
,[Int32]
,[UInt32]
,[Int64]
,[UInt64]
,[IntPtr]
,[UIntPtr]
,[Char]
,[Double]
,[Single]
- types
[decimal]
,[bigint]
,[string]
and[securestring]
- any other property-less types.
如果管道中的所有对象都属于同一类型,则上述按定义适用于所有对象.
If all objects in a pipeline are of the same type, the above by definition applies to all of them.
相反,如果管道中存在类型的 mix ,则适用以下逻辑:
By contrast, if there is a mix of types in the pipeline, the following logic applies:
-
任何原始类型总是的实例都打印相同的,即表示它们是单个值(不是通过调用对象的
.ToString()
方法获得的具有属性的对象( );例如12
或3.0
或hi
;基本类型与管道中后续对象的格式无关.
Any instances of primitive types always print the same, namely as a representation of the single value that they are (not an as an object with properties), obtained via a call to their
.ToString()
method; e.g.,12
or3.0
orhi
; primitive types have no bearing on the formatting of subsequent objects in the pipeline.
管道中的第一个非原始对象:
The first non-primitive object in the pipeline:
-
本身是根据其预定义的格式说明或上述默认规则(基于属性的数量)进行打印的.
is itself printed based on either its predefined formatting instructions or the default rules stated above (based on the number of properties).
锁定所有剩余的非原始对象的格式样式-列表还是表-:
locks in the format style - list vs. table - for all remaining non-primitive objects:
- 如果对象本身隐式使用
Format-Table
或Format-List
,则所有其余非原始对象也将使用. - 如果对象隐式使用
Format-Custom
(例如,对于Get-Date
,通过预定义格式),则为Format-List
已锁定.
- If the object itself implicitly uses
Format-Table
orFormat-List
, so will all remaining non-primitive objects. - If the object implicitly uses
Format-Custom
(e.g, in the case ofGet-Date
, via predefined formatting), it isFormat-List
that is locked in.
所有随后的非原始对象都将使用锁定的格式样式.
All subsequent non-primitive objects then use the locked-in format style.
Caveat: If
Format-Table
is locked in, the first non-primitive object alone determines the set of properties displayed as table columns, which can cause subsequent objects to seemingly disappear if they don't have these properties - such objects are still in the output stream, however, they're just not displayed - see this answer for a demonstration.
- 附带说明:自PSv5起,
Format-Table
的隐式使用会导致异步行为,这可能令人惊讶.参见此答案.
- On a side note: Since PSv5, implicit use of
Format-Table
results in asynchronous behavior that may be surprising; see this answer.
如果锁定的是
Format-List
,则不会丢失任何信息,因为每个对象的属性随后都会单独列出行.If it is
Format-List
that is locked in, no information is "lost", as each object's properties are then listed individually, on their own lines.这篇关于在一行中运行两个PowerShell命令时,为什么更改了输出格式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- If the type is a primitive type (see below): the object's