Проверка времени на локальном и удаленном компьютерах
Один из участников Windows PowerShell User Group в Charlotte как то спросил меня о проверке времени на удаленных компьютерах. Я решил пограться с этим.
Заметка: Для получения более обширной информации по вопросам синхронизации времени, ознакомьтесь со следующими постами: Configuring w32Time Service Logging и Configuring an Authoritative Time Server in Windows Server.
Конечно, можно воспользоваться WMI для запроса информации о времени на удаленной машине. Для этого используется класс Win32_LocalTime. Проблема в том, что каждая часть (часы, минуты и т.д.) – это отдельное свойство, и для получения значения времени его нужно собрать из трех отдельных свойств (конечно, если вам не нужна информация о дате – это еще три отдельных свойства).
Определение PDC-эмулятора
По умолчанию авторитетный сервер времени в домене – это контроллер домена, обладающий ролью FSMO — PDC Emulator. Самый простой способ получить имя этого сервера – воспользоваться командлетом Get-ADDomain, входящим в модуль Active Directory. В Windows PowerShell 3.0 вам не нужно загружать модуль Active Directory перед использованием этого командлета. Следующая команда возвращает PDC-эмулятор в моем домене:
PS C:\> (Get-ADDomain).pdcemulator
dc1.iammred.net
Проверка времени и даты на удаленном компьютере
Наиболее простой способ получить дате и время на удаленном компьютере – это использование командлета Get-Date. Используя возможность удаленного выполнения команд PowerShell, получить эту информацию довольно просто.
PS C:\> invoke-command -ComputerName dc1 -ScriptBlock {get-date}
Wednesday, October 31, 2012 1:23:42 PM
Команду можно существенно сократить, если воспользоваться псевдонимом icm для командлета Invoke-Command. Кроме того, благодаря тому, что ComputerName и ScriptBlock – это позиционные параметры, мы можем пропустить их имена.
PS C:\> icm dc1 {get-date}
Wednesday, October 31, 2012 1:24:24 PM
Если мне нужна вся доступная информация, я могу передать полученные результаты командлету Format-List.
PS C:\> icm dc1 {get-date} | fl *
DisplayHint : DateTime
PSComputerName : dc1
RunspaceId : 7cf0452c-688a-4e16-83f5-d9b0ec6ded6e
PSShowComputerName : True
DateTime : Wednesday, October 31, 2012 2:33:35 PM
Date : 10/31/2012 12:00:00 AM
Day : 31
DayOfWeek : Wednesday
DayOfYear : 305
Hour : 14
Kind : Local
Millisecond : 879
Minute : 33
Month : 10
Second : 35
Ticks : 634872908158794870
TimeOfDay : 14:33:35.8794870
Year : 2012
С другой стороны, мне может потребоваться определить разницу во времени между моим компьютером и сервером. В этом случае я могу воспользоваться командлетом New-TimeSpan для определения разницы между результатами двух команд Get-Date. Стоит принять во внимание, что на точность измерения повлияет время, необходимое для подключения к удаленному компьютеру, запуску на нем команды и передачи результатов ее выполнения на локальный компьютер. Как это повлияет на результат зависит от того, спешат часы моего компьютера относительно времени сервера, или наоборот отстают. Сама команда достаточно проста. Я использую результат командлета Get-Date на локальном компьютере в качестве начала временного интервала (timespan). Затем я использую время на удаленном сервере в качестве конечной точки.
PS C:\> new-timespan -Start (get-date) -end (icm dc1 {get-date})
Days : 0
Hours : 0
Minutes : 0
Seconds : 0
Milliseconds : -311
Ticks : -3116406
TotalDays : -3.60695138888889E-06
TotalHours : -8.65668333333333E-05
TotalMinutes : -0.00519401
TotalSeconds : -0.3116406
TotalMilliseconds : -311.6406
Синхронизация времени с внешними источниками
Разница во времени между моим компьютером и сервером меньше половины секунды – определенно в пределах разумного. Но что, если бы эта разница была больше? Ну, для начала я бы синхронизировал мой сервер с внешним источником. Для этого я бы использовал команду W32tm.
Заметка: Для дополнительной информации относительно синхронизации источников времени ознакомьтесь с этой статьей на TechNet.
Следующая команда запускает W32tm и указывает удаленному серверу DC1 синхронизировать время с time.windows.com. Выходные данный свидетельствуют об успешности этой операции.
PS C:\> icm dc1 {w32tm /config /syncfromflags:manual /manualpeerlist:time.windows.com}
Заметка: Использование этой команды требует прав администратора.
После того, как я синхронизировал время сервера с внешним источником, я синхронизирую мой локальный компьютер с сервером.
PS C:\> w32tm /resync
Sending resync command to local computer
The command completed successfully.
После синхронизации сервера и моей рабочей станции, я еще раз воспользуюсь командлетом New-TimeSpan для определения разницы во времени.
PS C:\> new-timespan -Start (get-date) -end (icm dc1 {get-date})
Days : 0
Hours : 0
Minutes : 0
Seconds : 0
Milliseconds : -270
Ticks : -2707415
TotalDays : -3.13358217592593E-06
TotalHours : -7.52059722222222E-05
TotalMinutes : -0.00451235833333333
TotalSeconds : -0.2707415
TotalMilliseconds : -270.7415
Если я решу перепроверить настройки источника времени на сервере, я использую команду W32tm для запроса конфигурации.
icm dc1 {w32tm /query /configuration}
Автор:
Ed Wilson, Microsoft Scripting Guy
Оригинал:
Страницы в социальных сетях:
Twitter: https://twitter.com/vsseth
Facebook: https://fb.com/inpowershell
VKontakte: https://vk.com/inpowershell
для тех кто тоже натолкнется на эту статью, invoke-command -ComputerName dc1 -ScriptBlock {get-date} занимает очень много времени, быстрее сделать через net time \\ComputerName
В данном случае бОльшая часть времени (в среднем примерно полсекунды) уходит на создание удаленной сессии. Время, требуемое для выполнения самой команды, будь то Get-Date или net time, примерно одинаковое.
Поэтому, если нужно чтобы на выполнение самой команды Get-Date уходило как можно меньше времени, можно заранее создать сессию к удаленному компьютеру и указать ее в параметре -Session командлета Invoke-Command.
Замерить скорость выполнения можно так:
А самым важным тут является то, что net time возвращает текстовую строку. И если для обчного просмотра текущего времени на удаленном компьютере этого достаточно, то для разного рода манипуляций с полученной информацией, если не рассматривать регулярные выражения (а хотя даже если и рассматривать) — тут все немного сложнее.
Командлет Get-Date возвращает нам объект [DateTime], который мы можем преобразовать в тот вид, который нам в данный момент нужен, а также использовать в разного рода сравнениях с другими объектами даты и времени, чего текстовая строка, возвращаемая командой net time, нам сделать не позволит.
То есть команда:
вернет ошибку.
Для того, чтобы попытка сравнения увенчалась успехом, нам потребуется результат (а точнее, его часть) выполнения команды net time конвертировать в объект DateTime. Например, так: