One network config script to rule them all

network_config_powershell

Recently I’ve had to build a set of PCs dedicated for digital signage (more on that soon) where part of the install involves setting a static IP address for each machine. Initially I thought I might just do the the manual way but got bored after the first machine and decided a Powershell script would be much more fun.

Googlewhacking led to a variety of pre-made scripts but every one in raw form had something missing or didn’t quite work as it was meant to. In the end by mixing and matching a few different ones, along with a couple of little tweaks hidden away in the comments section of some forum posts I’ve got something that does everything I want:

  • ask user to input an IP address
  • ask user to input a default gateway
  • set DNS from a hard-coded list
  • set WINS from a hard-coded list
  • disable DNS auto-registration
  • add DNS suffix
  • disable and re-enable the network adapter

I also wanted the script to work without needing to know the name of the network adapter in Windows (many scripts seemed to rely on having this in advance)

Without further ado let’s break it down…

Configuring base TCP/IP settings

The first part was generally the easiest, use WMI to find network adapters that are enabled and set to DHCP then use the NetworkAdapterConfiguration class to set properties. Use either read-host or a hard-coded variable depending on how much user input you want.

The gotcha in this section involves the SetDynamicDNSRegistration part, for Powershell to disable the tick box it needs ($false, $false) set as the input (other posts either only give one $false or even say use $true, which doesn’t seem to work)

Ref: http://msdn.microsoft.com/en-us/library/aa394217(v=vs.85).aspx
Ref: http://blogs.technet.com/b/danstolts/archive/2012/01/31/using-powershell-to-get-or-set-networkadapterconfiguration-view-and-change-network-settings-including-dhcp-dns-ip-address-and-more-dynamic-and-static-step-by-step.aspx

# configure NIC for static IP address
 # set IP address, subnet, DNS and WINS
 $NICs = Get-WMIObject Win32_NetworkAdapterConfiguration -computername . | where{$_.IPEnabled -eq $true -and $_.DHCPEnabled -eq $true}
 $ip = $(read-host "Enter the IP Address for this machine")
 $gateway = $(read-host "Enter the Default Gateway")
 Foreach($NIC in $NICs) {
 $subnet = "255.255.255.0"
 $dns = "192.168.0.1","192.168.0.2","192.168.0.3"
$NIC.EnableStatic($ip, $subnet)
 $NIC.SetGateways($gateway)
 $NIC.SetDNSServerSearchOrder($dns)
 $NIC.SetWINSServer("192.168.0.2","192.168.0.2")
 $NIC.SetDynamicDNSRegistration($false,$false)
 }

Setting DNS suffix

This caused more problems than I thought it would and is a little bit of a bodge if you have multiple NICs in your machine as it sets the suffix globally via “Append DNS Suffixes” box rather than the connection-specific or primary suffixes (both of which have to be set via registry edits

It’s not a problem for the desktop PCs I’m working on but exercise caution if you’re going to use this script on anything more complex (you have been warned!)
(Of course you don’t have to worry about this so much if you’re on AD as the primary is done for you on a domained PC)

Ref: http://powershell.com/cs/forums/p/10792/18524.aspx#18524

# Set DNS suffix
[wmiclass]$nac="Win32_Networkadapterconfiguration"
 $suffixes=@("yourinternaldnsuffix.local")
 $nac.SetDNSSuffixSearchorder($suffixes)

Disable and re-enable network card

Finally I wanted to give the NIC a kick to bring it up with the new settings (but without a reboot), again finding a script to do this without needing the network card name took a little while but here it is. Note the forced pauses to give the card time to start back up, you may need to tweak this dependent on your hardware.

Ref: http://www.petri.co.il/forums/showthread.php?t=44301

Once again also note it’ll disable all network adapters it finds so don’t run it on a vital production server with multiple network cards!!!

# set filter to find active NICs
$filter = "NetEnabled = 'True'"
$class = "Win32_NetworkAdapter"
$namespace = "root\cimv2"
$strComputer = "."
# Find all Active Ethernet network cards
$colItems = get-wmiobject -class $class -namespace $namespace -computername $strComputer -filter $filter
# Disable active network cards
 foreach ($objItem in $colItems) {
 write-host $objItem.Description
 $objItem.Disable()
 }
Start-sleep 5
# Enable active network cards
 foreach ($objItem in $colItems) {
 write-host $objItem.Description
 $objItem.Enable()
}
Write-Host "Waiting for network connection to become active..."
Start-sleep 20
ipconfig /all
Write-Host "=============================="
Write-Host "Network configuration complete"
Write-Host "=============================="

The complete script is available in SkyDrive, just remove the .txt from the filename to run it on your PC after downloading.

(network card image credit http://www.devcom.com)

Advertisements

One Response to One network config script to rule them all

  1. Pingback: Digital Signage – our journey (part 1) | gshaw0

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: