Theo has provided the crucial pointer in a comment:
(Get-ComputerInfo -Property $LST1 | Format-List | Out-String).Trim() |
Add-Content -Path $path -NoNewline
Let me elaborate:
To prevent leading and trailing empty lines in the output of Format-List
from showing up in a file via Out-File
/ >
, use Out-String
to create an in-memory string representation of the formatted output first,
which then allows you to apply .Trim()
to the resulting multi-line string in order to remove leading and trailing lines (whitespace in general) from Out-String
's output.
Since Out-String
itself renders the formatting instructions output by Format-List
, you can then use Set-Content
or Add-Content
to save / append the resulting string to a file.
The behavior of Out-String
:
Out-String
produces the same for-display representation that you get by default in the console - or via other Out-*
cmdlets, notably Out-File
/ >
- as a single, multi-line string by default.
While this representation may itself contain empty lines, as is typical, Out-String
additionally appends a trailing newline, even though there's no good reason to do so, as discussed in GitHub issue #14444.
In cases where you want to remove this extraneous trailing newline only, you can use the following approach, via the -replace
operator (the operation works with both Windows-style CRLF newlines (\r\n
) and Unix-style LF-only ones (\n
)):
(... | Out-String) -replace '\r?\n\z'
Or, less efficiently, using the -Stream
switch to output lines individually and then re-join them with newlines without a trailing one ("`n"
creates a LF-only newline, which PowerShell accepts interchangeably with CRLF newlines ("`r`n"
):
(... | Out-String -Stream) -join "`n"
Out-String
applied to output from external programs:
Out-String
can also be used to capture the lines output by external programs as a single, multi-line string (by default, PowerShell captures output line by line, resulting in an array of strings when captured in a variable).
However, this use of Out-String
is problematic:
There too the trailing newline that is appended can be a nuisance.
In Windows PowerShell there's an additional nuisance (which has since been corrected in PowerShell (Core) 7+): If you use a 2>&1
to merge stderr output into the success output stream, the first stderr line is formatted like a PowerShell error.
- Run
cmd /c 'echo yes & echo no >&2' 2>&1 | Out-String
to see the problem.
The following idiom avoids both problems (...
represents your external-program call):
$multiLineString = [string[]] (... 2>&1) -join "`n"
Note: The above uses a LF-only newline to join the array elements, which is usually sufficient. Use "`r`n"
for CRLF newlines or [Environment]::NewLine
for the OS-appropriate newline sequence.
Example:
The following cmd.exe
CLI call outputs both a stdout line and a stderr line, with 2>&1
on the PowerShell side merging the two into the success output stream.
PS> [string[]] (cmd /c 'echo yes & echo no >&2' 2>&1) -join "`n" |
ForEach-Object { "[$_]" } # just to visualize the string boundaries
[yes
no ]
Note: The trailing space after no
is owed to the unusual behavior of cmd.exe
's built-in echo
command: it includes the space before the >&2
redirection in its output.
(Get-ComputerInfo -Property $LST1 | Format-List | Out-String).Trim() | Add-Content -Path $path -NoNewline
– Homemaker