Create a Polling Loop in PowerShell

This is one way to create a polling loop in PowerShell. I’m sure there are several options, but this one works well for the use case.


I needed to start the refresh of a data model using the new Start-RsRestCacheRefreshPlan function I created, and then check a few seconds later to make sure it had started, using the Get-RsRestCacheRefreshPlanHistory function. Sounds easy enough right? The problem is that the service doesn’t update instantly to tell you that it had started. Also, the service sometimes takes longer, depending on load.

Start-Sleep isn’t ideal

Originally I had used the Start-Sleep command to wait 3 seconds ( Start-Sleep 3
. That worked fine on my machine, but when I deployed it to the server, I found I needed to bump it up to 6 seconds. At first that worked, but then a week later I needed to bump it up to 9 seconds. The problem here is obvious, if we force it to wait 9 seconds every time, even if the task was updated after 4 second, we’re wasting extra time. And those seconds are going to add up.

Instead, I was asked to allow the Get-RsRestCacheRefreshPlanHistory function to wait up to 15 seconds to get the answer it was looking for, but to stop as soon as it got the right answer. In this particular case @($someHistory).count -eq 1
is the “right answer”. But if it takes more than 15 seconds, then we just assume failure.

How to WHILE

The only problem with this request for me to “use a polling loop” was that I didn’t quite remember off the top of my head how to do something like this. So I pinged Doug Finke ( b | t ) and about 18 seconds later I had my solution.

Stepping through the logic

  1. First, we need to start the refresh
  2. Next, we find out what time it is
  3. Now we need to check the .count property of the $someHistory variable and see if it is less than 1, as soon as the .count property is 1 or more, the loop will stop
    1. The first time we do this check the variable will be empty, and will therefore be less than 1
  4. If we pass that check, we then go ahead and run our command to check the history and load the result of that check into the $someHistory variable
  5. Next, we check the current time and see if 15 seconds have elapsed yet. If 15 seconds have elapsed we run whatever the code inside the {} is, in this case it’s break keyword which is the other way we can end our loop.
  6. If we get all the way down to that last little } and neither of our conditions have been met, we just start the whole loop over again.

Here’s that chink of code again in case you need to build something similar.

$timer= Get-Date
while ((@($someHistory).count -lt 1)) {
  $someHistory = Get-RsRestCacheRefreshPlanHistoryRsReport /ReportCatalog
  if(((Get-Date)$timer).seconds -ge 15) {break}

We can finally do our check to see if @($someHistory).count -eq 1
and move on to the next step in our command.

Again, this is just the solution that worked well for me. If you know of an easier way to do this kind of polling, please share it in the comments

Until someone shows me a better way, I’m going to use this same technique to wait for my SQL Servers to be ready when I build them in Docker.

Please Share This:

You may also like:

2 Responses

  1. As a general practice, I recommend explicitly setting the initial value of the loop’s variable. That ensures that any subsequent running of the loop will have the correct value, and not the one that was last set. I understand that sometimes you only run a loop once, but we also sometimes alter the code later to reuse a loop, which can cause a problem without resetting the variable.

    1. Ryk,
      That’s a great point. I should probably go back and add that. Thanks for pointing that out

Leave a Reply to Aaron Nelson Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.


Subcribe to Blog Via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

What I'm Saying on Twitter

Subscribe via feedburner

%d bloggers like this: