Created
December 5, 2018 10:50
-
-
Save ooltcloud/620831658a0cd9055f53ae3ba3543ee1 to your computer and use it in GitHub Desktop.
Powershell と NTP を使用した簡易時刻同期 (udp の ntp プロトコル使用)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#-------------- | |
# NTP 時刻合わせ (NTP UDP:123) | |
#-------------- | |
# NTP 積算秒数の起点時刻 (JST) | |
$ntpEpoch = New-Object System.Datetime @(1900, 1, 1, 9, 0, 0) | |
# Big Endian の符号なし Int32 を取得 | |
Function getUInt32BE($bytes, $startIndex) { | |
# BE→LE 変換 | |
$a = $bytes[($startIndex + 3) .. $startIndex] | |
# UInt32 取得 | |
$b = [System.BitConverter]::ToUInt32($a, 0) | |
return $b | |
} | |
# 固定小数点(整数部 32bit / 小数部 32bit) を取得 | |
Function getFixedPointDecimal3232($bytes, $startIndex) { | |
# 整数部取得 | |
$int = getUInt32BE $bytes $startIndex | |
# 小数部取得 | |
$dec = getUInt32BE $bytes ($startIndex + 4) | |
# 合成 | |
$value = $int + $dec * [Math]::Pow(2,-32) | |
return $value | |
} | |
# タイムスタンプ値から JST を求める | |
Function getJST($timeSerial) { | |
$date = $ntpEpoch.AddSeconds($timeSerial) | |
return $date | |
} | |
# 送信電文作成 | |
Function getSendBytes() { | |
$buf = @() | |
# header | |
$li = 0 # 空設定 | |
$vn = 3 # Version 3 | |
$mode = 3 # Client Mode | |
$buf += [byte](($li -shl 6) + ($vn -shl 3) + $mode) | |
# stratum | |
$buf += [byte]0 # 空設定 | |
# poll | |
$buf += [byte]0 # 空設定 | |
# precision | |
$buf += [byte]0 # 空設定 | |
# RootDelay | |
$buf += @([Byte]0) * 4 # 空設定 | |
# RootDispersion | |
$buf += @([Byte]0) * 4 # 空設定 | |
# ReferenceID | |
$buf += @([Byte]0) * 4 # 空設定 | |
# Reference Timestamp | |
$buf += @([Byte]0) * 8 # 空設定 | |
# Origin Timestamp | |
$buf += @([Byte]0) * 8 # 空設定 | |
# Receive Timestamp | |
$buf += @([Byte]0) * 8 # 空設定 | |
# Transmit Timestamp | |
$buf += @([Byte]0) * 8 # 空設定 | |
return $buf | |
} | |
# NTP サーバーと通信 | |
Function inquiryNTP($ntpServerAddress, $sendBytes) | |
{ | |
$udp = New-Object Net.Sockets.UdpClient | |
$udp.Client.ReceiveTimeout = 2000 | |
try | |
{ | |
# UDP Port 123 に送信 | |
$a = $udp.Send($sendBytes, $sendBytes.Length, $ntpServerAddress, 123) | |
# 応答を受信 | |
$recvBytes = $udp.Receive([ref]$null) | |
# 終了 | |
$udp.Close() | |
return $recvBytes | |
} catch { | |
Throw | |
} finally { | |
$udp.Dispose() | |
} | |
} | |
# 受信電文解析 | |
Function getResult($recvBytes) { | |
# 初期化 | |
$result = @{} | |
# Transmit Timestamp | |
$ts = getFixedPointDecimal3232 $recvBytes 40 | |
$jst = getJST $ts | |
return $jst | |
} | |
# 時刻設定 (応答送信時刻に合わせます) | |
Function SetNTPDate($ntpServerAddress) { | |
try { | |
$send = getSendBytes | |
$recv = inquiryNTP $ntpServerAddress $send | |
$result = getResult $recv | |
} catch { | |
Throw | |
} | |
# 時刻設定 | |
Set-Date -Date $result | |
} | |
# 実行 | |
SetNTPDate "ntp.nict.jp" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
類似品。https://gist.github.com/ooltcloud/20e7d7551007370b4b8e345499d79cb3
上記で「いやそうじゃない、http じゃなくて ntp のままサクッと時刻合わせがしたいんである」という人向け。
そういうひとは桜時計( https://www.vector.co.jp/soft/win95/personal/se050672.html ) を使えって話なんだけども、実行または常駐しているのが見えるのは嫌だとか Windows 標準機能でなんとかならないか(フリーソフトは持ち込めない)という人向け。
そんなニーズがあるのかどうかは知らないが(汗