My code has the following function:
function status{
if ($args[0] -eq "Stopped"){
Write-Host -NoNewline "Stopped" -fore red
.....
}
}
and the function is used as:
...
Write-Host "$($count)) $($i.DisplayName) STATUS: $(status $i.State)"
...
The result after script execution is:
Stopped 1) XXXXXX STATUS:
Why "Stopped" is in the beginning of the line? can someone help me?
The function is only to change the text color. As the example -fore red
is to Stopped value.
CodePudding user response:
CodePudding user response:
Santiago Squarzon's helpful answer provides an effective solution; let me complement it with an explanation of what you tried:
Why "Stopped" is in the beginning of the line?
The reason is that Write-Host
doesn't write to PowerShell's success output stream and therefore doesn't "return" a value from your status
function.
Instead, Write-Host
instantly prints to the host (display; in PSv5 via the information stream), before exiting the function, and your function produces no success-stream output.
Since subexpressions (via $(...)
) are evaluated first in an expandable string (or command in general):
the
Write-Host
call inside yourstatus
function executes right away and prints at the start of the line.only then does the outer
Write-Host
call execute, which - due to the inner call's-NoNewLine
switch - prints on the same line, after what the function printed, and$(status $i.State)
, due to thestatus
call producing no success output, evaluates to the empty string.
A simple example can illustrate the problem:
Write-Host "foo: >>$(Write-Host bar)<<"
Output:
bar # The inner Write-Host printed right away.
foo >><< # $(Write-Host bar) produced no success output
Santiago's solution avoids this problem by replacing the Write-Host
call inside the function with sending a string (implicitly) to the success output stream, so that it becomes the function's "return value" that subexpression $(status $i.State)
expands to, and to make this string colored, ANSI / VT escape sequences are needed.
Note that while "$([char] 27)"
is required in Windows PowerShell to embed an ESC character in an expanable string, PowerShell (Core) 7 now offers escape sequence "`e"
Also, PowerShell (Core) 7.2 offers the automatic $PSStyle
variable, which, while more verbose, offers a more descriptive way to embed ANSI / VT escape sequences; e.g.:
# Prints only the word "green" in green.
"It ain't easy being $($PSStyle.Foreground.Green)green$($PSStyle.Reset)."
Note:
If you send strings with ANSI / VT sequences to the success output stream, as in the example above, colors are not automatically reset;
$PSStyle.Reset
is needed for a manual reset.By contrast, if
Write-Host
prints a string, it resets colors automatically.