Configuring Windows 10 defaults via Windows Autopilot using an MSI
Published Apr 16 2019 10:00 AM 46K Views
Microsoft

Windows Autopilot moves customers away from custom imaging and driver management, instead leveraging Microsoft Intune to transform a device into one that is ready for productive use. Intune supports a lot of different policies that can be used to configure the device, but in many cases there aren't any policies that enable configuring defaults.  For example, what if you wanted to configure the Start menu layout, but wanted the user to be able to change any part of it?

 

Most of these types of customizations can be done via scripts, similar to the way that you did them when you were building custom images.  But instead of baking them into the image, you now need to apply them to the device "just in time" - typically before a user signs on for the first time.  With Windows Autopilot, we can leverage the Enrollment Status Page (ESP) to ensure that these machine configurations are made before the user signs in.  But those capabilities vary by OS release:

 

  • Windows 10, version 1803 and above can leverage the ESP to block user login until all policies, certs, and device-targeted single-file MSIs (LOB apps) have been processed.
  • Windows 10, version 1809 and above adds the ability to block until Office 365 ProPlus has been installed.
  • Windows 10, version 1903 and above will have the ability to block util Win32 apps (installed by the Intune Management Extensions) and PowerShell scripts have been installed or processed.

So, you could just leverage PowerShell script to do the configuration steps that are necessary - but since few of you are deploying Windows 10, version 1903 broadly yet (not surprising, as it's not yet released), that would be rather limiting.

 

To do this in a way that works with Windows 10, version 1803 and above, you can take the same PowerShell script logic and embed it into a Windows Installer MSI; that MSI can then be targeted to a group of devices (e.g. All Autopilot Devices).  As long as you have enabled ESP and configured it to be blocking, this MSI install will complete before the user signs in.

 

Since I suspect quite a few of you have never created a "hand-crafted" MSI with an embedded PowerShell script, I thought it would be useful to publish an example.  You can find that example here:

 

https://github.com/mtniehaus/AutopilotBranding

 

Included in that example is a PowerShell script that performs the following customizations:

 

  • Customize start menu layout. By default it will apply a simple two-icon layout (similiar to the default one on Windows 10, version 1903, but without the Office app).
  • Configure background image. A custom theme is deployed with a background image; the default user profile is then configured to use this theme. (Note that this won't work if the user is enabled for Enterprise State Roaming and has previously configured a background image.)
  • Set time zone. The time zone will be set to the specified time zone name (Pacific Standard Time by default).
  • Remove in-box provisioned apps. A list of in-box provisioned apps will be removed.
  • Install updated OneDrive client per-machine. To support the latest OneDrive features, the client will be updated and installed per-machine (instead of the per-user default).
  • Disable the Microsoft Edge desktop icon. When using OneDrive Known Folder Move, this can cause duplicate (and unnecessary) shortcuts to be synced.

Feel free to download this from GitHub, customize it as you see fit, and then build your own custom MSI that can be deployed via Intune.  The necessary instructions for creating (building) the MSI are included in the GitHub repository.

 

If you can think of additional customizations that would be useful, feel free to send them to me via e-mail (mniehaus@microsoft.com), on Twitter (@mniehaus), or via GitHub (submit a new issue).  If you want to make some changes yourself, create your own fork and feel free to submit pull requests to have those changes integrated (as long as they are supportable).

15 Comments
Copper Contributor

This is excellent info, excited about 1903 waiting for win32 and powershell scripts to run at the ESP, that could make things really nice.

 

On the topic of the time zone, we're trying to find out how to automatically set this based on the location the autopilot process ran at.  It's all good setting all machines to a static time zone, but when machines are globally in different time zones, trying to figure out how to set this.  I tried enabling the 'Set time zone automatically' feature using a registry edit, and it does enable this but it doesn't seem to process the automatic setting of the time zone until the computer is restarted.  It also blocks the user from manually setting the time zone after that registry edit is set. 

 

Could be great if either the actual Windows 10 OOBE would specify a time zone (maybe even automatically select one based on location, show that to the user and let the user change it to what they want during OOBE).  Or if there's a way to set the registry entry to enable 'set time zone automatically' followed by some powershell command that forces the finding of the time zone automatically right on the spot.  

 

MDT was a bit easier in this regard, I just had the machine sync its time zone based on the server it used to image from.  :) 

Copper Contributor

@Mike McConnell You should be able to script the Time zone piece fairly easily using data from - https://ipstack.com/ to query your egress IP address and match the time zone to it.

 

I like the idea of doing this automatically and not relying on the built in Windows feature as I found that for some devices this doesn't want to work on startup and I ended up on a recent deployment setting this via a PS script that run after the build had completed.

 

Going to have a look at if I can script this to match the egress IP to a time zone that is aligned to the variables in Win10 and write that up. Then just need to work out how to add something to GitHub :)

