Function Set-NtpTimeV2 {
#Parametros
[CmdletBinding()]
Param (
[String]$Server = 'pool.ntp.org',
[Int]$MaxOffset = 10000 # (Milliseconds) Throw if network time offset is larger
)
# Construct a 48-byte client NTP time packet to send to the specified server
# (Request Header: [00=No Leap Warning; 011=Version 3; 011=Client Mode]; 00011011 = 0x1B)
[Byte[]]$NtpData = ,0 * 48
$NtpData[0] = 0x1B # NTP Request header in first byte
# NTP Transaction -------------------------------------------------------
$Socket = New-Object Net.Sockets.Socket([Net.Sockets.AddressFamily]::InterNetwork,
[Net.Sockets.SocketType]::Dgram,
[Net.Sockets.ProtocolType]::Udp)
Try {
$Socket.Connect($Server,123)
}
Catch {
Write-Error $_
Throw "Failed to connect to server $Server"
}
$t1 = Get-Date # Start of transaction... the clock is ticking...
Try {
[Void]$Socket.Send($NtpData)
[Void]$Socket.Receive($NtpData)
}
Catch {
Write-Error $_
Throw "Failed to communicate with server $Server"
}
$t4 = Get-Date # End of transaction time
$Socket.Close()
# -----------------------------------------------------------------------
# -----------------------------------------------------------------------
# Check the Leap Indicator (LI) flag for an alarm condition - extract the flag
# from the first byte in the packet by masking and shifting (dividing)
$LI = ($NtpData[0] -band 0xC0)/64 # Leap Second indicator
If ($LI -eq 3) {
Throw 'Alarm condition from server (clock not synchronized)'
}
# We now have the 64-bit NTP times, t3 is in the last 8 bytes of the received data.
# The NTP time is the number of seconds since 1/1/1900 and is split into an
# integer part (top 32 bits) and a fractional part, multipled by 2^32, in the
# bottom 32 bits.
# Convert Integer and Fractional parts of the (64-bit) t3 NTP time from the byte array
# $IntPart=0; Foreach ($Byte in $NtpData[40..43]) {$IntPart = $IntPart * 256 + $Byte}
# $FracPart=0; Foreach ($Byte in $NtpData[44..47]) {$FracPart = $FracPart * 256 + $Byte}
$IntPart = [BitConverter]::ToUInt32($NtpData[43..40],0)
$FracPart = [BitConverter]::ToUInt32($NtpData[47..44],0)
# Convert to Millseconds (convert fractional part by dividing value by 2^32)
$t3ms = $IntPart * 1000 + ($FracPart * 1000 / 0x100000000)
# Make sure the result looks sane...
If ([Math]::Abs($Offset) -gt $MaxOffset) {
# Network time is too different from server time
Throw "Network time offset exceeds maximum ($($MaxOffset)ms)"
}
# Create Output object and return
echo "Cogiendo hora y fecha presente en el equipo..."
$currentDate = Get-Date
echo "La fecha y hora actual del sistema es: $currentDate"
echo "Obteniedo la fecha y hora real del servidor NTP..."
echo "Configurando la fecha y hora real..."
$nuevaFechaHora=New-Object DateTime(1900,1,1,0,0,0,[DateTimeKind]::Utc)
$nuevaFechaHora = $nuevaFechaHora.AddMilliseconds($t3ms).ToLocalTime()
$nuevaFecha = Set-Date -Date $nuevaFechaHora
echo "La hora y fecha configurada es... $nuevaFecha"
}