Schedule a Service to Shutdown on Multiple Computers Before Applying Updates and Rebooting

Every network environment has its own requirements that are particular to it, depending on the types of servers and services running, the service level agreements in place between companies and their customers, as well as any other factors that may influence how decisions are made about maintaining the environment and its security etc.

When it comes to automation, there are cases where an administrator might need or want to completely stop a service that is running on a particular server or group of servers before beginning the update and reboot process. And depending on how the service is configured (automatic vs manual), it might need to be manually started after the reboot completes. Today I’m going to demonstrate how you can use BatchPatch to automate this process very easily on any number of target computers. You can schedule the process to run at a specific date/time, or you could simply configure it to run on-demand with a single click trigger.

Tutorial

  1. We’ll start by creating and saving a remote command in BatchPatch that will handle stopping the desired service. Click on ‘Actions > Execute remote process/command > Create/modify remote commands‘. In the window that appears click ‘Add Row’ and then insert the following command, substituting the name of the service you want to stop. In this example I’m just going to be stopping the DNS Client to illustrate the process, though realistically the DNS Client is not a service that anyone typically needs to be messing with. You can see in the screenshot that I’ve inserted the command into the command field, and I’ve given it a title in the title field. If you intend to use BatchPatch to start the service at some point, then go ahead and also create a row with a command to start the service. In most cases administrators probably have services that need to be running set to ‘Automatic’ so that they automatically start after a reboot. If this is the case for your service, then you won’t need to create a startservice command, but of course you should do whatever is needed for your situation. Click OK when finished.

    WMIC SERVICE where caption='DNS Client' CALL stopservice
    WMIC SERVICE where caption='DNS Client' CALL startservice

  2. Now that the stop service command has been created it would be wise to take a moment to test it and make sure it works as desired/expected. To test it we can simply select a target host in the grid, and then click on ‘Actions > Execute remote/process command > Execute saved remote commands > Stop DNS Client Service’. Then make sure that the service has been stopped as desired, either by reviewing the services console manually/directly on the target computer or by using ‘Actions > Services/Processes > List all services’ from within BatchPatch. This action will give you a list of all services and their current states.

  3. Once you have verified that your command works properly, you’re ready to create a job queue. The job queue is what will handle the process of sequentially executing the stop service command followed by the update/reboot command. Select ‘Actions > Job Queue > Create/modify job queue’. In the job queue window first find the command you created in the ‘Saved User-Defined Commands and Deployment’ grid in the lower left corner of the window. Double-click on your command (or use the right-arrow button) to add it as the first item in the queue. Next, add the ‘Download and install updates + reboot always’ command from the ‘Actions’ listbox in the upper left corner of the window. Input a title for the job queue, and then click the double-right-arrow button to save it. You should have something like the screenshot below. Close the window when you’re done.

  4. That’s practically all there is to it. Now if we want to run this job queue on-demand at any time, we can simply select the desired servers in the BatchPatch grid, and then click ‘Actions > Job Queue > Execute saved job queues > Tutorial 20190404’. Of course you’ll use whatever title you gave to your queue.

Other Considerations

  • If you want to have this job queue run as a scheduled task on a specific date/time, that’s easy to do. You’ll select the desired rows, click on ‘Actions > Task scheduler > Create/modify scheduled task’, and then select your saved job queue from the list of tasks, set the run time/date, and enable the scheduler. Check out this task scheduler tutorial for more details.
  • If your service is set to automatic, make sure that you guarantee a reboot will occur. For example in your job queue if you were to choose ‘Download and install updates + reboot if required’ a reboot will not be executed if the update installation doesn’t require it to complete the process. This means that if you have stopped the service and installed updates without a subsequent reboot, your service would be in the stopped state indefinitely without manual interaction. You could use a start service command in the job queue maybe after a 5 minute wait period after the update + reboot if required command, if desired. Or you could simply use a command that guarantees a reboot after the update process. There are numerous ways that this can be handled, and it all really just depends on your needs and preferences.
  • If your service is set to manual such that you need to incorporate a start service command into your job queue, that’s fine. However, you’ll want to make sure that the computer has ample time to complete its reboot before you issue the start service command. You can use a ‘Wait’ period in the job queue to handle this. There are more details here about some of the special items in the job queue such as the various ‘Wait’ commands.
Posted in Blog, General, Tutorials | Tagged , | Comments closed

The Best Software to Automate Windows Patching

Systems administrators have quite a few options when it comes to applying Windows updates to the computers that they’re responsible for. In smaller environments with looser requirements it might be totally sufficient to just manually install updates each month by logging on to each computer with Remote Desktop or some type of KVM solution, and then initiating the download, install, reboot process, and finally making sure computers come back online properly. It’s not necessarily an efficient process, but it can be sufficient in many cases. Of course this process becomes unwieldy quite quickly when the total number of computers being managed increases over a certain threshold. If requirements continue to stay loose, it might be that the administrator can shift to using Group Policy to gain a modicum of control over the updating process, thereby alleviating some of the pain of a completely manual process. This may or may not involve installing a WSUS server to help with controlling which updates are made available to target computers. But what happens when more control is needed? Administrators of environments that have stringent uptime requirements or brief maintenance windows or a large number of servers know that relying on just Group Policy to manage the update process simply won’t cut it. It’s hard to even call it “managing” the process because there isn’t much managing going on.

Why WSUS + Group Policy Objects Might Not Be Enough In Your Environment

