DSCResources/cVMNetworkAdapterVlan/cVMNetworkAdapterVlan.psm1
#region localizeddata if (Test-Path "${PSScriptRoot}\${PSUICulture}") { Import-LocalizedData -BindingVariable localizedData -filename cVMNetworkAdapterVlan.psd1 ` -BaseDirectory "${PSScriptRoot}\${PSUICulture}" } else { #fallback to en-US Import-LocalizedData -BindingVariable localizedData -filename cVMNetworkAdapterVlan.psd1 ` -BaseDirectory "${PSScriptRoot}\en-US" } #endregion Function Get-TargetResource { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] Param ( [Parameter(Mandatory)] [String] $Id, [Parameter(Mandatory)] [String] $Name, [Parameter(Mandatory)] [String] $VMName ) if(!(Get-Module -ListAvailable -Name Hyper-V)) { Throw $localizedData.HyperVModuleNotFound } $configuration = @{ Id = $Id Name = $Name VMName = $VMName } $arguments = @{ Name = $Name } if ($VMName -ne 'ManagementOS') { $arguments.Add('VMName',$VMName) } else { $arguments.Add('ManagementOS', $true) } try { Write-Verbose $localizedData.GetVMNetAdapter $adapterExists = Get-VMNetworkAdapter @arguments -ErrorAction SilentlyContinue if ($adapterExists) { Write-Verbose $localizedData.FoundVMNetAdapter $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) } } catch { Write-Error $_ } return $configuration } Function Set-TargetResource { [CmdletBinding()] Param ( [Parameter(Mandatory)] [String] $Id, [Parameter(Mandatory)] [String] $Name, [Parameter(Mandatory)] [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 } $arguments = @{ Name = $Name } if ($VMName -ne 'ManagementOS') { $arguments.Add('VMName',$VMName) } else { $arguments.Add('ManagementOS', $true) } try { Write-Verbose $localizedData.GetVMNetAdapter $adapterExists = Get-VMNetworkAdapter @arguments -ErrorAction SilentlyContinue 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 } else { throw $localizedData.NoVMNetAdapterFound } } catch { Write-Error $_ } } Function Test-TargetResource { [CmdletBinding()] [OutputType([System.Boolean])] Param ( [Parameter(Mandatory)] [String] $Id, [Parameter(Mandatory)] [String] $Name, [Parameter(Mandatory)] [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 } $arguments = @{ Name = $Name } if ($VMName -ne 'ManagementOS') { $arguments.Add('VMName',$VMName) } else { $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 SilentlyContinue 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 { throw $localizedData.VMNetAdapterDoesNotExist } } catch { Write-Error $_ } } Export-ModuleMember -Function *-TargetResource |