We’re updating our AD and as part of that I’m trying to update the DNS settings for the member servers but it’s not working as I’m expecting.
There are two primary issues:
The first and most pressing is that it’s not actually updating the DNS settings for the servers.
As far as I can tell the Invoke-Command is getting all the variables it needs from the start of the script, and it says it finds the old DNS settings and is setting the new addresses, but when looking at the server nothing has changed.
However if I just run:
invoke-command -ComputerName srv01 {Set-DnsClientServerAddress -InterfaceIndex 2 -ServerAddresses ('192.168.0.1', '192.168.0.2', '192.168.0.3') -ErrorAction Stop}
from the same client and terminal from which I run the script the settings are updated instantly.
The second problem is that the Status and Error CSV-files are not populated.
I expect that the problem there is that the Invoke-Command does not return the $StatusLog and $ErrorLog variables back to the main script to be processed.
I thought maybe I’d solved it by adding them both to the -ArgumentList and adding the $Using: keyword to the StatusLog and ErrorLog assignments in the Invoke-Command block, but I got the following error:
At [FILEPATH]:117 char:11
+ $Using:StatusLog += [PSCustomObject]@{
+ ~~~~~~~~~~~~~~~~
The assignment expression is not valid. The input to an assignment operator must be an object that is able to accept assignments, such as a variable or a property.
The two CSV-files are created, but they are empty.
Here’s the sanitized version of the script.
#Requires -version 5.1
[CmdLetBinding()]
Param (
[Parameter(Mandatory=$false)]
[ValidateSet('AD1','AD2')]
[string]$AD = 'AD1'
)
switch ($AD) {
'AD1' {
$AD = 'AD1'
$DC = 'ad1.domain.local'
$SB = 'OU=Servers,DC=ad1,DC=domain,DC=local'
$DNS = "('192.168.0.1', '192.168.0.2', '192.168.0.3')"
$OldDNS = '192\.168\.0\.1[1-3]'
break
}
'AD2' {
$AD = 'AD2'
$DC = 'ad1.domain.local'
$SB = 'OU=Servers,DC=ad2,DC=domain,DC=local'
$DNS = "(192.168.1.1, 192.168.1.2, 192.168.1.3)"
$OldDNS = '192\.168\.1\.1[1-3]'
break
}
default {
Write-Warning -Message 'No valid domain chosen. Run script again to try again'
exit
}
}
$CsvPath = 'C:\Temp'
$StatusCSV = Join-Path -Path $CSVPath -ChildPath "$(Get-Date -Format yyyyMMdd)-$($AD)-DnsClientStatus.csv"
$ErrorCSV = Join-Path -Path $CsvPath -ChildPath "$(Get-Date -Format yyyyMMdd)-$($AD)-DnsClientServerError.csv"
$ErrorLog = @()
$StatusLog = @()
$Servers = Get-ADComputer -Server $DC -Filter {(OperatingSystem -Like '*server*') -and (enabled -eq 'true')} -SearchBase $SB -Properties Name,OperatingSystem,OperatingSystemVersion,IPv4Address |
Sort-Object -Property OperatingSystem,Name |
Select-Object -Property Name,OperatingSystem,OperatingSystemVersion,IPv4Address
foreach ($Server in $Servers) {
# Test if the server is online and has WinRM enabled.
$pingtest = Test-Connection -ComputerName $Server.Name -Quiet -Count 1 -ErrorAction SilentlyContinue
$winrmtest = Test-WSMan -ComputerName $Server.Name -ErrorAction SilentlyContinue
if ($pingtest -and $winrmtest) {
Write-Verbose "Working on server: $($Server.Name)"
Invoke-Command -ComputerName $Server.Name -ArgumentList $Server, $DNS, $OldDNS -ScriptBlock {
$ifIndex = Get-NetRoute -DestinationPrefix '0.0.0.0/0' |
Sort-Object -Property { $_.InterfaceMetric + $_.RouteMetric } |
Select-Object -First 1 |
Select-Object -ExpandProperty InterfaceIndex
$currentDNS = (Get-DnsClientServerAddress -InterfaceIndex $ifIndex).ServerAddresses
if ($currentDNS -match $Using:OldDNS) {
Write-Verbose "Old DNS settings found on $($Using:Server.Name)"
Write-Verbose "Setting new DNS on $($Using:Server.Name)"
try {
Set-DnsClientServerAddress -InterfaceIndex $ifIndex -ServerAddresses $Using:DNS -Validate -ErrorAction Stop
$StatusLog += [PSCustomObject]@{
DataTime = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
Server = $Using:Server.Name
IP = $Using:Server.IPv4Address
Message = "Set new DNS"
}
}
catch {
Write-Warning "Failed to set new DNS on $($Using:Server.Name)"
$ErrorLog += [PSCustomObject]@{
DateTime = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
Server = $Using:Server.Name
IP = $Using:Server.IPv4Address
Error = 'Failed to set new DNS'
}
}
}
else {
Write-Warning "Unexpected DNS settings found on $($Using:Server.Name). Needs to be checked"
$ErrorLog += [PSCustomObject]@{
DateTime = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
Server = $Using:Server.Name
IP = $Using:Server.IPv4Address
Error = "Unexpected DNS settings"
}
}
}
}
else {
Write-Warning "$($Server.Name) is offline"
$ErrorLog += [PSCustomObject]@{
DateTime = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
Server = $Server.Name
IP = $Server.IPv4Address
Error = 'Server is offline'
}
}
}
$StatusLog | Export-Csv -Path $StatusCSV -Encoding UTF8 -NoTypeInformation -Delimiter ';'
$ErrorLog | Export-Csv -Path $ErrorCSV -Encoding UTF8 -NoTypeInformation -Delimiter ';'