I teach a scripting class for my local university. One of my students is stuck and asked me to look at her code and give her some clues. I added a few Write-Output statements to get an idea what was going on and the output of those Write-Output statements ended up in an open output file and not on the console. I am running PowerShell 7.2.2 on Ubuntu 20.04 on Multipass on my Macbook Pro. I stripped down the script to the following (this script is in tcowan/powershellbug) on Github:
#!/usr/bin/env pwsh
if ($args.length -lt 2) {
write-Output("Usage: ./f.ps1 path/to/output/file recordcount")
exit 1
}
# Convert arg[1] to integer and set as recordCount
try{
[int]$recordCount = $args[1] # The number of records that should be added to the output file
}
catch {
Write-Output("Error: Unable to convert arg[2] to integer")
exit 1
}
if ($recordCount -lt 0 -or -not ($recordCount -is [Int32]))
{
Write-Error "Error: RecordCount must be a number and cannot be less than 0"
exit 1
}
# Create output file
try{
# Set outputFile path
[string]$outputFile = $args[0]
New-Item -path $outputFile -force -erroraction stop | Out-Null
}
catch {
Write-Error -Message "Error: Unable to create new output file"
exit 1
}
Write-Output ("Writing $($recordCount) records to the output file")
function WriteToFile ($outputString)
{
try {
add-content -path $outputFile -value $outputString
}
catch {
Write-Output "Write failed to file $($outputFile): $($_)"
exit 1
}
}
function SetOutputTed ($newCmd)
{
Write-Output("this string should appear on the console and not in my output file")
WriteTofile($newCmd)
}
for($i = 0; $i -lt $recordCount; $i++)
{
write-output("This string should appear on the console and does.")
[string]$tempString = SetOutputTed ("Record $($i)")
WriteToFile($tempString)
write-output("This string should also appear on the console and does.")
}
exit 0
I reread the documentation of Write-Output, and found this:
This cmdlet is typically used in scripts to display strings and other objects on the console.
I committed the above script to a public repo on Github, and opened an issue. I must not understand PowerShell because this behavior was surprising. I got the following response to my issue number 17074:
Write-Output does not write directly to the console but instead writes to the output stream. If not captured (e.g. in a variable assignment) it will eventually make it's way to the console.
In this case you are assigning the output to the variable $tempString so this is the expected behavior.
I ran my test script on my Windows 10 system and got the same result. I don't recall which version of PowerShell is on my Windows machine but I think it is 7.x.
Changing the Write-Output calls to Write-Host is one workaround which works. What I am seeking is understanding.
Since I had to scan through 15 screens of open Github issues containing the string "Write-Output", I assume the developers are busy. I thought I would see if the experts here at StackOverflow could help me understand the response I received to this issue. I would like to share this with my students.