Reputation: 139
my $PSVersionTable output is as follows:
Name Value
---- -----
PSVersion 7.0.1
PSEdition Core
GitCommitId 7.0.1
OS Microsoft Windows 10.0.19041
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
If I enter
wsl -l | Get-Member
the output informs me that the output type is a String.
If I enter
(wsl -l).GetType()
the output informs me that the output type is Array.
The entire reason I'm looking at this is that I was trying to parse the output of that command and for a long, frustrating time, I was thinking that I was working with a single, contiguous string with embedded carriage return / line feeds, but it appears I'm actually working with an array of strings.
So my question: what do the parentheses around the command do to seemingly change the nature of the output of the executable? Is it that without the parentheses the output from 'wsl -l' is being streamed to Get-Member one line (array element) at a time?
Thank you!
Upvotes: 1
Views: 134
Reputation: 439647
If you want to use Get-Member
to inspect an object as-is, you mustn't use the pipeline, because the pipeline enumerates objects that are collection-like, and Get-Member
then reports the (distinct set of) types among the elements of the collection.
Instead, use Get-Member -InputObject
, which reports on collections as a whole:
Get-Member -InputObject (wsl -l) # -> shows the members of type System.Object[]
PowerShell streams the stdout output from external programs such as wsl
, line by line. That is, it sends each line as it is being received to the pipeline.
If you assign the command's output to a variable or enclose the command in ()
, the grouping operator, the stream output is collected:
If there's only one output line, a (single) [string]
instance is returned.
If there are multiple output lines, PowerShell collects them in a regular, [object[]]
-typed array for you, whose elements are [string]
instances in this case.
If you want to avoid this ambiguity and ensure that the result is always an array, you can use @()
, the array-subexpression operator - @(wsl -l)
- or, on assigning to a variable, type-constrain that variable as an array - [array] $out = wsl -l
To get a single, potentially multi-line string representation of the output, use the -join
operator:
(wsl -l) -join "`n" # or use [Environment]::NewLine instead of "`n"
[Environment]::NewLine
returns the platform-appropriate newline char. / sequence (LF-only ("`n"
) on Unix, CRLF ("`r`n"
) on Windows). However, PowerShell happily accepts either form on all platforms.
Note:
Out-String
cmdlet would return a single, multi-line string too, it invariably adds a trailing newline. (If you were to use -NoNewLine
, it wouldn't use any newlines).If you're using PowerShell [Core] v6.2+, you can alternatively use the Join-String
cmdlet:
wsl -l | Join-String -Separator "`n"
Upvotes: 1