Copper Contributor

@MattWhite That is a very interesting proposition.  I believe I could do that to address the issue for the time being.  

Copper Contributor

@Mike McConnellthink I have a first draft hacked together - will share shortly

Copper Contributor

@Mike McConnell Script is available on my blog - https://matthewjwhite.co.uk/2019/04/18/intune-automatically-set-timezone-on-new-device-build/

 

Tested and appears to execute as expected however YMMV

 

 

Copper Contributor

@MattWhite This is really cool.  Wasn't aware there was an API for Bing, though my lookup for the coordinates, while it reports as successful, never seems to return a value for '$TimeZone.resourceSets.resources.timeZone.windowsTimeZoneId' for my current location.  

I was able to get something working in a more simplified manner (with also some more manual effort) by getting the timezone field from http://ip-api.com/ and doing basic powershell if commands to change the output to something the set-timezone command uses.  Figured it out for most of the locations I'm worried about though your method is more dynamic.  I'll need to figure out why it's not getting the output that is expected.

 

Thank you!

Copper Contributor

@Mike McConnell can you sendnthe output file from the profram data folder to see what happened?

Copper Contributor

@MattWhite After running it through again it actually did work, it does seem to be working now, pretty cool.

My initial attempt didn't really give an error during the rest query, it returned status code 200 but '$TimeZone.resourceSets.resources.timeZone.windowsTimeZoneId' was blank.  Now it is populating and is working consistently.  Really cool script!

Copper Contributor

May just have been the api taking time to kick in possibly. 

 

I haven't done extensive testing but seems to do the things it should do, I may add some logic to make sure that it detects the timezone and is valid before trying to make the change.

 

Glad it's working though

Copper Contributor

Fantastic article! I really need to figure out how to use WiX Toolset. I was able to modify your Branding.ps1 script to include more modifications to HKLM and NTUSER.DAT

 

