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?
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?
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?
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_k ey_name);
to delete a value:
$reg_obj->DeleteValue($val ue_name);
http://search.cpan.org/~jdb/Win32-Registry-0.08/Registry.pm
to delete a key:
$reg_obj->DeleteKey($sub_k
to delete a value:
$reg_obj->DeleteValue($val
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)
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
}
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?
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
}
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.
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};
}
ASKER
Yes, it's an admin running it, but yes, the key has subkeys. I'll try the recursion then.
ASKER
I get an error:
value data cannot be a HASH reference at clearReg.pl line 13
value data cannot be a HASH reference at clearReg.pl line 13
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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.
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.
Anyway it's done the trick, thanks.
Open in new window