VMware Cloud Community
meistermn
Expert
Expert

get Set registry values in two different ways ?

I found two scripts which get and set the value for a registry key per powershell.

The first script does it native

http://www.wooditwork.com/2010/09/01/disk-timeout-settings-in-registry-for-vms-using-powercli/

The second script needs a third party tool called psremoteregistry

http://code.msdn.microsoft.com/PSRemoteRegistry

http://www.jasemccarty.com/blog/?p=691

Can anyone explain what the differens is?

Reply
0 Kudos
11 Replies
meistermn
Expert
Expert

In second step i wanted to get the antivirus symantec version from every vm.

I found already one , but I want it to combine it with the first one.

http://myitforum.com/cs2/blogs/yli628/archive/2007/02/13/powershell-script-to-get-symantec-antivirus...

After looking at the symantec side the registry is HKEY_LOCAL_MACHINE\Software\Intel\Landesk\VirusProtect6\Current Version

http://www.symantec.com/business/support/index?page=content&id=TECH103150&actp=search&viewlocale=en_...

The value of the ProductVersion is a dex value.

Symantec explains in the following KB articel how To convert the hexadecimal to a decimal number

Determining the version and build of Symantec AntiVirus Corporate

Edition or Norton AntiVirus Corporate Edition by using the registry

http://www.symantec.com/business/support/index?page=content&id=TECH99042&actp=search&viewlocale=en_U...

Reply
0 Kudos
meistermn
Expert
Expert

Now I am hanging at the script

$VMs = Get-VM | Where { $_.PowerState -eq "PoweredOn" and $_.guest.GuestFamily -eq "windowsGuest"}

$VMs = Get-VM "sv063050" | Where { $_.PowerState -eq "PoweredOn" -and $_.guest.GuestFamily -eq "windowsGuest"}

