MGoBlue93
MGoBlue93

Reputation: 684

String in PowerShell ProgressBar not Displaying

I'm trying to use a PowerShell progress bar and the -status parameter isn't working as advertised (or I'm reading the documentation incorrectly.

For simplicity sake, let's say I have a collection:

@("red", "green", "blue")

... and I have another method which iterates through that collection. But when it iterates, the processing takes a long time. So I want to give status to the user by placing a call to progressBar($i, $s) in the loop.

There's the code for progressBar:

function progressBar ($count, $color) {
  Write-Progress -Activity "My Progress Bar" -status "Doing stuff on $color" -percentComplete ($count / $totalItems * 100)
}

Which is corresponds with:

https://blogs.technet.microsoft.com/heyscriptingguy/2011/01/29/add-a-progress-bar-to-your-powershell-script/

where the author uses this example:

-status "Found Service $i"

But when I run my script, nothing shows up after "Doing stuff on" -- it's blank!

I always thought + was concatenation in PS... but doing this -status "Doing stuff on " + $color fails too!

Before posting, I read this:

How do I concatenate strings and variables in PowerShell?

... and the suggestion to use $($color) makes the cmdlet fail all together.

So, how can I get my entire string to appear in -status rather than it dropping the $color part?

Thanks!

===================================================

Hello again... I'm adding the full code per @BenH and @Persistent13's comments below.

$a = @("red", "green", "blue")

$counter    = 1
$totalItems = $a.Count

foreach ($color in $a) {

Write-Host $color "`n"
Start-Sleep -s 3
$counter += 1

progressBar $counter, $color
}

function progressBar ($i, $s) {
  Write-Progress -Activity "My Progress Bar" -status "Doing stuff on $s" -percentComplete ($i / $totalItems * 100)
}

Upvotes: 0

Views: 1252

Answers (2)

Sage Pourpre
Sage Pourpre

Reputation: 10323

Here's a working example using the less modified version of your code. There were some issues that needed to be addressed.

First, let's see the "new" code.

function progressBar ($i, $s,$totalItems) {
Write-Progress -Activity "My Progress Bar" -status "Doing stuff on $s" -percentComplete ($i / $totalItems * 100)
}

$a = @("red", "green", "blue")

$counter    = 0
$totalItems = $a.Count

foreach ($color in $a) {

    Write-Host $color "`n"
    Start-Sleep -s 3
    $counter += 1

    progressbar -i $counter -s $color -totalItems $totalItems
}

Status bar

As you can see, the status and its color variable are properly displayed.

There was a number of mistake though in your original code.

  1. Powershell is an interpreter and goes linearly top to bottom of your script. Therefore, it needs to have its function declared when you want to call it.
  2. Counter variable should be initialized to 0 in your code. Otherwise your percentComplete will exceed 100% (4/3 * 100) and generate an error.
  3. You try to use $totalItems inside your function but it is not made available to it through the function. That is not a good practice because it will fails if that variable is not defined in another script another time.
  4. You had comma in your function parameter. That is not how you pass parameters to powershell.
  5. String concatenation is done with the plus sign. However, when passing down a parameter, you need to encompass it between parenthesis. -status "Doing stuff on " + $color won't work while -status ("Doing stuff on " + $color) will. Even simpler, the auto-expand feature when using double-quoted string -status "Doing stuff on $color"

Now, while the modified code I provided to you is working, I'd suggest a few other improvements.

  1. Take the habit of naming your function parameters right from the start. It is far easier to identify issue when the code get bigger
  2. You do not need to add the new line character with Write-host. This is done by default (if you wanted the extra blank line though, that's good.)
  3. Instead of string concatenation, you can use double-quotes to encompass your variables so it auto-expands.

Also, because you were using a $countervariable, i'd personally had gone for a for loop instead of foreach so the counter is embedded without extra declaration.

Also, if you had a bigger array, it could have been worth it to calculate the offset right off to optimize the code.

function progressBar ($index,$Name, $Offset) {
    $PercentComplete = 0
    if ($index -gt 0) { $PercentComplete = $index * $Offset } # Avoid divide by 0 error for first item.
     Write-Progress -Activity "My Progress Bar" -status "Doing stuff on $Name" -percentComplete ($PercentComplete)
}

$ColorArray = @("red", "green", "blue")
$Offset = 1 / $ColorArray.Count * 100  # Calculate one time only instead of each iterations of the loop. 

# Because you use a counter, i'd use For instead of foreach.
for($i=0;$i -le $ColorArray.Count;$i++) { 
    $CurrentColor = $ColorArray[$i]

    Write-Host $CurrentColor "`n"
    Start-Sleep -s 3
    progressbar -index $i -Name $CurrentColor -Offset $Offset
}

Finally, just thought I'd mention it... Write-host automatically appends a new line if you do not use the -nonewline switch parameter. Maybe you wanted that extra blank line in there or maybe not... just thought it was worth to mention.

Upvotes: 2

Nick
Nick

Reputation: 1863

function progressBar ($Count, $color) {
    Write-Progress -Activity "My Progress Bar" -CurrentOperation "Doing stuff on 
    $color" -percentComplete ($Count / $totalItems * 100)
}

$a = @("red", "green", "blue")

$counter = 0
$totalItems = $a.Count

foreach ($color in $a) {

    Write-Host $color "`n"

    progressBar -Count $counter -color $color
    Start-Sleep -s 3
    $counter += 1
}

So I cannot explain why -Status is not showing data from variables. But looking back through all my progress bars I have never used it. Using -CurrentOperation Displays the variable contents on the bar. You had a number of syntax mistakes.

  • Your function declaration should be at the top
  • $Counter should start at 0
  • $Counter += 1 should be last

Upvotes: 1

Related Questions