PowerShell – Get/Set Windows Date/Time from NTP

|

Sometimes w32Time is not available or practical so we get this PowerShell script to pull NTP date/time and set the Windows Date/Time

<#
Majority of code is from:
Chris Warwick, @cjwarwickps, August 2012
chrisjwarwick.wordpress.com
#>

$sNTPServer = 'pool.ntp.org'

function Get-NTPDateTime ([string] $sNTPServer)
{
    $StartOfEpoch=New-Object DateTime(1900,1,1,0,0,0,[DateTimeKind]::Utc)   
    [Byte[]]$NtpData = ,0 * 48
    $NtpData[0] = 0x1B    # NTP Request header in first byte
    $Socket = New-Object Net.Sockets.Socket([Net.Sockets.AddressFamily]::InterNetwork, [Net.Sockets.SocketType]::Dgram, [Net.Sockets.ProtocolType]::Udp)
    $Socket.Connect($sNTPServer,123)
    
    $t1 = Get-Date    # Start of transaction... the clock is ticking...
    [Void]$Socket.Send($NtpData)
    [Void]$Socket.Receive($NtpData)  
    $t4 = Get-Date    # End of transaction time
    $Socket.Close()

    $IntPart = [BitConverter]::ToUInt32($NtpData[43..40],0)   # t3
    $FracPart = [BitConverter]::ToUInt32($NtpData[47..44],0)
    $t3ms = $IntPart * 1000 + ($FracPart * 1000 / 0x100000000)

    $IntPart = [BitConverter]::ToUInt32($NtpData[35..32],0)   # t2
    $FracPart = [BitConverter]::ToUInt32($NtpData[39..36],0)
    $t2ms = $IntPart * 1000 + ($FracPart * 1000 / 0x100000000)

    $t1ms = ([TimeZoneInfo]::ConvertTimeToUtc($t1) - $StartOfEpoch).TotalMilliseconds
    $t4ms = ([TimeZoneInfo]::ConvertTimeToUtc($t4) - $StartOfEpoch).TotalMilliseconds
 
    $Offset = (($t2ms - $t1ms) + ($t3ms-$t4ms))/2
    
    [String]$NTPDateTime = $StartOfEpoch.AddMilliseconds($t4ms + $Offset).ToLocalTime() 

    set-date $NTPDateTime
}

clear

get-date # Get Current Windows Date/Time

set-date "2015-12-2 12:00:00" # Set specific Windows Date/Time

Get-NTPDateTime -sNTPServer $sNTPServer # Get NTP Date/Time and Set Windows Date/Time

GitHub: https://gist.github.com/dkittell/56f957c850f1064cbea0

Reference: chrisjwarwick.wordpress.com

Originally Posted on December 3, 2015
Last Updated on February 12, 2016
All information on this site is shared with the intention to help. Before any source code or program is ran on a production (non-development) system it is suggested you test it and fully understand what it is doing not just what it appears it is doing. I accept no responsibility for any damage you may do with this code.