kitchen-hyperv 0.10.3 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/support/hyperv.ps1 CHANGED
@@ -1,233 +1,264 @@
1
- #requires -Version 2 -Modules Hyper-V
2
-
3
- #implicitly import hyperv module to avoid powercli cmdlets
4
- if ((Get-Module -Name 'hyper-v') -ne $null) {
5
- Remove-Module -Name hyper-v
6
- Import-Module -Name hyper-v
7
- }
8
- else {
9
- Import-Module -Name hyper-v
10
- }
11
-
12
- $ProgressPreference = 'SilentlyContinue'
13
-
14
-
15
- function New-DifferencingDisk {
16
- [cmdletbinding()]
17
- param (
18
- [parameter(Mandatory)]
19
- [ValidateNotNullOrEmpty()]
20
- [string[]]$Path,
21
- [parameter(Mandatory)]
22
- [ValidateNotNullOrEmpty()]
23
- [string]$ParentPath
24
- )
25
- if (-not (Test-Path $Path)) {
26
- $null = new-vhd @psboundparameters -Differencing
27
- }
28
- }
29
-
30
- function Assert-VmRunning {
31
- [cmdletbinding()]
32
- param([string]$Id)
33
-
34
- if ([string]::IsNullOrEmpty($Id)) {
35
- $Output = [pscustomobject]@{
36
- Name = ''
37
- State = ''
38
- }
39
- }
40
- else {
41
- $Output = Get-VM -Id $Id |
42
- ForEach-Object -Process {
43
- if ($_.State -notlike 'Running') {
44
- $_ |
45
- Start-VM -passthru
46
- }
47
- else {
48
- $_
49
- }
50
- } |
51
- Select-Object -Property Name, Id, State
52
- }
53
- $Output
54
- }
55
-
56
- function New-KitchenVM {
57
- [cmdletbinding()]
58
- param (
59
- $Generation = 1,
60
- $DisableSecureBoot,
61
- $MemoryStartupBytes,
62
- $StaticMacAddress,
63
- $Name,
64
- $Path,
65
- $VHDPath,
66
- $SwitchName,
67
- $VlanId,
68
- $ProcessorCount,
69
- $UseDynamicMemory,
70
- $DynamicMemoryMinBytes,
71
- $DynamicMemoryMaxBytes,
72
- $boot_iso_path,
73
- $EnableGuestServices,
74
- $AdditionalDisks
75
- )
76
- $null = $psboundparameters.remove('DisableSecureBoot')
77
- $null = $psboundparameters.remove('ProcessorCount')
78
- $null = $psboundparameters.remove('StaticMacAddress')
79
- $null = $psboundparameters.remove('UseDynamicMemory')
80
- $null = $psboundparameters.remove('DynamicMemoryMinBytes')
81
- $null = $psboundparameters.remove('DynamicMemoryMaxBytes')
82
- $null = $psboundparameters.remove('boot_iso_path')
83
- $null = $psboundparameters.remove('EnableGuestServices')
84
- $null = $psboundparameters.remove('VlanId')
85
- $null = $psboundparameters.remove('AdditionalDisks')
86
- $DisableSecureBoot = [Convert]::ToBoolean($DisableSecureBoot)
87
- $UseDynamicMemory = [Convert]::ToBoolean($UseDynamicMemory)
88
- $null = [bool]::TryParse($EnableGuestServices, [ref]$EnableGuestServices)
89
-
90
- $vm = new-vm @psboundparameters |
91
- Set-Vm -ProcessorCount $ProcessorCount -passthru
92
-
93
- if ($UseDynamicMemory) {
94
- $vm | Set-VMMemory -DynamicMemoryEnabled $true -MinimumBytes $DynamicMemoryMinBytes -MaximumBytes $DynamicMemoryMaxBytes
95
- }
96
- else {
97
- $vm | Set-VMMemory -DynamicMemoryEnabled $false
98
- }
99
- if (-not [string]::IsNullOrEmpty($boot_iso_path)) {
100
- Mount-VMISO -Id $vm.Id -Path $boot_iso_path
101
- }
102
- if (-not [string]::IsNullOrEmpty($StaticMacAddress)) {
103
- Set-VMNetworkAdapter -VMName $vm.VMName -StaticMacAddress $StaticMacAddress
104
- }
105
- if ($EnableGuestServices -and (Get-command Enable-VMIntegrationService -ErrorAction SilentlyContinue)) {
106
- Enable-VMIntegrationService -VM $vm -Name 'Guest Service Interface'
107
- }
108
- if (($VlanId -ne $null) -and (Get-command Set-VMNetworkAdapterVlan -ErrorAction SilentlyContinue)) {
109
- Set-VMNetworkAdapterVlan -VM $vm -Access -VlanId $VlanId
110
- }
111
- if ($AdditionalDisks -and (Get-command Add-VMHardDiskDrive -ErrorAction SilentlyContinue)) {
112
- foreach ($AdditionalDisk in $AdditionalDisks) {
113
- Add-VMHardDiskDrive -VM $vm -Path $AdditionalDisk
114
- }
115
- }
116
- if ($DisableSecureBoot -and ($Generation -eq 2) -and (Get-command Set-VMFirmware -ErrorAction SilentlyContinue)) {
117
- Set-VMFirmware -VM $vm -EnableSecureBoot Off
118
- }
119
- if ((Get-Command -Name Set-Vm).Parameters["AutomaticCheckpointsEnabled"]) {
120
- Set-VM -Name $vm.VMName -AutomaticCheckpointsEnabled $false
121
- }
122
- $vm | Start-Vm -passthru |
123
- foreach {
124
- $vm = $_
125
- do {
126
- start-sleep -seconds 2
127
- }
128
- while ($vm.state -notlike 'Running')
129
- $vm
130
- } |
131
- select Name, Id, State
132
- }
133
-
134
- function Get-VmIP($vm) {
135
- start-sleep -seconds 10
136
- $vm.networkadapters.ipaddresses |
137
- Where-Object {
138
- $_ -match '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$'
139
- } |
140
- Select-Object -First 1
141
- }
142
-
143
- Function Set-VMNetworkConfiguration {
144
- [CmdletBinding()]
145
- Param (
146
- [parameter(valuefrompipeline)]
147
- [object]$NetworkAdapter,
148
- [String[]]$IPAddress = @(),
149
- [String[]]$Gateway = @(),
150
- [String[]]$DNSServers = @(),
151
- [String[]]$Subnet = @()
152
- )
153
-
154
- $vm = Get-WmiObject -Namespace 'root\virtualization\v2' -Class 'Msvm_ComputerSystem' | Where-Object {
155
- $_.ElementName -eq $NetworkAdapter.VMName
156
- }
157
- $VMSettings = $vm.GetRelated('Msvm_VirtualSystemSettingData') | Where-Object {
158
- $_.VirtualSystemType -eq 'Microsoft:Hyper-V:System:Realized'
159
- }
160
- $VMNetAdapters = $VMSettings.GetRelated('Msvm_SyntheticEthernetPortSettingData')
161
-
162
- $NetworkSettings = @()
163
- foreach ($NetAdapter in $VMNetAdapters) {
164
- if ($NetAdapter.Address -eq $NetworkAdapter.MacAddress) {
165
- $NetworkSettings = $NetworkSettings + $NetAdapter.GetRelated('Msvm_GuestNetworkAdapterConfiguration')
166
- }
167
- }
168
-
169
- $NetworkSettings[0].IPAddresses = $IPAddress
170
- $NetworkSettings[0].DefaultGateways = $Gateway
171
- $NetworkSettings[0].DNSServers = $DNSServers
172
- $NetworkSettings[0].Subnets = $Subnet
173
- $NetworkSettings[0].ProtocolIFType = 4096
174
- $NetworkSettings[0].DHCPEnabled = $false
175
-
176
-
177
- $Service = Get-WmiObject -Class 'Msvm_VirtualSystemManagementService' -Namespace 'root\virtualization\v2'
178
- $setIP = $Service.SetGuestNetworkAdapterConfiguration($vm, $NetworkSettings[0].GetText(1))
179
-
180
- if ($setIP.ReturnValue -eq 4096) {
181
- $job = [WMI]$setIP.job
182
-
183
- while ($job.JobState -eq 3 -or $job.JobState -eq 4) {
184
- Start-Sleep 1
185
- $job = [WMI]$setIP.job
186
- }
187
-
188
- if ($job.JobState -ne 7) {
189
- $job.GetError()
190
- }
191
- }
192
- (Get-VM -Id $NetworkAdapter.VmId).NetworkAdapter | Select-Object Name, IpAddress
193
- }
194
-
195
- function Get-VmDetail {
196
- [cmdletbinding()]
197
- param($Id)
198
-
199
- Get-VM -Id $Id |
200
- ForEach-Object {
201
- $vm = $_
202
- do {
203
- Start-Sleep -Seconds 1
204
- }
205
- while (-not (Get-VmIP $vm))
206
-
207
- [pscustomobject]@{
208
- Name = $vm.name
209
- Id = $vm.ID
210
- IpAddress = (Get-VmIP $vm)
211
- }
212
- }
213
- }
214
-
215
- function Get-DefaultVMSwitch {
216
- [CmdletBinding()]
217
- param ($Name)
218
- Get-VMSwitch @PSBoundParameters |
219
- Select-Object -First 1 |
220
- Select-Object Name, Id
221
- }
222
-
223
- function Mount-VMISO {
224
- [cmdletbinding()]
225
- param($Id, $Path)
226
-
227
- if ((Get-VM -Id $Id).Generation -eq 2) {
228
- Add-VMDvdDrive (Get-VM -Id $Id).Name | Set-VMDvdDrive -VMName (Get-VM -Id $Id).Name -Path $Path
229
- }
230
-
231
- Set-VMDvdDrive -VMName (Get-VM -Id $Id).Name -Path $Path
232
- }
233
-
1
+ #requires -Version 2 -Modules Hyper-V
2
+
3
+ #implicitly import hyperv module to avoid powercli cmdlets
4
+ if ((Get-Module -Name 'hyper-v') -ne $null) {
5
+ Remove-Module -Name hyper-v
6
+ Import-Module -Name hyper-v
7
+ }
8
+ else {
9
+ Import-Module -Name hyper-v
10
+ }
11
+
12
+ $ProgressPreference = 'SilentlyContinue'
13
+
14
+
15
+ function New-DifferencingDisk {
16
+ [cmdletbinding()]
17
+ param (
18
+ [parameter(Mandatory)]
19
+ [ValidateNotNullOrEmpty()]
20
+ [string[]]$Path,
21
+ [parameter(Mandatory)]
22
+ [ValidateNotNullOrEmpty()]
23
+ [string]$ParentPath
24
+ )
25
+ if (-not (Test-Path $Path)) {
26
+ $null = new-vhd @psboundparameters -Differencing
27
+ }
28
+ }
29
+
30
+ function Assert-VmRunning {
31
+ [cmdletbinding()]
32
+ param([string]$Id)
33
+
34
+ if ([string]::IsNullOrEmpty($Id)) {
35
+ $Output = [pscustomobject]@{
36
+ Name = ''
37
+ State = ''
38
+ }
39
+ }
40
+ else {
41
+ $Output = Get-VM -Id $Id |
42
+ ForEach-Object -Process {
43
+ if ($_.State -notlike 'Running') {
44
+ $_ |
45
+ Start-VM -passthru
46
+ }
47
+ else {
48
+ $_
49
+ }
50
+ } |
51
+ Select-Object -Property Name, Id, State
52
+ }
53
+ $Output
54
+ }
55
+
56
+ function New-KitchenVM {
57
+ [cmdletbinding()]
58
+ param (
59
+ $Generation = 1,
60
+ $DisableSecureBoot,
61
+ $MemoryStartupBytes,
62
+ $StaticMacAddress,
63
+ $Name,
64
+ $Path,
65
+ $VHDPath,
66
+ $SwitchName,
67
+ $VlanId,
68
+ $ProcessorCount,
69
+ $UseDynamicMemory,
70
+ $DynamicMemoryMinBytes,
71
+ $DynamicMemoryMaxBytes,
72
+ $boot_iso_path,
73
+ $EnableGuestServices,
74
+ $AdditionalDisks
75
+ )
76
+ $null = $psboundparameters.remove('DisableSecureBoot')
77
+ $null = $psboundparameters.remove('ProcessorCount')
78
+ $null = $psboundparameters.remove('StaticMacAddress')
79
+ $null = $psboundparameters.remove('UseDynamicMemory')
80
+ $null = $psboundparameters.remove('DynamicMemoryMinBytes')
81
+ $null = $psboundparameters.remove('DynamicMemoryMaxBytes')
82
+ $null = $psboundparameters.remove('boot_iso_path')
83
+ $null = $psboundparameters.remove('EnableGuestServices')
84
+ $null = $psboundparameters.remove('VlanId')
85
+ $null = $psboundparameters.remove('AdditionalDisks')
86
+ $DisableSecureBoot = [Convert]::ToBoolean($DisableSecureBoot)
87
+ $UseDynamicMemory = [Convert]::ToBoolean($UseDynamicMemory)
88
+ $null = [bool]::TryParse($EnableGuestServices, [ref]$EnableGuestServices)
89
+
90
+ $vm = new-vm @psboundparameters |
91
+ Set-Vm -ProcessorCount $ProcessorCount -passthru
92
+
93
+ if ($UseDynamicMemory) {
94
+ $vm | Set-VMMemory -DynamicMemoryEnabled $true -MinimumBytes $DynamicMemoryMinBytes -MaximumBytes $DynamicMemoryMaxBytes
95
+ }
96
+ else {
97
+ $vm | Set-VMMemory -DynamicMemoryEnabled $false
98
+ }
99
+ if (-not [string]::IsNullOrEmpty($boot_iso_path)) {
100
+ Mount-VMISO -Id $vm.Id -Path $boot_iso_path
101
+ }
102
+ if (-not [string]::IsNullOrEmpty($StaticMacAddress)) {
103
+ Set-VMNetworkAdapter -VMName $vm.VMName -StaticMacAddress $StaticMacAddress
104
+ }
105
+ if ($EnableGuestServices -and (Get-command Enable-VMIntegrationService -ErrorAction SilentlyContinue)) {
106
+ Enable-VMIntegrationService -VM $vm -Name 'Guest Service Interface'
107
+ }
108
+ if (($VlanId -ne $null) -and (Get-command Set-VMNetworkAdapterVlan -ErrorAction SilentlyContinue)) {
109
+ Set-VMNetworkAdapterVlan -VM $vm -Access -VlanId $VlanId
110
+ }
111
+ if ($AdditionalDisks -and (Get-command Add-VMHardDiskDrive -ErrorAction SilentlyContinue)) {
112
+ foreach ($AdditionalDisk in $AdditionalDisks) {
113
+ Add-VMHardDiskDrive -VM $vm -Path $AdditionalDisk
114
+ }
115
+ }
116
+ if ($DisableSecureBoot -and ($Generation -eq 2) -and (Get-command Set-VMFirmware -ErrorAction SilentlyContinue)) {
117
+ Set-VMFirmware -VM $vm -EnableSecureBoot Off
118
+ }
119
+ if ((Get-Command -Name Set-Vm).Parameters["AutomaticCheckpointsEnabled"]) {
120
+ Set-VM -Name $vm.VMName -AutomaticCheckpointsEnabled $false
121
+ }
122
+ $vm | Start-Vm -passthru |
123
+ foreach {
124
+ $vm = $_
125
+ do {
126
+ start-sleep -seconds 2
127
+ }
128
+ while ($vm.state -notlike 'Running')
129
+ $vm
130
+ } |
131
+ select Name, Id, State
132
+ }
133
+
134
+ function Get-VmIP($vm) {
135
+ start-sleep -seconds 10
136
+ $vm.networkadapters.ipaddresses |
137
+ Where-Object {
138
+ $_ -match '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$'
139
+ } |
140
+ Select-Object -First 1
141
+ }
142
+
143
+ Function Set-VMNetworkConfiguration {
144
+ [CmdletBinding()]
145
+ Param (
146
+ [parameter(valuefrompipeline)]
147
+ [object]$NetworkAdapter,
148
+ [String[]]$IPAddress = @(),
149
+ [String[]]$Gateway = @(),
150
+ [String[]]$DNSServers = @(),
151
+ [String[]]$Subnet = @()
152
+ )
153
+
154
+ $vm = Get-CimInstance -Namespace 'root\virtualization\v2' -ClassName 'Msvm_ComputerSystem' -Filter "ElementName = '$($NetworkAdapter.VMName)'"
155
+
156
+ $VMSettings = Get-CimAssociatedInstance -InputObject $vm -ResultClassName 'Msvm_VirtualSystemSettingData' |
157
+ Where-Object { $_.VirtualSystemType -eq 'Microsoft:Hyper-V:System:Realized' }
158
+
159
+ $VMNetAdapters = Get-CimAssociatedInstance -InputObject $VMSettings -ResultClassName 'Msvm_SyntheticEthernetPortSettingData'
160
+
161
+ $NetworkSettings = @()
162
+ foreach ($NetAdapter in $VMNetAdapters) {
163
+ if ($NetAdapter.Address -eq $NetworkAdapter.MacAddress) {
164
+ $NetworkSettings += Get-CimAssociatedInstance -InputObject $NetAdapter -ResultClassName 'Msvm_GuestNetworkAdapterConfiguration'
165
+ }
166
+ }
167
+
168
+ if ($NetworkSettings.Count -eq 0) {
169
+ throw "No guest network adapter configuration found for MAC address $($NetworkAdapter.MacAddress) on VM $($NetworkAdapter.VMName)."
170
+ }
171
+
172
+ $NetworkSettings[0].IPAddresses = $IPAddress
173
+ $NetworkSettings[0].DefaultGateways = $Gateway
174
+ $NetworkSettings[0].DNSServers = $DNSServers
175
+ $NetworkSettings[0].Subnets = $Subnet
176
+ $NetworkSettings[0].ProtocolIFType = 4096
177
+ $NetworkSettings[0].DHCPEnabled = $false
178
+
179
+
180
+ $Service = Get-CimInstance -Namespace 'root\virtualization\v2' -ClassName 'Msvm_VirtualSystemManagementService'
181
+
182
+ # NetworkConfiguration is declared string[] of embedded instances; the CIM
183
+ # layer serializes the CimInstance for us, replacing WMI's GetText(1).
184
+ $setIP = Invoke-CimMethod -InputObject $Service -MethodName 'SetGuestNetworkAdapterConfiguration' -Arguments @{
185
+ ComputerSystem = $vm
186
+ NetworkConfiguration = @($NetworkSettings[0])
187
+ }
188
+
189
+ # 4096 means the method was accepted and is running as a job.
190
+ if ($setIP.ReturnValue -eq 4096) {
191
+ $job = $setIP.Job | Get-CimInstance
192
+
193
+ # 3 = Starting, 4 = Running.
194
+ while ($job.JobState -eq 3 -or $job.JobState -eq 4) {
195
+ Start-Sleep -Seconds 1
196
+ $job = $job | Get-CimInstance
197
+ }
198
+
199
+ # 7 = Completed. Anything else previously emitted the error and carried
200
+ # on, which hid a failed address assignment behind a successful create.
201
+ if ($job.JobState -ne 7) {
202
+ throw "Setting the guest network adapter configuration failed: $($job.ErrorDescription)"
203
+ }
204
+ }
205
+ elseif ($setIP.ReturnValue -ne 0) {
206
+ throw "Setting the guest network adapter configuration failed with return value $($setIP.ReturnValue)."
207
+ }
208
+
209
+ (Get-VM -Id $NetworkAdapter.VmId).NetworkAdapters | Select-Object Name, IPAddresses
210
+ }
211
+
212
+ function Get-VmDetail {
213
+ [cmdletbinding()]
214
+ param($Id)
215
+
216
+ Get-VM -Id $Id |
217
+ ForEach-Object {
218
+ $vm = $_
219
+ do {
220
+ Start-Sleep -Seconds 1
221
+ }
222
+ while (-not (Get-VmIP $vm))
223
+
224
+ [pscustomobject]@{
225
+ Name = $vm.name
226
+ Id = $vm.ID
227
+ IpAddress = (Get-VmIP $vm)
228
+ }
229
+ }
230
+ }
231
+
232
+ function Get-VmStatus {
233
+ [cmdletbinding()]
234
+ param($Id)
235
+
236
+ Get-VM -Id $Id -ErrorAction SilentlyContinue |
237
+ ForEach-Object {
238
+ [pscustomobject]@{
239
+ Name = $_.Name
240
+ Id = [string]$_.Id
241
+ State = [string]$_.State
242
+ }
243
+ }
244
+ }
245
+
246
+ function Get-DefaultVMSwitch {
247
+ [CmdletBinding()]
248
+ param ($Name)
249
+ Get-VMSwitch @PSBoundParameters |
250
+ Select-Object -First 1 |
251
+ Select-Object Name, Id
252
+ }
253
+
254
+ function Mount-VMISO {
255
+ [cmdletbinding()]
256
+ param($Id, $Path)
257
+
258
+ if ((Get-VM -Id $Id).Generation -eq 2) {
259
+ Add-VMDvdDrive (Get-VM -Id $Id).Name | Set-VMDvdDrive -VMName (Get-VM -Id $Id).Name -Path $Path
260
+ }
261
+
262
+ Set-VMDvdDrive -VMName (Get-VM -Id $Id).Name -Path $Path
263
+ }
264
+
metadata CHANGED
@@ -1,22 +1,36 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kitchen-hyperv
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.3
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven Murawski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-02-19 00:00:00.000000000 Z
11
+ date: 2026-08-23 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: base64
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.2'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: test-kitchen
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
31
  - - ">="
18
32
  - !ruby/object:Gem::Version
19
- version: '1.4'
33
+ version: '3.0'
20
34
  - - "<"
21
35
  - !ruby/object:Gem::Version
22
36
  version: '5'
@@ -26,7 +40,7 @@ dependencies:
26
40
  requirements:
27
41
  - - ">="
28
42
  - !ruby/object:Gem::Version
29
- version: '1.4'
43
+ version: '3.0'
30
44
  - - "<"
31
45
  - !ruby/object:Gem::Version
32
46
  version: '5'