Mar 102015

One of my latest projects at work was to write a powershell script to remove arbitrarily selected registry entries. Here are some tips for getting along with remove-itemproperty and the registry so that it works the first time. As always, if you have any corrections or something else I could try, let me know. I could have used the reg command but that’d be cheating. 😉

So let’s define a registry path. This should be enough to work with Remove-Itemproperty becuase it does accept paths.

$RegPath1 = 'HKLM:\SOFTWARE\Wow6432Node\Cisco Systems, Inc.\Communicator'

Unfortunately it isn’t. If we run the following:

Remove-ItemProperty -Path $RegPath1 -Name TftpServer1 -Force

Powershell gives us this nice error. Which is fun because in CM12 we are running as “nt authority\system,” the grand kahuna of all accounts. More godly than administrator.

ERROR: Remove-ItemProperty : Requested registry access is not allowed.
CiscoIPC_Regkey_Removal.ps1 (24): ERROR: At Line: 24 char: 12
ERROR: + $RegKey1 | Remove-ItemProperty -Name TftpServer1 -Force
ERROR: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ERROR: + CategoryInfo : PermissionDenied: (HKEY_LOCAL_MACH...c.\Communicator:String) [Remove-ItemProperty], SecurityException
ERROR: + FullyQualifiedErrorId : System.Security.SecurityException,Microsoft.PowerShell.Commands.RemoveItemPropertyCommand

There is another way to do this. Instead of giving Remove-ItemProperty the path, use it in conjunction with Get-ItemProperty. The following works.

$RegPath1 = 'HKLM:\SOFTWARE\Wow6432Node\Cisco Systems, Inc.\Communicator'

$RegKey1 = Get-ItemProperty $RegPath1

$RegKey1 | Remove-ItemProperty -Name TftpServer1 -Force

In this case were getting an the registry key as an object and passing it to Remove-ItemProperty, which works.

Now for detecting that the key is gone. One of the other issues I encountered is that if you’re going to use if() to see if the value still exists, you need two conditions.

  • The first condition is that value has a value or …
  • The second condition is that the value is equal to $null.

I ran into this existential dilemma whenever I used the first condition only is that the if() would fail if the key value was there but didn’t have any actual value to it, which happens. So we add an -or and check to see if it -eq $null. Like so:

if (($RegKey1.TftpServer1) -or ($RegKey1.TftpServer1 -eq $null)) {

And the $Checksum will be incremented if the value exists as either null or has a value. I’ll leave the significance of the checksum up to you.

As a side note: I really wish compliance settings in SCCM 2012 could allow for direct remediation (removal) of registry keys if they shouldn’t exist, but unfortunately that isn’t the case.