Changing Azure VM’s Default Locale

I had a task at work where I was asked if I could ensure that all new Azure Virtual Machines created had the default of being set up for English (United Kingdom) rather than English (United States), not an unreasonable request by any stretch, so last week I had a look into doing just that.

The customer project I am working on uses Virtual Machines for people to do their work and the new Virtual Machines are deployed using Octopus Deploy with some ARM templates and PowerShell – all good so far.

My initial thought was I wonder why you can’t have this as an option to choose when installing a new Virtual Machine from the portal, turns out its unlikely because in fact there are a number of settings you need to change in order for the new Virtual Machine to truly be set up for English (United Kingdom) rather than English (United States).

I started off by looking at running some PowerShell into a custom extension and running that when the Virtual Machine starts, after a lot of fiddling around and trying things it does work.

The PowerShell I was using looked something like this:-

Set-WinSystemLocale en-GB
Set-WinUserLanguageList -LanguageList en-GB -Force
Set-Culture -CultureInfo en-GB
Set-WinHomeLocation -GeoId 242
Set-TimeZone "GMT Standard Time"

# restart virtual machine to apply regional settings to current user. You could also do a logoff and login.
Start-sleep -Seconds 40

Note that the above PowerShell works, the only caveat to this is that once the Virtual Machine is available to connect to you can check the system local from

Control Panel > Clock and Region > Region > Administrative Tab >

Above, we can see that the Virtual Machine still defaults to English (United States) but with a reboot that will change to English (United Kingdom).

We want this to be the case for all users who might log onto the Virtual Machine, we could use PowerShell DSC (desired state config) to do this or a number of other ways.

When I reached out to twitter for some help and guidance on this I had a number of replies but this one was the solution I went for

Stuart was very kind to even create a GitHub repo to tackle this issue and you can find his solution to the problem there, he adds a custom script variable, passes in the commands to run and a timezone variable and “it’s basically using a combination of stuffing your script into customdata and having additionalUnattendContent run that script in a first logon.

To wrap this up it works: –

  • using PowerShell
  • using a custom extension with a PowerShell script
  • or by adding content to an Arm Template that runs a script upon user logon