Skip to content

Commit

Permalink
VMNetworkAdapter: fix some issues on NetworkSetting parameter (#205)
Browse files Browse the repository at this point in the history
  • Loading branch information
stehlih authored Jul 17, 2022
1 parent b0397fb commit 6c0e583
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 73 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ For older change log history see the [historic changelog](HISTORIC_CHANGELOG.md)
- Moved documentation to the HyperVDsc GitHub Wiki.
- Updated all examples to correct folders and naming so they show up
in the GitHub Wiki documentation and conceptual help.
- VMNetworkAdapter
- BREAKING CHANGE: Rename embedded instance class #203
- Fix multiple DNS IP adresses does not work #190
- NetworkSetting parameter is now optional and no default actions are taken if not specified

## [3.18.0] - 2022-06-04

Expand Down
119 changes: 64 additions & 55 deletions source/DSCResources/DSC_VMNetworkAdapter/DSC_VMNetworkAdapter.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ $script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US'
.PARAMETER VMName
Specifies the name of the VM to which the network adapter will be connected.
Specify VMName as ManagementOS if you wish to connect the adapter to host OS.
.PARAMETER IpAddress
Specifies the IpAddress information for the network adapter.
#>
function Get-TargetResource
{
Expand Down Expand Up @@ -88,7 +85,7 @@ function Get-TargetResource
$networkInfo = Get-NetworkInformation -VMName $VMName -Name $Name
if ($networkInfo)
{
$item = New-CimInstance -ClassName MSFT_NetworkSettings -Property $networkInfo -Namespace root/microsoft/windows/desiredstateconfiguration -ClientOnly
$item = New-CimInstance -ClassName VMNetworkAdapterNetworkSettings -Property $networkInfo -Namespace root/microsoft/windows/desiredstateconfiguration -ClientOnly
$configuration.Add('NetworkSetting', $item)
}

Expand Down Expand Up @@ -131,8 +128,8 @@ function Get-TargetResource
Specifies the MAC address for the network adapter. This is not applicable if VMName
is set to ManagementOS. Use this parameter to specify a static MAC address.
.PARAMETER IpAddress
Specifies the IpAddress information for the network adapter.
.PARAMETER NetworkSetting
Specifies the DHCP or IpAddress & DNS sever information for the network adapter.
.PARAMETER VlanId
Specifies the Vlan Id for the network adapter.
Expand Down Expand Up @@ -269,44 +266,45 @@ function Set-TargetResource

if ($VmName -ne 'ManagementOS')
{
$networkInfo = Get-NetworkInformation -VMName $VMName -Name $Name
if (-not $NetworkSetting)
if ($null -ne $NetworkSetting)
{
if ($networkInfo)
[boolean]$dhcpEnabled = $NetworkSetting.CimInstanceProperties['DHCPEnabled'].Value

if ($dhcpEnabled)
{
Write-Verbose -Message $script:localizedData.EnableDhcp
Set-NetworkInformation -VMName $VMName -Name $Name -Dhcp
}
}
else
{
$parameters = @{ }
if ($ipAddress = $NetworkSetting.CimInstanceProperties['IpAddress'].Value)
else
{
if (-not $ipAddress)
$parameters = @{}
if ($ipAddress = $NetworkSetting.CimInstanceProperties['IpAddress'].Value)
{
throw $script:localizedData.MissingIPAndSubnet
if (-not $ipAddress)
{
throw $script:localizedData.MissingIPAndSubnet
}
$parameters.Add('IPAddress', $ipAddress)
}
$parameters.Add('IPAddress', $ipAddress)
}
if ($subnet = $NetworkSetting.CimInstanceProperties['Subnet'].Value)
{
if (-not $subnet)
if ($subnet = $NetworkSetting.CimInstanceProperties['Subnet'].Value)
{
throw $script:localizedData.MissingIPAndSubnet
if (-not $subnet)
{
throw $script:localizedData.MissingIPAndSubnet
}
$parameters.Add('Subnet', $subnet)
}
if ($defaultGateway = $NetworkSetting.CimInstanceProperties['DefaultGateway'].Value)
{
$parameters.Add('DefaultGateway', $defaultGateway)
}
if ($dnsServer = $NetworkSetting.CimInstanceProperties['DnsServer'].Value)
{
$parameters.Add('DnsServer', $dnsServer)
}
$parameters.Add('Subnet', $subnet)
}
if ($defaultGateway = $NetworkSetting.CimInstanceProperties['DefaultGateway'].Value)
{
$parameters.Add('DefaultGateway', $defaultGateway)
}
if ($dnsServer = $NetworkSetting.CimInstanceProperties['DnsServer'].Value)
{
$parameters.Add('DnsServer', $dnsServer)
}

Set-NetworkInformation -VMName $VMName -Name $Name @parameters
Set-NetworkInformation -VMName $VMName -Name $Name @parameters
}
}

Write-Verbose -Message $script:localizedData.GetVMNetAdapterVlan
Expand Down Expand Up @@ -363,8 +361,8 @@ function Set-TargetResource
Specifies the MAC address for the network adapter. This is not applicable if VMName
is set to ManagementOS. Use this parameter to specify a static MAC address.
.PARAMETER IpAddress
Specifies the IpAddress information for the network adapter.
.PARAMETER NetworkSetting
Specifies the DHCP or IpAddress & DNS sever information for the network adapter.
.PARAMETER VlanId
Specifies the Vlan Id for the network adapter.
Expand Down Expand Up @@ -457,24 +455,28 @@ function Test-TargetResource
}
}

