推荐:VB.NET控制Hyper-V恢复快照

本文介绍了一个使用VB.NET编写的Hyper-V虚拟机管理工具,该工具可以获取虚拟机的状态、启动或关闭虚拟机,并且回滚到指定的快照。通过WMI接口实现了对Hyper-V虚拟机的远程管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Hyper-V 找了很多资料,想用软件控制“恢复快照”的操作,但都不尽如人意,自己做了一点优化,从恢复到完成约10秒,成功后才返回。源码是VB.NET,工程需要真实添加引用(工程-引用[右键]-添加引用-程序集)找到:

System.Management
然后添加一个工程模块:
Imports System
Imports System.Collections.Generic
Imports System.Management

#Region "Return Value Of RequestStateChange Method Of the Msvm_ComputerSystem Class"
'Return Value of RequestStateChange Method of the Msvm_ComputerSystem Class 
'This method returns one of the following values.
'Completed with No Error (0)
'DMTF Reserved (7–4095) 
'Method Parameters Checked - Transition Started (4096)
'Failed (32768) 
'Access Denied (32769) 
'Not Supported (32770) 
'Status is unknown (32771) 
'Timeout (32772) 
'Invalid parameter (32773) 
'System is in use (32774) 
'Invalid state for this operation (32775) 
'Incorrect data type (32776) 
'System is not available (32777) 
'Out of memory (32778)

'Common Utilities for the Virtualization Samples https://msdn.microsoft.com/en-us/library/cc723869(v=vs.85).aspx
'C# 实现 Hyper-V 虚拟机 管理 - PeterZhang - 博客园 http://www.cnblogs.com/Peter-Zhang/archive/2011/09/17/2179634.html
'通过Wmi实现Hyper-V远程管理(一) - 那家小伙 - 博客园 https://www.cnblogs.com/lsqandzy/p/5685926.html
'Hyper-V WMI Provider https://msdn.microsoft.com/en-us/library/cc136992(VS.85).aspx
'Hyper-V WMI Classes https://msdn.microsoft.com/en-us/library/cc136986(v=vs.85).aspx
'GetSummaryInformation method of the Msvm_VirtualSystemManagementService class https://msdn.microsoft.com/en-us/library/cc160706(VS.85).aspx
'获取hyperv和vmware虚机状态 / 蓝讯 http://www.lxway.com/452014012.htm
'Hyper-V WMI: Creating/Applying/Deleting Virtual Machine Snapshots – Taylor Brown's Blog https://blogs.msdn.microsoft.com/taylorb/2008/06/16/hyper-v-wmi-creatingapplyingdeleting-virtual-machine-snapshots/
'ApplyVirtualSystemSnapshot method of the Msvm_VirtualSystemManagementService class https://technet.microsoft.com/zh-cn/library/cc136767.aspx/

