Skip to content

Instantly share code, notes, and snippets.

@rileyz
Last active March 9, 2022 13:31
Show Gist options
  • Save rileyz/87786a986fa6cd6d4ec8d9c3e8576634 to your computer and use it in GitHub Desktop.
Save rileyz/87786a986fa6cd6d4ec8d9c3e8576634 to your computer and use it in GitHub Desktop.
<#
.SYNOPSIS
Script to assist with managing Office Add-ins via the OPENx Values in the HKCU registry.
.DESCRIPTION
Intended Use
This script was produced to assist in adding or removing Office Add-ins. In the Office
application, the settings dialog can be found in File > Options > Add-ins >
Manage Add-ins > Go.
In the registry, the OPENx Values can be found in the registry, for example.
HKCU:\SOFTWARE\Microsoft\Office\16.0\Excel\Options
For more information about the OPENx Values, please view the URL below.
https://bettersolutions.com/excel/add-ins/registry-keys.htm
About
This script was created to solve the issue of adding or removing a OPENx numbered Values,
because OPENx Values can be numbered and ordered differently for each user.
Known Defects/Bugs
* Bug where single quotes must be used for the parameter OfficeAddinsValueData, or double quotes
within the value cannot be escaped. The registry value data normally uses double quotes for
string encapsulation.
Code Snippet Credits
* https://github.com/rileyz/VMR-Stable/blob/master/Virtual%20Machine%20Runner/Framework/Core_CommonFunctions.ps1
* https://devblogs.microsoft.com/scripting/use-powershell-to-enumerate-registry-property-values/
Version History
1.00 2022-03-09
Initial release.
1.01 2022-03-09
Bug fix where if $OfficeOPENxArray was null, it would cause an error.
Copyright & Intellectual Property
Feel to copy, modify and redistribute, but please pay credit where it is due.
Feed back is welcome, please contact me on LinkedIn.
.LINK
Author:.......https://www.linkedin.com/in/rileylim
Source Code:..https://gist.github.com/rileyz/87786a986fa6cd6d4ec8d9c3e8576634
Article:......https://www
.EXAMPLE
Parameters example.
-Mode Add|Remove
Adding or removing the OPENx Value.
-OfficeAddinsRegistryKey 'HKCU:\SOFTWARE\Microsoft\Office\16.0\Excel\Options'
Path to HKCU Office application Options key.
-OfficeAddinsValueData '"C:\Program Files (x86)\Contoso\Finance.xla"'
Path to the Add-in
.EXAMPLE
To add a Excel Add-in to a user.
Manage-OfficeAddins -Mode add -OfficeAddinsRegistryKey 'HKCU:\SOFTWARE\Microsoft\Office\16.0\Excel\Options' -OfficeAddinsValueData '"C:\Program Files (x86)\Contoso\Finance.xla"'
.EXAMPLE
To add a Excel Add-in to a user.
Manage-OfficeAddins -Mode add -OfficeAddinsRegistryKey 'HKCU:\SOFTWARE\Microsoft\Office\16.0\Excel\Options' -OfficeAddinsValueData '/A "Contoso.PaySlip.Control"'
.EXAMPLE
To remove a Excel Add-in to a user.
Manage-OfficeAddins -Mode add -OfficeAddinsRegistryKey 'HKCU:\SOFTWARE\Microsoft\Office\16.0\Excel\Options' -OfficeAddinsValueData '"C:\Program Files (x86)\Contoso\Finance.xla"'
.EXAMPLE
To remove a Excel Add-in to a user.
Manage-OfficeAddins -Mode add -OfficeAddinsRegistryKey 'HKCU:\SOFTWARE\Microsoft\Office\16.0\Excel\Options' -OfficeAddinsValueData '/A "Contoso.PaySlip.Control"'
#>
# Function List ###################################################################################
Function Get-RegistryKeyPropertiesAndValues
{
<#
.Synopsis
This function accepts a registry path and returns all reg key properties and values
.Description
This function returns registry key properies and values.
.Example
Get-RegistryKeyPropertiesAndValues -path ‘HKCU:\Volatile Environment’
Returns all of the registry property values under the \volatile environment key
.Parameter path
The path to the registry key
.Notes
NAME: Get-RegistryKeyPropertiesAndValues
AUTHOR: ed wilson, msft
LASTEDIT: 05/09/2012 15:18:41
KEYWORDS: Operating System, Registry, Scripting Techniques, Getting Started
HSG: 5-11-12
.Link
Http://www.ScriptingGuys.com/blog
#Requires -Version 2.0
#>
Param(
[Parameter(Mandatory=$true)]
[string]$path)
Push-Location
Set-Location -Path $path
Get-Item . |
Select-Object -ExpandProperty property |
ForEach-Object {
New-Object psobject -Property @{“property”=$_;
"Value" = (Get-ItemProperty -Path . -Name $_).$_}}
Pop-Location
} #end function Get-RegistryKeyPropertiesAndValues
Function Manage-OfficeAddins {
Param ([Parameter(Mandatory=$true)][ValidateSet('Add','Remove')][string[]]$Mode,
[Parameter(Mandatory=$true)][String]$OfficeAddinsRegistryKey,
[Parameter(Mandatory=$true)][String]$OfficeAddinsValueData
)
#Load raw array with all OPENx registry values and data.
$RawArray = Get-RegistryKeyPropertiesAndValues "$OfficeAddinsRegistryKey" | where {$_.property -like 'OPEN*'}
#Bash array to split the values to get just the number.
$OfficeOPENxArray = @()
$RawArray | foreach {
Write-Debug "Property: $($_.property)"
Write-Debug "Value: $($_.Value)"
Write-Debug "OPENx: $(($_.property -split 'OPEN')[1])"
$PSCustomObject = [PSCustomObject]@{
RegistryValueNameX = [int]($_.property -split 'OPEN')[1]
RegistryValueData = $_.Value
}
$OfficeOPENxArray += $PSCustomObject
}
#Sorting to ensure ordering.
$OfficeOPENxArray = $OfficeOPENxArray | sort -Property RegistryValueNameX
Write-Debug $($OfficeOPENxArray | Out-String)
#Working out the next free number for OPENx.
if ($OfficeOPENxArray -eq $null) {
$NextFreeOPENxNumber = ''
} else {
$NextFreeOPENxNumber = (($OfficeOPENxArray[$($OfficeOPENxArray.Count - 1)].RegistryValueNameX)) + 1
}
Write-Debug "NextFreeOPENxNumber: $NextFreeOPENxNumber"
Write-Verbose "Manage-OfficeAddins mode is $Mode."
Switch ($Mode) {
'Add' {if (!($OfficeOPENxArray.RegistryValueData -contains $OfficeAddinsValueData)) {
Write-Verbose " Addin not found, adding $('OPEN' + "$NextFreeOPENxNumber") Value and Data."
$Result = Write-Registry -RegistryKey "$OfficeAddinsRegistryKey" -RegistryValueName $('OPEN' + "$NextFreeOPENxNumber") -RegistryValueData "$OfficeAddinsValueData" -RegistryValueType String
Write-Debug "Write-Registry result $Result."
} else {
Write-Verbose ' Addin found, no action required.'
}
}
'Remove' {$OfficeOPENxArray | foreach {
Write-Debug "RegistryValueNameX: $($_.RegistryValueNameX)"
Write-Debug "RegistryValueData: $($_.RegistryValueData)"
if ($_.RegistryValueData -contains "$OfficeAddinsValueData") {
if ($($_.RegistryValueNameX) -eq 0) {
$RemoveRegistryValue = 'OPEN'
} else {
$RemoveRegistryValue = $('OPEN' + $_.RegistryValueNameX)
}
Write-Verbose " Addin found, removing $RemoveRegistryValue Value and Data."
Remove-ItemProperty -Path "$OfficeAddinsRegistryKey" -Name $RemoveRegistryValue
}
}
}
}
} #End Function Manage-OfficeAddins
Function Write-Registry {
Param ([Parameter(Mandatory=$true)][String]$RegistryKey,
[Parameter(Mandatory=$true)][String]$RegistryValueName,
[String]$RegistryValueData,
[Parameter(Mandatory=$true)][String]$RegistryValueType,
[Switch]$EnableReflectiontoWOW3264Node)
#Need to add logic to write to WOW3264Node if in 64bit system via switch.
Try {Switch ((Get-ItemProperty -Path $RegistryKey -Name $RegistryValueName -ErrorAction SilentlyContinue).$RegistryValueName.gettype().name)
{'String' {$RegistryValueTypeCheck = 'String'}
'Int32' {$RegistryValueTypeCheck = 'DWord'}
'Int64' {$RegistryValueTypeCheck = 'QWord'}
'String[]' {$RegistryValueTypeCheck = 'MultiString'}
'Byte[]' {$RegistryValueTypeCheck = 'Binary'}
Default {Return 'Unable to discover registry type for overwrite check'}}}
Catch {$RegistryValueTypeCheck = $null}
If ($RegistryValueTypeCheck -ne $null)
{If ($RegistryValueTypeCheck -ne $RegistryValueType)
{Return 'Registry type mismatch'}}
#Force create the registry path.
If (((Test-Path $RegistryKey) -replace "`n|`r") -eq 'False')
{$null = New-Item -Path $RegistryKey -Force}
Switch ($RegistryValueTypeCheck)
{MultiString {#Writing registry MultiString value.
$MultiStringArray = Get-ItemProperty -Path $RegistryKey | Select-Object -ExpandProperty $RegistryValueName
$MultiStringArray = @($MultiStringArray | where {$_ -ne $RegistryValueData})
If ($MultiStringArray -notcontains $RegistryValueData)
{$MultiStringArray += $RegistryValueData}
#Not in use yet, needs coded into params.
If ($Remove -eq $true)
{$MultiStringArray = @($MultiStringArray | where { $_ -ne $RegistryValueData })}
Set-ItemProperty -Path $RegistryKey -type $RegistryValueTypeCheck -Name $RegistryValueName -Value $MultiStringArray
Try {$RegistryWriteCheck = Get-ItemProperty -Path $RegistryKey | Select-Object -ExpandProperty $RegistryValueName
If ($RegistryWriteCheck -contains $RegistryValueData)
{$RegistryWriteCheck = $null
Return '0'}
Else{Return 'Unexpected value on validation'}}
Catch {Return 'Error'}}
Default {#Writing registry String, Dword, Qword, value.
$null = New-ItemProperty -Path $RegistryKey -Name $RegistryValueName -Value $RegistryValueData -PropertyType $RegistryValueType -Force
Try {$RegistryWriteCheck = (Get-ItemProperty -Path $RegistryKey | Select-Object -ExpandProperty $RegistryValueName)
If ($RegistryWriteCheck -eq $RegistryValueData)
{$RegistryWriteCheck = $null
Return '0'}
Else{Return 'Unexpected value on validation'}}
Catch {Return 'Error'}}}
#https://social.technet.microsoft.com/Forums/windowsserver/en-US/6ccf94ee-9a15-49fc-9abf-0050b66b0643/registry-how-to-test-the-type-of-a-value
#http://blogs.technet.com/b/heyscriptingguy/archive/2015/04/02/update-or-add-registry-key-value-with-powershell.aspx
#http://stackoverflow.com/questions/27238523/editing-a-multistring-array-for-a-registry-value-in-powershell
#http://www.jonathanmedd.net/2014/02/testing-for-the-presence-of-a-registry-key-and-value.html
#https://msdn.microsoft.com/en-us/library/microsoft.win32.registryvaluekind(v=vs.110).aspx
} #End Function Write-Registry
#<<< End Of Function List >>>
# Setting up housekeeping #########################################################################
$DebugPreference = 'SilentlyContinue' #SilentlyContinue|Continue
$VerbosePreference = 'SilentlyContinue' #SilentlyContinue|Continue
#<<< End of Setting up housekeeping >>>
# Start of script work ############################################################################
Manage-OfficeAddins -Mode add -OfficeAddinsRegistryKey 'HKCU:\SOFTWARE\Microsoft\Office\16.0\Excel\Options' -OfficeAddinsValueData '"C:\Program Files (x86)\Contoso\Finance.xla"'
Manage-OfficeAddins -Mode add -OfficeAddinsRegistryKey 'HKCU:\SOFTWARE\Microsoft\Office\16.0\Excel\Options' -OfficeAddinsValueData '/A "Contoso.PaySlip.Control"'
Manage-OfficeAddins -Mode Remove -OfficeAddinsRegistryKey 'HKCU:\SOFTWARE\Microsoft\Office\16.0\Excel\Options' -OfficeAddinsValueData '"C:\Program Files (x86)\Contoso\Finance.xla"'
Manage-OfficeAddins -Mode Remove -OfficeAddinsRegistryKey 'HKCU:\SOFTWARE\Microsoft\Office\16.0\Excel\Options' -OfficeAddinsValueData '/A "Contoso.PaySlip.Control"'
#<<< End of script work >>>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment