In larger Active Directory environments the synchronization of time on all
domain controllers is essential for a healthy AD. AD services will run into
problems if the times on domain controllers are ‘out-of-sync’ especially
Kerberos (the authentication mechanism used by Windows Active Directory) is
sensitive to this.
To check for the domain controllers and their delta (the deviation from their
own local time entry and the time on the domain controller the machine
synchronizes with) the command
W32tm can be used.
The output is a bit hard to read though so i made a little script that
extracts the NTP offset and its syncing DC to list it in a small GUI.
the output looks like this:
the GUI is generated with
SAPIEN’s great PrimalForms Community Edition. the code is
added here so you can use it for yourself. the script does not need any
configuration because it uses the
ActiveDirectory PowerShell module to get all domain
controllers from a Directory.
#Generated Form Function
function GenerateForm
{
########################################################################
#
Code Generated By: SAPIEN Technologies PrimalForms (Community Edition)
v1.0.10.0
# Generated On: 9-7-2013 14:38
# Generated By: Bas
Huygen
########################################################################
#region Import the
Assemblies
[reflection.assembly]::loadwithpartialname("System.Drawing") |
Out-Null
[reflection.assembly]::loadwithpartialname("System.Windows.Forms") |
Out-Null
#endregion
#region Generated Form Objects
$form1 = New-Object
System.Windows.Forms.Form
$label3 = New-Object
System.Windows.Forms.Label
$tbNTskew = New-Object
System.Windows.Forms.TextBox
$btnext = New-Object
System.Windows.Forms.Button
$btPrevious = New-Object
System.Windows.Forms.Button
$tbMaster = New-Object
System.Windows.Forms.TextBox
$label2 = New-Object
System.Windows.Forms.Label
$label1 = New-Object
System.Windows.Forms.Label
$tbDC = New-Object
System.Windows.Forms.TextBox
$InitialFormWindowState = New-Object
System.Windows.Forms.FormWindowState
#endregion Generated Form Objects
#----------------------------------------------
#Generated Event Script
Blocks
#----------------------------------------------
#Provide Custom
Code for events specified in PrimalForms.
#the ActiveDirectory module is used to list all domain controllers into an
array called $ArrayDC
Import-Module
ActiveDirectory
$index=0
$ArrayDC=(Get-ADDomainController -Filter *|select
name)
#Function Get-DCTime runs w32tm /monitor on the tested DC
#all subsequent
sentences extract the values and list them in the textboxes
Function
Get-DCTime($index){
$testit=$ArrayDC[$index].name
$tbDC.appendtext($testit)
$substr=(w32tm
/monitor /computers:$testit|where{$_ -like
"*NTP:*"})
$NTPvalue=$substr.substring(9,20)
$tbNTskew.appendtext($NTPvalue)
$RefID=$substr.substring(36)
$tbMaster.appendtext($RefID)}
#the previous and next buttons invoke Get-DCTime on a previous- or next
indexID
$btPrevious_OnClick=
{
$tbDC.clear()
$tbNTskew.clear()
$tbMaster.clear()
$index=$index
- 1
Get-DCTime $index
}
$btnext_OnClick=
{
$tbDC.clear()
$tbNTskew.clear()
$tbMaster.clear()
$index=$index
+ 1
Get-DCTime $index
}
$OnLoadForm_StateCorrection=
{#Correct the initial state of the form to
prevent the .Net maximized form issue
$form1.WindowState =
$InitialFormWindowState
}
#----------------------------------------------
#region Generated Form
Code
$System_Drawing_Size = New-Object
System.Drawing.Size
$System_Drawing_Size.Height =
232
$System_Drawing_Size.Width = 407
$form1.ClientSize =
$System_Drawing_Size
$form1.DataBindings.DefaultDataSourceUpdateMode =
0
$form1.Name = "form1"
$form1.Text = "AD Time services checker"
$label3.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Point = New-Object
System.Drawing.Point
$System_Drawing_Point.X = 41
$System_Drawing_Point.Y
= 115
$label3.Location = $System_Drawing_Point
$label3.Name =
"label3"
$System_Drawing_Size = New-Object
System.Drawing.Size
$System_Drawing_Size.Height =
23
$System_Drawing_Size.Width = 125
$label3.Size =
$System_Drawing_Size
$label3.TabIndex = 7
$label3.Text = "NTP Offset
relative to"
$form1.Controls.Add($label3)
$tbNTskew.DataBindings.DefaultDataSourceUpdateMode =
0
$System_Drawing_Point = New-Object
System.Drawing.Point
$System_Drawing_Point.X = 190
$System_Drawing_Point.Y
= 112
$tbNTskew.Location = $System_Drawing_Point
$tbNTskew.Name =
"tbNTskew"
$System_Drawing_Size = New-Object
System.Drawing.Size
$System_Drawing_Size.Height =
20
$System_Drawing_Size.Width = 177
$tbNTskew.Size =
$System_Drawing_Size
$tbNTskew.TabIndex = 6
$form1.Controls.Add($tbNTskew)
$btnext.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Point = New-Object
System.Drawing.Point
$System_Drawing_Point.X = 191
$System_Drawing_Point.Y
= 164
$btnext.Location = $System_Drawing_Point
$btnext.Name =
"btnext"
$System_Drawing_Size = New-Object
System.Drawing.Size
$System_Drawing_Size.Height =
23
$System_Drawing_Size.Width = 75
$btnext.Size =
$System_Drawing_Size
$btnext.TabIndex = 5
$btnext.Text =
"Next"
$btnext.UseVisualStyleBackColor =
$True
$btnext.add_Click($btnext_OnClick)
$form1.Controls.Add($btnext)
$btPrevious.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Point = New-Object
System.Drawing.Point
$System_Drawing_Point.X = 109
$System_Drawing_Point.Y
= 164
$btPrevious.Location = $System_Drawing_Point
$btPrevious.Name =
"btPrevious"
$System_Drawing_Size = New-Object
System.Drawing.Size
$System_Drawing_Size.Height =
23
$System_Drawing_Size.Width = 75
$btPrevious.Size =
$System_Drawing_Size
$btPrevious.TabIndex = 4
$btPrevious.Text =
"Previous"
$btPrevious.UseVisualStyleBackColor =
$True
$btPrevious.add_Click($btPrevious_OnClick)
$form1.Controls.Add($btPrevious)
$tbMaster.DataBindings.DefaultDataSourceUpdateMode =
0
$System_Drawing_Point = New-Object
System.Drawing.Point
$System_Drawing_Point.X = 190
$System_Drawing_Point.Y
= 72
$tbMaster.Location = $System_Drawing_Point
$tbMaster.Name =
"tbMaster"
$System_Drawing_Size = New-Object
System.Drawing.Size
$System_Drawing_Size.Height =
20
$System_Drawing_Size.Width = 177
$tbMaster.Size =
$System_Drawing_Size
$tbMaster.TabIndex = 3
$form1.Controls.Add($tbMaster)
$label2.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Point = New-Object
System.Drawing.Point
$System_Drawing_Point.X = 41
$System_Drawing_Point.Y
= 75
$label2.Location = $System_Drawing_Point
$label2.Name =
"label2"
$System_Drawing_Size = New-Object
System.Drawing.Size
$System_Drawing_Size.Height =
23
$System_Drawing_Size.Width = 100
$label2.Size =
$System_Drawing_Size
$label2.TabIndex = 2
$label2.Text = "Synchs
with"
$label2.add_Click($handler_label2_Click)
$form1.Controls.Add($label2)
$label1.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Point = New-Object
System.Drawing.Point
$System_Drawing_Point.X = 41
$System_Drawing_Point.Y
= 37
$label1.Location = $System_Drawing_Point
$label1.Name =
"label1"
$System_Drawing_Size = New-Object
System.Drawing.Size
$System_Drawing_Size.Height =
23
$System_Drawing_Size.Width = 143
$label1.Size =
$System_Drawing_Size
$label1.TabIndex = 1
$label1.Text = "Domain
Controller Name: "
$form1.Controls.Add($label1)
$tbDC.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Point =
New-Object System.Drawing.Point
$System_Drawing_Point.X =
190
$System_Drawing_Point.Y = 34
$tbDC.Location =
$System_Drawing_Point
$tbDC.Name = "tbDC"
$System_Drawing_Size =
New-Object System.Drawing.Size
$System_Drawing_Size.Height =
20
$System_Drawing_Size.Width = 177
$tbDC.Size =
$System_Drawing_Size
$tbDC.TabIndex = 0
$form1.Controls.Add($tbDC)
#endregion Generated Form Code
#Save the initial state of the form
$InitialFormWindowState =
$form1.WindowState
#Init the OnLoad event to correct the initial state of the
form
$form1.add_Load($OnLoadForm_StateCorrection)
#Show the
Form
$form1.ShowDialog()| Out-Null
} #End Function
#Call the Function
GenerateForm