#End Region
Public Class VMManagement

        Public Shared Property HostServer As String = "hostServer"
        Public Shared Property UserName As String = "username"
        Public Shared Property Password As String = "password"

        Public Shared Function GetVMState(ByVal vmName As String) As VMState
            Dim vmState As VMState = VMState.Undefined
            Dim co As ConnectionOptions = New ConnectionOptions()
            co.Username = UserName
            co.Password = Password

            Dim manScope As ManagementScope = New ManagementScope(String.Format("\\{0}\root\virtualization", HostServer), co)
            manScope.Connect()

            Dim queryObj As ObjectQuery = New ObjectQuery("SELECT * FROM Msvm_ComputerSystem")
            Dim vmSearcher As ManagementObjectSearcher = New ManagementObjectSearcher(manScope, queryObj)
            Dim vmCollection As ManagementObjectCollection = vmSearcher.Get

            For Each vm As ManagementObject In vmCollection
                'Debug.Print(vm("ElementName").ToString & " state: " & vm("EnabledState").ToString)

                If String.Compare(vm("ElementName").ToString, vmName, True) = 0 Then
                    vmState = ConvertStrToVMState(vm("EnabledState").ToString)
                    Exit For
                End If
            Next

            Return vmState
        End Function

        Public Shared Function StartUp(ByVal vmName As String) As Boolean

            Return ChangeVMState(vmName, VMState.Enabled)
        End Function

        Public Shared Function ShutDown(ByVal vmName As String) As Boolean
            Return ChangeVMState(vmName, VMState.Disabled)
        End Function

        Public Shared Function RollBack(ByVal vmName As String, ByVal snapShotName As String) As Boolean
            Dim co As ConnectionOptions = New ConnectionOptions()
            co.Username = UserName
            co.Password = Password

            Dim manScope As ManagementScope = New ManagementScope(String.Format("\\{0}\root\virtualization", HostServer), co)
            manScope.Connect()

            Dim queryObj As ObjectQuery = New ObjectQuery("SELECT * FROM Msvm_ComputerSystem")
            Dim vmSearcher As ManagementObjectSearcher = New ManagementObjectSearcher(manScope, queryObj)
            Dim vmCollection As ManagementObjectCollection = vmSearcher.Get()

            Dim opResult As Object = Nothing
            ' loop the virtual machines
            Dim vm As ManagementObject
            For Each vm In vmCollection
                Debug.Print("find vm name:" & vm("ElementName").ToString)
                ' find the vmName virtual machine, then get the list of snapshot
                If String.Compare(vm("ElementName").ToString, vmName, True) <> 0 Then Continue For
                Dim queryObj1 As ObjectQuery = New ObjectQuery(String.Format("SELECT * FROM Msvm_VirtualSystemSettingData WHERE SystemName='{0}' and SettingType=5", vm("Name").ToString))
                Dim vmSearcher1 As ManagementObjectSearcher = New ManagementObjectSearcher(manScope, queryObj1)
                Dim vmCollection1 As ManagementObjectCollection = vmSearcher1.Get()
                Dim snapshot As ManagementObject = Nothing
                ' find and record the snapShot object
                Dim snap As ManagementObject
                For Each snap In vmCollection1
                    Debug.Print("find snap name:" & snap("ElementName").ToString)
                    If String.Compare(snap("ElementName").ToString, snapShotName, True) <> 0 Then Continue For
                    snapshot = snap
                    Exit For
                Next

                Dim queryObj2 As ObjectQuery = New ObjectQuery("SELECT * FROM Msvm_VirtualSystemManagementService")
                Dim vmSearcher2 As ManagementObjectSearcher = New ManagementObjectSearcher(manScope, queryObj2)
                Dim vmCollection2 As ManagementObjectCollection = vmSearcher2.Get()

                Dim virtualSystemService As ManagementObject = Nothing
                For Each o As ManagementObject In vmCollection2
                    Debug.Print(o.ToString)
                    virtualSystemService = o
                    Exit For
                Next

                If ConvertStrToVMState(vm("EnabledState").ToString) <> VMState.Disabled Then
                    '关机
                    ShutDown(vm("ElementName").ToString)
                    'Threading.Thread.Sleep(1000)
                    For i As Integer = 0 To 100 Step 1
                        Debug.Print(Now & vbTab & GetVMState(vmName).ToString)
                        If GetVMState(vmName) = VMState.Disabled Then Exit For
                        Threading.Thread.Sleep(345)
                    Next
                End If

                'Threading.Thread.Sleep(10000)

                Debug.Print("vm.Path {0} ", vm.Path.Path)
                Debug.Print("snapshot.Path {0} ", snapshot.Path.Path)
                '
                'Dim inParams As ManagementBaseObject = virtualSystemService.GetMethodParameters("ApplyVirtualSystemSnapShot")
                'inParams("ComputerSystem") = vm.Path.Path
                'inParams("SnapshotSettingData") = snapshot.Path.Path
                'opResult = virtualSystemService.InvokeMethod("ApplyVirtualSystemSnapShot", inParams, Nothing)
                '
                'Dim obj(1) As Object
                'obj(0) = vm.Path
                'obj(1) = snapshot.Path
                'opResult = virtualSystemService.InvokeMethod("ApplyVirtualSystemSnapShot", obj)
                '
                '应用快照
                opResult = virtualSystemService.InvokeMethod("ApplyVirtualSystemSnapShot", New Object() {vm.Path, snapshot.Path}) '此操作的无效状态
                If opResult.ToString = "0" Then

                    'Threading.Thread.Sleep(1000)
                    For i As Integer = 0 To 100 Step 1
                        Debug.Print(Now & vbTab & GetVMState(vmName).ToString)
                        If GetVMState(vmName) = VMState.Suspended Then Exit For
                        Threading.Thread.Sleep(345)
                    Next
                    'Threading.Thread.Sleep(10000)
                    '开机
                    StartUp(vm("ElementName").ToString)

                    For i As Integer = 0 To 100 Step 1
                        Debug.Print(Now & vbTab & GetVMState(vmName).ToString)
                        If GetVMState(vmName) = VMState.Enabled Then Exit For
                        Threading.Thread.Sleep(345)
                    Next
                End If
                Exit For
            Next

            '\\WQSERVER\root\virtualization:Msvm_VirtualSystemManagementService.CreationClassName="Msvm_VirtualSystemManagementService",Name="vmms",SystemCreationClassName="Msvm_ComputerSystem",SystemName="WQSERVER"
            'vm.Path \\WQSERVER\root\virtualization:Msvm_ComputerSystem.CreationClassName="Msvm_ComputerSystem",Name="6EDCD1EB-F2E1-4706-9050-7E5ED649186B" 
            'snapshot.Path \\WQSERVER\root\virtualization:Msvm_VirtualSystemSettingData.InstanceID="Microsoft:0E284464-6774-4A3A-AF5B-F544F716BB80" 
            'Debug.Print("return:" & opResult("ReturnValue").ToString)
            Debug.Print(opResult.ToString)
            Return "0" = opResult.ToString
        End Function

        Public Shared Function GetVMSnapShotList(ByVal vmName As String) As List(Of SnapShot)
            Dim shotList As New List(Of SnapShot)
            Dim co As ConnectionOptions = New ConnectionOptions()
            co.Username = UserName
            co.Password = Password

            Dim manScope As ManagementScope = New ManagementScope(String.Format("\\{0}\root\virtualization", HostServer), co)
            manScope.Connect()

            Dim queryObj As ObjectQuery = New ObjectQuery("SELECT * FROM Msvm_ComputerSystem")
            Dim vmSearcher As ManagementObjectSearcher = New ManagementObjectSearcher(manScope, queryObj)
            Dim vmCollection As ManagementObjectCollection = vmSearcher.Get()

            Dim str As String = ""
            ' loop through the machines
            Dim vm As ManagementObject
            For Each vm In vmCollection

                str += "Snapshot of " + vm("ElementName").ToString + "\r\n"
                'Get the snaplist
                If String.Compare(vm("ElementName").ToString, vmName, True) = 0 Then
                    Dim queryObj1 As ObjectQuery = New ObjectQuery(String.Format("SELECT * FROM Msvm_VirtualSystemSettingData WHERE SystemName='{0}' and SettingType=5", vm("Name").ToString))
                    Dim vmSearcher1 As ManagementObjectSearcher = New ManagementObjectSearcher(manScope, queryObj1)
                    Dim vmCollection1 As ManagementObjectCollection = vmSearcher1.Get()

                    Dim snap As ManagementObject
                    For Each snap In vmCollection1
                        Dim ss As SnapShot = New SnapShot()
                        ss.Name = snap("ElementName").ToString
                        ss.CreationTime = DateTime.ParseExact(snap("CreationTime").ToString.Substring(0, 14), "yyyyMMddHHmmss", Nothing).ToLocalTime()
                        ss.Notes = snap("Notes").ToString
                        shotList.Add(ss)
                    Next
                End If
            Next

            Return shotList
        End Function

        Private Shared Function ChangeVMState(ByVal vmName As String, ByVal toState As VMState) As Boolean
            Dim toStateCode As String = ConvertVMStateToStr(toState)
            If toStateCode = String.Empty Then
                Return False
            End If

            Dim co As ConnectionOptions = New ConnectionOptions()
            co.Username = UserName
            co.Password = Password

            Dim manScope As ManagementScope = New ManagementScope(String.Format("\\{0}\root\virtualization", HostServer), co)
            manScope.Connect()

            Dim queryObj As ObjectQuery = New ObjectQuery("SELECT * FROM Msvm_ComputerSystem")
            Dim vmSearcher As ManagementObjectSearcher = New ManagementObjectSearcher(manScope, queryObj)
            Dim vmCollection As ManagementObjectCollection = vmSearcher.Get()

            Dim o As Object = Nothing
            Dim vm As ManagementObject
            For Each vm In vmCollection
                If String.Compare(vm("ElementName").ToString, vmName, True) = 0 Then
                    o = vm.InvokeMethod("RequestStateChange", New Object() {toStateCode})
                    Exit For
                End If
            Next
            Return "0" = o.ToString
        End Function

        Private Shared Function ConvertStrToVMState(ByVal statusCode As String) As VMState
            Select Case statusCode
                Case "0" : Return VMState.Unknown
                Case "2" : Return VMState.Enabled
                Case "3" : Return VMState.Disabled
                Case "32768" : Return VMState.Paused
                Case "32769" : Return VMState.Suspended
                Case "32770" : Return VMState.Starting
                Case "32771" : Return VMState.Snapshotting
                Case "32773" : Return VMState.Saving
                Case "32775" : Return VMState.InvalidOperation
                Case "32774" : Return VMState.Stopping
                Case "32776" : Return VMState.Pausing
                Case "32777" : Return VMState.Resuming
            End Select
            Return VMState.Undefined
        End Function

        Private Shared Function ConvertVMStateToStr(ByVal vmState As VMState) As String
            Select Case vmState
                Case VMState.Unknown : Return "0"
                Case VMState.Enabled : Return "2"
                Case VMState.Disabled : Return "3"
                Case VMState.Paused : Return "32768"
                Case VMState.Suspended : Return "32769"
                Case VMState.Starting : Return "32770"
                Case VMState.Snapshotting : Return "32771"
                Case VMState.Saving : Return "32773"
                Case VMState.Stopping : Return "32774"
                Case VMState.InvalidOperation : Return "32775"
                Case VMState.Pausing : Return "32776"
                Case VMState.Resuming : Return "32777"
            End Select
            Return "0"
        End Function
    End Class

    '/ <summary>
    '/-        Undefined      --> "Not defined"
    '/0        Unknown        --> "Unknown"
    '/2        Enabled        --> "Running" 
    '/3        Diabled        --> "Off"
    '/32768    Paused         --> "Paused"
    '/32769    Suspended      --> "Saved"
    '/32770    Starting       --> "Starting"
    '/32771    Snapshotting   --> "Snapshooting
    '/32773    Saving         --> "Saving"
    '/32774    Stopping       --> "Shuting down
    '/32776    Pausing        --> "Pausing"
    '/32777    Resuming       --> "Resuming"
    '/ </summary>
    Public Enum VMState
        Undefined
        Unknown
        Enabled
        Disabled
        Paused
        Suspended
        Starting
        Snapshotting
        Saving
        Stopping
        InvalidOperation
        Pausing
        Resuming
    End Enum

    Public Class SnapShot
        Public Property Name() As String
        Public Property CreationTime() As DateTime
        Public Property Notes() As String

    End Class


'再添加测试代码:

Public Module ModMain

    Public Sub Main()


        VMManagement.HostServer = "虚拟机宿主机计算机名或IP"
        VMManagement.UserName = "用户名"
        VMManagement.Password = "密码"
        Console.WriteLine(VMManagement.GetVMState("虚拟机名").ToString)
        Console.WriteLine(VMManagement.RollBack("虚拟机名", "快照名"))


        Console.ReadKey()
    End Sub

End Module


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值