Синхронизация времени в Windows
21 Nov 2017Стандартная команда Windows для синхронизации времени
Как понял, других адекватных вариантов синхронизации в Windows нет.
w32tm /resync
... либо
net time \\dc1 /set
Получение точного времени с сайта nist.time.gov и установка
Такой вариант, с натяжкой можно назвать синхронизацией.
#Включаем все протоколы
$AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'
[System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols
$webRequest = Invoke-WebRequest -UseBasicParsing -Uri 'https://nist.time.gov/actualtime.cgi?lzbc=siqm9b'
$milliseconds = [int64](($webRequest.Content -replace '.*time="|" delay=".*') / 1000)
#Добавляем +5 часов (мой часовой пояс) к полученному времени
$TimeNow = ((New-Object -TypeName DateTime -ArgumentList (1970, 1, 1)).AddMilliseconds($milliseconds)).AddHours(5)
Set-Date $TimeNow
DSC модуль для синхронизации времени
#plTimeSync.psm1
enum Ensure
{
Absent
Present
}
[DscResource()]
class plTimeSync
{
[DscProperty(Key)]
[string]$ComputerName = $ENV:COMPUTERNAME
[DscProperty(Key)]
[string]$NTPTimeServers = "time.nist.gov,0x1 time.windows.com,0x1 ru.pool.ntp.org,0x1"
[DscProperty(Mandatory)]
[Ensure] $Ensure
[void] Set()
{
$CheckNTP = $this.TestNTPSync()
if ($this.ensure -eq [Ensure]::Present) {
if (-not $CheckNTP)
{
$this.SetupNTPServers()
}
} else {
if ($CheckNTP) {
Write-Verbose -Message "Do not do anything"
}
}
}
[bool] Test()
{
$present = $this.TestNTPSync()
if ($this.Ensure -eq [Ensure]::Present) {
#Write-Verbose -Message "Optimal time synchronisation"
return $present
} else {
return -not $present
}
}
[plTimeSync] Get()
{
$present = $this.TestNTPSync()
if ($present)
{
$this.Ensure = [Ensure]::Present
} else {
$this.Ensure = [Ensure]::Absent
}
return $this
}
[bool] TestNTPSync()
{
$present = $true
$w32tmComp = $this.ComputerName
#Write-Verbose -Message $w32tmComp
$psi = New-object System.Diagnostics.ProcessStartInfo
$psi.CreateNoWindow = $true
$psi.UseShellExecute = $false
$psi.RedirectStandardOutput = $true
$psi.RedirectStandardError = $true
$psi.FileName = "c:\Windows\System32\w32tm.exe"
$psi.Arguments = "/monitor /nowarn /computers:$w32tmComp"
$process = New-Object System.Diagnostics.Process
$process.StartInfo = $psi
$process.Start() | Out-Null
$process.WaitForExit()
$NUTOutputExe = $process.StandardOutput.ReadToEnd()
$w32tmOut = $NUTOutputExe
Write-Verbose -Message "Monitor: $w32tmOut"
$startW32tm = $w32tmOut.IndexOf("NTP")
$endW32tm = $w32tmOut.LastIndexOf("s ")
[float]$icmp = $w32tmOut.Substring(($startW32tm + 5), (($endW32tm - $startW32tm) - 5))
Write-Verbose -Message "Precision: $icmp"
if ($icmp -le "15") {
Write-Verbose -Message "Optimal time synchronisation"
$present = $true
}
if ($icmp -gt "300") {
Write-Verbose -Message "Critical. Over 5 minutes time difference!"
$present = $false
}
return $present
}
[void] SetupNTPServers()
{
$registryPathConfig = "HKLM:\SYSTEM\CurrentControlSet\Services\W32Time\Config"
$NameAnnounceFlags = "AnnounceFlags"
$ValueAnnounceFlags = "10"
New-ItemProperty -Path $registryPathConfig -Name $NameAnnounceFlags -Value $ValueAnnounceFlags `
-PropertyType DWORD -Force | Out-Null
$NamePosPhase = "MaxPosPhaseCorrection"
$ValuePosPhase = "4294967295"
New-ItemProperty -Path $registryPathConfig -Name $NamePosPhase -Value $ValuePosPhase `
-PropertyType DWORD -Force | Out-Null
$NameNegPhase = "MaxNegPhaseCorrection"
$ValueNegPhase = "4294967295"
New-ItemProperty -Path $registryPathConfig -Name $NameNegPhase -Value $ValueNegPhase `
-PropertyType DWORD -Force | Out-Null
$registryPathParameters = "HKLM:\SYSTEM\CurrentControlSet\Services\W32Time\Parameters"
$NameNtpServer = "NtpServer"
$ValueNtpServer = $this.NTPTimeServers
New-ItemProperty -Path $registryPathParameters -Name $NameNtpServer -Value $ValueNtpServer `
-PropertyType String -Force | Out-Null
$NameType = "Type"
$ValueType = "NTP"
New-ItemProperty -Path $registryPathParameters -Name $NameType -Value $ValueType `
-PropertyType String -Force | Out-Null
$registryPathNtpClient = "HKLM:\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpClient"
$NamePollInterval = "SpecialPollInterval"
$ValuePollInterval = "900"
New-ItemProperty -Path $registryPathNtpClient -Name $NamePollInterval -Value $ValuePollInterval `
-PropertyType DWORD -Force | Out-Null
Restart-Service W32Time
$w32tmOutput = & 'w32tm' '/resync'
#$w32tmOutput = & 'w32tm' '/resync'
#$w32tmOutput = & 'w32tm' '/resync'
$encFrom = [System.Text.Encoding]::GetEncoding("cp866")
$encTo = [System.Text.Encoding]::GetEncoding("windows-1251")
$bytes = $encTo.GetBytes($w32tmOutput)
$bytes = [System.Text.Encoding]::Convert($encFrom, $encTo, $bytes)
$w32tmOutput = $encTo.GetString($bytes)
Write-Verbose -Message "Message: $w32tmOutput"
}
}
########################################################################
#plTimeSync.psd1
@{
# Script module or binary module file associated with this manifest.
RootModule = 'plTimeSync.psm1'
DscResourcesToExport = 'plTimeSync'
# Version number of this module.
ModuleVersion = '0.0.1'
# ID used to uniquely identify this module
GUID = 'b7a03575-d967-4acf-b964-c6210ac6c6eb'
# Author of this module
Author = 'Pavel Satin'
# Company or vendor of this module
CompanyName = 'Pavel Satin'
# Copyright statement for this module
Copyright = '(c) 2017 Pavel Satin. All rights reserved.'
# Description of the functionality provided by this module
# Description = ''
# Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '5.0'
# Name of the Windows PowerShell host required by this module
# PowerShellHostName = ''
}