If you’re trying to manage Windows updates in your environment with just GPOs and WSUS, there are some very important things to consider:

  • Machines get stuck during reboot: Sometimes computers hang while shutting down or starting up. This is an inevitable fact. The more computers you’re dealing with, the more likely you are to see one or more get stuck during the reboot. If you’re relying solely on WSUS + GPO scheduled installations/reboots, it can be hard to determine that a machine got stuck if you aren’t monitoring it in real-time. If you have a different tool that alerts you of down/offline servers, that’s great, but you probably have it disabled during your maintenance window since you know computers will be going offline at that time. The result is that at the end of the maintenance window when you turn back on your alerting tool, you all of a sudden discover which servers are stuck offline, but now it’s too late to resolve the issues *before* the end of the maintenance window. In an environment with uptime guarantees you’re probably already getting calls from customers at this point asking why they can’t access X, Y, or Z.

    But what about the case where the server gets stuck during the shutdown process? You could end up in a situation where the server completed installing updates, but it gets stuck somehow such that the reboot does not occur. The server might still be online and responding to requests, so it doesn’t trigger your alert system, but the update process has not officially completed because the reboot never took place. When your maintenance window is over, you won’t discover this very easily or at all, and the machine will be in a questionable state and might still be vulnerable to whatever issues were supposed to be fixed by the updates that were installed since the installation never actually got to complete since the reboot never occurred.
  • Unexpected slow update processing causes reboots to be initiated at unexpected times: We all wish Windows updates always installed rapidly, but sometimes there are issues, and things just don’t go as quickly as we expect or need. If a scheduled update process is taking longer than expected, the reboot can occur at an unexpected time. If you aren’t monitoring the installation process in real-time then you might end up with a surprise reboot that occurs when you didn’t want it to. However, if you have a tool that provides you with real-time monitoring capability you’ll know the process is going slower than expected, and so you can make the necessary arrangements to deal with that before an unexpected reboot occurs.
  • Critical services not starting after reboot: Sometimes services fail to start after a reboot. It’s just one of those things that can happen sometimes. The more servers you’re dealing with, the greater the likelihood is that something like this could happen. The sooner you are able to discover which servers have critical services in a stopped state, the better. However, you need to be able to confirm that the reboot occurred before checking the state of services, which again is very difficult when you don’t have a real-time monitoring solution in place for the update and reboot process. It also helps significantly to have a tool that can quickly tell you which computers have automatic services in a stopped state.
  • Server dependencies create challenges for update and reboot timing: It is not uncommon for there to be dependencies in groups of servers such that one server cannot be taken offline at the same time as another, or one server can/should only be rebooted when another server is online etc. The more dependencies that exist, the more an administrator can benefit from having a tool that allows precise scheduling and/or on-demand execution as well as real-time monitoring. A tool like BatchPatch is even capable of orchestrating complex sequences to update and reboot servers in specific orders with lots of control and flexibility over exactly what happens and when, allowing you to configure one-click actions that handle the updating and rebooting of numerous computers in particular orders and with particular dependencies.
  • Virtual machines: In environments with many virtual machines it becomes important to coordinate the update and reboot timing of the guests and hosts so that host operating systems don’t reboot during or before guest update processes complete, for example.

A Better Option

If you’re at the point where manual updating or GPOs and WSUS alone aren’t cutting it anymore, BatchPatch might be the tool for you.

Posted in Blog, General | Tagged , , , | Comments closed

Using the Row Template Configurator to Automatically Apply Job Queues and Scheduled Tasks to New Rows When They Are Added to the Grid

BatchPatch has a very neat feature that is probably not used nearly as much as it would be used if more people realized it existed, and if they understood what it is. It’s called the ‘Row Template Configurator‘ and it can be found under ‘Grid > Row template configurator…‘ inside the software. The row template configurator enables the BatchPatch administrator to automatically apply column values to new rows when they are added to the grid. For example, if you are using the grid synchronize feature to automatically add new hosts to your BatchPatch grid on a scheduled basis, you might want those new hosts to be added to the grid with certain fields automatically applied, such as a scheduled task or job queue. Wouldn’t it be nice if you could have an almost-completely hands-off configuration, such that if you put new computers on your network and add them to Active Directory in a particular OU, and then have BatchPatch synchronize its grid with that OU on a scheduled basis, then when new rows get added to the grid (one new row per new computer in the OU), those new rows can automatically have scheduled tasks applied to deploy Windows Updates or third-party software or whatever you want. Pretty cool, I think.

Using the Row Template Configurator to Automatically Apply Values to Desired Fields

  1. The first thing that we need to do is create a standard row in BatchPatch that contains the elements we want new rows to have automatically applied. I’ve added a row to the grid, and I have applied a recurring scheduled task to “Install downloaded updates + reboot if required.” Note, you can use any host name for this step, but for the sake of this example I’ve just called my host ‘TEMPLATE’ for obvious reasons.
  2. Next click on ‘Grid > Row template configurator…‘ to launch the configurator form.
  3. Make sure the row that you created in the BP grid in the first step is selected/highlighted, and then click ‘Create/update row template based on selected row in main BatchPatch grid‘. When you do this you’ll see that the columns from the main grid, excluding the host name, are added to the row template.
  4. Now that the row template has been created for the grid (note, you can create one row template for each BatchPatch grid), if you want the template to actually be utilized when adding new hosts to the that grid, you must first enable the template, which you can do by clicking on the ‘Enabled’ radio button in the upper right corner of the ‘Row Template Configurator’ form. Then click OK.
  5. At this point the row template has been created for the BatchPatch grid, and it’s currently enabled. Now if you add a new row to the grid either manually or automatically through the grid synchronize feature, that new row will automatically receive the row template fields, which in this case is a recurring scheduled task to “Install downloaded updates + reboot if required” every Saturday night. In the screenshot below you can see that I’ve removed the row that we used to create the template, and then I’ve added five hosts, each of which automatically received the template values.
