Home: Perl Programming Help: Beginner:
Editing remote registry help



StarkRavingCalm
User

Dec 6, 2013, 7:31 AM


Views: 7048
Editing remote registry help

I have several hundred machines that are auto registering to an old DNS zone that we are trying to retire.
Instead of visiting all of them, I have been connecting via remote registry and editing the key.

Is there a good perl module for doing this?
Has anyone had any luck with this type of a scenario?

One snag may be that the key is never the same, although in the same tree.
i.e.. HKLM\SYSTEMControlSet001\Services\Tcpip\Parameters\Interfaces\{SOMEREALLYLONGHEXSTRING}\Domain

I would need the value for Domain to be blanked out.
It will then auto-register in the AD domain it's registered in .



Thanks in advance


FishMonger
Veteran / Moderator

Dec 6, 2013, 7:46 AM


Views: 7046
Re: [StarkRavingCalm] Editing remote registry help

Take a look at the Win32::TieRegistry module.
http://search.cpan.org/~adamk/Win32-TieRegistry-0.26/lib/Win32/TieRegistry.pm


StarkRavingCalm
User

Dec 17, 2013, 12:52 PM


Views: 6944
Re: [FishMonger] Editing remote registry help

I have a script that is getting me partly there:




Code
#!/usr/bin/perl 
use warnings;
use strict;

my %RegHash;
use Win32::TieRegistry( TiedHash => \%RegHash );
use Data::Dumper;
my $Key = $RegHash{"HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Services\\Tcpip\\Parameters\\Interfaces"};
print Dumper keys %$Key;

my $VAR1 = bless( {}, 'Win32::TieRegistry' );


I can get a list of everything under ..Interfaces but the issue I have is that the subkeys of ..Interfaces are different on every machine and I need to read a value in each of the subkeys.

As an example, this is the key I need to read:
HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Services\\Tcpip\\Parameters\\Interfaces\\UniqueHEXIdentifier\Domain

Has anyone had to do something like this before?


Thanks in advance


FishMonger
Veteran / Moderator

Dec 17, 2013, 2:05 PM


Views: 6930
Re: [StarkRavingCalm] Editing remote registry help

First, you should group all of your use statements together and don't intermix code between the use statements.

You don't need to declare %RegHash as a lexical. That hash is declared as a package global which gets exported.

You syntax for importing that hash is incorrect.


Code
#!/usr/bin/perl 

use warnings;
use strict;
use Win32::TieRegistry( TiedHash => '%RegHash' );
use Data::Dumper;


my $interfaces = $RegHash{'HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Tcpip\Parameters\Interfaces'};

foreach my $interface (keys %$interfaces) {
print Dumper $interfaces->{$interface}{Domain};
}



StarkRavingCalm
User

Dec 18, 2013, 6:26 AM


Views: 6853
Re: [FishMonger] Editing remote registry help

That worked perfectly! Thanks!

Now I need to:

Use a list of remote hosts.
And if it returns a Domain key with a particular value, to remove it. I will look into the second part first.


StarkRavingCalm
User

Dec 18, 2013, 10:51 AM


Views: 6833
Re: [StarkRavingCalm] Editing remote registry help

Ok, maybe not perfectly....

If a key has a particular value, I will need to go back around and remove it in a separate action and for that I will need the full path to the key, not just the value of said key.

So, should I, modify the code to show the full path
OR
Only show those keys which meet the criteria for the value?


Thoughts?


FishMonger
Veteran / Moderator

Dec 18, 2013, 11:51 AM


Views: 6827
Re: [StarkRavingCalm] Editing remote registry help

Are you saying that you don't know how to show or save the path?


Code
#!/usr/bin/perl  

use warnings;
use strict;
use Win32::TieRegistry( Delimiter => '/', TiedHash => '%RegHash' );
use Data::Dumper;

my $path = 'HKEY_LOCAL_MACHINE/SYSTEM/ControlSet001/Services/Tcpip/Parameters/Interfaces';
my $interfaces = $RegHash{$path};

foreach my $interface (keys %$interfaces) {
print "reg path: $path/$interface\n";
print Dumper $interfaces->{$interface}{Domain};
}



StarkRavingCalm
User

Dec 18, 2013, 1:33 PM


Views: 6821
Re: [FishMonger] Editing remote registry help

Thanks, that just what I needed.

Yeah, sometimes when a module is involved I get confused...Blush


StarkRavingCalm
User

Jan 9, 2014, 7:26 AM


Views: 6364
Re: [StarkRavingCalm] Editing remote registry help

So this gets me the results I am looking for in terms of printing out the values but I am having a hard time making it into a hash. I am guessing it is because they are scalars containing hash elements.

Is there a easy way to create a hash from what is already there?

key is $path/$interface
value is $interfaces->{$interface}{Domain}


Thanks


FishMonger
Veteran / Moderator

Jan 9, 2014, 7:36 AM


Views: 6363
Re: [StarkRavingCalm] Editing remote registry help

I'm not sure what you're wanting. The data is already in a hash but you could split out some of that data to build a new hash.

What do you what in the new hash? What should the hash keys be and what should the values be?


(This post was edited by FishMonger on Jan 9, 2014, 7:37 AM)


FishMonger
Veteran / Moderator

Jan 9, 2014, 7:53 AM


Views: 6358
Re: [StarkRavingCalm] Editing remote registry help

Is this what you're looking for?

Code
#!/usr/bin/perl 

use warnings;
use strict;
use Win32::TieRegistry( Delimiter => '/', TiedHash => '%RegHash' );
use Data::Dumper;

