Recently I was tasked with the job of changing the DNS search order on all the windows servers we use in my company. Since I didn’t want to change it manually by going into the TCP/IP settings of the NIC on each server I decided to write a script to help me do this.
I am working in a sensitive production environment so I needed to not only change the settings but also check that the changes were made successfully on all servers. To accomplish this I added some functionality to the script to confirm that the changes were made and write all the information to a log file. This log file could then be reviewed later for errors.
I have built the script in three different sections – variables, functions and script main. To begin with I will quickly explain the variables section.
VARIABLES
I don’t like working with too many absolute paths in my scripts because one needs to change them if they are moved to another computer or location. Therefore I use the following code so I always have an object pointing to the script directory.
$scriptpath = $MyInvocation.MyCommand.Path
$dir = Split-Path $scriptpath
When used, $dir will always point to the directory where the script was run. $log_dir specifies the path to a directory names /logs which will be used later on.
The script takes input from a file called “servers.txt” which must be placed in the script directory. $servers is an array created and populated by running Get-Content on “servers.txt”. The parameters section contains the $dns1, $dns2, $dns3 objects which will be set on the servers listed in “servers.txt” – remember to fill these out with the appropriate values before running the script.
#VARIABLES
$DebugPreference = "continue"
$scriptpath = $MyInvocation.MyCommand.Path
$dir = Split-Path $scriptpath
$log_dir = "$dir\logs"
$servers = @(gc "$dir\servers.txt")
#parameters - Add the desired DNS servers below
[string]$dns1 = "192.168.1.2"
[string]$dns2 = "192.168.1.3"
[string]$dns3 = "192.168.1.4"
That covers the variables section – now to the functions. The script is built on four different functions which I will go over now.
FUNCTIONS
1. Function Create-Log
function Create-Log {
$time = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
$logFilePath = "$log_dir\SetStaticDNS_$time.log"
New-Item -ItemType File $logFilePath -Force
}
This little function simply creates a logfile in $dir\logs\ which will be used by the script to record the results of attempting to change the DNS settings on each server.
2. Function Write-ToLog
function Write-ToLog {
param (
[string]$message
)
$time = Get-Date
$logEntryStr = "$time`t" + $message
$logEntryStr | Out-File -Append $logFilePath -Width 400
}
Write-ToLog takes a parameter “message” and appends it to the log file with a time stamp
3. Get-ActiveNicIP
function Get-ActiveNicIP {
param (
[Parameter(Mandatory=$true)][string]$computer
)
Write-ToLog -message "Getting IP of 'active' interface on $computer ..."
$conx = Test-Connection -ComputerName $computer -Count 1
$ActiveIP = $conx.IPV4Address.IPAddressToString
Write-ToLog -message "Active IP on $computer is $ActiveIP"
return $ActiveIP
}
Some servers can have several NICs/Teams in use and I wanted to make sure that I only change the DNS settings on the NIC which answers to the hostname of the server. Get-ActiveNicIP simply pings the server given as the parameter “computer” and returns the IP which answers.
4. Function Set-StaticDNS
function Set-StaticDNS {
param (
[Parameter(Mandatory=$true)][string]$computer,
[Parameter(Mandatory=$true)][string]$ActiveIP
)
Write-ToLog -message "Attempting to set DNS search order on computer $computer on the interface with the IP $ActiveIP"
#get dns info via WMI
$wmi = Get-WmiObject win32_networkadapterconfiguration -filter "ipenabled = 'true'" -ComputerName $computer | ? { $_.IPAddress -match $ActiveIP }
#set dns search order via WMI
$wmi.SetDNSServerSearchOrder($DnsSearchOrder)
#confirm that dns search order was set to desired value.
$StrdnsSearchOrder = $dnsSearchOrder | Out-String
$wmi2 = Get-WmiObject win32_networkadapterconfiguration -filter "ipenabled = 'true'" -ComputerName $computer | ? { $_.IPAddress -match $ActiveIP }
$StrWmiDnsSearchOrder = $wmi2.DNSServerSearchOrder | Out-String
if ($StrWmiDnsSearchOrder -eq $StrdnsSearchOrder) {
Write-ToLog -message "Setting the DNS search order was successful. Value is now $dnsSearchOrder"
}
else {
Write-ToLog -message "Error - Setting the DNS search order failed!"
}
}
The Set-Static DNS function takes a computer and an IP as parameters and then uses WMI to change the DNS search order on the NIC.
That covers the functions – now to the script main.
SCRIPT MAIN
#SCRIPT MAIN
clear
$dnsSearchOrder = @()
$dnsSearchOrder += @($dns1)
$dnsSearchOrder += @($dns2)
$dnsSearchOrder += @($dns3)
$logFilePath = Create-Log
Write-ToLog -message "Starting script Set-StaticDNS.ps1...."
Write-ToLog -message "Setting DNS search order on all servers in 'servers.txt' to $dnsSearchOrder"
Write-ToLog -message "----------------------------------------------------------------------------------------------------------`n`n"
$servers | % {
$ActiveIP = Get-ActiveNicIP -computer $_
Set-StaticDNS -computer $_ -ActiveIP $ActiveIP
}
Write-ToLog -message "`n`n----------------------------------------------------------------------------------------------------------"
Write-ToLog -message "Script run ended."
The script main simply loops through the $servers array and runs the Get-ActiveNipIP and Set-StaticDNS functions on each server.
That should explain how the script works. I have copied in the full script below.
Enjoy!
################################################################################################
##Script: Set-StaticDNS.ps1
##
##Description: Sets the DNS search order on the servers given as input in servers.txt
#+ to the IP addresses specified in the parameters section.
##Created by: Noam Wajnman
##Creation Date: December 9, 2013
################################################################################################
#FUNCTIONS
function Create-Log {
$time = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
$logFilePath = "$log_dir\SetStaticDNS_$time.log"
New-Item -ItemType File $logFilePath -Force
}
function Write-ToLog {
param (
[string]$message
)
$time = Get-Date
$logEntryStr = "$time`t" + $message
$logEntryStr | Out-File -Append $logFilePath -Width 400
}
function Get-ActiveNicIP {
param (
[Parameter(Mandatory=$true)][string]$computer
)
Write-ToLog -message "Getting IP of 'active' interface on $computer ..."
$conx = Test-Connection -ComputerName $computer -Count 1
$ActiveIP = $conx.IPV4Address.IPAddressToString
Write-ToLog -message "Active IP on $computer is $ActiveIP"
return $ActiveIP
}
function Set-StaticDNS {
param (
[Parameter(Mandatory=$true)][string]$computer,
[Parameter(Mandatory=$true)][string]$ActiveIP
)
Write-ToLog -message "Attempting to set DNS search order on computer $computer on the interface with the IP $ActiveIP"
#get dns info via WMI
$wmi = Get-WmiObject win32_networkadapterconfiguration -filter "ipenabled = 'true'" -ComputerName $computer | ? { $_.IPAddress -match $ActiveIP }
#set dns search order via WMI
$wmi.SetDNSServerSearchOrder($DnsSearchOrder)
#confirm that dns search order was set to desired value.
$StrdnsSearchOrder = $dnsSearchOrder | Out-String
$wmi2 = Get-WmiObject win32_networkadapterconfiguration -filter "ipenabled = 'true'" -ComputerName $computer | ? { $_.IPAddress -match $ActiveIP }
$StrWmiDnsSearchOrder = $wmi2.DNSServerSearchOrder | Out-String
if ($StrWmiDnsSearchOrder -eq $StrdnsSearchOrder) {
Write-ToLog -message "Setting the DNS search order was successful. Value is now $dnsSearchOrder"
}
else {
Write-ToLog -message "Error - Setting the DNS search order failed!"
}
}
#VARIABLES
$DebugPreference = "continue"
$scriptpath = $MyInvocation.MyCommand.Path
$dir = Split-Path $scriptpath
$log_dir = "$dir\logs"
$servers = @(gc "$dir\servers.txt")
#parameters - Add the desired DNS servers below
[string]$dns1 = "192.168.1.2"
[string]$dns2 = "192.168.1.3"
[string]$dns3 = "192.168.1.4"
#SCRIPT MAIN
clear
$dnsSearchOrder = @()
$dnsSearchOrder += @($dns1)
$dnsSearchOrder += @($dns2)
$dnsSearchOrder += @($dns3)
$logFilePath = Create-Log
Write-ToLog -message "Starting script Set-StaticDNS.ps1...."
Write-ToLog -message "Setting DNS search order on all servers in 'servers.txt' to $dnsSearchOrder"
Write-ToLog -message "----------------------------------------------------------------------------------------------------------`n`n"
$servers | % {
$ActiveIP = Get-ActiveNicIP -computer $_
Set-StaticDNS -computer $_ -ActiveIP $ActiveIP
}
Write-ToLog -message "`n`n----------------------------------------------------------------------------------------------------------"
Write-ToLog -message "Script run ended."
Like this:
Like Loading...