3

Because of a change in networking equipment I might need to set a bunch of machines NICs back to auto negotiate. What's the best way to automate this? I'm thinking an Autoit compiled exe pushed out through group policy or SCCM. Please post your script if you have an example. I'm not sure that all the systems I'm hitting will have the same NICs so something that would reset all known cards to auto would be great.

Thanks! -Mathew

MathewC
  • 6,877
  • 9
  • 38
  • 53

4 Answers4

4

Here's a script to do what you're looking for. You're going to need to do some "homework" to get it to work, though:

Option Explicit

Const HIVE_HKLM = &H80000002
Const REG_DEVICE_PATH = "SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}"
Const DEBUGGING = 1

Dim objRegistry, arrSubkeys, strSubkey, strComputer, regexpSubkey, strValue, dictDriverChanges, strDriverName

Set dictDriverChanges = CreateObject("Scripting.Dictionary")

' For each given NIC, add an item for the driver description string (case insensitive match) and the value name and value that
' should be set in the NIC's properties
Set dictDriverChanges.Item("Broadcom NetXtreme 57xx Gigabit Controller") = CreateObject("Scripting.Dictionary")
dictDriverChanges.Item("Broadcom NetXtreme 57xx Gigabit Controller").Add "ValueName", "*SpeedDuplex"
dictDriverChanges.Item("Broadcom NetXtreme 57xx Gigabit Controller").Add "Value", "0"


' Pattern to match on subkeys - exactly 4 digits
Set regexpSubkey = new Regexp
regexpSubkey.Global = True
regexpSubkey.Pattern = "\d{4,4}"

' Comptuer to run against. Set to "." for the local computer, or specify the computer-name of a remote machine
strComputer = "."

Set objRegistry = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")

objRegistry.EnumKey HIVE_HKLM, REG_DEVICE_PATH, arrSubkeys

' Did we get back any strSubkeys?
If IsArray(arrSubkeys) Then
    For Each strSubkey In arrSubkeys

        ' Is this a subkey we want to look at
        If regexpSubkey.Execute(strSubkey).Count = 1 Then 
            objRegistry.GetStringValue HIVE_HKLM, REG_DEVICE_PATH & "\" & strSubkey, "DriverDesc", strValue

            ' Loop through all the drivers we know about looking for this driver
            For Each strDriverName in dictDriverChanges
                If UCase(strDriverName) = UCase(strValue) Then
                    If DEBUGGING = 1 Then WScript.Echo "Located driver " & strValue & ". Setting value " & dictDriverChanges.Item(strDriverName).Item("ValueName") & " to " & dictDriverChanges.Item(strDriverName).Item("Value")
                    objRegistry.SetStringValue HIVE_HKLM, REG_DEVICE_PATH & "\" & strSubkey, dictDriverChanges.Item(strDriverName).Item("ValueName"), dictDriverChanges.Item(strDriverName).Item("Value")
                End If
            Next ' strDriverName
        End If

    Next ' strSubkey
End If

You will need to locate the "DriverDesc" value for each kind of NIC you're going to want to change. (Look in the registry under the REG_DEVICE_PATH at each of the subkeys there to find the various DriverDesc values). I've included instructions for a Broadcom 57xx controller in the script. You will need to identify the registry value name and value setting for each kind of NIC and then add entries like those on lines 11-15 for each kind of NIC.

This runs against the local computer right now. It wouldn't be too hard to make it take the computer name on the command-line and run against remote computers. Alternatively, you can just run it locally on each machine.

You will need to reboot the machine after the script runs for the change to take effect. If you're running this on Windows Vista or Windows 7 be aware that it must run in an "Elevated" context. (It was developed on Windows 7 and works fine on Windows XP...)

That should fix you up.

Evan Anderson
  • 141,071
  • 19
  • 191
  • 328
3

I haven't done anything like this in some time, but I believe that the method for changing this will vary by each NIC card, and possibly by each version of the NIC driver.

IMO the best way to handle it would be to make the change in the registry. If you have less than a dozen models of PC its is probably not that hard, otherwise, uck.

duffbeer703
  • 20,077
  • 4
  • 30
  • 39
  • 2
    This will be a registry setting that will vary in location on a NIC-driver for NIC-driver basis. On Windows 2000+ OS's, you'll find the settings under HKLM\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}. There are subkeys for each network adapter. It would be fairly trivial to write a script to loop through the subkeys looking for known drivers and then setting the appropraite per-driver setting in the subkey. The number of different models of NIC that you have will make all the difference. – Evan Anderson Aug 05 '09 at 12:27
  • I've written that script, since I had nothing better to do this morning... >smile< I should be working, I suppose. – Evan Anderson Aug 05 '09 at 14:24
1

Probably the best option is WMI scripting.

Here's an example to get you started, it reads the network card information. Setting them for a remote computer is easy - change the computername variable to an array, loop through them, and call the set method instead of get.

There's a few examples of WMI scripts on serverfault already.

gbjbaanb
  • 3,852
  • 1
  • 22
  • 27
  • I don't believe that every NIC driver reports this information in a standard manner. That script you linked to, for example, returns a null value for the "AutoSense" parameter on my Broadcom NIC in this Dell Latitude D630 I'm using... – Evan Anderson Aug 05 '09 at 12:28
  • I'd have thought it would be mapped appropriately by the driver... if you can edit the value in device manager properties, then you can edit the value via the WMI equivalent. But that assumes all drivers are good. Still, if you can use WMI to the values in the registry instead, that's good too, but that too assumes the registry values are the same per NIC. Its never easy is it. – gbjbaanb Aug 06 '09 at 08:55
1

I'll go against the flow here and suggest that you make the changes by hand. Pre-configure the new device to be the same fubar settings as the old (100/full or whatever) then go through and reset the network device and the computers one at a time. It's a huge obnoxious job, but it is better to make sure everything comes up, and you only have to do it once.

To err is human, to really botch things up requires a script.

chris
  • 11,784
  • 6
  • 41
  • 51
  • 1
    Bah! Humans make mistakes of a totally random nature. I wouldn't trust a human to do this procedure properly on any significant number of computers (and I say that with full knowledge that I know that I'd screw it up myself!). This is a simple operation. Test the script well and let it go. It won't make random and senseless mistakes like humans do. – Evan Anderson Aug 05 '09 at 14:23
  • In the case of random versions of windows and random network drivers, you're better off changing and testing than writing a giant all-encompassing script to try to fix all of these at once. – chris Aug 05 '09 at 14:36