Guillaume CR
Guillaume CR

Reputation: 3016

How to edit the text that was already written to console with PowerShell?

For example, robocopy will display the percentage of a file that is being copied. The percentage will change without the need to write more output to the console. How can I emulate the same behavior, where text that was already written to the console gets modified?

Upvotes: 1

Views: 829

Answers (3)

Matt
Matt

Reputation: 46710

You could try something like this. It uses $host.UI.RawUI.CursorPosition to determine where the console text is currently writing and manipulating that to overwrite previously written text.

Simple Test

I have adapted your "Lorem ipsum" example to use $host.UI.RawUI.CursorPosition.

$text = "Lorem ipsum dolor sit amet"
$origpos = $host.UI.RawUI.CursorPosition
Write-Host $text -NoNewLine
Start-Sleep -s 4
$host.UI.RawUI.CursorPosition = $origpos
Write-Host "consectetur adipiscing elit"

The following example will cycle the characters in $scroll giving the impression of a rotating line. All this does is run a sleep command for 10 seconds. Depending on your needs you would obviously not need to run all this code.

$scroll = "/-\|/-\|"
$idx = 0
$job = Invoke-Command -ComputerName $env:ComputerName -ScriptBlock { Start-Sleep -Seconds 10 } -AsJob

$origpos = $host.UI.RawUI.CursorPosition
$origpos.Y += 1

while (($job.State -eq "Running") -and ($job.State -ne "NotStarted"))
{
    $host.UI.RawUI.CursorPosition = $origpos
    Write-Host $scroll[$idx] -NoNewline
    $idx++
    if ($idx -ge $scroll.Length)
    {
        $idx = 0
    }
    Start-Sleep -Milliseconds 100
}
# It's over - clear the activity indicator.
$host.UI.RawUI.CursorPosition = $origpos
Write-Host 'Complete'

Caveat: Both this and the test will not work as intended in ISE. Also if not used correctly your cursor can end up in a weird place after.

Upvotes: 3

Bill_Stewart
Bill_Stewart

Reputation: 24525

Your answer can be shortened thus:

$text = "Lorem ipsum dolor sit amet"
Write-Host -NoNewLine "$text`r"
Start-Sleep -Seconds 2
Write-Host -NoNewLine ("`b" * $text.Length)
Write-Host "consectetur adipiscing elit"

Upvotes: 0

Guillaume CR
Guillaume CR

Reputation: 3016

Full credit goes to @Bill_Stewart for this answer.

$text = "Lorem ipsum dolor sit amet"
Write-Host $text -NoNewLine
Start-Sleep -s 2
for ($i = 0; $i -lt $text.Length; $i++){
    Write-Host `b -NoNewLine
}
Write-Host "consectetur adipiscing elit"

Upvotes: 0

Related Questions