Posted in Blog, General, Tutorials | Tagged | Comments closed

Remotely Patch and Reboot Multiple Computers

If you’ve stumbled upon this page, it’s probably because you are looking for a simple method to remotely apply Windows updates to multiple computers on your network, simultaneously. Not only that but you also want to be able to have the entire patch and reboot process automated so that you can pretty much just press a button and watch your target computers update and reboot themselves with as little interaction as possible. Well, you came to the right place!

BatchPatch is a tool designed for systems administrators to remotely manage Windows updates as well as third-party software on their network of computers. Configuration is simple, and there is no remote agent installation to perform. You pretty much just configure your network to work with BatchPatch, and then you can start patching right away.

Features:

Some of the primary features of BatchPatch include the following. However, for a more complete list check out the home page:

Additional capabilities:

In reality the capabilities of BatchPatch are relatively limitless when it comes to Windows networks. Almost anything that isn’t already built-in to the software can still usually be accomplished with some amount of customization. The application can work with WSUS or without it, in domain environments or in standalone or workgroup settings, and it can even be used to apply Windows updates to computers on so-called “air-gapped” high-security networks that are completely segregated from internet-connected computers.

Download:

We encourage you to download the free evaluation version of BatchPatch so that you can try it out for yourself in your environment. Our website has many dozens of tutorials on virtually every possible topic and use case for the software, so please do check those out.

Contact us:

If you encounter any problems or if you have any questions that do not appear to be answered on the website, please feel free to reach out to us to discuss.

Posted in Blog, General, Tutorials | Tagged , , , | Comments closed

When ‘Uninstall individual update Windows 10/2016’ in BatchPatch Fails to Remove an Update

Unfortunately there are cases where remotely removing an update from numerous computers can prove to be more challenging than it seems like it ought to be, especially when you have a great tool like BatchPatch at your disposal. BatchPatch has a built-in feature Actions > Windows updates > Uninstall individual update (requires KB ID) – Windows 10/2016 for uninstalling individual updates from Windows 10 and Windows 2016 target computers, but it is not always successful. Today I’m going to describe why it doesn’t work 100% of the time, and I’m going to show you how you can complete the task of removing an update from multiple Windows 10 or Windows 2016 computers, using BatchPatch, when the BatchPatch built-in feature for this purpose fails.

For the sake of this tutorial we are going to remove KB4487006 from a single Windows 2016 computer in our lab, but of course you can use this same method to remove an update from numerous remote computers, simultaneously, simply by selecting multiple computers in your BatchPatch grid when you execute the action.

Demonstrating the failure to remove an update using the built-in option in BatchPatch:

First let’s try to remove the update using the built-in function in BatchPatch. I know in advance that it will fail, but I want to show you what the failure looks like. I’m going to select Actions > Windows updates > Uninstall individual update (requires KB ID) – Windows 10/2016, and then I’ll enter the KB ID into the form that is presented before clicking OK. The screenshots below illustrate this process.

In the screenshot below you can see that the command took only 15 seconds to run before returning ‘Exit Code: 1’. Not surprisingly, it’s also the case that the update was not actually removed from the target computer.

Why the built-in removal method did not work:

The first question we need to answer is why was the update not removed? Here is a copy of the actual command that BatchPatch executed on the target computer:

powershell.exe -ExecutionPolicy Bypass -command "$SearchUpdates = dism /online /get-packages | findstr 'Package_for'; $updates = $SearchUpdates.replace('Package Identity : ', '') | findstr 'KB4487006'; DISM.exe /Online /Remove-Package /PackageName:$updates /quiet /norestart"

Essentially what the command above does is identify the update’s package identity in Windows, using DISM.exe and findstr. The way that we discover the package identity is by searching for the string ‘KB4487006’ in a list of all of the packages that have been installed. After the package identity has been discovered, DISM.exe is used once again but this time to remove the update by passing the package identity of the update to the DISM /remove-package command. This works great when the package identity contains the KB ID. The problem, unfortunately, is that the package identity will not always include the KB ID. It’s almost as if Microsoft’s goal was to make this as difficult as possible for us!

In the screenshot below I have executed the following command at the PowerShell prompt of the target computer in order to view the list of all packages, including their package identities, that have been installed:

dism /online /get-packages /format:table

We can further refine the list of packages to only include packages for Windows updates because all of the updates begin with the text Package_for. We use the findstr command for that purpose, as you can see in the command and screenshot below.

dism /online /get-packages | findstr 'Package_for'

You can see in the screenshot above that not all of the updates contain the KB ID, and in particular the KB4487006 that we are trying to remove is not identifiable by KB ID in that list. This is why the BatchPatch built-in function ‘Uninstall individual update Windows 10/2016’ fails to remove update KB4487006. It can’t find it!

One other important consideration is the display language setting in your operating system. For example, if Windows is configured to display in German instead of English, then instead of Package Identity the DISM results will display Paketidentität and Paketidentit?t like in the screenshots below. Since the DISM commands that we are using for update removal rely on the PowerShell findstr command and .Replace() method, if there is a language mismatch in the search string as compared to the OS display language, the command will fail.

How to remove the update using BatchPatch with a custom command:

Unfortunately in order for us to be able to remotely remove the desired update from our target computers using BatchPatch, we have to first identify the package identity for KB4487006. This requires some manual effort. We start by listing out all of the installed update package identities on a target computer where KB4487006 is known to be installed. We use the following command to do that:

dism /online /get-packages | findstr 'Package_for'

