DSC Script resource - thoughts

This topic contains 3 replies, has 2 voices, and was last updated by Profile photo of Tony Wainwright Tony Wainwright 1 year, 3 months ago.

  • Author
    Posts
  • #30850
    Profile photo of Tony Wainwright
    Tony Wainwright
    Participant

    Hi all,

    I am using push DSC to configure a 2 node Hyper-V cluster on Windows 2012 R2 Datacenter. This configuration creates a NIC Team called 'HostTeam' and a virtual switch called HostSwitch that is allowed to use the Management OS.

    One of the problems I noticed was that one of my NIC's, the NIC Team and the virtual switch all had the same MAC address and was generating a System error 16945 (MAC conflict: A port on the virtual switch has the same MAC as one of the underlying team members on Team Nic Microsoft Network Adapter Multiplexor Driver). The solution is to change the MAC Address on the NIC Team before creating the virtual switch. This 'breaks' the DSC configuration as manual input is required.

    My boss wants me to automate the resolution, so I have been forced to add a Script resource to the DSC file. I have tested this and it does work, however I did find it difficult to find much information (in simple terms I can grasp) regarding the TestScript and GetScript

    Script SetNicTeamMac {
        SetScript = { 
            # Set MAC Address of NIC Team
            # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            # Get Adapter Names & MAC Addresses
            $NIC = Get-NetAdapter
    
            # Check for Duplicates and remove dashes
            $Dup = ($NIC.MacAddress | Group | ?{$_.Count -gt 1}).Values
            If ($Dup -gt 1){
                $DupNIC = $NIC | Where {$_.MACAddress -eq $Dup} | Select Name, @{N='MacAddress'; E={$_.MacAddress -replace '-',""}}
    
                # Get Highest MAC, convert to Decimal, increment by 1 and convert back to Hex
                $Max = $NIC | Sort MACAddress | Select @{N='MacAddress'; E={$_.MacAddress -replace '-',""}} -Last 1
                $Dec = [Convert]::ToInt64($Max.MacAddress, 16)
               ++$Dec
                $Mac = [Convert]::ToString($Dec, 16)
    
                # Assign to HostTeam - vLanId set to 0 as vSwitch will be tagged 
                Set-NetAdapterAdvancedProperty -InterfaceDescription "Microsoft Network Adapter Multiplexor Driver" -DisplayName "Mac Address" -DisplayValue $Mac
            }
        }
        TestScript = {
            $MacAddress = Get-NetAdapter HostTeam | Select MacAddress
            return ($MacAddress.MacAddress -eq $Mac)
        }
        GetScript = {
            $MacAddress = Get-NetAdapter HostTeam | Select MacAddress
            Return @{
                MacAddress = $MacAddress.MacAddress
            }
        }
        DependsOn = '[cNetworkTeam]NetworkTeam'
    }
    

    I'd appreciate it if someone could give me some pointers (ways to improve) what I've done.
    Thanks
    Tony

  • #30884
    Profile photo of Don Jones
    Don Jones
    Keymaster

    TestScript is supposed to check for your desired configuration and return $true or $false. If it returns $false, SetScript is run to correct the problem. Get is supposed to return a hash table containing the current configuration; it's not illegal to return an empty hash table. If you're not using Get-DscConfiguration, then GetScript isn't called.

    But basically, it looks like what you're doing is correct.

  • #30902
    Profile photo of Tony Wainwright
    Tony Wainwright
    Participant

    Thanks Don, nice explanation – which leads me to review my code as this will run everytime as TestScript just checks for a MAC address on HostTeam

    If I place my tests (does the NIC Team have the same MAC address as a physical NIC) in the TestScript section, can I reuse the variables (and the contents) in the SetScript section or do I need to re-define and populate those variables?

    Tony

  • #30905
    Profile photo of Tony Wainwright
    Tony Wainwright
    Participant

    Here is the updated Script:

            Script SetNicTeamMac {
                SetScript = { 
                    # Set MAC Address of Host Team
                    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                    $DupNIC = $NIC | Where {$_.MACAddress -eq $Dup} | Select Name, @{N='MacAddress'; E={$_.MacAddress -replace '-',""}}
    
                    # Get Highest MAC, convert to Decimal, increment by 1 and convert back to Hex
                    $Max = $NIC | Sort MACAddress | Select @{N='MacAddress'; E={$_.MacAddress -replace '-',""}} -Last 1
                    $Dec = [Convert]::ToInt64($Max.MacAddress, 16)
                    ++$Dec
                    $Mac = [Convert]::ToString($Dec, 16)
    
                    # Assign to HostTeam - vLanId set to 0 as vSwitch will be tagged 
                    Set-NetAdapterAdvancedProperty -InterfaceDescription "Microsoft Network Adapter Multiplexor Driver" -DisplayName "Mac Address" -DisplayValue $Mac
                }
                TestScript = {
                    # Get Adapter Names & MAC Addresses
                    $NIC = Get-NetAdapter
                    # Check for Duplicates and remove dashes
                    $Dup = ($NIC.MacAddress | Group | ?{$_.Count -gt 1}).Values
                    If ($Dup -gt 1){
    	                # Get duplicate NICs
     		            # Check for NIC* in NIC Name
            		    $DupName = $Dup | Where {$_.Name -Like 'NIC*'}
    				}
    
                    return ($DupName -eq 'NIC*')
                }
                GetScript = {
                    $MacAddress = Get-NetAdapter HostTeam | Select MacAddress
                    Return @{
                        MacAddress = $MacAddress.MacAddress
                    }
                }
                DependsOn = '[cNetworkTeam]NetworkTeam'
            }
    

    Your thoughts please.
    Tony

You must be logged in to reply to this topic.