function Get-NtpTime { # A function that sends UDP packets to NTP server # via IPv4 or IPv6 to obtain the precise time. # # return: datetime (based local timezone) # $null (no server or something went wrong) param([string]$NtpServer) try { # NTP packet (48 bytes) $ntpData = New-Object byte[] 48 $ntpData[0] = 0x1B # Send to ntp server via 123/UDP $addresses = [System.Net.Dns]::GetHostAddresses($NtpServer) $udpClient = $null foreach ($addr in $addresses) { try { $udpClient = New-Object System.Net.Sockets.UdpClient($addr.AddressFamily) $endpoint = New-Object System.Net.IPEndPoint($addr, 123) $udpClient.Connect($endpoint) # Received a response [void]$udpClient.Send($ntpData, $ntpData.Length) $udpClient.Client.ReceiveTimeout = 1500 $response = $udpClient.Receive([ref]$endpoint) if ($response) { $udpClient.Close() break } } catch { $udpClient.Close() $udpClient = $null } } if (-not $udpClient) { return $null } # NTP timestamps are stored in bytes 40-47 (based on January 1, 1900) $intPart = [BitConverter]::ToUInt32(($response[43..40]), 0) $fracPart = [BitConverter]::ToUInt32(($response[47..44]), 0) $ms = ($fracPart * 1000) / 0x100000000 $secondsSince1900 = $intPart $unixEpochOffset = 2208988800 $unixSeconds = $secondsSince1900 - $unixEpochOffset $dateTime = (Get-Date "1970-01-01T00:00:00Z").AddSeconds($unixSeconds).AddMilliseconds($ms) return $dateTime.ToLocalTime() } catch { return $null } } # End of function Get-NtpTime $vmname = "###YOUR VM NAME###" $password = ConvertTo-SecureString "###USERS PASSWORD###" -AsPlainText -Force $username = "###COMPUTERNAME(or DOMAIN)\USERNAME###" $cred = New-Object System.Management.Automation.PSCredential($username , $password) $ntpserver = "ntp.nict.jp" # Check Hyper-V module Import-Module Hyper-V -ErrorAction SilentlyContinue if (!(Get-Command Get-VM -ErrorAction SilentlyContinue)) { return "Error: no hyper-v role or hyper-v cmdlet." } # Check VM status is running $vmstatus = Get-VM -Name $vmname -ErrorAction SilentlyContinue if ($vmstatus -eq $null) { return "Error: no such vm." } elseif ($vmstatus.State -ne "Running") { return 0 # vm state not running } $baseTime = Get-NtpTime -NtpServer $ntpserver if ($basetime) { # Write-Host "$($basetime) is get from $($ntpserver)" } else { $basetime = Get-Date # Write-Host "$($basetime) is get from local pc time" } $vmTime = Invoke-Command -VMName $vmname -ScriptBlock {Get-Date} -Credential $cred -ErrorAction SilentlyContinue if ($vmTime) { $diff = $baseTime - $vmTime return [int][Math]::Abs($diff.TotalSeconds) } else { retnrn "Error: could not get time from vm." }