Powershell 实现 Hyper-V 虚拟机 管理

时间:2021-06-23 15:32:54

  本文包括使用powershell启动、关闭Hyper-V虚拟机,及获得虚拟机状态、虚拟机快照、根据快照回滚虚拟机。

1. 启动

 1 param
2 (
3 [string]$hostServer = $(throw "param -host server is required."),
4 [string]$vmName = $(throw "param -virtual machine name is required.")
5 )
6
7 function GetImageState
8 {
9 param
10 (
11 [string]$image = $(throw "param -image is required."),
12 [string]$hostServer = $(throw "param -hostserver is required.")
13 )
14 $virtualMachines = Get-WmiObject -Class "MSVM_ComputerSystem" -Namespace "root\virtualization" -ComputerName $hostServer;
15 foreach ($virtualMachine in $virtualMachines)
16 {
17 if ($image -ieq $virtualMachine.ElementName)
18 {
19 return $virtualMachine.EnabledState;
20 }
21 }
22 throw "Cannot get the state of image [$image] on host server [$hostServer]";
23 }
24
25 function WaitImageToState
26 {
27 param
28 (
29 [string]$image = $(throw "param -image is required."),
30 [string]$hostServer = $(throw "param -hostserver is required."),
31 [int]$state = $(throw "param -$state is required."),
32 [int]$timeOut = $(throw "param -$timeOut is required.")
33 )
34 do
35 {
36 $timeOut = $timeOut - 5;
37 sleep (5);
38 $currentState = GetImageState -image:$image -hostserver:$hostServer;
39 if ($currentState -eq $state)
40 {
41 return;
42 }
43
44 if ($timeOut -le 0)
45 {
46 throw "Wait for image [$image] to state [$state] time out.";
47 }
48 }while($true);
49 }
50
51 "Start up the virtual machine..." + $hostServer
52 Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
53 $virtualMachines = Get-WmiObject -Class "MSVM_ComputerSystem" -Namespace "root\virtualization" -ComputerName $hostServer;
54 $virtualMachineRun = 2;
55 foreach ($virtualMachine in $virtualMachines)
56 {
57 if($virtualMachine.ElementName -eq $vmName)
58 {
59 $result = $virtualMachine.RequestStateChange($virtualMachineRun);
60 if ($result.ReturnValue -ne 4096)
61 {
62 throw "Failed to send start request to VM - " + $virtualMachine;
63 }
64 WaitImageToState -image:$virtualMachine.ElementName -hostserver:$hostServer -state:$virtualMachineRun -timeOut:60;
65 }
66 }
67 $vmName + "startup Finished!"

2. 关闭

 1 param
2 (
3 [string]$hostServer = $(throw "param -host server is required."),
4 [string]$vmName = $(throw "param -virtual machine name is required.")
5 )
6
7 function GetImageState
8 {
9 param
10 (
11 [string]$image = $(throw "param -image is required."),
12 [string]$hostServer = $(throw "param -hostserver is required.")
13 )
14 $virtualMachines = Get-WmiObject -Class "MSVM_ComputerSystem" -Namespace "root\virtualization" -ComputerName $hostServer;
15 foreach ($virtualMachine in $virtualMachines)
16 {
17 if ($image -ieq $virtualMachine.ElementName)
18 {
19 return $virtualMachine.EnabledState;
20 }
21 }
22 throw "Cannot get the state of image [$image] on host server [$hostServer]";
23 }
24
25 function WaitImageToState
26 {
27 param
28 (
29 [string]$image = $(throw "param -image is required."),
30 [string]$hostServer = $(throw "param -hostserver is required."),
31 [int]$state = $(throw "param -$state is required."),
32 [int]$timeOut = $(throw "param -$timeOut is required.")
33 )
34 do
35 {
36 $timeOut = $timeOut - 5;
37 sleep (5);
38 $currentState = GetImageState -image:$image -hostserver:$hostServer;
39 if ($currentState -eq $state)
40 {
41 return;
42 }
43
44 if ($timeOut -le 0)
45 {
46 throw "Wait for image [$image] to state [$state] time out.";
47 }
48 }while($true);
49 }
50
51 "Shutdown the virtual machine..."
52 Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
53 $virtualMachines = Get-WmiObject -Class "MSVM_ComputerSystem" -Namespace "root\virtualization" -ComputerName $hostServer;
54 $virtualMachineRun = 3;
55 foreach ($virtualMachine in $virtualMachines)
56 {
57 if($virtualMachine.ElementName -eq $vmName)
58 {
59 $result = $virtualMachine.RequestStateChange($virtualMachineRun);
60 if ($result.ReturnValue -ne 4096)
61 {
62 throw "Failed to send start request to VM - " + $virtualMachine;
63 }
64 WaitImageToState -image:$virtualMachine.ElementName -hostserver:$hostServer -state:$virtualMachineRun -timeOut:60;
65 }
66 }
67 $vmName + "Shutdown Finished!"

