Всем доброго пятничного вечера! Сегодня поговорим о синхронизации времени, если со службой w32time что-то идёт не так. Заодно попробуем сверить часы с каким-нибудь местным сервером, если служба решила отдохнуть от нас и остановиться.
Очень не хочется откатываться на общение с batch скриптами, поэтому попробуем пообщаться с w32tm напрямую из PowerShell.
Для последующих применений я написал функцию TimeSync с обязательным параметром IP:
function TimeSync
{
Param([Parameter(Mandatory=$true)]$IP)
$service = "W32Time"
$time = (Get-Service -Name $service).Status
if ($time = "Running")
{
Write-Host "Служба $service была запущена ранее."
Write-Host "Пытаюсь синхронизироваться..."
w32tm /resync
Sleep(5)
$curdatetime = Get-Date -Format "yyyy.MM.dd HH:mm"
Write-Host "Сейчас на хосте: $curdatetime"
}
else
{
Write-Host "Служба $service остановлена!"
Write-Host "Пытаюсь запустить $service и установить автоматический тип запуска..."
Set-Service -Name $service -StartupType Automatic
Start-Service -Name $service
Sleep(5)
if ((Get-Service -Name $service).Status = "Running")
{
Write-Host "Служба $service успешно запущена!"
Write-Host "Пытаюсь добавить узел синхронизации $IP..."
w32tm /config /syncfromflags:manual /manualpeerlist:$IP
Write-Host "Пытаюсь синхронизироваться с узлом $IP..."
w32tm /resync
$curdatetime = Get-Date -Format "yyyy.MM.dd HH:mm"
Write-Host "Сейчас на хосте: $curdatetime"
}
else
{
Write-Host "Не удалось запустить службу $service..."
}
}
}
Принцип работы функции прост: если служба запущена вызываем ручную синхронизацию, если же служба отдыхает — пытаемся её разбудить, задать сервер для синхронизации и синхронизироваться.
Указав IP-адрес сервера для сверки времени, вызываем функцию:
TimeSync -IP 192.168.1.100
Основная проблема функции TimeSync в том, что ответ от команды w32tm возвращается в кодировке cp866. Поэтому без явного объявления этой кодировки никак не обойтись.
Собираю итоговый вариант скрипта, указывая нужную кодировку:
[System.Console]::Title = "Синхронизация времени"
[Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("cp866")
function TimeSync
{
Param([Parameter(Mandatory=$true)]$IP)
$service = "W32Time"
$time = (Get-Service -Name $service).Status
if ($time = "Running")
{
Write-Host "Служба $service была запущена ранее."
Write-Host "Пытаюсь синхронизироваться..."
w32tm /resync
Sleep(5)
$curdatetime = Get-Date -Format "yyyy.MM.dd HH:mm"
Write-Host "Сейчас на хосте: $curdatetime"
}
else
{
Write-Host "Служба $service остановлена!"
Write-Host "Пытаюсь запустить $service и установить автоматический тип запуска..."
Set-Service -Name $service -StartupType Automatic
Start-Service -Name $service
Sleep(5)
if ((Get-Service -Name $service).Status = "Running")
{
Write-Host "Служба $service успешно запущена!"
Write-Host "Пытаюсь добавить узел синхронизации $IP..."
w32tm /config /syncfromflags:manual /manualpeerlist:$IP
Write-Host "Пытаюсь синхронизироваться с узлом $IP..."
w32tm /resync
$curdatetime = Get-Date -Format "yyyy.MM.dd HH:mm"
Write-Host "Сейчас на хосте: $curdatetime"
}
else
{
Write-Host "Не удалось запустить службу $service..."
}
}
}
TimeSync -IP 192.168.1.100
Write-Host
Write-Host "Это окно закроется автоматически..."
Sleep(10)
Главное, не забыть запустить всё это дело от имени администратора!
Скрипт можно скомпилировать в исполняемый файл, используя модуль PS2EXE.
А с другой стороны можно всё низвести до базовых команд и пришпандорить к планировщику.
Например, накидаем скрипт и назовём его sync.ps1:
Start-Service w32time -Verbose w32tm /config /syncfromflags:manual /manualpeerlist:192.168.1.100 # <= IP-адрес Вашего NTP w32tm /resync # Get-Date # <= Если требуется просмотреть результат
Теперь создадим ещё один скрипт и наречём его sync_job.ps1:
$trigger = New-ScheduledTaskTrigger -At 0:01 -Daily $user = "NT AUTHORITY\SYSTEM" $action= New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "disk:\path\to\script\sync.ps1" # <= Прописываем путь к файлу sync.ps1 Register-ScheduledTask -TaskName "SyncTime" -Trigger $trigger -User $user -Action $action -RunLevel Highest –Force
Запускаем скрипт sync_job.ps1 для создания ежедневного задания в планировщике и радуемся автоматизации процесса.