I am working on a script that will delete App-V keys stored in the registry. When a user opens an application, it creates a key within the following location:
HKLM\SOFTWARE\Microsoft\AppV\MAV\Configuration\Packages\**PackageID**\UserConfigEx\**SID**
The PackageID
and the SID
are unique each time and I want to be able to delete the SID
subkey within each PackageID
key.
The user will enter the SID and then I would like to use a wildcard (if possible) to navigate into each Package ID which is present.
So far I have the following:
#Take user input
$SID = Read-Host "Please enter users SID"
$computer = Read-Host "Please enter computer name"
#Test connection
Write-Host "Connecting to $computer"
if (Test-Connection -ComputerName $computer -Quiet -BufferSize 16 -Count 1) {
#Connect to registry and delete key
try
{
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey(‘LocalMachine’, $computer)
$regKey = $reg.OpenSubKey(“HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\AppV\\MAV\\Configuration\\Packages\\*\\UserConfigEx\\$SID”,$true )
if ($regkey.GetValue(“$SID”))
{
$regKey.DeleteValue(“$SID”)
Write-Host
Write-Host "$SID key deleted successfully" -ForegroundColor Green
}
else
{
Write-Host
Write-Host "No keys with this SID exist." -ForegroundColor Red
}
} catch {
$ErrorMessage = $_.Exception.Message
Write-Host "Unable to connect to $computer. Error: $($ErrorMessage)." -ForegroundColor Red
}
} else
{
Write-Host "Unable to connect to $computer. Please ensure correct computer name / IP address has been entered correctly." -ForegroundColor Red
}
If I run this I receive:
You cannot call a method on a null-valued expression.
At line:51 char:9
+ if ($regkey.GetValue(“$SID”))
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
I am using some of the script which I received help with here to remotely connect to the machine.
The .NET registry API doesn't support wildcards (
*
) in key paths.$regKey.GetValue()
failed, because$regKey = $reg.OpenSubKey(...)
returned$null
due to not finding a key, and calling a method on$null
always results in the error message quoted in the question.By contrast, PowerShell's registry provider, via the
*-Item*
cmdlets, does, but you need PowerShell remoting in order to use it remotely.PowerShell remoting is enabled by default on Windows Server 2012 and above; on older OS versions you can enable it by running
Enable-PSRemoting
on the target machine(s) (requires PSv3+).With PowerShell remoting enabled, you need to wrap your code in an
Invoke-Command -ComputerName <name> { ... }
call (to which you may have to pass credentials too).If enabling PowerShell remoting is not an option, you must emulate wildcard-based matching via a nested loop based on per-element wildcard matching of the results from
.GetSubkeyNames()
.As an aside: you never need to escape
\
as\\
in PowerShell strings; PowerShell uses`
as the escape character inside"..."
, so the only character you need to escape there is`
itself, as``
.A PowerShell remoting-based solution:
Note that
Invoke-Command -ComputerName ...
must be called from an elevated session (Run As Administrator
):