We know that KB4487006 is installed on the computer, and so we can deduce that its package identity must be one of the ones that begins with ‘Package_for_RollupFix‘. Furthermore, it happens to be the case that these rollups supersede previously installed rollups, so if you are trying to remove the most recently installed rollup due to the fact that after you installed it recently it started causing problems for you, you can use the ‘State’ column in the table in the screenshot below to see that of the four rollups listed, three of them are showing the state value as ‘Superseded‘ while just one is showing ‘Installed‘. In this case since I know the most recent rollup is the one that I’m trying to remove, I already know that the one showing ‘Installed‘ is the KB4487006.

dism /online /get-packages /format:table

However, to further confirm/verify that the KB4487006 is Package_for_RollupFix~31bf3856ad364e35~amd64~~14393.2828.1.11, let’s check out the KB4487006 page on Microsoft’s website. You can simply google KB4487006 to find this page:

https://support.microsoft.com/en-us/help/4487006/windows-10-update-kb4487006

At the top of the page we can see Build 14393.2828:


So now we have confirmation that KB4487006 is Package_for_RollupFix~31bf3856ad364e35~amd64~~14393.2828.1.11 Just in case you missed it, the reason is because the package identity contains the build number 14393.2828.

So now if we want to remove this update from multiple target computers using BatchPatch, we can do it by executing a remote command in BatchPatch with the following syntax. Note the command below is identical to the command that BatchPatch’s built-in function runs with one exception, which is that instead of using KB4487006 as our search string, we substitute it with 14393.2828:

powershell.exe -ExecutionPolicy Bypass -command "$SearchUpdates = dism /online /get-packages | findstr 'Package_for'; $updates = $SearchUpdates.replace('Package Identity : ', '') | findstr '14393.2828'; DISM.exe /Online /Remove-Package /PackageName:$updates /quiet /norestart"

NOTE: The command above contains /norestart, which will prevent the target computer from restarting after the command executes. For most updates a reboot will be required to complete the uninstallation, so if you use the /norestart switch you will need to issue a reboot command after it finishes. Alternatively you may remove /norestart from the command so that the target computer reboots itself to complete the uninstallation process.

ALSO NOTE: As described earlier in this posting, if you’re using a different OS display language, you’ll have to modify your command accordingly. For example, if the display language is German, the above command would have to be changed to this instead (we replaced Package Identity with Paketidentit?t) :

powershell.exe -ExecutionPolicy Bypass -command "$SearchUpdates = dism /online /get-packages | findstr 'Package_for'; $updates = $SearchUpdates.replace('Paketidentit?t : ', '') | findstr '14393.2828'; DISM.exe /Online /Remove-Package /PackageName:$updates /quiet /norestart"

To execute the command in BatchPatch select ‘Actions > Execute remote process/command > Create/modify remote command 1‘. Then enter the command and click ‘Execute’ to execute it on the selected rows.

Note, this command seems to always return Exit Code: 1, even when it completes successfully. Also note, removing update rollups like this one can take a long time for processing to complete *after* the command executes. That is to say that if you execute the command without /norestart, the computer will automatically reboot, but it might not be accessible after that for a couple of minutes while it goes through the typical “configuring updates – don’t turn off your computer” screen. One thing to consider doing is issue a ping command in BatchPatch before you execute the uninstallation command. This would enable you to easily see when the computer goes offline and comes back online. Alternatively if you issue the command with the /norestart switch, you could put it in a job queue and have the job queue execute a reboot when the command completes.

Also note, if you attempt to execute this command directly on a selected computer at the command line, as opposed to running it in BatchPatch, you will need to run the command in a cmd prompt, not in a powershell prompt. The syntax provided above for running it in BatchPatch is the same syntax that can be used to run it in a cmd prompt, but to run it in a powershell prompt you would need to modify it slightly, otherwise it will fail. You are certainly welcomed to modify it as you see fit, but I just wanted to make sure that you’re aware that it will not work as-is in a powershell prompt.

Posted in Blog, General, Tutorials | Tagged , | Comments closed

Deploying a Registry Key / Value to HKEY_CURRENT_USER (HKCU) or All Users in HKEY_USERS (HKU)

A question that comes up periodically is “How can I deploy a registry key or value to the HKEY_CURRENT_USER (HKCU) hive of the registry on a target computer or group of computers?”

If you were to follow the tutorial at this link to deploy a .reg file to target computers, you might have unexpected results if the key/value described inside the .reg file is intended for the HKCU hive of the target computer registry. If you deploy the .reg file and then take a look in HKCU, you might not see the key/value created. There are a couple of reasons for this.

Understanding the HKEY_CURRENT_USER (HKCU) Registry Hive

First, HKCU represents the registry hive of the current user. When you deploy a .reg file in BatchPatch, the current user is going to be the user that executed the deployment. However, you probably want the registry key/value to end up in the current user hive for the user who logs on to the target computer, not the user who deploys the registy key/value in BatchPatch. So, if you are trying to deploy to HKCU, then you would need to execute the deployment with the same user account under which you want to be able to see the registry key/value exist on the target computer. In some cases this might work well for your needs, but below I will show you another way to accomplish the task by deploying to HKU instead of HKCU, which might be better suited for you, depending on exactly what you need to accomplish.

Second, if you are deploying a registry key/value, using the method linked above, directly to HKCU, then you need to set your BatchPatch ‘remote execution context’ for the deployment to ‘Elevated token‘ as opposed to ‘SYSTEM‘. More details on configuring the ‘remote execution context’ here: ‘Remote Execution Context‘. If you deploy to HKCU under the ‘SYSTEM’ remote execution context, the registry key/value will actually end up under the Local System account’s registry hive, which is not what you want. However, below I demonstrate a more effective and simpler way of deploying a registry key/value to HKCU by not actually deploying directly to HKCU but instead deploying to HKU for each user that has logged on to the computer.

