Re-enable Microsoft Office Add-ins with PowerShell

We have some products that include MS Office add-ins that are regularly disabled by the various Office applications because they’re “blamed” for an app crash. Two examples of this are HP Autonomy WorkSite EDMS and Shoretel Communicator.

This script is designed to be deployed and run by scheduled task on all workstations in a domain.

It goes through the registry and finds all matching disabled items and COM add-ins, and re-enables them.

The Office application in question still needs to be restarted after this script has been run. Users usually don’t notice that these add-ins have become disabled, and that causes issues. At least this will cause the add-in to load at the next load of the application in question.

<#
.SYNOPSIS
Enable-DisabledOfficeAddins.ps1 – Enable specific Office add-ins
.DESCRIPTION
Re-enables specific Microsoft Office add-ins that are:
1. Listed in Disabled Items
2. Disabled in COM Add-Ins
This is designed to re-enable troublesome add-ins that often get disabled by Office. In this case,
it's add-ins for the HP Interwoven WorkSite EDMS product.
The best use for this is to add a scheduled task that runs every 15 minutes or so. Note that the Office application
in question also needs to be restarted for the add-in to load again.
You could also potentially attach a trigger to the following Event Log events:
-Application Log EventID 1000 Source "Application Error"
-Application Log EventID 59 Source "Outlook" – OL2013 logs this event when it disables an add-in
Update: This was originally written as a user-scope script, but I've modified it to run at the machine level. This makes it
easier to run invisibly as a scheduled task.
.OUTPUTS
Output is to log file in c:\temp\enable_addins.log by default
.LINK
https://daniel.streefkerkonline.com/re-enable-microsoft-office-add-ins-with-powershell/
.NOTES
Written By: Daniel Streefkerk
Website: http://daniel.streefkerkonline.com
Twitter: http://twitter.com/dstreefkerk
Change Log
v1.0, 09/04/2014 – Initial version
v1.4, 14/05/2014 – Modified to work against HKLM instead of HKCU
#>
#region Setup
# Match these strings when looking at the disabled items
$disabledItemSearchStrings = "interwoven","worksite"
$comAddInSearchStrings = "imFileSite", "IWRibbon", "zWorkSite", "oUTR02K", "WorkSiteOffice2007Addins" #zWorkSite is a custom add-in we use in-house, the others are standard
$disabledItemsCount = 0
$comAddinsCount = 0
$logFile = "c:\temp\enable_addins.log"
$loadBehaviours = @{ 0 = "Unloaded, Do not load automatically";
1 = "Loaded, Do not load automatically";
2 = "Unloaded, Load at startup";
3 = "Loaded, Load at startup";
8 = "Unloaded, Load on demand";
9 = "Loaded, Load on demand";
16 = "Loaded, Load first time, then load on demand"
}
#endregion
#region Functions
# Basic logging functionality
Function LogWrite
{
Param ([string]$LogText)
Write-Host $LogText
Add-content $logFile value $LogText
}
#endregion
LogWrite "—————start—————"
LogWrite "Running script at $(Get-Date) on $env:COMPUTERNAME"
#region Delete add-ins from Disabled items in registry
# Recurse through the MS Office registry keys under HKEY_USERS to find "DisabledItems" keys for domain users
$disabledItemKeys = Get-ChildItem Path "Registry::HKEY_USERS\S-1-5-21-*\Software\Microsoft\Office" Recurse ErrorAction SilentlyContinue WarningAction SilentlyContinue | ? FilterScript {($_.Name -clike "*DisabledItems*") -and ($_.ValueCount -gt 0)}
# If there was an error reading the registry, or there are no keys found, exit
if (($disabledItemKeys -eq $null) -or ($disabledItemKeys.Count -eq 0)) { exit }
# Loop through they DisabledItem keys for each office application
foreach ($key in $disabledItemKeys) {
# Loop through the disabled items within each application
foreach ($disabledItem in $key.GetValueNames()) {
# Convert the binary-encoded add-in name to text. Remove the null characters to make this a comparable string
$itemName = [Text.Encoding]::ASCII.getString($key.GetValue($disabledItem)).Replace("`0","")
# If the name doesn't match one of our search strings, go to the next item
if (($itemName | Select-String Pattern $disabledItemSearchStrings).Matches.Count -le 0) { break }
LogWrite "$itemName matched search pattern."
# Delete the disabled item value from the registry
Remove-ItemProperty Path "Registry::$($key.Name)" Name $disabledItem
LogWrite "Removed $itemName from DisabledItems in registry."
$disabledItemsCount ++
}
}
LogWrite "$disabledItemscount disabled items re-enabled"
#endregion
#region Enable COM add-ins
$officeUserAddins = Get-ChildItem Path "HKCU:\Software\Microsoft\Office" Recurse ErrorAction SilentlyContinue WarningAction SilentlyContinue | ? FilterScript {($_.Name -like "*Addins*") -and ($_.ValueCount -gt 0)}
# If there was an error reading the registry, or there are no keys found, exit
if (($officeUserAddins -eq $null) -or ($officeUserAddins.Count -eq 0)) { exit }
# Loop through all Office Add-ins that match our search strings and don't have a LoadBehavior = 3
foreach ($userAddin in ($officeUserAddins | ? FilterScript {($_ | Select-String Pattern $comAddInSearchStrings) -and ($_.Property -eq "LoadBehavior") -and ($_.GetValue("LoadBehavior") -ne 3)})) {
LogWrite "$($userAddin.Name) LoadBehavior set to '$($loadBehaviours[$userAddin.GetValue("LoadBehavior")])'. Attempting to set it to '$($loadBehaviours[3])'."
# Set the LoadBehavior to 3 as it should be.
Set-ItemProperty Path "Registry::$($userAddin.Name)" Name "LoadBehavior" Value 3
LogWrite "LoadBehaviour for $($userAddin.Name) corrected. Now set to: '$($loadBehaviours[$userAddin.GetValue("LoadBehavior")])'."
$comAddinsCount ++
}
LogWrite "$comAddinsCount COM add-ins' LoadBehavior value corrected"
LogWrite "—————-end—————-"
#endregion