Wednesday, July 10, 2013

script to check synchronization of time service (NTP Offset) of the Domain Controllers in an Active Directory in a GUI

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

No comments:

Post a Comment