It’s important to understand that the HKEY_CURRENT_USER (HKCU) hive of the registry is really just a view or mirror of a particular SID’s subkey under HKEY_USERS (HKU). That is to say that under HKU you will see one SID for each user account that has been created on the computer. In the screenshot below you can see the SIDs for the built-in accounts above the SIDs for the actual user accounts that have logged on to the computer.

The most effective way of deploying a registry key/value to HKCU is to actually not deploy directly to HKCU but rather to deploy to HKEY_USERS\SID of the desired user(s). Realistically in most cases if you are trying to deploy a registry key/value to HKCU, you want that registry key/value to be deployed for all users of the computer, not just a particular one. Although we may add functionality in a future version of BatchPatch that enables the administrator to easily deploy a registry key/value to all SIDs under HKEY_USERS, currently the only way to do this is with a custom script. Below you can see the script that I have written to handle this process.

Script to Create a Registry Key and Value Under All SIDs in HKEY_USERS

Registry DWORD (REG_DWORD) Example:

strComputer = "."
strRegPathSuffix = "\Software\Microsoft\Office\15.0\Common\Identity"
strRegValueName = "EnableADAL"
intRegValueDec = "1"
Const HKEY_USERS = &H80000003
 
Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
strKeyPath = ""
oReg.EnumKey HKEY_USERS, strKeyPath, arrSubKeys
 
For Each subkey In arrSubKeys
    'wscript.echo subkey
    'We only want to do something if the subkey does not contain any of the following: .DEFAULT or S-1-5-18 or S-1-5-19 or S-1-5-20 or _Classes
    If NOT ((InStr(1,subkey,".DEFAULT",1) > 0) OR (InStr(1,subkey,"S-1-5-18",1) > 0) OR (InStr(1,subkey,"S-1-5-19",1) > 0) OR (InStr(1,subkey,"S-1-5-20",1) > 0) OR (InStr(1,subkey,"_Classes",1) > 0)) Then
	'Create desired registry key/value
	strKeyPath = subkey & strRegPathSuffix
	'wscript.echo strKeyPath
	oReg.CreateKey HKEY_USERS, strKeyPath
	oReg.SetDWORDValue HKEY_USERS, strKeyPath, strRegValueName, intRegValueDec
    End If
Next

Registry String (REG_SZ) Example:

strComputer = "."
strRegPathSuffix = "\Software\Microsoft\Windows\CurrentVersion\Run"
strRegValueName = "ApplicationName"
strRegValue = "C:\Some Folder\Path To\Application.exe"
Const HKEY_USERS = &H80000003
 
Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
strKeyPath = ""
oReg.EnumKey HKEY_USERS, strKeyPath, arrSubKeys
 
For Each subkey In arrSubKeys
    'wscript.echo subkey
    'We only want to do something if the subkey does not contain any of the following: .DEFAULT or S-1-5-18 or S-1-5-19 or S-1-5-20 or _Classes
    If NOT ((InStr(1,subkey,".DEFAULT",1) > 0) OR (InStr(1,subkey,"S-1-5-18",1) > 0) OR (InStr(1,subkey,"S-1-5-19",1) > 0) OR (InStr(1,subkey,"S-1-5-20",1) > 0) OR (InStr(1,subkey,"_Classes",1) > 0)) Then
	'Create desired registry key/value
	strKeyPath = subkey & strRegPathSuffix
	'wscript.echo strKeyPath
	oReg.CreateKey HKEY_USERS, strKeyPath
	oReg.SetStringValue HKEY_USERS, strKeyPath, strRegValueName, strRegValue
    End If
Next

If you run one of the above scripts on a single computer as-is, it will enumerate all of the subkeys under HKEY_USERS, and then it will insert the desired registry key and value (the reg key and value are defined at the top of the script) into each of the HKEY_USERS subkeys for any actual user who has logged on to the computer. We skip any subkeys that contain “.DEFAULT” or “S-1-5-18” or “S-1-5-19” or “S-1-5-20” or “_Classes” so that we only end up inserting the desired key/value into the subkeys that correspond to actual users of the computers.

Executing the Script

If you want to run the script, save the script text to a text file with a .vbs extension. For the sake of this example we’ll just call it script.vbs. You could double-click on script.vbs to run it on a single computer. However, if you want to deploy the script to numerous computers, using BatchPatch, it’s very quick and easy to that. Of course the first thing you should do is modify the script so that the registry key and value that will be deployed are the key and value that you are trying to deploy. Modify the values for strRegPathSuffix, strRegValueName, and intRegValuDec so that you can deploy the desired key and value.

Note, on the target computer when the script runs the key must be created first in order for the value to be created successfully, so in the script you can see that we create the key first and then we create the value immediately after that. You will not be able to create the value if the key does not already exist and you do not create it.

To deploy the registry key/value to numerous computers using BatchPatch, all we really have to do is deploy the script to those computers. When the script is executed on those computers, the registry key/value will be created for each user that has logged on to the computer, based on the SIDs that the script finds in HKEY_USERS. Select the desired computers in the BatchPatch grid, and then click on ‘Actions > Deploy > Create/modify

Your deployment should look like the screenshot above. When you execute it, BatchPatch will copy the script.vbs file to each of the highlighted target computers, and then it will execute the script on each of those computers too. The result will be that each user who has ever logged on to any of the target computers will see the registry key/value under his/her own HKCU hive of the registry. NOTE: If a user has not ever logged on to one of the target computers, then when he/she logs on for the first time he/she will not see the key/value under his/her own HKCU hive of the registry because the script cannot create the key/value for users who don’t already exist on the computer. In such a case you would have to re-run the script after a new user has logged on to the computer for the first time, because that user’s SID will only exist in HKEY_USERS *after* he/she logs on to the computer for the first time.

