diff --git a/CHANGELOG.md b/CHANGELOG.md index 68d06c2..e188ba9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ For older change log history see the [historic changelog](HISTORIC_CHANGELOG.md) ## [Unreleased] +- VMHardDiskDrive + - `Get-TargetResource` no longer throws when the VM does not exist. Returns + `Ensure = 'Absent'` so `Test-TargetResource` correctly reports the resource + is not in desired state instead of aborting the configuration - Fixes + [Issue #223](https://github.com/dsccommunity/HyperVDsc/issues/223). - HyperVDsc - BREAKING CHANGE - Renamed _xHyper-V_ to _HyperVDsc - fixes [Issue #69](https://github.com/dsccommunity/HyperVDsc/issues/213). diff --git a/source/DSCResources/DSC_VMHardDiskDrive/DSC_VMHardDiskDrive.psm1 b/source/DSCResources/DSC_VMHardDiskDrive/DSC_VMHardDiskDrive.psm1 index 85f4322..268f7b4 100644 --- a/source/DSCResources/DSC_VMHardDiskDrive/DSC_VMHardDiskDrive.psm1 +++ b/source/DSCResources/DSC_VMHardDiskDrive/DSC_VMHardDiskDrive.psm1 @@ -31,6 +31,24 @@ function Get-TargetResource Assert-Module -ModuleName 'Hyper-V' + # Check if the VM exists before querying its hard disk drives. + # When the VM has not been created yet (e.g., during initial provisioning + # with dependsOn), return Absent rather than throwing so that + # Test-TargetResource can report the resource is not in desired state. + $vm = Get-VM -Name $VMName -ErrorAction SilentlyContinue + if ($null -eq $vm) + { + Write-Verbose -Message ($script:localizedData.VMNotFound -f $VMName) + return @{ + VMName = $VMName + Path = $null + ControllerType = $null + ControllerNumber = $null + ControllerLocation = $null + Ensure = 'Absent' + } + } + $hardDiskDrive = Get-VMHardDiskDrive -VMName $VMName -ErrorAction Stop | Where-Object -FilterScript { $_.Path -eq $Path } diff --git a/source/DSCResources/DSC_VMHardDiskDrive/en-US/DSC_VMHardDiskDrive.strings.psd1 b/source/DSCResources/DSC_VMHardDiskDrive/en-US/DSC_VMHardDiskDrive.strings.psd1 index 5864aac..b09e80d 100644 --- a/source/DSCResources/DSC_VMHardDiskDrive/en-US/DSC_VMHardDiskDrive.strings.psd1 +++ b/source/DSCResources/DSC_VMHardDiskDrive/en-US/DSC_VMHardDiskDrive.strings.psd1 @@ -1,6 +1,7 @@ ConvertFrom-StringData @' DiskFound = Found hard disk '{0}' attached to VM '{1}'. DiskNotFound = Hard disk '{0}' missing from VM '{1}' + VMNotFound = VM '{0}' not found. CheckingDiskIsAttached = Checking if the disk is already attached to the VM. CheckingExistingDiskLocation = Checking if there is an existing disk in the specified location. AddingDisk = Adding the disk '{0}' to VM '{1}'. diff --git a/tests/Unit/DSC_VMHardDiskDrive.Tests.ps1 b/tests/Unit/DSC_VMHardDiskDrive.Tests.ps1 index 60ae4cc..c5315d5 100644 --- a/tests/Unit/DSC_VMHardDiskDrive.Tests.ps1 +++ b/tests/Unit/DSC_VMHardDiskDrive.Tests.ps1 @@ -50,6 +50,7 @@ try Mock -CommandName Assert-Module It 'Should return a [System.Collections.Hashtable] object type' { + Mock -CommandName Get-VM { return [PSCustomObject]@{ Name = $testVMName } } Mock -CommandName Get-VMHardDiskDrive { return $stubHardDiskDrive } $result = Get-TargetResource -VMName $testVMName -Path $testhardDiskPath @@ -58,6 +59,7 @@ try } It 'Should return "Present" when hard disk is attached' { + Mock -CommandName Get-VM { return [PSCustomObject]@{ Name = $testVMName } } Mock -CommandName Get-VMHardDiskDrive { return $stubHardDiskDrive } $result = Get-TargetResource -VMName $testVMName -Path $testhardDiskPath @@ -66,6 +68,7 @@ try } It 'Should return "Absent" when hard disk is not attached' { + Mock -CommandName Get-VM { return [PSCustomObject]@{ Name = $testVMName } } Mock -CommandName Get-VMHardDiskDrive $result = Get-TargetResource -VMName $testVMName -Path $testhardDiskPath @@ -73,8 +76,28 @@ try $result.Ensure | Should -Be 'Absent' } + It 'Should return "Absent" when VM does not exist' { + Mock -CommandName Get-VM + Mock -CommandName Get-VMHardDiskDrive + + $result = Get-TargetResource -VMName $testVMName -Path $testhardDiskPath + + $result.Ensure | Should -Be 'Absent' + $result.Path | Should -BeNullOrEmpty + } + + It 'Should not call Get-VMHardDiskDrive when VM does not exist' { + Mock -CommandName Get-VM + Mock -CommandName Get-VMHardDiskDrive + + $null = Get-TargetResource -VMName $testVMName -Path $testhardDiskPath + + Assert-MockCalled -CommandName Get-VMHardDiskDrive -Times 0 -Scope It + } + It 'Should assert Hyper-V module is installed' { Mock -CommandName Assert-Module + Mock -CommandName Get-VM { return [PSCustomObject]@{ Name = $testVMName } } Mock -CommandName Get-VMHardDiskDrive { return $stubHardDiskDrive } $null = Get-TargetResource -VMName $testVMName -Path $testhardDiskPath