6

This code adds lines, even when using "-NoNewline"

$LST1="OsName","OsVersion","TimeZone","CsName"
$LST2="CsManufacturer","CsModel","CsSystemType","BiosBIOSVersion","BiosReleaseDate"
$MEM1 = (Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property capacity -Sum | Foreach {"{0:N2}" -f ([math]::round(($_.Sum / 1GB),2))})
$Pro1 = "systemname","DeviceID","numberOfCores","NumberOfLogicalProcessors"

Add-Content OutText.txt "OS Information:" -NoNewline
Get-ComputerInfo -Property $LST1 | Format-List | Out-File -Encoding ASCII -FilePath OutText.txt -Append
Add-Content OutText.txt "Hardware Information:" -NoNewline
Get-ComputerInfo -Property $LST2 | Format-List | Out-File -Encoding ASCII -FilePath OutText.txt -Append
Add-Content OutText.txt "RAM: $RAM1 GB" -NoNewline
Get-WmiObject -class win32_processor -Property  $Pro1 | Select-Object -Property $Pro1 | Out-File -FilePath OutText.txt -Encoding ASCII -Append

Too many lines breaks:

Too many lines breaks

2
  • 2
    Use something like (Get-ComputerInfo -Property $LST1 | Format-List | Out-String).Trim() | Add-Content -Path $path -NoNewline Commented May 15, 2021 at 9:56
  • 1
    That did it, THANK YOU!!! Commented May 17, 2021 at 20:25

2 Answers 2

5

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.

Sign up to request clarification or add additional context in comments.

Comments

0

I use the following to strip the Cr/Lf added by Out-String.

$YourVariableHere = $($YourVariableHere.Substring(0,($YourVariableHere.Length-2)))

You can adjust the number at the end if there is more than one Cr/Lf you want to remove.

HTH

1 Comment

That works (with CRLF, but not LF), but note that the enclosing $(...) is unnecessary (and, in general, can have side effects). A more concise (though perhaps conceptually more complex, regex-based) solution that works with both CRLF and LF-only newlines is: $YourVariableHere -replace '\r?\n\z'. '(?:\r?\n)+\z' would remove all trailing newlines; '(?:\r?\n){2}\z' would remove 2, for instance.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.