In PART 2 on deploying to HKCU, I demonstrate how to deploy to HKCU for future users— users who have never logged on to the target computers but who *will* log on at some point in the future.

Posted in Blog, General, Tutorials | Tagged , , , , , , | Comments closed

Copying Files from Target Computers to the Local BatchPatch Computer

Occasionally someone asks how they can use BatchPatch to copy files from target computers back to the BatchPatch computer. While BatchPatch has a built-in function for copying files to target computers, it does not have a built-in function for copying files from target computers back to the local BatchPatch computer. Fortunately even when an action is not built-in to BatchPatch, in most cases it’s still very easy to use BatchPatch to accomplish the desired task. Below I will demonstrate how to use BatchPatch to copy a file from desired target computers back to the BatchPatch computer. We will accomplish this task using the ‘Local Process / Command’ feature in BatchPatch.

  1. Select the desired target hosts in the BatchPatch grid, and then click ‘Actions > Execute local process/command > Create/modify local command 1’
  2. In the ‘Local Process/Command 1’ window insert the following command. Of course you will need to replace the file paths in your command with whatever you need for your task. We are going to use xcopy to perform the file copy.

    Note, the destination directory specified in the command has a trailing backslash. This is necessary in some cases for xcopy to know that we are talking about a folder and not a file. Without the trailing backslash, depending on the paths used, xcopy might prompt you for input while the task is running to specify if it’s a directory or file. The problem is that we need the command to run silently without any prompting, otherwise the command will hang indefinitely because it is running hidden on the target computers. There is no way for you to respond to prompts for input while the task is executing in BatchPatch. So, if the xcopy command does not contain the trailing backslash, it might hang indefinitely. When that happens in BatchPatch we will just see ‘Executing…’ forever.

    Also note, my command contains $computer as a variable that BatchPatch will automatically replace with the actual host name from the Host column in the grid. This lets us copy a file from each target computer to a local folder, and then in the local folder a subfolder with the target computer name will be created as the destination location.

    This is the command to insert into the BatchPatch ‘Local Process/Command 1’ window:

    xcopy "\\$computer\c$\someFolder\someFile.ext" "C:\someFolder\$computer\"


    When BatchPatch executes the command above for the first row in the grid, after BatchPatch substitutes $computer for the actual computer name in the Host column for the executing row, the actual command that will get executed is:

    xcopy "\\TargetHost1\c$\someFolder\someFile.ext" "C:\someFolder\TargetHost1\"
  3. That’s actually all there is to it! You can highlight all of the desired hosts at the same time and then execute the command. You’ll end up with a folder on the BatchPatch computer with one subfolder for each target computer. Each of those subfolders will be named after the target computer. And then the desired file from each target computer will be copied into the corresponding subfolder on the BatchPatch computer.
Posted in Blog, General, Tutorials | Tagged | Comments closed

BatchPatch Service Stuck Starting?

When you want or need to have BatchPatch execute scheduled tasks even if the BatchPatch computer is not logged-on and/or you have not launched BatchPatch, the BatchPatch ‘run-as-service’ feature enables you to install BatchPatch to run as a service. You can then run any grids in this service instance so that the scheduled tasks defined in those grids will be executed regardless of whether or not anyone is actually logged on to the BatchPatch computer. This has obvious benefits. For more information on setting up and utilizing the service instance, please review this link.

Reasons for BatchPatch Service Getting Stuck Starting or Failing to Start Altogether

Under normal operating circumstances it’s very quick a painless to install and operate the service using the default installation parameters. 99% of users will be able to do this without issue. The service will install and operate without any problems on an unmodified fresh installation of Windows. However, occasionally we hear of a user having issues where the service appears to install successfully, but in the Windows Services console it gets stuck in the “starting” state. We have identified the following possible causes for this situation.

  1. Windows executable security block: Make sure that Windows has not put a security block on BatchPatch.exe, BatchPatchService.exe, or BatchPatchServiceInstance.exe. To check, right-click on each of these files and view Properties > General. If a file is blocked you’ll have an ‘Unblock‘ option as shown in the screenshot below. The BatchPatch.exe file will be located wherever you chose to put it. The BatchPatchService.exe and the BatchPatchServiceInstance.exe will be located in the directory that you selected to install the BatchPatch service (default is C:\Program Files (x86)\BatchPatch\Service )
  2. Service runner account has never logged on: If the account that you are using to install the service has never logged-on to the computer before, that could be the source of the problem. Make sure that you have logged on to the computer at least one time with the user account that will be running the service. If you use right-click run-as to run BatchPatch as a different user account from the account that you are logged-on to the computer with, make sure to log on to the computer separately with the run-as account one time. After you have logged on with the runner account once, you may switch back to the other account and then continue using right-click run-as to launch BatchPatch as the runner account without being logged on to the computer with that account.
  3. Launching BatchPatch from inside a .zip file: Make sure that you are not running the BatchPatch.exe directly from inside the BatchPatch.zip file. Please first extract the batchpatch.exe to a location on disk using the .zip extraction tool of your choice, and then double-click the batchpatch.exe to launch it. Do not simply “open” the batchpatch.zip file and double-click the batchpatch.exe without first extracting the batchpatch.exe to a new location on disk. If you launch BatchPatch directly from the unextracted .zip file and then proceed to install the service, it could create a situation where incorrect or unexpected permissions prevent the service from starting successfully.
  4. Permissions issue with service installation location: The default location for the installation of the BatchPatch service is ‘C:\Program Files (x86)\BatchPatch\Service’. If you find that the service is stuck starting, it could be due to unexpected or unusual permissions being applied to that folder. In this case we recommend uninstalling the service and then attempting to reinstall it using an installation directory that’s inside the user profile for the user running the service (e.g. if ‘SomeUser’ is the service runner account, then install the service in ‘C:\Users\SomeUser\BatchPatch\Service’ or similar location). It might be the case that modifying the permissions on the original ‘C:\Program Files (x86)\BatchPatch\Service’ directory would also fix the problem, so long as the service runner account has full read/write access to that directory. Both options are probably worth trying to see if one works for you.
  5. Service runner account is not local administrator: Make sure the service runner account is a member of the local administrators group on the computer. Membership in the local administrators group may not be required for the service to run successfully, but it’s the first best thing to try if you are having problems trying to run the service with an account that is not a member of the local administrators group. If you can get things working properly with the account in the local administrators group first, then you can work from there as a starting point if you still want to run the service without local administrator permission, in which case you would still need, at the very least, to grant the runner account the ‘Log on as a service’ security policy setting.