my $path = 'HKEY_LOCAL_MACHINE/SYSTEM/ControlSet001/Services/Tcpip/Parameters/Interfaces';
my $interfaces = $RegHash{$path};

my %domain;
foreach my $interface (keys %$interfaces) {
$domain{$interface} = $interfaces->{$interface}{Domain};
}

print Dumper \%domain;


If you want the full path as the key, then adjust the assignment to this:

Code
$domain{"$path/$interface"} = $interfaces->{$interface}{Domain};



(This post was edited by FishMonger on Jan 9, 2014, 7:58 AM)


StarkRavingCalm
User

Jan 9, 2014, 8:04 AM


Views: 6353
Re: [FishMonger] Editing remote registry help

Perfect! That's EXACTLY what I am looking for!

It all being scalars really throws me and I was trying to de-reference it to put it into a new hash.

But hey, that's why I am on the beginners forum ; )


Now to clear the values....


(This post was edited by StarkRavingCalm on Jan 9, 2014, 8:08 AM)


StarkRavingCalm
User

Jan 14, 2014, 6:46 AM


Views: 6293
Re: [StarkRavingCalm] Editing remote registry help

Ok, needed to change things up a little so I could see which contained my legacy domain and which did not.

I pushed them into arrays and it get the output as expected.

The issue I am facing now is trying to delete these results.
No matter what I try, I always get the error:

delete argument is not a HASH or ARRAY element or slice at perl-test-regkey1.pl.
txt line 60.

Even if I run it as a one-liner with the full path hard-coded:

delete "/HKEY_LOCAL_MACHINE/SYSTEM/ControlSet001/Services/Tcpip/Parameters/Interfaces/{CA63C07B-817D-4E9F-BAD8-ADDFC3FD3F36}/Domain/olddomain";

Full code follows




Code
#!/usr/bin/perl   

use warnings;
use strict;
use Win32::TieRegistry( Delimiter => '/', TiedHash => '%RegHash' );
use Data::Dumper;


my $legacydomain = 'olddomain';
my @equal;
my @notEqual;
#my $deletestring = @equal/olddomain;


my $path = '/HKEY_LOCAL_MACHINE/SYSTEM/ControlSet001/Services/Tcpip/Parameters/Interfaces';
my $interfaces = $RegHash{$path};

my %domain;
foreach my $interface (keys %$interfaces) {
#$domain{$interface} = $interfaces->{$interface}{Domain};
$domain{"$path/$interface"} = $interfaces->{$interface}{Domain};
}

#print Dumper \%domain;


foreach my $key (sort keys %domain )
{

print "Looking at $_\n";

if ( $domain{$key} =~ /olddomain/ig)
{
push(@equal, $key);
next;
}
else
{
push(@notEqual, $key);
next;
}

}

print "\n\n";
print "These contain olddomain\n";
print join("\n",@equal);

print "\n\n";
print "These DO NOT!!\n";
print join("\n",@notEqual);






foreach my $item (@equal)
{
delete "$item/Domain/olddomain";
}



FishMonger
Veteran / Moderator

Jan 14, 2014, 7:21 AM


Views: 6292
Re: [StarkRavingCalm] Editing remote registry help

You need to delete the item/key from the tied hash i.e. %RegHash.

All of the other vars are copies of portions of that hash and are no longer associated/tied to the registry.


StarkRavingCalm
User

Jan 14, 2014, 7:51 AM


Views: 6290
Re: [FishMonger] Editing remote registry help

 
Should this work?


delete "$item/$key";


FishMonger
Veteran / Moderator

Jan 14, 2014, 8:07 AM


Views: 6288
Re: [StarkRavingCalm] Editing remote registry help

No

That is a simple string, not the tied hash to the registry.

You need to use the delete function on the %RegHash hash.

delete $RegHash{ full HKEY path to the registry key to be deleted }


(This post was edited by FishMonger on Jan 14, 2014, 8:12 AM)


StarkRavingCalm
User

Jan 14, 2014, 8:56 AM


Views: 6277
Re: [FishMonger] Editing remote registry help

Something like this?


Code
 delete $RegHash{"/HKEY_LOCAL_MACHINE/SYSTEM/ControlSet001/Services/Tcpip/Parameters/Interfaces/{CA63C07B-817D-4E9F-BAD8-ADDFC3FD3F36}/Domain/olddomain"}



FishMonger
Veteran / Moderator

Jan 14, 2014, 9:15 AM


Views: 6273
Re: [StarkRavingCalm] Editing remote registry help

Yes, but in this case "olddomain" is the value, not the key. The delete function would be used to delete the "Domain" key, not its value.

If you need to clear that VALUE, then instead of using the delete function, you simply make an assignment.


Code
$RegHash{"/HKEY_LOCAL_MACHINE/SYSTEM/ControlSet001/Services/Tcpip/Parameters/Interfaces/{CA63C07B-817D-4E9F-BAD8-ADDFC3FD3F36}/Domain"} = '';


or

Code
$RegHash{"/HKEY_LOCAL_MACHINE/SYSTEM/ControlSet001/Services/Tcpip/Parameters/Interfaces/{CA63C07B-817D-4E9F-BAD8-ADDFC3FD3F36}/Domain"} = undef;



(This post was edited by FishMonger on Jan 14, 2014, 9:16 AM)


StarkRavingCalm
User

Jan 14, 2014, 9:38 AM


Views: 6266
Re: [FishMonger] Editing remote registry help

That worked!!

Thank you!

Now I just need to play with it to get to to work off of the @equal array and have it use a list of remote machines instead of the local machine (done as POC).