Closed utterances-bot closed 2 years ago
How do you get around challenges of finding Tz for devices built OnPrem?
I don't. This is a "best efforts" approach. Hopefully a device connected to an onPrem network would still get an external IP that was delegated somewhat close to their actual location.
With newer PowerShell versions based on .NET 6, you can do a native lookup of the IANA time zone ID without having your own lookup table which is pretty neat.
Can't post a picture here, but calling [System.TimeZoneInfo]::FindSystemTimeZoneById('Australia/Sydney')
in PowerShell 7.2.x will give you the goods.
Awesome find @mjr4077au I'll definitely check that out
I received a lot of external help for this, but some managed code you can add to PowerShell 5.1 to use icu.dll to convert out an IANA time zone to Windows.
This was heavily inspired by Raymond Chen's sample C code from here as a proof of concept: https://devblogs.microsoft.com/oldnewthing/20210527-00/?p=105255
This could work really nicely in combination with your excellent suggestion of ipinfo.io via a proactive remediation script, something that I'll possibly play around with tomorrow.
$cp = [System.CodeDom.Compiler.CompilerParameters]::new()
$cp.CompilerOptions = '/unsafe'
Add-Type -CompilerParameters $cp -Namespace ICU -Name TimeZoneConverter -MemberDefinition '
[DllImport("icu", ExactSpelling = true, CharSet = CharSet.Unicode)]
private static unsafe extern int ucal_getWindowsTimeZoneID(ushort* id, int len, ushort* winid, int winidCapacity, int* status);
[DllImport("icu", ExactSpelling = true, CharSet = CharSet.Unicode)]
private static unsafe extern int ucal_getTimeZoneIDForWindowsID(ushort* winid, int len, IntPtr region, ushort* id, int idCapacity, int* status);
private const int bufsize = 256;
public static unsafe string IANAtoWindows(string id)
{
fixed (char* pId = id)
{
int status = 0;
var buffer = stackalloc ushort[bufsize];
var length = ucal_getWindowsTimeZoneID((ushort*)pId, id.Length, buffer, bufsize, &status);
var outstr = Marshal.PtrToStringUni((IntPtr)buffer, length);
return !String.IsNullOrWhiteSpace(outstr) ? outstr : null;
}
}
public static unsafe string WindowsToIANA(string winid, string region)
{
fixed (char* pWinId = winid)
{
int status = 0;
var buffer = stackalloc ushort[bufsize];
var regptr = Marshal.StringToHGlobalAnsi(region);
var length = ucal_getTimeZoneIDForWindowsID((ushort*)pWinId, winid.Length, regptr, buffer, bufsize, &status);
var outstr = Marshal.PtrToStringUni((IntPtr)buffer, length);
Marshal.FreeHGlobal(regptr);
return !String.IsNullOrWhiteSpace(outstr) ? outstr : null;
}
}
'
PS C:\Users\username> [ICU.TimeZoneConverter]::IANAtoWindows('Australia/Sydney')
AUS Eastern Standard Time
PS C:\Users\username> [ICU.TimeZoneConverter]::WindowsToIANA('AUS Eastern Standard Time','AU')
Australia/Sydney
I was hoping that this would be the remedy to my time zone issues. Alas, I've discovered that even the GPS module is reporting the wrong information and that's likely what's throwing off the time zone in the first place. Unfortunately do to us using a web filter/proxy, the IP method wouldn't work either.
i'm trying to do to set country but have trouble convert from country to geoid. could you help me please?
Dynamically set the time zone of a device in Intune using Azure Maps & PowerShell | Powers Hell
Let me start off by saying I wish I didn’t have to write this post. Setting the correct time zone of a Windows device shouldn’t be this difficult, especially with all of the management possibilities provided to us with Intune and the entire endpoint management stack. But here we are!
https://powers-hell.com/2020/08/31/setting-the-time-zone-of-an-intune-managed-device-using-azure-maps-powershell/