Tuesday, July 14, 2009

Change DNS on multiple computers

Ok, here is the background. We needed to get rid of some old hardware and replace them with new kit. These servers was DC/DNS and unfortunately we couldn't re-use the IP addresses which meant that all the DNS settings on the servers (the clients used DHCP) needed to get updated.

My client at the time was planning to do this manually, which was not smart at all. Even though their server park was only about 900 servers. So what to do? Obviously scripting was the answer so I put this little script together for them.

Do note that I couldn't get proper formatting (especially TAB) in this post so the script might look a bit strange. Also note that line breaks are not always correct, so test it first in your lab! I take NO responsibility for the script and it is your responsibility to test it in a lab environment!

-Script Begins-
'============================================================
' NAME: replaceDNS_Server.vbs
'
' AUTHOR: Jimmy Andersson, Q Advice AB
' DATE: 19/11/2008
' Version: 1.0 - initial version
'
' COMMENT: Used to replace an IP entry for the DNS settings with a new IP. It will
' do a ping test before trying to connect to the remote machine. Do note that it
' ONLY replaces the IP if it is found, if it can't find the IP nothing will happen
' and it will also return the name of the machine it didn't find it on. If a NIC is
' DHCP ENABLED it will not change anything on that particular NIC.
'
' USAGE: cscript ReplaceDNS_Server.vbs
'
' NOTE: If you don't have access it will just move on to the next one in the list.
' If you want to save the output' pipe it to a text file.
' Example: cscript ReplaceDNS_Server.vbs > output.txt
'============================================================

On Error Resume Next

'============================================================

'====== Specify input file and open it - One computer name per row ========
'============================================================
strFilename = "C:\serverNames.txt"

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTS = objFSO.OpenTextFile(strFilename)

Do Until objTS.AtEndOfStream
strComputer = objTS.ReadLine
DoObject strComputer
Loop
objTS.Close

'============================================================
'====== Sub to replace a DNS entry ================================
'============================================================
Sub DoObject(strComputer)

strOldDNSServer = "10.80.255.122" ' Specify which DNS IP that should be replaced

strNewDNSServer = "10.80.255.206" ' Specify the new DNS IP

' Run ping test before starting to run WMI queries
strPingStatus = PingStatus(strComputer)
If strPingStatus = "Success" Then ' See return codes in the Function

Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

' Only do changes if IP is enabled and DHCP is not used
Set colNicConfigs = objWMIService.ExecQuery _
("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = TRUE AND DHCPEnabled = FALSE")

For Each objNicConfig In colNicConfigs
wScript.Echo VbCrLf & "Computer: " & strComputer
wScript.Echo VbCrLf & " Network Adapter " & objNicConfig.Index
arrDNSServerSearchOrder = objNicConfig.DNSServerSearchOrder

wScript.Echo " DNS Server Search Order - Before:"
If Not IsNull(objNicConfig.DNSServerSearchOrder) Then
For Each strDNSServer In objNicConfig.DNSServerSearchOrder
wScript.Echo " " & strDNSServer
Next
End If

blnFound = 0
For i = 0 to UBound(arrDNSServerSearchOrder)
If arrDNSServerSearchOrder(i) = strOldDNSServer Then
arrDNSServerSearchOrder(i) = strNewDNSServer
blnFound = 1
End If
Next

If blnFound Then
retSetDNS = objNicConfig.SetDNSServerSearchOrder(arrDNSServerSearchOrder)
If retSetDNS = 0 Then
wScript.Echo " Replaced " & strOldDNSServer & " with " & _
strNewDNSServer & " in DNS search order."

Else
wScript.Echo " Unable to change DNS server search order."
End If

Else
WScript.Echo " DNS server " & strOldDNSServer & " not found."
End If
Next

Set colNicConfigs = objWMIService.ExecQuery _
("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = TRUE")
For Each objNicConfig In colNicConfigs
wScript.Echo VbCrLf & "Computer: " & strComputer & " -- " & "DHCP Enabled => NO changes done."
wScript.Echo VbCrLf & String(80, "-")
Next

Else
wScript.Echo VBCrLf & "Computer: " & strComputer & " -- " & "Didn't answer ping => NO changes done."

' Return which machines that didn't answered on ping
wScript.Echo VbCrLf & String(80, "-")
End If

End Sub

'============================================================
'====== Function for w32_PingStatus WMI class =======================
'============================================================
Function PingStatus(strComputer)
On Error Resume Next

