I've harped on Windows Time before and I assume it will plague me until the day I die. We (once again) are seeing issues with time sync in our domain. I "think" I finally got things stable but in the interim I wanted to keep an active eye on our PDC so I know if it moved to a different domain controller.
I created the below script to do that for me. I set a recurring scheduled task that fires every 15 minutes on my task engine server. The script uses a fixed PDC but could be tweaked to track it if it moves. I simply wanted an "idiot light" that annoyed me if the PDC wasn't where I expected it to be. The first 4 alerts come as detected, then it backs off to once every hour.
Edit it as needed before running.
Param(
[Switch]$Console = $false #--[ Set to true to enable local console result display. Defaults
to false ]--
)
<#==============================================================================
File Name : Get-PDC.ps1
Original Author : Kenneth C. Mazie (kcmjr AT
kcmjr.com)
:
Description : The domain PDC is
determined using DNS SRV records and is then
: compared to a preset. If they don't match an email is sent.
:
Notes : Normal operation is with
no command line options. Run from a
: recurring scheduled task
every 15 minutes or as desired. Outbound
: email messages are sent
every 15 minutes first hour, then once an hour
: until the expected PDC is
restored or the script is edited.
:
Arguments : Command line options for
testing:
: - "-console $true" will enable
local console echo
:
Warnings : None
:
Legal : Public Domain. Modify and
redistribute freely. No rights reserved.
: SCRIPT PROVIDED "AS
IS" WITHOUT WARRANTIES OR GUARANTEES OF
: ANY KIND. USE AT YOUR OWN RISK. NO TECHNICAL
SUPPORT PROVIDED.
:
Credits : Code snippets and/or ideas
came from many sources including but
: not limited to the following:
:
Last Update by : Kenneth C. Mazie
Version History : v1.0 - 10-26-17 - Original
Change History : v1.1 - 11-13-17 - Edited
console output. Changed count method.
: v1.2 - 11-27-17 - Added AD
module import
: v1.3 - 11-18-17 - Changed
PDC detection method.
#>
$CurrentVersion = 1.3 <#--[ Denotes
current version
:
==============================================================================#>
#Requires
-version 4
Clear-Host
Import-Module ActiveDirectory
$Script:Recipient = "me@mydomain.com" #--[ Email
recipient address goes here ]--
$Script:Subject = 'PDC Change
Detected'
$Script:MailServer = '10.10.5.5' #--[ Mail server
IP goes here ]--
$Script:MailFrom = 'Powershell@mydomain.com' #--[ Email
sender goes here ]--
$ScriptName = ($MyInvocation.MyCommand.Name).split(".")[0]
$Script:LogFile = $PSScriptRoot+"\"+$ScriptName+"_{0:MM-dd-yyyy_HHmmss}.log" -f (Get-Date)
$Script:FlagFile = "$PSScriptRoot\$ScriptName.flag"
$Domain = ""
$Count = 0
$ExpectedName = "dc01" #--[ Expected
PDC name goes here ]--
$ExpectedIP = "10.10.5.100" #--[ Expected
PDC IP goes here ]--
#--[ Get Domain
]-------------------------------------------------------------
While ($Domain -eq ""){
$Domain = (Get-ADDomain).DNSroot
Sleep -millisec 500
$Count++
}
#--[ Read data
file to determine what to do ]---------------------------------
If (Test-Path -Path $Script:FlagFile -PathType Leaf -ErrorAction SilentlyContinue){
$Script:ErrorCount = [int](Get-Content -Path $Script:FlagFile -ErrorAction SilentlyContinue)
}Else{
$Script:ErrorCount = 0
Add-Content $Script:FlagFile -Value $Script:ErrorCount
}
#[array]$Lookup
= (nslookup -type=SRV _ldap._tcp.pdc._msdcs.$Domain)
#$PDCname =
($Lookup[8].split('.'))[0]
#$PDCip =
(($Lookup[8].split('='))[1]).trim()
$FSMO = Get-ADDomain | Select-Object DistinguishedName, SchemaMaster, DomainNamingMaster, InfrastructureMaster, PDCEmulator, RIDMaster
$DetectedName = ($FSMO.PDCEmulator).Split(".")[0]
$DetectedIP = (Test-Connection $PDC -count 1 | select Ipv4Address).Ipv4Address
If ($Console){
Write-Host "Previous
Errors :"$Script:ErrorCount -ForegroundColor Yellow
Write-Host "Expected
PDC : $ExpectedName" -ForegroundColor cyan
Write-Host "Expected
IP : $ExpectedIP" -ForegroundColor cyan
Write-Host "Detected
PDC : $DetectedName" -ForegroundColor yellow
write-host "Detected
IP : $DetectedIP" -ForegroundColor yellow
}
$Script:Message = @()
$Script:Message += '<html><br><font face="verdana,arial,sans-serif" color=red><strong>---===¦ ATTENTION ¦===---</strong></font><hr><br>
<strong>A change was detected in the normally assigned domain PDC.</strong><br>
<ul><li>Domain name : <strong>'+$Domain+'</strong></li></ul>
<ul>
<li>Expected PDC DNS name : <strong>'+$ExpectedName+'</strong></li>
<li>Expected PDC IP : <strong>'+$ExpectedIP+'</strong></li>
</ul><ul>
<li>Detected PDC DNS name : <strong>'+$DetectedName+'</strong></li>
<li>Detected PDC IP : <strong>'+$DetectedIP+'</strong></li>
</ul>
- This check is run every 15 minutes to detect the domain PDC.<br>
- Due to the way time services are configured in the domain, changes to which domain controller holds the role can affect time sync.<br>
- If this change was intentional, no harm done, however this alert will continue until stopped or the proper DC is selected/detected as PDC.<br>
- To minimize email spam, after the first 4 alerts emails will go out once per hour.<br>
- Script executed from and must be paused on : '+$env:computername+'
'
If (($PDCname -eq $TargetName) -and ($PDCip -eq $TargetIP)){
remove-item -Path $Script:FlagFile -Force -Confirm:$false
Add-Content $Script:FlagFile -Value "0"
If ($Console){Write-Host "`nValues
Match. Resetting Error Count"`n -ForegroundColor Green }
}Else{
remove-item -Path $Script:FlagFile -Force -Confirm:$false
Add-Content $Script:FlagFile -Value (($Script:ErrorCount -as [int]) + 1)
$Script:Message += '
<br>Running error count $Script:ErrorCount
</HTML>
'
IF (($Script:ErrorCount -le 4) -or (!($Script:ErrorCount%4))){
$SMTP = new-object System.Net.Mail.SmtpClient($Script:MailServer)
$Email = New-Object System.Net.Mail.MailMessage
$Email.Body = $Script:Message
$Email.IsBodyHtml = $true
$Email.To.Add($Script:Recipient)
$Email.From = $Script:MailFrom
$Email.Subject = $Script:Subject
$SMTP.Send($Email)
$Email.Dispose()
$SMTP.Dispose()
$Script:ErrorCount = [int](Get-Content -Path $Script:FlagFile -ErrorAction SilentlyContinue)
If ($Console){Write-Host "New Error
Count :"$Script:ErrorCount`n -ForegroundColor Yellow}
}
}