3. 获得虚拟机状态 (状态码参考:http://msdn.microsoft.com/en-us/library/cc136822(VS.85).aspx

 1 param
2 (
3 [string]$hostServer = $(throw "param -hostserver is required."),
4 [string]$vmName = $(throw "param -vmName is required.")
5 )
6
7 $status = -1
8 $virtualMachines = Get-WmiObject -Class "MSVM_ComputerSystem" -Namespace "root\virtualization" -ComputerName $hostServer
9 foreach ($virtualMachine in $virtualMachines)
10 {
11 if ($vmName -ieq $virtualMachine.ElementName)
12 {
13 $status = $virtualMachine.EnabledState
14 break
15 }
16 }
17
18 switch($status)
19 {
20 -1 {throw "Cannot get the state of vmName [$vmName] on host server [$hostServer]"}
21 2 {"Running."}
22 3 {"Closed."}
23 32768 {"Paused."}
24 32769 {"Saved."}
25 32770 {"Starting."}
26 32773 {"Saving."}
27 32774 {"Stopping."}
28 32776 {"Pausing."}
29 32777 {"Restoring."}
30 default {"Unknow Status."}
31 }

4. 获得虚拟机快照列表

 1 param
2 (
3 [string]$hostServer = $(throw "param -host server is required."),
4 [string]$vmName = $(throw "param -virtual machine name is required.")
5 )
6
7 $virtualMachines = Get-WmiObject -Class "MSVM_ComputerSystem" -Namespace "root\virtualization" -ComputerName $hostServer;
8 foreach ($virtualMachine in $virtualMachines)
9 {
10 if($virtualMachine.ElementName -eq $vmName)
11 {
12 # get snapshots of the virtual machine
13 $queryStr = "SELECT * FROM Msvm_VirtualSystemSettingData WHERE SystemName='" + $virtualMachine.Name + "' and SettingType=5";
14 $snapShots = Get-WmiObject -Query $queryStr -Namespace "root\virtualization" -ComputerName $hostServer;
15
16 foreach ($aSnapShot in $snapShots)
17 {
18 $aSnapShot.ElementName
19 [System.DateTime]::ParseExact($aSnapShot.CreationTime.Substring(0,14), "yyyyMMddHHmmss", $null).ToLocalTime().ToString()
20 $aSnapShot.Notes
21 }
22 }
23 }

5. 根据快照回滚虚拟机

 1 param
2 (
3 [string]$hostServer = $(throw "param -hostServer is required."),
4 [string]$vmName = $(throw "param -virtual machine name is required."),
5 [string]$snapshotName = $(throw "param -snapshotName is required.")
6 )
7
8 function GetImageState
9 {
10 param
11 (
12 [string]$image = $(throw "param -image is required."),
13 [string]$hostServer = $(throw "param -hostserver is required.")
14 )
15 $virtualMachines = Get-WmiObject -Class "MSVM_ComputerSystem" -Namespace "root\virtualization" -ComputerName $hostServer;
16 foreach ($virtualMachine in $virtualMachines)
17 {
18 if ($image -ieq $virtualMachine.ElementName)
19 {
20 return $virtualMachine.EnabledState;
21 }
22 }
23 throw "Cannot get the state of image [$image] on host server [$hostServer]";
24 }
25
26 function WaitImageToState
27 {
28 param
29 (
30 [string]$image = $(throw "param -image is required."),
31 [string]$hostServer = $(throw "param -hostserver is required."),
32 [int]$state = $(throw "param -$state is required."),
33 [int]$timeOut = $(throw "param -$timeOut is required.")
34 )
35 do
36 {
37 $timeOut = $timeOut - 5;
38 sleep (5);
39 $currentState = GetImageState -image:$image -hostserver:$hostServer;
40 if ($currentState -eq $state)
41 {
42 return;
43 }
44
45 if ($timeOut -le 0)
46 {
47 throw "Wait for image [$image] to state [$state] time out.";
48 }
49 }while($true);
50 }
51
52
53 "Rollback the virtual machine..."
54 $virtualMachines = Get-WmiObject -Class "MSVM_ComputerSystem" -Namespace "root\virtualization" -ComputerName $hostServer;
55 $virtualSystemService = Get-WmiObject -Class "Msvm_VirtualSystemManagementService" -Namespace "root\virtualization" -ComputerName $hostServer;
56 foreach ($virtualMachine in $virtualMachines)
57 {
58 if($virtualMachine.ElementName -eq $vmName)
59 {
60 # get snapshot of the virtual machine
61 $queryStr = "SELECT * FROM Msvm_VirtualSystemSettingData WHERE SystemName='" + $virtualMachine.Name + "' and SettingType=5";
62 $snapShots = Get-WmiObject -Query $queryStr -Namespace "root\virtualization" -ComputerName $hostServer;
63 foreach ($aSnapShot in $snapShots)
64 {
65 # revert to specified snapshot
66 if ($aSnapShot.ElementName -ieq $snapshotName)
67 {
68 # apply snapshot
69 $result = $virtualSystemService.ApplyVirtualSystemSnapShot($virtualMachine.__PATH, $aSnapShot.__PATH);
70 if ($result.ReturnValue -ne 0)
71 {
72 throw "Failed to apply snapshot ["+$snapshotName+"] to VM ["+$image+"]";
73 }
74 WaitImageToState -image:$virtualMachine.ElementName -hostserver:$hostServer -state:32769 -timeOut:120;
75 }
76 }
77 }
78 }
79 "Finished rollback!"