5 min read

ConfigMgr - Change NetAdapter settings using Configuration Item / Baseline

ConfigMgr - Change NetAdapter settings using Configuration Item / Baseline

The Case

The customer wanted "Energy Efficient Ethernet" (EEE) NetAdapter turned off, and what better way to do this than using a Configuration Item/Baseline?

I'm gonna maybe over-explain this a bit, and do more things with powershell than necessary, but that is just to demonstrate more options and things you can do.
if your not interested you can just skipt the "breakdown" part and find the discovery and remediation scripts at the bottom.

Content:

  1. Breakdown
    1. Getting the intel we need
    2. Using the intel that we got
    3. The Compliance Rule
  2. Discovery Script
  3. Remediation Script
  4. Compliance Rule

Breakdown

First, what I've found on our devices is that EEE is only available on ethernet adapters, so we will just look for those.
So, we need to find if this is a setting we can change with some sort of script, and my go-to as a first is always powershell.

Getting the intel that we need

To get netadapters using powershell, we use the quite obvious cmdlet

Get-NetAdapter | ft -AutoSize

Which will give some nice output about our available adapters, maybe something like this:

Name InterfaceDescription ifIndex Status MacAddress LinkSpeed
Bluetooth-nätverksanslutning Bluetooth Device (Personal Area Network) 26 Disconnected MAC-ADDRESS 3 Mbps
vEthernet (ViaMonstraNAT) Hyper-V Virtual Ethernet Adapter #2 19 Up MAC-ADDRESS 10 Gbps
Wi-Fi Intel(R) Wi-Fi 6 AX201 160MHz 15 Up MAC-ADDRESS 1.2 Gbps
Ethernet Intel(R) Ethernet Connection (10) I219-LM 14 Disconnected MAC-ADDRESS 0 bps
vEthernet (Default Switch) Hyper-V Virtual Ethernet Adapter 39 Up MAC-ADDRESS 10 Gbps

Using this, we get an output which shows us some good properties to filter on when selecting the adapters we want.
To pick those adapters that we want to change

$AdapterName = "Ethernet"
$SelectedAdapters = Get-NetAdapter | where ({$_.Name -eq $AdapterName -And $_.Status -eq "Up"})

Now we got the Ethernet Adapters in $SelectedAdapters
And we can now choose to show all the advanced properties of these adapters

$AdapterName = 'Ethernet'
$SelectedAdapters = Get-NetAdapter | where ({$_.Name -eq $AdapterName -And $_.Status -eq "Up"}) | Select -Expand Name
Foreach($Adapter in $SelectedAdapters){
    Get-NetAdapterAdvancedProperty -Name $Adapter
}

Listing you all the advanced properties for these adapters and we can see some values that we can use for our discovery script.

So, we now know what the setting is called and we know that the "RegistryValue" is 0 or 1 (True/false/, on/off), what we need to change and what to target.

Using the intel that we got

The script needed to target this is quite easy and small, we are gonna look for adapters with the advanced property with an DisplayName which equals "Energy Efficient Ethernet" and has a RegistryValue of "1" (on)

$SettingDisplayName = 'Energy Efficient Ethernet'
$RegistryValue = '1'
Get-NetAdapterAdvancedProperty | Where ({$_.DisplayName -eq "$SettingDisplayName" -and $_.RegistryValue -eq $RegistryValue})

And as we can get these values, we can put it together and make an discovery script out of it, all we need to do is make a script, that if a condition is met or not, it will output 0 or 1.
If the take the above as an example, we can look for any adapter, with the advanced property "Energy Efficient Ethernet" which is turned on, and if it is, then output "1", simply by adding "Select -Expand RegistryValue" which will select and expand the value of the property "RegistryValue".

Get-NetAdapterAdvancedProperty | Where ({$_.DisplayName -eq "$SettingDisplayName" -and $_.RegistryValue -eq $RegistryValue}) | Select -Expand RegistryValue

As this property already is "0" or "1", we can use that as output for our discoveryscript by saving it in a varible and then using a switch to output what we want, depending on what is set.

$RegistryValue = Get-NetAdapterAdvancedProperty | Where ({$_.DisplayName -eq "$SettingDisplayName" -and $_.RegistryValue -eq $RegistryValue}) | Select -ExpandProperty RegistryValue
Switch($RegistryValue){
    "1" {Write-Output 1}
    "0" {Write-Output 0}
}