Other Possible Reasons for BatchPatch Service Getting Stuck Starting

If you discover a different cause for the service getting stuck in the “starting” state on your computer or simply failing to start altogether, we would really appreciate if you could please reach out to us to let us know, so that we can update this posting accordingly. Thanks!

Posted in Blog, General, Tutorials | Tagged , , | Comments closed

Online Cached Mode Fails to Download Update: Illegal characters in path. HRESULT: -2146233079

For those of you using BatchPatch in online cached mode… Starting with Windows 10/2016 version 1709 you might start seeing these two errors occur together in the ‘Local Agent Log’ column:

An exception occurred during a WebClient request.. HRESULT: -2146233079
Failed: Illegal characters in path.

The Problem:

Starting with Windows 10/2016 build 1709 Microsoft began publishing some updates with different/new update URLs in the update metadata as compared to all previous versions of Windows.

These new update URLs are formatted like this:

http://tlu.dl.delivery.mp.microsoft.com/filestreamingservice/files/096dd15c-70d9-4d48-b99c-0272f32a1853?P1=1521499885&P2=301&P3=2&P4=DS9%2bc8sTV40DeDsw3Rjf98wBE%2bifv2dl%2fV%2buaU9HtGw%3d

Instead of like this:

http://download.windowsupdate.com/c/msdownload/update/software/secu/2018/04/windows10.0-kb4093107-x64_b5d9c24dfcf332de6968faeb867a31a2d6a10e8b.cab

The URLs that Microsoft embeds in the metadata for Windows updates is how BatchPatch knows where to download updates from when BatchPatch is running in online ‘cached mode’. Unfortunately, updates with the new URL format are not able to be downloaded in a web browser or by BatchPatch. As such, when you have online cached mode enabled, if you try to update a system that is running Windows 10/2016 version 1709 or later, you might see an error. If that happens, then in your ‘Local Agent Log’ column you will see something similar to what I have pasted below. Generally, all three of these things will likely be true in order for you to be experiencing the problem described in this blog posting. If you are not seeing all three of the below items in your ‘Local Agent Log’ column, you might be experiencing a different issue:

  1. A filename that ends with this text:
    %3d
  2. Exception text:
    An exception occurred during a WebClient request.. HRESULT: -2146233079
  3. Exception text:
    Failed: Illegal characters in path

Sample Local Agent Log That Contains The Aforementioned Exception Text:

Local Agent Log
::Begin download
 
1> 80f5d408-146c-4819-b094-424d7bafa43f?P1=1518618864&P2=301&P3=2&P4=XQl9XGC2jopOymNc05rGw5X11vmG1pBIUA6TVBR5N5s%3d :: Attempt 1: Failure: An exception occurred during a WebClient request.. HRESULT: -2146233079. Attempt 2: Failure: An exception occurred during a WebClient request.. HRESULT: -2146233079.
 
::End download
 
Files downloaded: 0
Files located in cache: 0
Files excluded by filter: 0
Files initiated by another row: 0
Failures: 1
 
::Begin file copy operation
 
1> 80f5d408-146c-4819-b094-424d7bafa43f?P1=1518618864&P2=301&P3=2&P4=XQl9XGC2jopOymNc05rGw5X11vmG1pBIUA6TVBR5N5s%3d :: Failed: Illegal characters in path.
 
::End file copy operation
 
Files copied: 0
Files skipped: 0
Failures: 1

Workarounds:

  1. Disable cached mode. When BatchPatch is running in normal/default mode with no caching, this issue does not exist. If you do not have a specific need for using cached mode, then I would recommend you simply disable it and run in normal/default mode.
  2. Enable offline mode. When BatchPatch is running in offline mode (aka: offline cached mode) this issue does not exist. Offline mode will generally only install Security Updates, so it may not be optimal for you to run in this mode at all times if you want other updates to be installed. It depends on your needs and preference. If you can disable cached mode altogether, then the previous option is the best option. If you must use cached mode, then you can use offline cached mode to get the security updates installed that fail with the issue described in this blog posting.
  3. Download the .msu update file directly from the Microsoft Update Catalog. You can find your update in the catalog by going to the catalog site and searching for the desired update or by submitting the search query yourself into your browser with a link formatted as follows, but of course you’ll need to substitute the KB ID of the update that you are searching for the KB ID that is used in my link here:
    https://www.catalog.update.microsoft.com/Search.aspx?q=KB4480116

    Then after downloading the .msu update file you can deploy it directly to target computers using BatchPatch’s deployment feature. You may use this tutorial to guide you through the deployment process: Remotely Deploy a Standalone MSU File to Multiple Computers

  4. Install a WSUS server in your environment. Use it to cache the updates. Then use BatchPatch in default/normal (non-cached) mode to trigger the distribution/installation.
