Click here to Skip to main content
15,881,803 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I need to read the
SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters\PhysicalHostName
Registry Key to get the Host Name of a Hyper V VM.

I can connect and also retrieve alot of information trough wmi in other parts of the program, but i stumble if it comes to reading a registry Key :(

Im aware that theres a way to retrieve the names of all vm-names through the /virtualization/ namespace. However thats not want i need since i have to target the vms directly. The Code doesn't have to be in vb.net i can also translate c#.

Additional Debugging Information:
The isConnected state of the ManagementScope is true
The OutParams("sValue") returns nothing

It would be sooo nice if someone could help me in this matter x.x !

What I have tried:

VB
Dim strStringValue As String = ""
            Dim objManagementScope As ManagementScope
            Dim objManagementClass As ManagementClass
            Dim objManagementBaseObject As ManagementBaseObject

            Dim intRegistryHive As Integer = 80000002
            Dim strSubKeyName As String = "SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters"
            Dim strValueName As String = "PhysicalHostName"


            strSubKeyName = strSubKeyName.Trim
            strValueName = strValueName.Trim

            If (strSubKeyName.Length > 0) Then
                'Connect to the specified computer registry
                objManagementScope = New ManagementScope

                With objManagementScope
                    With .Path
                        .Server = m_ComputerName
                        .NamespacePath = "root\default"
                    End With

                    With .Options
                        .EnablePrivileges = True
                        .Impersonation = ImpersonationLevel.Impersonate
                        .Username = frmMain.txtUserName.Text
                        .Password = frmMain.txtPassword.Text
                    End With

                    .Connect()
                End With

                'Retrieve the required value from the registry

                If objManagementScope.IsConnected Then
                    objManagementClass = New ManagementClass("StdRegProv")

                    With objManagementClass
                        .Scope = objManagementScope
                        objManagementBaseObject = .GetMethodParameters("GetStringValue")

                        With objManagementBaseObject
                            .SetPropertyValue("hDefKey", CType("&H" & Hex(intRegistryHive), Long))
                            .SetPropertyValue("sSubKeyName", strSubKeyName)
                            .SetPropertyValue("sValueName", strValueName)
                        End With

                        Dim OutParams As ManagementBaseObject = .InvokeMethod("GetStringValue", objManagementBaseObject, Nothing)
                        strStringValue = CType(OutParams("sValue"), String)
                        If strStringValue = Nothing Then strStringValue = ""
                    End With
                End If
            End If

            Return strStringValue
        Catch ex As Exception
            Return ""
        End Try


The problem is probably somewhere in
VB
If objManagementScope.IsConnected Then
               objManagementClass = New ManagementClass("StdRegProv")

               With objManagementClass
                   .Scope = objManagementScope
                   objManagementBaseObject = .GetMethodParameters("GetStringValue")

                   With objManagementBaseObject
                       .SetPropertyValue("hDefKey", CType("&H" & Hex(intRegistryHive), Long))
                       .SetPropertyValue("sSubKeyName", strSubKeyName)
                       .SetPropertyValue("sValueName", strValueName)
                   End With

                   Dim OutParams As ManagementBaseObject = .InvokeMethod("GetStringValue", objManagementBaseObject, Nothing)
                   Dim tst As Object = OutParams("sValue")
                   strStringValue = CType(OutParams("sValue"), String)
                   If strStringValue = Nothing Then strStringValue = ""
               End With
           End If
Posted
Updated 17-Jul-17 5:45am
v2

Try using the registry classes in the Microsoft.Win32 namespace:
VB.NET
Using hive = RegistryKey.OpenRemoveBaseKey(RegistryHive.LocalMachine, m_ComputerName, RegistryView.Default)
    Using key = hive.OpenSubKey("SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters", False)
        If key IsNot Nothing Then
            strStringValue = CStr(key.GetValue("PhysicalHostName"))
        End If
    End Using
End Using

RegistryKey Class | Microsoft Docs[^]
 
Share this answer
 
Comments
Member 13262965 16-Jun-17 11:26am    
Hi Richard,

thank you for answering to my question :) !

Unfortunately this won't work for me since the OpenRemoteBaseKey seems to need the RemoteRegistry Service to be running (which is disabled by default).

Is there another way to do it ?
Or do i have to use RemoteKey and the Service ?