But! Maybe there isn't any Ethernet Adapters with EnergyEfficientEthernet properties? Well, we need to add some handling for those cases as well, and if there isn't any adapter with those setting, we can see them as compliant, right?
So, if there is none, the "$RegistryValue" string should be empty or null and using "If([string]::IsNullOrEmpty($RegistryValue)){}" we can chose to output "0" if this is true, and we can then "break" the script at that point.

If([string]::IsNullOrEmpty($RegistryValue)){
    Write-Output 0
    break
}

Remediating the setting

Now we got a script that we can use as a discovery script and checking compliance, and then we need to put together another one which will be used to remediate these settings.
As it happens, there is a pscmdlet for that as well,
"set-NetAdapterAdvancedProperty"!

.Synopsis
Sets the advanced properties of a network adapter.

.Description
The Set-NetAdapterAdvancedProperty cmdlet sets the advanced properties of a network adapter. Changes are made directly into the registry for the computer. Many of the common advanced properties can be controlled through a cmdlet, such as the Set-NetAdapterRss or Set-NetAdapterLso cmdlets.

Using the information we got putting the discovery script together, we can quite fast build a remediation script.

We need to:

  1. Get all adapters with EEE set to 1
    $SettingDisplayName = 'Energy Efficient Ethernet'
    $GetRegistryValue = '1' #What we are looking for
    $AdaptersWithEEEActive = Get-NetAdapterAdvancedProperty | Where ({$.DisplayName -eq "$SettingDisplayName" -and $.RegistryValue -eq $GetRegistryValue}) | Select -ExpandProperty Name
  2. Change the setting for each adapter
    $SetRegistryValue = '0' #What we are changing to
    Foreach($Adapter in $AdaptersWithEEEActive){
    set-NetAdapterAdvancedProperty -Name $Adapter -DisplayName $SettingDisplayName -RegistryValue $SetRegistryValue
    }

As one!

$SettingDisplayName = 'Energy Efficient Ethernet'
$GetRegistryValue = '1'
$SetRegistryValue = '0'
$AdaptersWithEEEActive = Get-NetAdapterAdvancedProperty | Where ({$_.DisplayName -eq "$SettingDisplayName" -and $_.RegistryValue -eq $GetRegistryValue}) | Select -ExpandProperty Name
Foreach($Adapter in $AdaptersWithEEEActive){
    set-NetAdapterAdvancedProperty -Name $Adapter -DisplayName $SettingDisplayName -RegistryValue $SetRegistryValue
}

The Compliance Rule

The compliance rule for this is the easy part

  1. Name it
  2. Rule type = Value
  3. The Setting must comply with the following Rule = "The value returned by the specified script" Equals "0"
  4. Check "Run the specified remediation script when this setting is noncompliant"

And now you can just put this in a Configuration Baseline and deploy it to the devices where you want this to be remediated!


Discovery Script

$SettingDisplayName = 'Energy Efficient Ethernet'
$RegistryValue = '1'
$RegistryValue = Get-NetAdapterAdvancedProperty | Where ({$_.DisplayName -eq "$SettingDisplayName" -and $_.RegistryValue -eq $RegistryValue}) | Select -ExpandProperty RegistryValue
If([string]::IsNullOrEmpty($RegistryValue)){
    Write-Output 0
    break
}
Switch($RegistryValue){
    "1" {Write-Output 1}
    "0" {Write-Output 0}
}

Remediation Script

$SettingDisplayName = 'Energy Efficient Ethernet'
$GetRegistryValue = '1'
$SetRegistryValue = '0'
$AdaptersWithEEEActive = Get-NetAdapterAdvancedProperty | Where ({$_.DisplayName -eq "$SettingDisplayName" -and $_.RegistryValue -eq $GetRegistryValue}) | Select -ExpandProperty Name
Foreach($Adapter in $AdaptersWithEEEActive){
    set-NetAdapterAdvancedProperty -Name $Adapter -DisplayName $SettingDisplayName -RegistryValue $SetRegistryValue
}

Compliance Rule

Name Condition Severity Remediate
EEE Setting Value Equals 0 Information Yes