Posted in Blog, General, Tutorials | Tagged , | Comments closed

Remotely Deploying Windows Feature Update Version 1809 (the ‘October 2018 Update’)

In order to use BatchPatch to deploy Windows 10 feature update 1809, please follow the method outlined below. The normal Windows Update actions in BatchPatch are not sufficient for installing the feature updates to Windows 10. Also note just for the sake of clarity that even though these are considered Windows 10 feature updates, the Windows Update Agent (WUA) puts these in the update classification called Upgrades. EDIT: Starting with the April 2020 release of BatchPatch, feature updates can also now also be installed using the normal Windows update actions, though cached mode must be disabled in order for that to be successful.

  1. Obtain the Windows 10 Media Creation Tool from Microsoft. Follow this link and then choose the option to download the tool. Be careful to not select the option to ‘Update now’ because at the time of this writing the above link will have both options– a link to update the current computer plus a separate link to download the Windows 10 Media Creation Tool. If you choose ‘Update now’ you’ll begin the update process for the computer that you are using to view that webpage. Instead choose the ‘Download tool now’ option, though note that it’s very possible that Microsoft could change the language or the text on the download button by the time you are reading this to something other than ‘Download tool now’. Also note, the Windows 10 Media Creation Tool does not let you choose which version of Windows 10 it will download. It will only ever download the latest release, which at the time of this writing is version 1809. If you have another means of obtaining Windows 10 media, such as through a volume licensing agreement with Microsoft, then you may do that instead of using the media creation tool.
  2. Launch the Windows 10 Media Creation Tool that you downloaded in the previous step. NOTE, you *must* be logged on to the computer as a local administrator when you launch the tool. For reasons that Microsoft has not made clear, it is *not* sufficient to use run-as to launch the media creation tool elevated as administrator. Instead you have to actually be logged on to the computer with the admin account before you launch the tool. Otherwise you’ll end up launching the tool as a standard user and clicking through screens until the tool itself notifies you that it cannot complete its job.
  3. Use the Windows 10 Media Creation Tool to create installation media. When you run the tool you will be prompted to select either ‘Upgrade this PC now’ or ‘Create installation media (USB flash drive, DVD, or ISO file) for another PC. The goal here is not to upgrade the current PC but rather to obtain media that can be used to update other PCs, so choose the second option to ‘Create installation media…’ and then click ‘Next’.
  4. Select the desired language, edition, and architecture, and then click ‘Next’.
  5. Choose which media to use. For this tutorial you should select ISO as the media type. When you click ‘Next’ you will be prompted to choose a disk location for the ISO file to be saved. Choose a folder and then wait until the download completes. It will take some time because it’s ~4GB.
  6. Extract the ISO contents to a folder on your computer. When the download completes you will need to browse to the ISO file location. Many different tools can be used to extract the contents of the ISO file. We prefer 7-zip, which is free, for this sort of thing. When the extraction is complete you should have all of the feature update installation files in a single folder.
  7. Create a BatchPatch deployment. In BatchPatch click on Actions > Deploy > Create/modify. In the Deployment interface that appears, browse to the folder where you extracted the ISO contents, and select the setup.exe as the file to deploy. Make sure to tick the ‘Copy entire directory‘ box and the ‘Leave entire directory‘ box. When the upgrade/installation is being performed, Windows will reboot the target computer multiple times during the process. The installation/upgrade process must have access to all of the files required for the upgrade. Having both of the checkboxes ticked will ensure that the process has all of the needed files available to it during the installation. After the upgrade is complete you may delete the files from the target computer(s), but just make sure that you don’t delete them until the upgrade process is 100% complete. In your BatchPatch deployment configuration you will also need to add the following parameters:
    /auto upgrade /quiet

  8. Execute the deployment. In the deployment configuration from the previous step you can either save the deployment to execute later by using the double-right-arrow ‘>>’ button, or you can execute the deployment now for the currently selected rows in the BatchPatch grid by clicking the Execute now button. If you saved the deployment configuration for later, then when you are ready to deploy the upgrade to your target computers, go ahead an execute it by clicking Actions > Deploy > Execute deployment, and then choose the deployment that you just created/saved. The process will take some time to complete because BatchPatch has to copy the entire multi-gigabyte media folder to the target computer(s) before it can execute the upgrade. When BatchPatch shows Exit Code: 0 (SUCCESS) for a given target computer it means that the BatchPatch process has completed, but you should still expect that the target computer(s) will still be working and will still reboot at least one time but possibly multiple times while Windows is upgraded and configured, so be patient and let it complete!

    NOTE: We have had a couple of reports from users who received the following error:

    Deployment: Error: Access to the path '\\TargetComputer\C$\Program Files\BatchPatch\deployment\autorun.inf' is denied.

    It’s unclear why these users experienced this error even though most other users have executed the deployment successfully without encountering the error. My guess is it might have something to do with the application used to extract the .ISO file and the way permissions were applied or inherited. Regardless, if you encounter this error it can be resolved quickly and easily by just deleting the autorun.inf file from the source directory after extracting the ISO contents but before executing the actual deployment for any target computers. In this way when BatchPatch copies the installation files to the target computer, the autorun.inf won’t even be there, so this error won’t occur.

Posted in Blog, General, Tutorials | Tagged , , , | Comments closed