1

I have created a script which will search for the following registry value HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperationsand if it is present, delete it.

However, I am struggling to query the single value I want to delete rather than all values within ..\Session Manager\. I have the following code:

$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey(‘LocalMachine’, $computer)
$regKey = $reg.OpenSubKey(“SYSTEM\\CurrentControlSet\\Control\\Session Manager\\”,$true )

foreach ($key in $regKey.GetValueNames()) {

if ($key -eq “PendingFileRenameOperations”)
  {
    $regKey.DeleteValue($key)
    Write-Host "PendingFileRenameOperations key deleted successfully" -ForegroundColor Green
  }
else
  {
    Write-Host "Key does not exist. Please assign to Second Line for further investigation" -ForegroundColor Red
  }
}

Which outputs the following:

Key does not exist. No further action required
Key does not exist. No further action required
Key does not exist. No further action required
Key does not exist. No further action required
Key does not exist. No further action required
Key does not exist. No further action required
Key does not exist. No further action required
Key does not exist. No further action required
Key does not exist. No further action required
Key does not exist. No further action required
Key does not exist. No further action required
Key does not exist. No further action required
Key does not exist. No further action required
Key does not exist. No further action required
Key does not exist. No further action required
PendingFileRenameOperations key deleted successfully

Is it possible to just output either Key does not exist. No further action required or PendingFileRenameOperations key deleted successfully rather than querying every single value?

ryanmaddock
  • 134
  • 1
  • 2
  • 15
  • Let's get some terms straight first. Are you actually looking for a subkey? Because your code is looking for a value ***not*** a subkey. – EBGreen Mar 19 '18 at 14:37
  • Apologies, I was unsure of the correct terminology. I have amended this now. It is the Value which I am trying to delete. – ryanmaddock Mar 19 '18 at 14:42
  • The Subkey object ($regKey in your code) has a .GetValue() method. Just use that and if the returned value is not null then delete the value. – EBGreen Mar 19 '18 at 14:43
  • Use `Get-ItemProperty` and `Remove-ItemProperty` cmdlets... Manually interacting with .net classes should be avoided when possible. – Maximilian Burszley Mar 19 '18 at 14:51

1 Answers1

3

To expound on my comment:

$ErrorActionPreference = 'SilentlyContinue'
$Path = 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager'
$Name = 'PendingFileRenameOperations'
If (Get-ItemProperty -Path $Path -Name $Name)
{
    Remove-ItemProperty -Path $Path -Name $Name
    "Property '$Name' removed."
}
Else
{
    "Property '$Name' did not exist."
}

For your specific question, create a flag variable:

$Flag = $True
foreach ($property in $regKey.GetValueNames())
{
  if ($property -eq 'PendingFileRenameOperations')
  {
    $regKey.DeleteValue($property)
    Write-Host "PendingFileRenameOperations key deleted successfully" -ForegroundColor Green
    $Flag = $False
    break
  }
}
if ($Flag)
{
  Write-Host 'Property does not exist. Please assign to Second Line for further investigation' -ForegroundColor Red
}

And with respect to @EBGreen's suggestion:

If ($regKey.GetValue('PendingFileRenameOperations'))
{
    $regKey.DeleteValue('PendingFileRenameOperations')
    Write-Host 'PendingFileRenameOperations property deleted successfully' -ForegroundColor Green
}
Else
{
    Write-Host 'Property does not exist. Please assign to Second Line for further investigation' -ForegroundColor Red
}
Maximilian Burszley
  • 18,243
  • 4
  • 34
  • 63
  • Unless I am missing something the poster is doing this remotely. – EBGreen Mar 19 '18 at 14:55
  • Again, maybe I'm blind but the first line is opening the LOCALMACHINE hive on whatever computer's name is in $computer. – EBGreen Mar 19 '18 at 14:57
  • @EBGreen I see what you mean now. I glossed over that since OP didn't explicitly say he was trying to do this remotely. In that case, he could always use wmi (which is the easier way to go) or utilize WinRM – Maximilian Burszley Mar 19 '18 at 14:59
  • Meh, I move around to a lot of different environments and it is pretty common for WinRM to be disabled but remote registry to be enabled. Of course I always point out that this is a silly configuration. It rarely helps. In these situations I find the .Net classes the easiest to use but it is really just personal preference. – EBGreen Mar 19 '18 at 15:01
  • @EBGreen I end up with a lot of runas situations with different sets of credentials and the .net classes are hard to pass such credentials unlike the wmi cmdlets in my experience. I've updated my answer to address his question after re-reading it – Maximilian Burszley Mar 19 '18 at 15:03
  • I still think it is silly to iterate all the values when .GetValue() will return null if the value does not exist. – EBGreen Mar 19 '18 at 15:05
  • @EBGreen Updated with your suggestion. I don't do a lot of remote registry so I wasn't aware of that one – Maximilian Burszley Mar 19 '18 at 15:08
  • At the end of the day it is an admin scripting language so whichever way you do it if you get the result you need then by definition you did it right. :) – EBGreen Mar 19 '18 at 15:08
  • Thanks for the suggestions both. Yes sorry forgot to mention it is a remote script. @EBGreen - your suggestion has worked perfectly. Marked as answered. – ryanmaddock Mar 20 '18 at 07:50