1

Afternoon all,

I've got a script that runs scheduled tasks on some remote computers through Cimsessions.

Start-ScheduledTask -CimSession $CimSessions -TaskName "<Task-Name>"

I then have a timer that runs in a Do/Until loop until the tasks are completed. However, the loop ends when one server has completed the task even if others have finished. Is there a way I can re-write my loop to continue until all servers have registered that their task is not running

$StartTime = Get-Date
Do{
    $ElapsedTime = (Get-Date) - $StartTime
    $TotalTime = "{0:HH:mm:ss}" -f ([datetime]$ElapsedTime.Ticks)
    $CurrentLine = $host.UI.RawUI.CursorPosition
    Write-Output "Running Scheduled Task... [Total Elapsed Time: $(stc $TotalTime yellow)]"
    sleep -s 2
    $host.UI.RawUI.CursorPosition = $CurrentLine

}Until((Get-ScheduledTask -CimSession $CimSessions -TaskName "<Task-Name").State -ne 'Running')

Note: the line of code $(stc $TotalTime yellow) is just a custom function that changes the color of the text to yellow

Fitzgery
  • 558
  • 5
  • 14
  • I think, instead of `until` you could use `while((Get-ScheduledTask ....).State -contains 'Running')` if I understand correctly – Santiago Squarzon Oct 18 '22 at 17:36
  • 1
    @SantiagoSquarzon, you know, you really need to start posting things as an answer so I can give you the proper credit lol. but that small change helped! I forgot/didnt think about ``-contains`` operator – Fitzgery Oct 18 '22 at 17:54
  • your fault for asking interesting questions while i'm also working :^) but you could self-answer explaining how you could solve the issue – Santiago Squarzon Oct 18 '22 at 17:59

1 Answers1

1

The condition:

Until((Get-ScheduledTask -CimSession $CimSessions -TaskName "<Task-Name>").State -ne 'Running')

Is saying, "run this loop and stop as soon as there is one object with it's State property not equal to Running". What you want instead is, "run this loop while there are objects having the State property equal to Running", hence the condition should be:

# with `-contains`
while((Get-ScheduledTask -CimSession $CimSessions -TaskName "<Task-Name>").State -contains 'Running')

# with `-in`
while('Running' -in (Get-ScheduledTask -CimSession $CimSessions -TaskName "<Task-Name>").State)

As aside, you could greatly simplify the task of $ElapsedTime = (Get-Date) - $StartTime by leveraging the StopWatch Class. Here is a little example:

$timer = [System.Diagnostics.Stopwatch]::StartNew()
do {
    $timer.Elapsed.ToString('hh\:mm\:ss')
    Start-Sleep 1
} until($timer.Elapsed.Seconds -ge 5)
Santiago Squarzon
  • 41,465
  • 5
  • 14
  • 37