對 WMIC 的後續呼叫會返回帶有偏離時區的本地日期時間
問題
在我們的公司環境中,我們使用了幾個使用 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
問題
- 有人可以解釋這種行為嗎?
- 什麼會影響 WMIC 的結果?
- 你會認為這是一種錯誤嗎?
- 可以做哪些其他分析來縮小範圍?
這現在是一個已知的 Windows 錯誤。
在內部有一個全域變數記憶體 DST 偏移量,該偏移量將其值保持 5 分鐘。5 分鐘後,該值消失,讓您的當地時間跳躍。
此邏輯用於 RS5/1809,但未用於 19H1 或 Windows Server 2012 R2。
解決方法:
- 足夠頻繁地引導機器,以便在機器執行較長時間時 LocalDateTime 和 LastBootUpTime 不會以不同的時區結束
- 使用在啟動時執行的腳本將 InstallDate 設置為上次重新啟動的時間也應該可以避免該問題