' Uses the local machine as the system to ping from
strWorkstation = "."


Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strWorkstation & "\root\cimv2")

Set colPings = objWMIService.ExecQuery _
("SELECT * FROM Win32_PingStatus WHERE Address = '" & strComputer & "'")


For Each objPing in colPings ' Return codes
Select Case objPing.StatusCode

Case 0 PingStatus = "Success"
Case 11001 PingStatus = "Status code 11001 - Buffer Too Small"
Case 11002 PingStatus = "Status code 11002 - Destination Net Unreachable"
Case 11003 PingStatus = "Status code 11003 - Destination Host Unreachable"
Case 11004 PingStatus = "Status code 11004 - Destination Protocol Unreachable"
Case 11005 PingStatus = "Status code 11005 - Destination Port Unreachable"
Case 11006 PingStatus = "Status code 11006 - No Resources"
Case 11007 PingStatus = "Status code 11007 - Bad Option"
Case 11008 PingStatus = "Status code 11008 - Hardware Error"
Case 11009 PingStatus = "Status code 11009 - Packet Too Big"
Case 11010 PingStatus = "Status code 11010 - Request Timed Out"
Case 11011 PingStatus = "Status code 11011 - Bad Request"
Case 11012 PingStatus = "Status code 11012 - Bad Route"
Case 11013 PingStatus = "Status code 11013 - TimeToLive Expired Transit"
Case 11014 PingStatus = "Status code 11014 - TimeToLive Expired Reassembly"
Case 11015 PingStatus = "Status code 11015 - Parameter Problem"
Case 11016 PingStatus = "Status code 11016 - Source Quench"
Case 11017 PingStatus = "Status code 11017 - Option Too Big"
Case 11018 PingStatus = "Status code 11018 - Bad Destination"
Case 11032 PingStatus = "Status code 11032 - Negotiating IPSEC"
Case 11050 PingStatus = "Status code 11050 - General Failure"
Case Else PingStatus = "Status code " & objPing.StatusCode & _
" - Unable to determine cause of failure."
End Select
Next

End Function

-Script Ends-

Monday, October 27, 2008

MVP Award

Yes, I got awarded for the 10th time this year. So I'm still a DS MVP :)

Thursday, July 3, 2008

Again, I'm too lazy...

Ok, so what has been going on since the last post... Well, the project is going forward. Too much stuff going on at the same time since my team are migrating in all continents at the same time - a lot of coordination is going on! From management side the schedule shifts on a daily basis which makes it really hard to plan accordingly - but that's the way it is as everybody knows.

Besides that one of my best friends got married in May - Awesome wedding! They will be the host and hostess on my wedding. Oh! I might not have told you.... Yes, I'm getting married Aug 16th. And I'm looking forward to it!

Ok, I have to be honest - we have a wedding sharepoint site (thank you Thomas Bittner and Daniel Wessels!) and I have a MS project plan as well.... Jesper said: "you're such a geek! A Sharepoint site for your wedding!" (don't remember the exact words, but that was the gist of it). Well, what can I say - I'm a geek! As most people know already!

Some tech stuff - are 3rd party software really ready for a Server Core? It is an open question - and my experience is - not yet. Which will open the discussion about why... Correct? The reason why is because most of the companies still install antivirus on their domain controllers and the install package require a GUI, which means it is a big no-no. The same goes for printer installations (well, many cases). This will open up a sub-question, do you really need AV on your domain controllers? My answer is: depending on your security and network design - I know it is an open answer. But think about it and post a comment! :)

Thursday, May 1, 2008

Long time since last post

Ok, I know there has been a long time since I blogged.... A lot have happened so let me summarise.

- My mate Mark Arnold have married Laura Hunter. And I was the bestman, well I tried at least... Since I couldn't attend the tour of Philly our mates bought a doll as my stand-in which now have its own blog! :)

- The Windows Server 2008 Security Resource Kit is released, I wrote a chapter in it.

- I've been to Redmond/Seattle to attend the MVP summit.

- Our wedding site is up :) Yes, I'm getting married in August!!!

Monday, December 3, 2007

Windows Server 2008 Schema

I just finished documenting the default Schema for Windows Server 2008. Let me know if you want a copy of it.

Monday, October 22, 2007

MVP Award

It was some time ago since my last post. I'm currently very busy doing domain migrations in a project for HP so I don't have much time to blog.
But one update is that I received the MVP Award for Directory Services again, this is my ninth year in a row... Which means I must get a life :)

Monday, August 13, 2007