Sometimes when patching a SharePoint farm with multiple SharePoint servers the SharePoint Configuration Wizard or the Central Admin complains that one or more servers in the farm are missing a specific fix although this fix has actually been installed on these server.
If you read certain blog posts or forum entries you will usually find the recommendation to run Get-SPProduct -local to fix this problem.
Why does this happen and why will executing the Powershell command Get-SPProduct -local fix the problem?
First of all let me explain how SharePoint Configuration Wizard running on one machine knows about fixes installed on the another machine in the same farm before SharePoint Configuration Wizard has been executed on these other machines.
A common understanding is that SharePoint updates are split into two different steps:
- Installation of the actual binaries on the machine
- Execution of the SharePoint Configuration Wizard to perform updates in the SharePoint databases
The reality is not that simple.
As explained in the past the SharePoint Configuration Wizard does not only perform database updates - it also does lots of stuff on the local machine like copying files around, settings ACLs on files, ...
A less known fact is that installing the binaries also updates some information in the SharePoint config database.
How does this happen?
The installation packages for SharePoint fixes include some custom actions which (e.g.) guarantee that the WWW Publishing Service of IIS and the SharePoint Timer Services (owstimer.exe) get stopped before the binaries are installed and that these services will be restarted afterwards.
In addition one of these custom actions sets the CreateProductVersionJob registry value to "1" if the patch installed successfully:
Whenever the SharePoint Timer Services starts it checks the value of this registry key and verifies if it is set to 1. If this is the case the SharePoint timer service creates an instance of the Product Version Job timerjob based on the SPProductVersionJobDefinition which is scheduled to execute directly after the start of the SharePoint timer service.
This timerjob uses the windows installer information on the local machine and updates the information about all installed SharePoint packages (including all installed SharePoint hotfixes) in the SharePoint configuration database. At the end of this timerjob the CreateProductVersionJob registry value is set back to 0 to ensure that the timerjob is not created during the next restarts of the timer service.
In theory that should guarantee that the information about all installed patches on each machine in the SharePoint farm is correctly updated whenever the SharePoint Timer service starts on this box after a hotfix has been installed. But in some scenarios this can fail. Common reasons for this are that the SharePoint timer job is disabled on a specific server in the farm. Other reasons are that the account of the SharePoint Timer services does not have permission to read the information about the installed patches from the registry and therefor cannot update the information in the SharePoint Config DB.
The workaround using Get-SPProduct -local
Why does Get-SPProduct -local help here?
The reason is simple: this Powershell command performs exactly the same steps as done by the Product Version Job timerjob. You would not expect this as this Powershell command starts with a "Get" verb. It is not obvious that this command performs update operations in the SharePoint database - but before retrieving the information for the current server from the database the Powershell command first ensures that this information is accurate by updating the information in the SharePoint configuration database.
When using this command the operation is performed directly in powershell.exe and not in a timerjob and it will use the account of the powershell.exe - usually the account of the person logged on to the machine which is often a different account than the farm account used by the SharePoint timer service.
Improvements in the SharePoint Configuration Wizard
In the past the SharePoint Configuration Wizard only verified if the most current patches are installed on all servers in the farm and showed a report with the servers which are missing fixes.
The latest version of the SharePoint Configuration Wizard (currently released with August 2016 CU for SharePoint 2016) has been updated to perform the same operation as the Product Version Job timerjob and Get-SPProduct -local if it identifies that the server it is running on is on the list of servers that misses a specific fix.
That means that running the SharePoint Configuration Wizard will fix the patch registration for the local server automatically if required - of course it cannot do this in case that other servers in the farm are affected. But running the SharePoint Configuration Wizard on these other servers will correct the issue on these servers without a need to run the Get-SPProduct -local Powershell command.
For SharePoint 2013 it is planned to release this change in a couple of months in one of the next CUs.