В нашей компании мы используем несколько командных файлов, которые используют WMIC для получения текущего времени. Обычно для печати в файлах журнала, но также для включения отметки времени в имени файла.
Начиная с Windows 10 - мы не помним, чтобы наблюдали такое поведение в Windows 7 - мы заметили, что некоторые из наших анализаторов файлов журнала (они создают хорошие графики для оценки), казалось, рисовали странные вещи. После некоторого исследования мы обнаружили, что для коротких периодов времени вызов WMIC возвращает другую метку времени .
Вот как мы называем WMIC и что он возвращает.
C:\> WMIC.exe OS Get localdatetime /value
LocalDateTime=20191114112607.134000+060
Теперь мы провели эксперимент и вызывали WMIC каждую секунду в течение большего периода времени. Вот выдержка из полученных временных меток:
20191114112607.134000+060
20191114122608.394000+120
20191114122609.687000+120
[...]
20191114123105.161000+120
20191114123106.431000+120
20191114113107.672000+060
Мы живем в регионе в часовом поясе MEZ, то есть UTC + 1. Вот почему мы ожидаем отметки времени с указанием +060
минут. Мы также не ожидаем, что это изменится, кроме случаев, когда два раза в год, то есть когда летнее время переключается на MESZ (UTC + 2) и наоборот.
Как вы можете видеть на временных метках выше: почти ровно 5 минут WMIC возвращает временную метку +120
.
Я также записал в журнал вывод некоторых других вызовов, чтобы проверить, является ли это глобальной проблемой Windows или, скорее, поведением wmic. Все вроде как (глючит?) Поведение WMIC.
Все функции / программы и даже другой вызов WMIC вернули ожидаемое время. Это мой сценарий
while ($true) {
Get-Date -Format G
Get-TimeZone
$timeservers | ForEach-Object {
$server = $_
w32tm.exe /stripchart /computer:$server /dataonly /samples:1 | Out-Default
}
cmd.exe /c date /T | Out-Default
cmd.exe /c time /T | Out-Default
WMIC.exe Path Win32_LocalTime Get /Format:value | Out-Default
# All 'correct' except:
WMIC.exe OS Get localdatetime /value | Out-Default
Start-Sleep -Seconds 1
}
. Результат выполнения сценария выше показывает, что только вызов OS Get localdatetime
возвращает «неправильную» метку времени.Мы поискали в журнале событий системы и приложений записи, которые могли бы рассказать нам, почему это происходит, но никаких записей в журнале не было. Я также проверил планировщик заданий, не было ли запланировано какое-то действие, когда это произойдет, но ничего.
Информация о часовом поясе в реестре
C:\>reg query HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation
Bias REG_DWORD 0xffffffc4
DaylightBias REG_DWORD 0xffffffc4
DaylightName REG_SZ @tzres.dll,-321
DaylightStart REG_BINARY 00000300050002000000000000000000
DynamicDaylightTimeDisabled REG_DWORD 0x0
StandardBias REG_DWORD 0x0
StandardName REG_SZ @tzres.dll,-322
StandardStart REG_BINARY 00000A00050003000000000000000000
TimeZoneKeyName REG_SZ W. Europe Standard Time
ActiveTimeBias REG_DWORD 0xffffffc4
Теперь это известная ошибка Windows.
Внутри есть глобальная переменная, которая кэширует смещение DST, которое сохраняет свое значение в течение 5 минут. Через 5 минут значение исчезнет, и местное время будет скачкообразным.
Эта логика использовалась в RS5/1809, но не использовалась в 19H1 или в Windows Server 2012 R2.
Обходные пути:
Загружайте машины достаточно часто, чтобы LocalDateTime и LastBootUpTime не могли оказаться с разными часовыми поясами, когда машина работает в течение длительного времени.
Установка InstallDate на время последней перезагрузки с помощью сценария, который запуски при запуске также должны избегать проблемы