Link to home
Start Free TrialLog in
Avatar of Belazir
Belazir

asked on

Delete registry keys

I need a little script to delete some registry keys on a terminal server that I'm administering.  I basically need the same key deleting for every user, the key is in the SOFTWARE section, and I want all subkeys of the named key deleting too.  I've tried to do this in .NET and I can work it on my PC but it won't work on the server, I get one of those helpful non-specific error messages - I've a separate question open for that but I'm getting tumbleweeds at the moment.

So in essence I need to iterate through the keys in HKEY_USERS and check for existence of a key under SOFTWARE, deleting it and all its subkeys if it exists.

Can anyone assist please?
Avatar of Adam314
Adam314


use Win32::TieRegistry (Delimiter => '/');
 
delete $Registry->{"HKEY_USERS/$_/path/to/the/key/you/want/to/delete/"} foreach (keys %{ $Registry->{HKEY_USERS} });

Open in new window

Avatar of Belazir

ASKER

Looks close, but the key won't be in every reg entry under Users.  How would I add to this to (a) test whether the key name ends with _Classes (in which case it won't be there) and (b) whether the key is actually there?  Or will this not error and just ignore it if the key isn't there?
Avatar of Suhas .
Please go through the module Win32::Registry

http://search.cpan.org/~jdb/Win32-Registry-0.08/Registry.pm 

to delete a key:
 $reg_obj->DeleteKey($sub_key_name);

to delete a value:
 $reg_obj->DeleteValue($value_name);
Avatar of Belazir

ASKER

Su - with all due respect, if I had time to do that I probably wouldn't have posted a question here.  I'm looking for a quick win.  Thx B
The Win32::Registry module is obsolete, and it's documentation even states this on the FIRST line, stateing you should use Win32::TieRegistry!!!

The code I gave will simply skip that key if the registry key does not exist.  It will not cause an error.

For checking if the key name ends in _Classes, and if it exists (which is probably not necessary from your description, but anyways)

foreach (keys %{ $Registry->{HKEY_USERS} }) {
    next if /_Classes$/;    #skip keys ending in _Classes
    next unless exists($Registry->{'HKEY_USERS/$_/path/to/key/to/delete'}) #skip if key doesn't exist
    delete $Registry->{"HKEY_USERS/$_/path/to/the/key/to/delete/"}; #delete
}

Open in new window

Avatar of Belazir

ASKER

So now I have the attached (modified slightly).

However the keys aren't deleting.  I know they're now passing both the conditions because my print line is running, so it knows the key exists - but it's not deleting.

Any idea why, or how I find out what the error is?
use Win32::TieRegistry (Delimiter => '/');
 
foreach (keys %{ $Registry->{HKEY_USERS} }) {
    next if /_Classes/;    #skip keys ending in _Classes
    next unless exists($Registry->{'HKEY_USERS/'.$_.'SOFTWARE/MyKey/'}); #skip if key doesn't exist
    print 'HKEY_USERS/'.$_.'SOFTWARE/MyKey/'."\n";
    delete $Registry->{'HKEY_USERS/'.$_.'SOFTWARE/MyKey/'}; #delete
} 

Open in new window

Does the user running the script have permission to delete keys for other users?  This probably means the user running the script has to be Administrator.  

Also, if the key you are trying to delete has subkeys, they will have to be deleted first.  Attached is a script that will delete recursively all the subkeys, then delete the requested key.
use Win32::TieRegistry (Delimiter => '/');
 
foreach (keys %{ $Registry->{HKEY_USERS} }) {
    next if /_Classes/;    #skip keys ending in _Classes
    next unless exists($Registry->{'HKEY_USERS/'.$_.'SOFTWARE/MyKey/'}); #skip if key doesn't exist
    print 'HKEY_USERS/'.$_.'SOFTWARE/MyKey/'."\n";
    DeleteRecursive("HKEY_USERS/${_}SOFTWARE/MyKey/");
}
 
sub DeleteRecursive {
	my $key=shift;
	$key .= "/" unless $key =~ m|/$|;  #make sure key ends in slash
	DeleteRecursive("$key$_") foreach (keys %{$Registry->{$key}});
	delete $Registry->{$key};
}

Open in new window

Avatar of Belazir

ASKER

Yes, it's an admin running it, but yes, the key has subkeys.  I'll try the recursion then.
Avatar of Belazir

ASKER

I get an error:

  value data cannot be a HASH reference at clearReg.pl line 13
ASKER CERTIFIED SOLUTION
Avatar of Adam314
Adam314

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Belazir

ASKER

That seems to be doing the trick.  Wish I could have got this working in .NET as this is very slow, the keys I'm deleting are big...
I doubt it would have been faster in .NET.  I'm guessing either way, the program is making calls to the same windows API.  
Avatar of Belazir

ASKER

There's an API though in .NET that deletes all rather than using recursion so it doesn't need to keep returning control to the application.

Anyway it's done the trick, thanks.