ForEach ($VM in $VMs) {

$reg = [[Microsoft.Win32.RegistryKey]|http://Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $VM.Guest.Hostname)

Write-Host "Registry Value for: "$VM.Guest.Hostname ": " $reg.OpenSubKey("Software\INTEL\LANDesk\VirusProtect6\CurrentVersion\").GetValue("ProductVersion")

}

Reply
0 Kudos
LucD
Leadership
Leadership

The first method uses the .Net method to access remote registries.

The fact that you have access to the .Net object from within PowerShell is one of the many strengths you'll find in PowerShell.

The second method uses a PowerShell module to provide a number of registry functions.

Both methods will work equally well and both are accepted methods in PowerShell.

The only (small) difference I can see is that the module is most probably provided as-is, in other words I wonder if you could open a call for the module with Microsoft.

The .Net objects on the other hand are an official, supported Microsoft product.

I would say, use what you're most comfortable with Smiley Wink

____________

Blog: LucD notes

Twitter: lucd22


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

LucD
Leadership
Leadership

What is the problem with the script ?

Do you get any error messages ? Or does it just hang ?

____________

Blog: LucD notes

Twitter: lucd22


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
meistermn
Expert
Expert

I get the following error message

You cannot call a method on a null-valued expression.

At :line:6 char:137

+ Write-Host "Registry Value for: "$VM.Guest.Hostname ": " $reg.OpenSubKey("Software\INTEL\LANDesk\VirusProtect6\CurrentVersion\").GetValue <<<< ("ProductVersion")

Reply
0 Kudos
meistermn
Expert
Expert

1.) Must on the guest system be powershell installed ?

2.) How does the authorization work to the registry ? Must the xp client were powershell is installed in the same domain ?

Reply
0 Kudos
meistermn
Expert
Expert

That is strange. From a client directly in the domain the folloing script works. From an client form a workgroup it sometimes works.

$VMs = Get-VM "sv063050" | Where { $_.PowerState -eq "PoweredOn" }

  1. SOFTWARE\INTEL\LANDesk\VirusProtect6\CurrentVersion

ForEach ($VM in $VMs) {

$reg = http://Microsoft.Win32.RegistryKey::OpenRemoteBaseKey('LocalMachine', $VM.Guest.Hostname)

Write-Host "Registry Value for: "$VM.Guest.Hostname ": " $reg.OpenSubKey("SOFTWARE\INTEL\LANDesk\VirusProtect6\CurrentVersion\").GetValue("ProductVersion")

  1. Registry Value is in a decimal format

$deci = $reg.OpenSubKey("SOFTWARE\INTEL\LANDesk\VirusProtect6\CurrentVersion\").GetValue("ProductVersion")

Write-Host "deci" $deci

  1. Convert the Decimal value to hex valuae

$hex = ::ToString($deci,16)

Write-Host " Registry Value in HEX " $hex

Which methode do I did to get the first four digits of the hex value ?

I want to do this what is decribed in the symantec articel

http://www.symantec.com/business/support/index?page=content&id=TECH99042&actp=search&viewlocale=en_U...

To convert the hexadecimal to a decimal number

1.Separate the first four digits of the hexadecimal number from the last four digits of the hexadecimal number.

For example, the hexadecimal number 034e02ee becomes 034e and 02ee.

2.Convert the first four-digit hexadecimal number to decimal, using Calc.exe or some other method.

For example, the hexadecimal number 034e becomes 846. The last two digits of this number specifies the build number. In this case, a value of 846 means build 46.

3.Convert the second four-digit hexadecimal number to decimal, using Calc.exe or some other method.

For example, the hexadecimal number 02ee becomes 750. This number specifies the version number. In this case, a value of 750 means version 7.50.

Reply
0 Kudos
meistermn
Expert
Expert

I found an issue with the script , when I want to run it against all windows vm's.

There are several case why the script can break.

a) WIndows 64 bit vm's which have a different registry path

b.) no registry path , when there is no anivirus installed

c.) a newer antivirus version e.g 11

Im sure the test-path cmdlet is the right thing to go.

http://blogs.technet.com/b/heyscriptingguy/archive/2010/03/10/hey-scripting-guy-march-10-2010.aspx

$path = "HKCU:\Software\ScriptingGuys\Test"

If(-not(Test-Path -Path $path))

{

New-Item -Path $path -Force

New-ItemProperty -Path $path -Name Update -Value "Updated"

}

Else

{

Set-ItemProperty -Path $path -Name Update -Value "New Update"

}

Would this mean following for my script:

$path = "HKLM:\SOFTWARE\INTEL\LANDesk\VirusProtect6\CurrentVersion"

If(-not(Test-Path -Path $path))

{ Write-Host "Symantec Antivirus Version 10 not installed or 64 Bit System for :" $VM.Guest.Hostname

Else

{

$reg = http://Microsoft.Win32.RegistryKey::OpenRemoteBaseKey('LocalMachine', $VM.Guest.Hostname)

Write-Host "Registry Value for: "$VM.Guest.Hostname ": " $reg.OpenSubKey("SOFTWARE\INTEL\LANDesk\VirusProtect6\CurrentVersion\").GetValue("ProductVersion")

$deci = $reg.OpenSubKey("SOFTWARE\INTEL\LANDesk\VirusProtect6\CurrentVersion\").GetValue("ProductVersion")

Write-Host "deci" $deci

  1. COnvert Decimal to Hex

$hex = ::ToString($deci,16)

Write-Host " Registry Value in HEX " $hex

}

Reply
0 Kudos
LucD
Leadership
Leadership

The OpenRemoteBaseKey method uses the RPC service on the target machine to access the remote registry.

That probably explains why the method fails on some guests.

Afaik, the Test-Path cmdlet will only work for the local registry.

The following function does the same thing but then for renote registries. It will return $true or $false depending if the registry path exists or not.

function Test-RemoteRegistryPath{
	param(
		$registry,
		$path
	)
	
	$location = $registry
	$path.Split("\") | %{
		$location = $registry.OpenSubkey($_)
		if(!$location){$false; break}
	}
	$true
}


$regPath = "SOFTWARE\INTEL\LANDesk\VirusProtect6\CurrentVersion\"
$MachineName = '.'
$reg = [http://Microsoft.Win32.RegistryKey|http://Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $MachineName)

Test-RemoteRegistryPath $reg $regPath

____________

Blog: LucD notes

Twitter: lucd22


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
meistermn
Expert
Expert

Hello Luc,

I have some more questions.

1.) The Test-path cmdlet works remote.

2.) The remote regirsty service depends on the rpc service. Does this mean , if either is not started , no powershell script will get registry access? If so that would mean that in front of this both service have to be checked.

I tried following:

The rpc service can per default not be stop (not from gui and not from command) . I proved this with command net stopp rpcss .

The second case i stopped the remote registry service. AH. If this service does not run, no remote powershell script for registry checks will work.

3.) The test-path cmdlet can only prove the registry key , but not a registry value.

Reply
0 Kudos
meistermn
Expert
Expert

I found it. The problems are the credentials.

For example, the vm's are in different domains and the client from where the powershell runs is in a workgroup.

So first step is to get the credential of the user. Maybe a step a head is to get all domains from active directory.

I start with two domains. This was the problem, why the script has aborted.

I have to questions about my script , how can get all domains , but does this mean I need a user account in every domain to get this info?

The second is how to get the domain from win32_computersystem directly in if els construct.

Get-WmiObject win32_computersystem -ComputerName $VMs -Credential(Get-Credential)

Reply
0 Kudos