Today the goal is to tie together some concepts that I’ve written about in the past in order to demonstrate how you can use the Advanced Multi-Row Queue Sequence to execute certain actions on some hosts with a contingency that something must be true on another host before the additional hosts begin operations.
The Plan
Here is the overall picture of what we’re going to do:
Host1:
1. Check if there is enough disk space. If the available disk space is less than a desired threshold, then stop executing the multi-row queue sequence. If there is enough disk space available, then go on to the next step.
2. Stop a specific service. If this action fails, stop executing the multi-row queue sequence. If it completes, then move on to the next step.
3. Set the service to manual. If this action fails, stop executing the multi-row queue sequence. If it completes, then move on to the next step.
4. Install Windows Updates and reboot.
5. Start the stopped service. If this action fails, stop executing the multi-row queue sequence. If it completes, then move on to the next step.
6. Set the service back to automatic. If this action fails, stop executing the multi-row queue sequence. If it completes, then move on to the next step.
7. Only after all previous actions are complete should the next two hosts begin their operations.
Host2:
1. Check if there is enough disk space. If the available disk space is less than a desired threshold, terminate the queue for this host only, but still proceed with the rest of the multi-row queue sequence for Host3.
2. Deploy Firefox
Host3:
1. Run a custom script
Scripts
In all cases with these scripts we return 0 for success and a non-zero integer (1) for failure. This enables us to use the job queue special items for ‘Terminate queue if previous actions fails/errors’ and ‘Abort advanced multi-row sequence if previous action fails/errors’. If the script returns 1, then those special items will consider it failed and will abort/terminate. If the script returns 0, those items will consider it successful and move on to the next step in the queue.
GetCDriveSpace.vbs
'Gets the free space on C drive. If free space is less than specified threshold return 1. Else return 0. 'Cocobolo Software LLC April 2017. on error resume next Err.Clear Dim freeMB Const MBCONVERSION = 1048576 Set objWMIService = GetObject("winmgmts:\\localhost\root\cimv2") 'Get C drive space Set colLogicalDisk = objWMIService.ExecQuery("Select * from Win32_LogicalDisk") For Each objLogicalDisk in colLogicalDisk If objLogicalDisk.DeviceId = "C:" Then freeMB = objLogicalDisk.freespace/MBCONVERSION End If Next If freeMB < 500 Then wscript.quit(1) Else wscript.quit(0) End If |
StopService.vbs
'Stops the specified service and returns 0 if successful else returns non-0 'Cocobolo Software LLC February 2018. 'Usage: cscript.exe "C:\Your Script Repository\StopService.vbs" "Your service display name goes here" 'The first argument from the command line is assigned to strServiceDisplayName strServiceDisplayName = WScript.Arguments(0) on error resume next Err.Clear Set objWMIService = GetObject("winmgmts:\\localhost\root\cimv2") Set colServices = objWMIService.ExecQuery("Select * from Win32_Service where DisplayName='" & strServiceDisplayName & "'") For Each objService in colServices ReturnValue = objService.StopService() wscript.quit(ReturnValue) Next |
StartService.vbs
'Starts the specified service and returns 0 if successful else returns non-0 'Cocobolo Software LLC February 2018. 'Usage: cscript.exe "C:\Your Script Repository\StartService.vbs" "Your service display name goes here" 'The first argument from the command line is assigned to strServiceDisplayName strServiceDisplayName = WScript.Arguments(0) on error resume next Err.Clear Set objWMIService = GetObject("winmgmts:\\localhost\root\cimv2") Set colServices = objWMIService.ExecQuery("Select * from Win32_Service where DisplayName='" & strServiceDisplayName & "'") For Each objService in colServices ReturnValue = objService.StartService() wscript.quit(ReturnValue) Next |
SetServiceToManual.vbs
'Sets the specified service to manual and returns 0 if successful else returns non-0 'Cocobolo Software LLC February 2018. 'Usage: cscript.exe "C:\Your Script Repository\SetServiceToManual.vbs" "Your service display name goes here" 'The first argument from the command line is assigned to strServiceDisplayName strServiceDisplayName = WScript.Arguments(0) on error resume next Err.Clear Set objWMIService = GetObject("winmgmts:\\localhost\root\cimv2") Set colServices = objWMIService.ExecQuery("Select * from Win32_Service where DisplayName='" & strServiceDisplayName & "'") For Each objService in colServices ReturnValue = objService.ChangeStartMode("manual") wscript.quit(ReturnValue) Next |
SetServiceToAutomatic.vbs
'Sets the specified service to automatic and returns 0 if successful else returns non-0 'Cocobolo Software LLC February 2018. 'Usage: cscript.exe "C:\Your Script Repository\SetServiceToAutomatic.vbs" "Your service display name goes here" 'The first argument from the command line is assigned to strServiceDisplayName strServiceDisplayName = WScript.Arguments(0) on error resume next Err.Clear Set objWMIService = GetObject("winmgmts:\\localhost\root\cimv2") Set colServices = objWMIService.ExecQuery("Select * from Win32_Service where DisplayName='" & strServiceDisplayName & "'") For Each objService in colServices ReturnValue = objService.ChangeStartMode("automatic") wscript.quit(ReturnValue) Next |
Create Custom Script Deployments
For each script file we need to create a deployment in BatchPatch. I have all of my scripts in a single folder on my BatchPatch computer.
Select ‘Actions > Deploy > Create/modify’, and then for each script create a deployment that looks like the following screenshots, and save those deployments using the double-right-arrow button. Note, the DiskCheck.vbs deployment has no parameters, but each of the other deployments has the desired service name as its only parameter:
Create Job Queue For Each Host
Before we create the Advanced Multi-Row Queue Sequence we have to create a job queue for each host. The job queue will be the step by step list of operations that we want each host to execute inside of the advanced multi-row queue sequence.
Select ‘Actions > Job Queue > Create / modify’ and then create the following job queues for each host. You can ‘apply queue’ to each host/row accordingly:
Note, for the places where we want to abort the entire multi-row queue sequence if the previous action fails/errors, we always add that special item right before the ‘terminate queue if previous action fails/errors’ because if we terminated the queue first, then the queu would not be running and could therefore not execute the command to abort the entire multi row queue sequence. However, in the case of Host2, we want to *only* terminate the queue if the previous action fails/errors, but we do not want to abort the entire multi-row queue sequence.
Assembling the Advanced Multi-Row Queue Sequence
Finally we will create our sequence. I’ve gone ahead and added a new row to the grid called ‘SequenceExecutionRow’ which is essentially a dummy row that is used just for the multi-row queue sequence.
- With that special row selected, choose ‘Actions > Job Queue > Create / modify advanced multi-row queue sequence’
- In the window that appears enter a Sequence Name and select the radio button for ‘Create Sequence Execution Row’, and apply it to the SequenceExecutionRow
- Next highlight Host1 and choose the radio button ‘Set Sequence Position Number’ with a value of 1.
- Do the same with Host2 and Host3.
- Finally we are ready to execute the sequence. Highlight the SequenceExecutionRow and select ‘Actions > Job Queue > Execute advanced multi-row queue sequence.