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
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-date; Get-ADPrincipalGroupMembership username | Select-Object name
Format-List for all output following Get-Date, which explains the each-property-on-its-own line output from the Get-ADPrincipalGroupMembership ... command.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 output instances of type [pscustomobject], which, due to their having just 1 property in this case, locked in tabular display, i.e., implicit use of Format-Table, with the selected property as the only column, i.e., just Name here. Since the [datetime] type output by Get-Date doesn't have a Name property, Get-Date's output was effectively invisible.Read on for background information and the complete rules.
PowerShell's default display formatting is optimized for objects of the same type, as that is the typical case.
If a pipeline contains a mix of types, the specific formatting that results by default depends on:
See the next section for details.
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
Caveat: The output from Format-* cmdlets are formatting instructions rather than the original data, which makes this output unsuitable for further programmatic processing.
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:
.ToString() representation is output.Format-Table; 5 or more? -> Format-List.Note: Primitive is used loosely here to refer to:
$true, namely [Boolean], [Byte], [SByte], [Int16], [UInt16], [Int32], [UInt32], [Int64], [UInt64], [IntPtr], [UIntPtr], [Char], [Double], [Single][decimal], [bigint], [string] and [securestring]If all objects in a pipeline are of the same type, the above by definition applies to all of them.
By contrast, if there is a mix of types in the pipeline, the following logic applies:
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 or 3.0 or hi; 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 or Format-List, so will all remaining non-primitive objects.Format-Custom (e.g, in the case of Get-Date, via predefined formatting), it is Format-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.
Format-Table results in asynchronous behavior that may be surprising; see this answer.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.