Thank you in advance !
Richard Deeming 16-Jun-17 11:42am    
You should be able to use WMI - there are lots of examples on Google. Most of them seem to be using PowerShell, but there are a few in C# - eg: Read Registry Value using WMI in C# [^]

The only obvious difference from your code is the hDefKey parameter - try replacing:
.SetPropertyValue("hDefKey", CType("&H" & Hex(intRegistryHive), Long))
with
.SetPropertyValue("hDefKey", intRegistryHive)

Also:
OutParams("sValue")
should probably be
OutParams.Properties("sValue").Value
[no name] 17-Jul-17 16:10pm    
Hey man, can you please help me with my newest question? I am trying to find out how to move a desktop application to a random folder :)
Member 13262965 16-Jun-17 12:16pm    
I can easily replace the SetPropertyValue lines but when i replace the outparams i get a HRESULT -2147467259 (= 0x80004005 = Unspecified Error) which seems do be caused by the fact that the OutParams are set to nothing when i try to retreive the .Value .

I wonder if it is something network based .. which would be really weird because i can retreive the installed Software(which is also done through registry via wmi) CPU(via wmi query) etc. without any error.
Member 13262965 16-Jun-17 12:19pm    
Thats the Code im using to retrieve the Software information... dont get why that works absolutely fine ..

Private Sub getSoftwareList(ByRef SwLst As SortedList(Of String, SoftwareKomponent), ByVal HKEY As UInteger, ByVal regPath As String, ByVal UserName As String, ByVal SoftwareType As String)

        Dim Sw As SoftwareKomponent

        Dim Path As ManagementPath = New ManagementPath("\\" & m_ComputerName & "\root\default")
        Me.Path = Path

        Dim keyToRead() As String = New String() {"DisplayName", "DisplayVersion", "Publisher"} 'Array mit auszulesenden Werten
        Dim softValue() As String = New String() {"", "", ""} 'Array für gelesene Werte

        Dim DisplayName As String = ""
        Dim DisplayVersion As String = ""
        Dim Publisher As String = ""
        Dim Software As String = ""

        Dim RegMgmPath As ManagementPath = New ManagementPath("StdRegProv") 'Standard Registrierungspfad in "Path" schreiben
        Dim registry As ManagementClass = New ManagementClass(Me, RegMgmPath, Nothing) 'Vollständiger Pfad zur Registry in "registry" schreiben

        Dim methodArgs As Object() = New Object() {HKEY, regPath, Nothing}
        Dim returnValue As UInteger = CUInt(registry.InvokeMethod("EnumKey", methodArgs))

        If methodArgs(2) IsNot Nothing Then
            Dim subKeys As String() = TryCast(methodArgs(2), [String]())

            If Not subKeys Is Nothing Then


                Dim inParams As ManagementBaseObject = registry.GetMethodParameters("GetStringValue")

                For Each subKey As String In subKeys
                    For j As Integer = 0 To keyToRead.GetUpperBound(0)
                        inParams("sSubKeyName") = regPath & subKey
                        inParams("sValueName") = keyToRead(j)

                        Dim outParams1 As ManagementBaseObject = registry.InvokeMethod("GetStringValue", inParams, Nothing)
                        softValue(j) = outParams1("sValue")

                    Next

                    Dim outParams As ManagementBaseObject = registry.InvokeMethod("GetStringValue", inParams, Nothing)

                    Sw = New SoftwareKomponent
                    Sw.UserName = UserName
                    Sw.SoftwareType = SoftwareType
                    Sw.DisplayName = softValue(0)
                    Sw.DisplayVersion = softValue(1)
                    Sw.Publisher = softValue(2)
                    Sw.Software = subKey.ToUpper
                    If Not SwLst.ContainsKey(subKey.ToUpper) Then
                        SwLst.Add(subKey.ToUpper, Sw)
                    End If
                Next

            End If

        End If

    End Sub


End Class
Since nobody seems to be willing to answer i close the question. I didnt found my error so far. I can read all regKeys but the one i want to read.
 
Share this answer
 
Comments
Dave Kreskowiak 17-Jul-17 12:42pm    
If you can get the names and values of other keys, except this one key, it would suggest to me that security was setup on those keys making the data available only to administrators and admins of the HyperV.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900