Windows VM time not updated after hibernate/resume

Here is my version with a wait loop for the guest agent service.

Bash:
#! /usr/bin/bash

vmid="$1"
phase="$2"
vmconf="/etc/pve/qemu-server/$vmid.conf"

if [[ "$phase" == "post-start" ]]; then
    # waiting for vm guest service to start
    started="false"
    loopstart=$EPOCHSECONDS
    while [[ "$started" == "false" ]]; do
        qm guest cmd $vmid ping && started="true"
        if [[ "$started" == "false" ]]; then
            sleep 2
        fi
        if (( EPOCHSECONDS-loopstart > 60 )); then
            echo "timeout for vm guest service start"
            break
        fi
    done

    # sync VM time after resume or start
    if [[ "$started" == "true" ]]; then
        if grep -q "ostype: win" $vmconf; then
            newdate=$(date +"%d-%m-%y")
            newtime=$(date +"%H:%M")
            echo "resync windows time"
            qm guest exec $vmid "cmd" "/c net stop W32Time & date $newdate & time $newtime & net start W32Time & w32tm /resync /nowait"
        else
            echo "resync linux time"
            echo '{"execute":"guest-set-time"}' | socat stdin unix-connect:"/var/run/qemu-server/$vmid".qga
        fi
    else
        echo "vm guest service not running"
        exit 1
    fi
 
  • Like
Reactions: _gabriel
Here is my version with a wait loop for the guest agent service.

Thanks, sadly when we resync, it resync to the bios time (at the time of hibernate) and not the correct external time server
So maybe the best option is without the resync

For time, we can set the second, here is my current version :


Bash:
    #wait for qemu guest agent to be available
    loopstart=$EPOCHSECONDS
    while ! qm guest cmd $vmid ping; do
        (( EPOCHSECONDS - loopstart > 10 )) && exit 0
        sleep 1
    done

    if grep -q "ostype: win10" "$file"; then
        echo "## Resync windows time ##"
        date=$(date +"%d-%m-%y")
        time=$(date +"%H:%M:%S")
        qm guest exec $vmid "cmd" "/c net stop W32Time & date $date & time $time & net start W32Time " || true
    else
        echo "## Resync Linux time ##"
        qm guest exec "$vmid" "service" "systemd-timesyncd" "restart" || true
    fi
 
Last edited:
I had some other problems if the timediff was too big, "The computer did not resync because the required time change was too big."
I fiddled around with the reg key MaxNegPhaseCorrection, MaxPosPhaseCorrection and LastKnownGoodTime (
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\w32time\Config).
But in the end it worked best if i unregister and register the w32tm configuration.

My windows server vm is domain joined.
I would not recommend this workaround for production use, but i would also not recommend to save production servers memory state to disk.

Code:
qm guest exec $vmid "cmd" "/c net stop W32Time & date $newdate & time $newtime & w32tm /unregister & w32tm /register & net start W32Time & w32tm /resync /rediscover /nowait"
 

About

The Proxmox community has been around for many years and offers help and support for Proxmox VE, Proxmox Backup Server, and Proxmox Mail Gateway.
We think our community is one of the best thanks to people like you!

Get your subscription!

The Proxmox team works very hard to make sure you are running the best software and getting stable updates and security enhancements, as well as quick enterprise support. Tens of thousands of happy customers have a Proxmox subscription. Get yours easily in our online shop.

Buy now!