$networkInfo = Get-NetworkInformation -VMName $VMName -Name $Name
if (-not $NetworkSetting)
if ($null -ne $NetworkSetting)
{
if ($networkInfo)
{
Write-Verbose -Message $script:localizedData.NotDhcp
return $false
}
}
else
{
if (-not $networkInfo)
$networkInfo = Get-NetworkInformation -VMName $VMName -Name $Name

[boolean]$dhcpEnabled = $NetworkSetting.CimInstanceProperties['DHCPEnabled'].Value

if ($dhcpEnabled)
{
Write-Verbose -Message $script:localizedData.Dhcp
return $false
if (-not $networkInfo.DHCPEnabled)
{
Write-Verbose -Message $script:localizedData.NotDhcp
return $false
}
}
else
{
if ($networkInfo.DHCPEnabled)
{
Write-Verbose -Message $script:localizedData.Dhcp
return $false
}

$ipAddress = $NetworkSetting.CimInstanceProperties['IpAddress'].Value
$subnet = $NetworkSetting.CimInstanceProperties['Subnet'].Value
$defaultGateway = $NetworkSetting.CimInstanceProperties['DefaultGateway'].Value
Expand All @@ -497,10 +499,15 @@ function Test-TargetResource
return $false
}

if ($dnsServer -and -not $networkInfo.DNSServer.Split(',').Contains($dnsServer))
if ($dnsServer )
{
Write-Verbose -Message $script:localizedData.DNSServerNotConfigured
return $false
$missingDns = $dnsServer | Where-Object {$networkInfo.DNSServer -notcontains $_}

if ($missingDns.Count -gt 0)
{
Write-Verbose -Message $script:localizedData.DNSServerNotConfigured
return $false
}
}
}
}
Expand Down Expand Up @@ -601,18 +608,20 @@ function Get-NetworkInformation

if ($networkSettings.DHCPEnabled)
{
return $null
return @{
DHCPEnabled = $true
}
}
else
{
return @{
DHCPEnabled = $false
IpAddress = $networkSettings.IPAddresses -join ','
Subnet = $networkSettings.Subnets -join ','
DefaultGateway = $networkSettings.DefaultGateways -join ','
DnsServer = $networkSettings.DNSServers -join ','
DnsServer = $networkSettings.DNSServers
}
}

}

function Set-NetworkInformation
Expand Down Expand Up @@ -645,7 +654,7 @@ function Set-NetworkInformation
$DefaultGateway,

[Parameter(ParameterSetName = 'Static')]
[System.String]
[System.String[]]
$DnsServer
)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
[ClassVersion("2.0.0.0")]
Class NetworkSettings
Class VMNetworkAdapterNetworkSettings
{
[Write, Description("IpAddress to give the network adapter. Only used if not Dhcp. Required if not Dhcp.")] string IpAddress;
[Write, Description("Subnet to give the network adapter. Only used if not Dhcp. Required if not Dhcp.")] string Subnet;
[Write, Description("DefaultGateway to give the network adapter. Only used if not Dhcp.")] string DefaultGateway;
[Write, Description("DNS server to give the network adapter. Only used if not Dhcp.")] string DnsServer;
[Write, Description("Specifies whether DHCP is enabled on the network adapter within the guest operating system.")] boolean DHCPEnabled;
[Write, Description("IPAddress configured on the network adapter within the guest operating system.")] string IPAddress;
[Write, Description("Subnet configured on the network adapter within the guest operating system.")] string Subnet;
[Write, Description("Default IP gateway configured on the network adapter within the guest operating system.")] string DefaultGateway;
[Write, Description("One or more DNS servers configured on the network adapter within the guest operating system.")] string DnsServer[];
};

[ClassVersion("2.0.0.0"), FriendlyName("VMNetworkAdapter")]
Expand All @@ -15,7 +16,7 @@ class DSC_VMNetworkAdapter : OMI_BaseResource
[Required, Description("Virtual Switch name to connect to.")] String SwitchName;
[Required, Description("Name of the VM to attach to. If you want to attach new VM Network adapter to the management OS, set this property to 'ManagementOS'.")] String VMName;
[Write, Description("Use this to specify a Static MAC Address. If this parameter is not specified, dynamic MAC Address will be set.")] String MacAddress;
[Write, Description("Network Settings of the network adapter. If this parameter is not supplied, DHCP will be used."), EmbeddedInstance("NetworkSettings")] String NetworkSetting;
[Write, Description("Network Settings of the network adapter. If this parameter is not supplied, DHCP will be used."), EmbeddedInstance("VMNetworkAdapterNetworkSettings")] String NetworkSetting;
[Write, Description("Use this to specify a Vlan id on the Network Adapter.")] String VlanId;
[Write, Description("Ensures that the VM Network Adapter is Present or Absent. The default value is `Present`."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure;
[Read, Description("Returns `$true` if the network adapter uses a dynamic MAC address.")] Boolean DynamicMacAddress;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ Configuration Example
SwitchName = 'SETSwitch'
MacAddress = '001523be0c00'
VMName = 'MyVM01'
NetworkSetting = NetworkSettings
NetworkSetting = VMNetworkAdapterNetworkSettings
{
IpAddress = '192.168.0.100'
Subnet = '255.255.255.255'
DefaultGateway = '192.168.0.1'
DnsServer = '192.168.0.1'
DnsServer = @( '192.168.0.1', '192.168.0.2' )
}
}
}
19 changes: 9 additions & 10 deletions tests/Unit/DSC_VMNetworkAdapter.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,12 @@ try
}

$propertiesStatic = @{
IpAddress = "192.168.0.1"
Subnet = "255.255.255.0"
DHCPEnabled = $false
IpAddress = "192.168.0.1"
Subnet = "255.255.255.0"
}

$networkSettingsStatic = New-CimInstance -ClassName NetworkSettings -Property $properties -Namespace root/microsoft/windows/desiredstateconfiguration -ClientOnly
$networkSettingsStatic = New-CimInstance -ClassName VMNetworkAdapterNetworkSettings -Property $propertiesStatic -Namespace root/microsoft/windows/desiredstateconfiguration -ClientOnly

$TestAdapter = [PSObject]@{
Id = $MockHostAdapter.Id
Expand Down Expand Up @@ -98,7 +99,7 @@ try
IpAddress = '10.10.10.10'
Subnet = '255.255.255.0'
DefaultGateway = '10.10.10.1'
DnsServer = '10.10.10.1'
DnsServer = @( '10.10.10.1' )
}
}

Expand Down Expand Up @@ -132,7 +133,7 @@ try
IpAddress = '10.10.10.10'
Subnet = '255.255.255.0'
DefaultGateway = '10.10.10.1'
DnsServer = '10.10.10.1'
DnsServer = @( '10.10.10.1', '10.10.10.2' )
}
}

Expand Down Expand Up @@ -170,7 +171,6 @@ try
}
Mock -CommandName Remove-VMNetworkAdapter
Mock -CommandName Set-VMNetworkAdapterVlan
Mock -CommandName Get-NetworkInformation
Mock -CommandName Set-NetworkInformation

It 'should not throw error' {
Expand All @@ -184,7 +184,6 @@ try
Assert-MockCalled -CommandName Set-VMNetworkAdapterVlan -Exactly 0
Assert-MockCalled -commandName Add-VMNetworkAdapter -Exactly 1
Assert-MockCalled -commandName Remove-VMNetworkAdapter -Exactly 0
Assert-MockCalled -CommandName Get-NetworkInformation -Exactly 1
Assert-MockCalled -CommandName Set-NetworkInformation -Exactly 1
}
}
Expand Down Expand Up @@ -324,11 +323,11 @@ try
}
}

Context 'Adapter exists but network settings are not correct' {
Context 'Adapter exists and network settings are not specified' {
Mock -CommandName Get-VMNetworkAdapter -MockWith { $MockAdapter }
Mock -CommandName Get-VMNetworkAdapterVlan -MockWith { $MockAdapterVlanTagged }
Mock -CommandName Get-NetworkInformation -MockWith {
@{ Dhcp = $false }
@{ DHCPEnabled = $false }
}

It 'should return false' {
Expand All @@ -339,7 +338,7 @@ try
}
It 'should call expected Mocks' {
Assert-MockCalled -commandName Get-VMNetworkAdapter -Exactly 1
Assert-MockCalled -commandName Get-NetworkInformation -Exactly 1
Assert-MockCalled -commandName Get-NetworkInformation -Exactly 0
}
}
}
Expand Down

0 comments on commit 6c0e583

Please sign in to comment.