Write-Host "Setting Registry Settings"
reg.exe add "HKLM\SOFTWARE\Policies\Microsoft\Windows\CloudContents" /V DisableWindowsConsumerFeatures /T REG_DWORD /D 1 /f | Out-Host
reg.exe add "HKLM\SOFTWARE\Policies\Microsoft\Internet Explorer\Main" /V DisableFirstRunCustomize /T REG_DWORD /D 1 /f | Out-Host
reg.exe add "HKLM\SOFTWARE\Policies\Microsoft\Windows\Personalization" /V LockScreenImage /T REG_EXPAND_SZ /D "%SystemRoot%\Web\Screen\[removed]BG.jpg" /f | Out-Host
reg.exe add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters" /V AllowEncryptionOracle /T REG_DWORD /D 2 /f | Out-Host
reg.exe add "HKLM\SOFTWARE\Policies\Microsoft\OneDrive" /V SilentAccountConfig /T REG_DWORD /D 1 /f | Out-Host
reg.exe add "HKLM\SOFTWARE\Policies\Microsoft\OneDrive" /V KFMSilentOptIn /T REG_SZ /D [removed] /f | Out-Host
reg.exe add "HKLM\SOFTWARE\Policies\Microsoft\OneDrive" /V KFMSilentOptInWithNotification /T REG_DWORD /D 0 /f | Out-Host
reg.exe add "HKLM\SOFTWARE\Policies\Microsoft\OneDrive" /V FilesOnDemandEnabled /T REG_DWORD /D 1 /f | Out-Host
reg.exe load HKLM\TempUser "C:\Users\Default\NTUSER.DAT" | Out-Host
reg.exe add "HKLM\TempUser\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" /v MapDrive /t REG_EXPAND_SZ /d "PowerShell.exe -ExecutionPolicy Bypass -windowstyle hidden -command C:\ProgramData\[removed]\MapDrive.ps1" /f | Out-Host
reg.exe add "HKLM\TempUser\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes" /v InstallTheme /t REG_EXPAND_SZ /d "%SystemRoot%\resources\OEM Themes\Autopilot.theme" /f | Out-Host
reg.exe add "HKLM\TempUser\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\People" /v PeopleBand /t REG_DWORD /d 0 /f | Out-Host
reg.exe add "HKLM\TempUser\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v LaunchTo /t REG_DWORD /d 1 /f | Out-Host
reg.exe add "HKLM\TempUser\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer" /v ShowFrequent /t REG_DWORD /d 0 /f | Out-Host
reg.exe add "HKLM\TempUser\SOFTWARE\Microsoft\Windows\CurrentVersion\Search" /v SearchboxTaskbarMode /t REG_DWORD /d 1 /f | Out-Host
reg.exe add "HKLM\TempUser\SOFTWARE\Microsoft\Windows\CurrentVersion\Ext\Settings\{31D09BA0-12F5-4CCE-BE8A-2923E76605DA}" /v Flags /t REG_DWORD /d 1 /f | Out-Host
reg.exe add "HKLM\TempUser\Control Panel\Desktop" /v LogPixels /t REG_DWORD /d 96 /f | Out-Host
reg.exe add "HKLM\TempUser\Control Panel\Desktop" /v Win8DpiScaling /t REG_DWORD /d 1 /f | Out-Host
reg.exe unload HKLM\TempUser | Out-Host

The OneDrive updater portion is brilliant. I'll be using that again!

 

Because I'm not familiar with WiX, I have to XCOPY files using a Win32 app, targeting the machine. This includes a logon script (mapped drives) and a folder containing the images for the desktop slideshow.

Copper Contributor
Any word on this being available to download for preview / beta? I looked in our VL center and doesn't seem available to download, only lists about 3 versions of 1809 last one updated March 2019
Copper Contributor

Thanks for creating this.  Very impressive.  What if we only want to use some aspects of it, ie: I don't want to change the background or Start menu Layout but I do want to invoke the UWP app removal, etc.

Copper Contributor

@MattWhite I have been doing your proposition for a quite some time but the real struggle is to find an accurate IP Geolocation API, I have tried you suggestion ipstack and the other one in the comments ip-api but when I test it with VPN the accuracy is bad high are the chances to end up with different time zone. I will try another services maybe 3rd time is the charm, I am thinking of trying https://www.abstractapi.com/ip-geolocation-api do you have any experience with it? or if you have any other suggestion I'm all ears.

Copper Contributor

Hi @Michael Niehaus thanks for your work.
I'm trying to cusotmize the theme deploy during autopilot but our theme is a *.deskthemepack file instead a *.theme.
With that package theme isn't applied

 

I've tried adding an invoke command:

 

$Windows10Theme = "C:\Windows\Resources\OEMThemes\RED.deskthemepack"
Invoke-Expression $Windows10Theme

 

but this doesn't work during autopilot, works instead with OS already started.

 

Copper Contributor

@Zoki303 this seems to be a good alternative to abstractapi.com: https://ipbase.com/products/ip-geolocation-api/ - they offer a free plan and provide with an easy-to-understand playground. 

Version history
Last update:
‎Apr 16 2019 10:56 AM
Updated by: