DyJohnnY
Enthusiast
Enthusiast

Find the name of the DB Server for vCenter

Hi,

I'm trying to make a script that will locate the vCenter VM and its database in a cluster. we have the frontend and DB on separate VMs.

However I'm not sure how to find the name of the database server. Is this information coded somewhere in vCenter? or perhaps some of its XML files?

Thanks,
Ionut

IonutN ( blog - www.rivnet.ro)
0 Kudos
10 Replies
RvdNieuwendijk
Leadership
Leadership

The connection with the vCenter database is probably made with an ODBC connection. You can find the ODBC connections in the registry under  HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBC.INI. For every connection there is a subkey. You can easily create a PowerShell script to read from the registry. Something like:

(Get-ItemProperty HKLM:\SOFTWARE\ODBC\ODBC.INI\vCenter).Server


Regards, Robert

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition
0 Kudos
LucD
Leadership
Leadership

You can make this a bit more intelligent by looking up the DSN name for the vCenter DB and then retrieving the servername.

Somehting like this

$vcName = $defaultVIServer.Name
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $vcName)
$vcKeys = $reg.OpenSubKey("SOFTWARE\\VMware, Inc.\\VMware VirtualCenter\\DB")
$dsnName = $vcKeys.GetValue("1")
$odbcKeys = $reg.OpenSubKey("SOFTWARE\\ODBC\\ODBC.INI\\" + $dsnName)
$dbServer = $odbcKeys.GetValue("Server")

Write-Host
"vCenter server:" $vcName
Write-Host
"vCenter DB server:" $dbServer

Note that the script assumes you have a connection to the vCenter open.

The script was tested against vCenter 4.1.

It could be that for other vCenter version you will have to update the registry path to the vCenter keys.


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

maishsk
Expert
Expert

You will of course have to know the name of the vCenter Server and I assume that the ODBC DSN Connection is the only one that is on the machine and it has the letter "V" in the name.

You can do it remotely.

$ComputerName = "<COMPUTERNAME>"

$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $computerName)

$regkey = $reg.OpenSubKey("SOFTWARE\\ODBC\\ODBC.INI")


$match = $regkey.GetSubKeyNames() -match "*V*"

if ($match) {

     $regkey = $reg.OpenSubKey("SOFTWARE\\ODBC\\ODBC.INI\\$($match)")
     Write-Host Your Database server for your vCenter is $regkey.GetValue("Server")
     } else {
     Write-Warning "Could not find the correct value"
     }
Maish Saidel-Keesing • @maishsk • http://technodrone.blogspot.com • VMTN Moderator • vExpert • Co-author of VMware vSphere Design
0 Kudos
maishsk
Expert
Expert

And of course I like your way better Luc!

Maish Saidel-Keesing • @maishsk • http://technodrone.blogspot.com • VMTN Moderator • vExpert • Co-author of VMware vSphere Design
0 Kudos
RvdNieuwendijk
Leadership
Leadership

If you run the script locally on the vCenter server, you can do it in a one-liner:

(Get-ItemProperty -Path HKLM:\SOFTWARE\ODBC\ODBC.INI\$((Get-ItemProperty -Path "HKLM:\SOFTWARE\VMware, Inc.\VMware VirtualCenter\DB")."1")).Server

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition
0 Kudos
DyJohnnY
Enthusiast
Enthusiast

Hi guys,

Thanks for all the feedback... I did initially do somehting similar, but I got an error and gave up.

A few more clarifications

I need to access this remotely, a single script for all instances, so I cannot run them locally.

I'm using windows 2008 R2 64bit as guest OS for vCenter.

The error i'm getting is this...

PS C:\> $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine',
$vcName)
PS C:\> $vcKeys = $reg.OpenSubKey("SOFTWARE\\VMware, Inc.\\VMware VirtualCenter\
\DB")
PS C:\> $dsnName = $vcKeys.GetValue("1")
You cannot call a method on a null-valued expression.
At line:1 char:28
+ $dsnName = $vcKeys.GetValue <<<< ("1")
    + CategoryInfo          : InvalidOperation: (GetValue:String) [], RuntimeE
   xception
    + FullyQualifiedErrorId : InvokeMethodOnNull

I suspected 2 things:

1. The key is stored elsewhere (I checked and via regedit from 32bit windows I get access to the WOW6432 node)

2. The key has security setup on it and cannot be accessed remotely - I am domain admin on the computer, i get full access, I also checked effective permissions I have permissions.

So, anyone have any Idea how to access the 64bit key remotely?

Thanks,

Ionut

IonutN ( blog - www.rivnet.ro)
0 Kudos
LucD
Leadership
Leadership

Unless you have .Net 4 the 32 or 64 View option will not be available.

An alternative is to use WMI to get the 64-bit registry key value.

I used the function from the Access 64bit registry values from 32bit powershell post

The ODBC keys can be retrieved like before.

function GetValueFromRegistryThruWMI([string]$computername, $regkey, $value)    
{    
    #constant for the HLKM
   
  $HKLM = "&h80000002"          #creates an SwbemNamedValueSet object
 
    $objNamedValueSet = New-Object -COM "WbemScripting.SWbemNamedValueSet"          #adds the actual value that will requests the target to provide 64bit-registry info
 
    $objNamedValueSet.Add("__ProviderArchitecture", 64) | Out-Null          #back to all the other usual COM objects for WMI that you have used a zillion times in VBScript
 
    $objLocator = New-Object -COM "Wbemscripting.SWbemLocator"         $objServices = $objLocator.ConnectServer($computername,"root\default","","","","","",$objNamedValueSet)          $objStdRegProv = $objServices.Get("StdRegProv")           # Obtain an InParameters object specific to the method.
   
  $Inparams = ($objStdRegProv.Methods_ | where {$_.name -eq "GetStringValue"}).InParameters.SpawnInstance_()            # Add the input parameters
   
  ($Inparams.Properties_ | where {$_.name -eq "Hdefkey"}).Value = $HKLM         ($Inparams.Properties_ | where {$_.name -eq "Ssubkeyname"}).Value = $regkey         ($Inparams.Properties_ | where {$_.name -eq "Svaluename"}).Value = $value          #Execute the method
   
  $Outparams = $objStdRegProv.ExecMethod_("GetStringValue", $Inparams, "", $objNamedValueSet)           #shows the return value
   
  ($Outparams.Properties_ | where {$_.name -eq "ReturnValue"}).Value           if (($Outparams.Properties_ | where {$_.name -eq "ReturnValue"}).Value -eq 0)        {           $result = ($Outparams.Properties_ | where {$_.name -eq "sValue"}).Value           return $result       }    }    $vcName = $defaultVIServer.Name $dsnName = (GetValueFromRegistryThruWMI $vcName "SOFTWARE\VMware, Inc.\VMware VirtualCenter\DB" "1")[1] $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $vcName) $odbcKeys = $reg.OpenSubKey("SOFTWARE\\ODBC\\ODBC.INI\\" + $dsnName) $dbServer = $odbcKeys.GetValue("Server") Write-Host "vCenter server:" $vcName Write-Host "vCenter DB server:" $dbServer


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

0 Kudos
DyJohnnY
Enthusiast
Enthusiast

Hi,

Still it does not work, i get the same error, so I must be hitting some other problem.

I've decided to create some alias names in DNS, derived from the name of the vcenter instance, and I just do a query in DNS then a query in vCenter.

I also changed the ODBC to use the alias I created

It's not scripting it via ODBC, but the effort of getting data out registry remotely, esp on 2008 R2 seems not worth it.

IonutN ( blog - www.rivnet.ro)
0 Kudos
LucD
Leadership
Leadership

Could it be that there is a permission problem on the registry entries ?


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

0 Kudos
DyJohnnY
Enthusiast
Enthusiast

I checked, I have full permissions with the domain admin account, checked running using regedit from another 2008 R2 instance.

IonutN ( blog - www.rivnet.ro)
0 Kudos