Назад | Перейти на главную страницу

Последующие вызовы WMIC возвращают localdatetime с другим часовым поясом.

Эта проблема

В нашей компании мы используем несколько командных файлов, которые используют 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 на время последней перезагрузки с помощью сценария, который запускается при запуске, также поможет избежать проблемы.