DSCResources/cVMNetworkAdapterVlan/cVMNetworkAdapterVlan.psm1
# Fallback message strings in en-US DATA localizedData { # same as culture = "en-US" ConvertFrom-StringData @' HyperVModuleNotFound=Hyper-V PowerShell Module not found. VMNameAndManagementTogether=VMName cannot be provided when ManagementOS is set to True. MustProvideVMName=Must provide VMName parameter when ManagementOS is set to False. GetVMNetAdapter=Getting VM Network Adapter information. FoundVMNetAdapter=Found VM Network Adapter. NoVMNetAdapterFound=No VM Network Adapter found. VMNetAdapterDoesNotExist=VM Network Adapter does not exist. PerformVMVlanSet=Perfoming VM Network Adapter VLAN setting configuration. IgnoreVlan=Ignoring VLAN configuration when the opeartion mode chosen is Untagged. VlanIdRequiredInAccess=VlanId must be specified when chosen operation mode is Access. MustProvideNativeVlanId=NativeVlanId must be specified when chosen operation mode is Trunk. PrimaryVlanIdRequired=PrimaryVlanId is required when the chosen operation mode is Community or Isolated or Promiscuous. AccessVlanMustChange=VlanId in Access mode is different. It will be changed. AdaptersExistsWithVlan=VM Network adapter exists with required VLAN configuration. NativeVlanMustChange=NativeVlanId in Trunk mode is different and it wil be changed. AllowedVlanListMustChange=AllowedVlanIdList is different in trunk mode. It will be changed. PrimaryVlanMustChange=PrimaryVlanId is different and must be changed. SecondaryVlanMustChange=SecondaryVlanId is different and must be changed. SecondaryVlanListMustChange=SecondaryVlanIdList is different and must be changed. AdapterExistsWithDifferentVlanMode=VM Network adapter exists with different Vlan configuration. It will be fixed. '@ } if (Test-Path "$PSScriptRoot\$PSCulture") { Import-LocalizedData LocalizedData -filename "cVMNetworkAdapterVlan.psd1" -BaseDirectory "$PSScriptRoot\$PSCulture" } Function Get-TargetResource { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] Param ( [Parameter(Mandatory)] [String] $Name ) if(!(Get-Module -ListAvailable -Name Hyper-V)) { Throw $localizedData.HyperVModuleNotFound } $Arguments = @{ Name = $Name } Write-Verbose $localizedData.GetVMNetAdapter try { $AdapterExists = Get-VMNetworkAdapter @Arguments -ErrorAction Stop if ($AdapterExists) { Write-Verbose $localizedData.FoundVMNetAdapter $Configuration = $Arguments $Configuration.Remove('Name') $Configuration.Add('AdapterMode',$AdapterExists.VlanSetting.OperationMode) $Configuration.Add('VlanId',$AdapterExists.VlanSetting.AccessVlanId) $Configuration.Add('NativeVlanId',$AdapterExists.VlanSetting.NativeVlanId) $Configuration.Add('PrimaryVlanId',$AdapterExists.VlanSetting.PrimaryVlanId) $Configuration.Add('SecondaryVlanId',$AdapterExists.VlanSetting.SecondaryVlanId) $Configuration.Add('SecondaryVlanIdList',$AdapterExists.VlanSetting.SecondaryVlanIdListString) $Configuration.Add('AllowedVlanIdList',$AdapterExists.VlanSetting.AllowedVlanIdListString) } $Configuration } catch { Write-Error $_ } } Function Set-TargetResource { [CmdletBinding()] Param ( [Parameter(Mandatory)] [String] $Name, [Parameter()] [Bool] $ManagementOS, [Parameter()] [String] $VMName, [Parameter()] [ValidateSet('Untagged','Access','Trunk','Communnity','Isolated','Promiscuous')] [String] $AdapterMode = 'Untagged', [Parameter()] [uint32] $VlanId, [Parameter()] [uint32] $NativeVlanId, [Parameter()] [String] $AllowedVlanIdList, [Parameter()] [uint32] $PrimaryVlanId, [Parameter()] [uint32] $SecondaryVlanId, [Parameter()] [String] $SecondaryVlanIdList ) if(!(Get-Module -ListAvailable -Name Hyper-V)) { Throw $localizedData.HyperVModuleNotFound } if ($VMName -and $ManagementOS) { throw $localizedData.VMNameAndManagementTogether } if ((-not $ManagementOS) -and (-not $VMName)) { throw $localizedData.MustProvideVMName } $Arguments = @{ Name = $Name } if ($VMName) { $Arguments.Add('VMName',$VMName) } elseif ($ManagementOS) { $Arguments.Add('ManagementOS', $true) } try { Write-Verbose $localizedData.GetVMNetAdapter $AdapterExists = Get-VMNetworkAdapter @Arguments -ErrorAction Stop if ($AdapterExists) { Write-Verbose $localizedData.FoundVMNetAdapter $SetArguments = $Arguments $SetArguments.Remove('Name') $SetArguments.Add('VMNetworkAdapterName',$Name) switch ($AdapterMode) { 'Untagged' { $SetArguments.Add('Untagged',$true) break } 'Access' { $SetArguments.Add('Access',$true) $SetArguments.Add('VlanId',$VlanId) break } 'Trunk' { $SetArguments.Add('Trunk',$true) $SetArguments.Add('NativeVlanId',$NativeVlanId) if ($AllowedVlanIdList) { $SetArguments.Add('AllowedVlanIdList',$AllowedVlanIdList) } break } 'Community' { $SetArguments.Add('Community',$true) $SetArguments.Add('PrimaryVlanId',$PrimaryVlanId) if ($SecondaryVlanId) { $SetArguments.Add('SecondaryVlanId',$SecondaryVlanId) } break } 'Isolated' { $SetArguments.Add('Isolated',$true) $SetArguments.Add('PrimaryVlanId',$PrimaryVlanId) if ($SecondaryVlanId) { $SetArguments.Add('SecondaryVlanId',$SecondaryVlanId) } break } 'Promiscuous' { $SetArguments.Add('Promiscuous',$true) $SetArguments.Add('PrimaryVlanId', $PrimaryVlanId) if ($SecondaryVlanIdList) { $SetArguments.Add('SecondaryVlanIdList', $SecondaryVlanIdList) } break } } } Write-Verbose $localizedData.PerformVMVlanSet Set-VMNetworkAdapterVlan @SetArguments -ErrorAction Stop } catch { Write-Error $_ } } Function Test-TargetResource { [CmdletBinding()] [OutputType([System.Boolean])] Param ( [Parameter(Mandatory)] [String] $Name, [Parameter()] [Bool] $ManagementOS, [Parameter()] [String] $VMName, [Parameter()] [ValidateSet('Untagged','Access','Trunk','Communnity','Isolated','Promiscuous')] [String] $AdapterMode = 'Untagged', [Parameter()] [uint32] $VlanId, [Parameter()] [uint32] $NativeVlanId, [Parameter()] [String] $AllowedVlanIdList, [Parameter()] [uint32] $PrimaryVlanId, [Parameter()] [uint32] $SecondaryVlanId, [Parameter()] [String] $SecondaryVlanIdList ) if(!(Get-Module -ListAvailable -Name Hyper-V)) { Throw $localizedData.HyperVModuleNotFound } if ($VMName -and $ManagementOS) { throw $localizedData.VMNameAndManagementTogether } if ((-not $ManagementOS) -and (-not $VMName)) { throw $localizedData.MustProvideVMName } $Arguments = @{ Name = $Name } if ($VMName) { $Arguments.Add('VMName',$VMName) } elseif ($ManagementOS) { $Arguments.Add('ManagementOS', $true) } switch ($AdapterMode) { 'Untagged' { if ($VlanId -or $NativeVlanId -or $PrimaryVlanId -or $SecondaryVlanId -or $AllowedVlanIdList -or $SecondaryVlanIdList) { Write-Verbose $localizedData.IgnoreVlan } break } 'Access' { if (-not $VlanId) { throw $localizedData.VlanIdRequiredInAccess } break } 'Trunk' { if (-not $NativeVlanId) { throw $localizedData.MustProvideNativeVlanId } break } 'Community' { if (-not $PrimaryVlanId) { throw $localizedData.PrimaryVlanIdRequired } break } 'Isolated' { if (-not $PrimaryVlanId) { throw $localizedData.PrimaryVlanIdRequired } break } 'Promiscuous' { if (-not $PrimaryVlanId) { throw $localizedData.PrimaryVlanIdRequired } break } } try { #There is a remote timing issue that occurs when VLAN is set just after creating a VM Adapter. This needs more investigation. Sleep until then. Start-Sleep -Seconds 10 Write-Verbose $localizedData.GetVMNetAdapter $AdapterExists = Get-VMNetworkAdapter @Arguments -ErrorAction Stop if ($AdapterExists) { Write-Verbose $localizedData.FoundVMNetAdapter if ($AdapterExists.VlanSetting.OperationMode -eq $AdapterMode) { switch ($AdapterExists.VlanSetting.OperationMode) { 'Access' { if ($VlanId -ne $AdapterExists.VlanSetting.AccessVlanId) { Write-Verbose $localizedData.AccessVlanMustChange return $false } else { Write-Verbose $localizedData.AdaptersExistsWithVlan return $true } break } 'Trunk' { if ($NativeVlanId -ne $AdapterExists.VlanSetting.NativeVlanId) { Write-Verbose $localizedData.NativeVlanMustChange return $false } elseif ($AllowedVlanIdList -ne $AdapterMode.VlanSetting.AllowedVlanIdListString) { Write-Verbose $localizedData.AllowedVlanListMustChange return $false } else { Write-Verbose $localizedData.AdaptersExistsWithVlan return $true } break } 'Untagged' { if ($AdapterMode -eq 'Untagged') { Write-Verbose $localizedData.AdaptersExistsWithVlan Write-Verbose $localizedData.IgnoreVlan return $true } break } ('Community' -or 'isolated') { if ($PrimaryVlanId -ne $AdapterExists.VlanSetting.PrimaryVlanId) { Write-Verbose $localizedData.PrimaryVlanMustChange return $false } elseif ($SecondaryVlanId -ne $AdapterExists.VlanSetting.SecondaryVlanId) { Write-Verbose $localizedData.SecondaryVlanMustChange return $false } else { Write-Verbose $localizedData.AdaptersExistsWithVlan return $true } break } 'Promiscuous' { if ($PrimaryVlanId -ne $AdapterExists.VlanSetting.PrimaryVlanId) { Write-Verbose $localizedData.PrimaryVlanMustChange return $false } elseif ($SecondaryVlanIdList -ne $AdapterExists.VlanSetting.SecondaryVlanIdListString) { Write-Verbose $localizedData.SecondaryVlanListMustChange return $false } else { Write-Verbose $localizedData.AdaptersExistsWithVlan return $true } } } } else { Write-Verbose $localizedData.AdapterExistsWithDifferentVlanMode return $false } } else { Write-Warning $localizedData.VMNetAdapterDoesNotExist } } catch { Write-Error $_ } } |