I recently had the need for a function that worked like the WScript.Sleep
method in Windows Script Host (WSH) but could wake a script up early if necessary.
I was writing a script that had to modify a registry setting and restart a service
on 150 servers. I needed a delay between the stopping of the service and the
starting of the service. Basically, I wanted to wait until the service stopped
before starting it up again.
Unfortunately, the Sleep method is a finite setting, and to the best of my
knowledge, you can't wake the script up early. For example, you can't wake up
the script if the service stops immediately. I thought about creating a While...Wend
statement that uses the InterrogateService method of Windows Management Instrumentation's
(WMI's) Win32_Service class to interrogate the service for the status of Service
Not Active. However, I realized that if the service's status failed to go to
an inactive status, the script would be caught in an endless loop. I
needed a function that provided a set time delay as well as checked for the
Service Not Active status—whichever event happened first would prompt
the script to move on to the next server.
To meet this need, I created the Delay function. The function uses a While...Wend
loop to continually check for two conditions:
- Whether the specified time delay (which is passed to the function as a parameter)
has elapsed
- Whether a specified second condition (e.g., when a service goes to an inactive
status) has been met
If the second condition occurs before the specified time delay has elapsed,
the function wakes the script up early, so to speak. (What actually happens
is that when one of the conditions is met, the script exits the function, which
ends the sleep period.)
As Listing 1 shows, the Delay function first
uses VBScript's Now function to set a start point and assigns that value to
the MarkTime variable. The Delay function then initializes a counter to zero.
Next, a While...Wend loop increments the counter by the number of seconds elapsed
between the start time and the current time. To obtain the number of elapsed
seconds, the Delay function uses VBScript's DateDiff function to compare the
value in the MarkTime variable to the value returned by another execution of
the Now function. When the counter equals the number seconds passed as a parameter
or when the second condition is met, the function ends.
To call the function, you simply pass the number of seconds as a parameter
with code such as
Delay(5)
Listing 2 shows how I used the Delay function
in one part of my registry script. (This code is for illustration purposes only.)
As callout A in Listing 2 shows, I set the
time delay for 15 seconds. Callout B shows how the script calls the Delay function
into action for each server's service. Callout C highlights the second condition.
For this condition, the function uses the Win32_Service class's InterrogateService
method to check for the Service Not Active status, which has a value of 6. When
the service has an inactive status or when 15 seconds are up, the function ends,
thereby waking up the script.
The Delay function proved quite beneficial in my script. If I had used the
Sleep function and set the script to sleep for 15 seconds per server, there
would have been 37.5 minutes of sleep time (15 X 150/60). The Delay function
substantially reduced the sleep time. Because the service typically stopped
after about 3 seconds, the script slept for only 3 seconds per server (3 X 150/60),
reducing the sleep time to only about 7.5 minutes.
End of Article