Hey, Scripting Guy! Weekend Scripter: Configuring an Authoritative Time Server in Windows Server


Bookmark and Share


 


Microsoft Scripting Guy Ed Wilson here. I finally had a chance to sit down and catch my breath from the 2010 Scripting Games. I reviewed some awesome scripts, and learned many new tricks. I happened to notice that my desktop computer clock was about five minutes slow. I checked and the domain controller was also slow. After looking around, I realized I had never set an external time source for my domain controller—something that was kind of easy to miss because it is running Windows Server 2008 R2 Core Edition.


After doing a bit of research, I ran across an excellent knowledge base article that talks about configuring an authoritative time server in Windows Server. The article KB816042 contains a number of registry entries. Hmm, I thought, an opportunity to write a Windows PowerShell script.


The complete ConfigureInternetTimeSource.ps1 script is seen here.


 


ConfigureInternetTimeSource.ps1


Param($computer = "Hyperv", $user = "nwtraders\administrator")
$psSession = New-PSSession -ComputerName $computer -Credential $user

Invoke-Command -Session $PSSession -ScriptBlock {
 $timeRoot = "HKLM:\SYSTEM\CurrentControlSet\services\W32Time"
 $ntpServer = "time.windows.com,0x1 nist1-ny.ustiming.org,0x1"
 Set-ItemProperty -path "$timeroot\parameters" -name type -Value "NTP"
 Set-ItemProperty -path "$timeroot\parameters" -name NtpServer -Value $ntpServer
 
 Set-ItemProperty -path "$timeroot\config" -name AnnounceFlags -Value 5
 Set-ItemProperty -path "$timeroot\config" -name MaxPosPhaseCorrection -Value 1800
 Set-ItemProperty -path "$timeroot\config" -name MaxNegPhaseCorrection -Value 1800
   
 Set-ItemProperty -path "$timeroot\TimeProviders\NtpServer" -name Enabled -Value 1
 Set-ItemProperty -path "$timeroot\TimeProviders\NtpClient" -name SpecialPollInterval -Value 900
 
 Register-WmiEvent -Query `
  "select * from __InstanceModificationEvent within 5 where targetinstance isa 'win32_service'" `
  -SourceIdentifier stopped

 Stop-Service -Name w32Time
 Wait-Event -SourceIdentifier stopped
 Start-Service -Name w32Time
 
 Unregister-Event -SourceIdentifier stopped
 Remove-Event -SourceIdentifier stopped
} # end invoke-command

Remove-PSSession -Session $psSession


Because I want to run this script against a remote computer, I create a Windows PowerShell remote session:


$psSession = New-PSSession -ComputerName $computer -Credential $user


After the session has been created, I use it to set the registry keys. But because I want all of my commands to be executed at the same time, I use a single Invoke-Command ScriptBlock. The command therefore begins as seen here:


Invoke-Command -Session $PSSession -ScriptBlock {


Everything else is basically between the curly brackets for the ScriptBlock. The commands to modify the registry are seen here:


$timeRoot = "HKLM:\SYSTEM\CurrentControlSet\services\W32Time"
 $ntpServer = "time.windows.com,0x1 nist1-ny.ustiming.org,0x1"
 Set-ItemProperty -path "$timeroot\parameters" -name type -Value "NTP"
 Set-ItemProperty -path "$timeroot\parameters" -name NtpServer -Value $ntpServer
 
 Set-ItemProperty -path "$timeroot\config" -name AnnounceFlags -Value 5
 Set-ItemProperty -path "$timeroot\config" -name MaxPosPhaseCorrection -Value 1800
 Set-ItemProperty -path "$timeroot\config" -name MaxNegPhaseCorrection -Value 1800
   
 Set-ItemProperty -path "$timeroot\TimeProviders\NtpServer" -name Enabled -Value 1
 Set-ItemProperty -path "$timeroot\TimeProviders\NtpClient" -name SpecialPollInterval -Value 900


After the registry entries have been made, it is time to stop and to start the w32time service. Before stopping the w32time service, I create a temporary WMI event consumer by using the Register-WmiEvent cmdlet. This will monitor the status of services on the computer. When an __InstanceModificationEvent occurs (such as stopping or starting a service), an event is triggered. The code to do this is seen here:


Register-WmiEvent -Query `
  "select * from __InstanceModificationEvent within 5 where targetinstance isa 'win32_service'" `
  -SourceIdentifier stopped


Now I stop the w32time service, and wait for the WMI event to be generated. After the event has been generated, I know that it is safe to start the service back up again:


Stop-Service -Name w32Time


 Wait-Event -SourceIdentifier stopped


 Start-Service -Name w32Time


The last thing to do is to clean up a little bit by unregistering the event consumer and deleting the events:


Unregister-Event -SourceIdentifier stopped


 Remove-Event -SourceIdentifier stopped


} # end invoke-command


When I am finished doing that, I remove the Windows PowerShell session by using the Remove-PSSession cmdlet as shown here:


Remove-PSSession -Session $psSession


Regedit can be used remotely to view registry keys in Hkey_Local_Machine and in Hkey_Users. Some of the registry settings modified by the script are seen in the following image.


Image of some registry settings modified by script


 


If you want to know exactly what we will be looking at tomorrow, follow us on Twitter or Facebook. If you have any questions, send e-mail to us at scripter@microsoft.com or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.


 


Ed Wilson and Craig Liebendorfer, Scripting Guys


 

Comments (0)

Skip to main content