BGIn-Place Upgrades


If (You Enjoy Reading)

I thought that was a clever title, but it seems more confusing the longer I look at it… anyway, this is the follow up post to take BGinfo from MDT, and add it’s capabilities to the ConfigMgr In-Place Upgrade Task Sequence Process.  If you’ve been working with in-place upgrade task sequences, you’ll know they are a different beast than regular OSD.  You can’t just call an application and expect it to show up on the screen.. like in OSD, you can say Command Line Step: notepad.exe… and guess what, a notepad.exe window opens during the TS.. freaking amazing!

In Place Upgrades also have new challenges we didn’t really have before with OSD.  OSD (bare metal) typically meant it was a clean image, we didn’t have end users sitting in front of it while installing the OS, didn’t have user profiles already full of “super precious data”, we really didn’t need to worry about the end user experience.  Now here comes Windows 10, Love it or love it, it’s here to stay, Windows as a Service, it means once OSD is done, that was the easy part, now we have to “touch” that computer every 6 months with a large upgrade.  Now we do have users to worry about, we have their precious little datas, and we have to deal with users who don’t read emails, and don’t read popups, and don’t read “ARE YOU SURE” dialog boxes, who just click “Sure” when something pops up, then freak out when it reboots 15 minutes later after they “consented” to an update.  And because they were working on large sales strategy document they only save on their desktop (Where else would you save business critical documents), and because the moon was full and the person sneezed in the cube adjacent, their document is now gone, or corrupted, or missing 4 days of edits!   Anyway, my point, we have the privilege of attempting to provide a decent user experience and making the process the most user friendly while still applying a huge upgrade that is ripping out the guts of the OS and dropping in the newer OS, with features they didn’t really request, and unknown stability with their current business apps.  But I digress…

Where was I going with that… oh yeah, ways to let the user know that hey “A BIG UPGRADE IS HAPPENING… SAVE YOUR STUFF”.  I’ve done this in the past with changing the Lock Screen, creating a method to prevent a user from logging on, but what if the user is logged in, they started the TS, but still just don’t get it… how about we temporarily change the background and put up a message that displays for that logged on user until the moment that beautiful first reboot happens?  I say, why not… lets do it.  My idea, steal MDT’s Bginfo “Set Status” Step, and add it to the In Place upgrade TS.  I copied  over the “Use MDT Tool Kit” Step, and “Set Status 2” Step, but when it ran that step in the TS… ERROR city.  Figured it was too easy. So this is what I had to do.



Assuming you followed the last blog, you’re most of the way there. (I’ve provided all of the files in the zip download, so you can steal those or create your own)

Your folder structure will look like this basically:

  • BGInfo64.exe – Download Here
  • vbs scripts – to be used for the custom fields
  • ServiceUI.exe – Take from MDTPackage\Tools\x64
  • BGI file(s) – Create new, or steal from MDT – Included in my download
  • Image file (.bmp) – Create new, or steal from MDT – Included in my download

Open your BGI File with BGInfo64 and add your fields and text (or modify the one I’ve provided)
imageNote, this will be different than the one we used for OSD, as this time, it is running in the OS, and not WinPE.
Set your Background, note, do not use the full path, just the name of the file, as all of the required files are located in the same directory.

Ok, the BGInfo part is done, feel free to press Preview and confirm it looks how you want, when you’re satisfied, save everything, and create your ConfigMgr package and distribute
Now that you have your package ready, its time to add it to the TS
Run Command Line Step

Basically, we’re stealing the logic from the ztiSetBackground.wsf file in MDT Scripts, and manually creating the command line:
"bginfo64.exe WinUpgradeGaryTown.BGI /nolicprompt /silent /timer:0"
But you’d quick learn, that doesn’t work… you need to use ServiceUI.exe to make it visible, which once you figure out that syntax, you get this:

Now add a condition that it only runs if it was user imitated.  no point in changing the background is no one is there to see it. 🙂
Also have seen this step failed if a user is NOT logged on.  So recommend you set to "Continue on Error" if you plan to have it run without checking to see if  a user is logged on, and run it without a user logged on.

TS Variable = _SMSTSUserStarted = True


Now, sit back and watch your TS give the user something they can’t avoid… unless their desktop is completely covered with files / icons…


BGinfo Updating MDT Default Templates

If you use MDT, then you’re familiar with their use of changing the background and adding system information during the OSD process.  This is pretty handy to get some basic info, but with a little tweaking, you can add additional data that can be very useful to make visible during OSD.

Basics, the required files used during this process are stored here: MDT Package\Tools\x64 & x86


It currently comes with old version of bginfo 4.20, the current version when writing this is 4.25.  I replace the ones that come bundled with the updated version. Download BGInfo

In the x86 folder is where the templates and images files are located.  This will also be the folder you add your custom .vbs files, but we’ll get to that later.

the .BGI files are the bginfo “database” files that contain the template information (layout, options, background choice).  The .BMP files are the images referenced in the .BGI files. The image files are 800x600, so they can look fuzzy on high-res screens. This image below is STEP_02.BMP (referenced by STEP_02.BGI) - Called during "Set Status 2" Step in a MDT enabled Task Sequence.

Bginfo then overlays additional information:
This image below is pretty close to the default, after adding 2 of the items Mike Terrill blogged about, and one additional Item based on a TS Variable.

Here is my current template after a few additional modifications, which I go into more detail below.

Following Mike’s blog, I added the BIOS Mode & Secure Boot Fields, as well as the Make & Model information (WQL Query), pulled directly from his post.  I then proceeded to add Processor Model & BIOS version, then several TS Variables.

Make sure you’ve downloaded the updated bginfo.exe files and place them into their corresponding MDT folders (x86 & x64).  Then on the x86 folder (even if on x64 machine), open bginfo.exe

At this point in the reading, you have hopefully stopped and read Mike’s blog, as I don’t want to completely plagiarize,  and this will be pretty similar.
(Sorry, the default fonts are hard to see against the default black background)

Once you launch the tool, go ahead and open STEP_02.BGI file in the x86 folder.

If you click on “Background” you’ll see the name of the background file that is associated with the template: Step_02.bmp, which is located in the same x86 folder, as shown in the earlier pictures.

At this point you can start to modify to get it how you like.  Mine now looks like this: (Keep reading, I’ll get to the Custom Fields)



I broke it into a few categories, WinPE info, which is the current OS when STEP_02 runs, so the commands are being run against the WinPE image.  This is why you get a MININT-XXXXXX computer name and no workgroup, as WinPE isn’t in your domain, and auto generates the computer name.

I then broke out hardware info about the physical machine into it’s own area, which includes additional built in options, and a few additional vbs scripts.

Finally, pulling in OSD information from the TS that is running.  To achieve this, in the TS, I write those items to the WinPE registry, so I can easily harvest it from bginfo.  Since it's written to the WinPE registry, it's only temporary, and you don't need to worry about cleaning it up later, it goes away after the reboot.

To add fields, click "Custom" right under the fields list.


Click New…


Choose the method to pull your info, in the example I’m using WMI Query to get the BIOS version.

Here are a few example WMI Queries: Note, WMIExplorer was really handy to dig around and find information that I wanted to display.


.VBS Files (must all be placed in the x86 folder, even if using x64, place them in the x86 folder)

NOTE, the .vbs files do not work if you try to run it from the command prompt, but they do work in bginfo.  If you want to test the scripts, replace echo with wscript.echo, then remove the wscript before using in bginfo.  Don't ask me, it's just the way it is.

Here are the .vbs scripts used.  I heard Mike will be updating the ones he posted, the ones below are the original.  They work fine in PE, and that was good enough for me, I don't need them to be fancy.  If you want to clean them up, be my guest, I basically found a template thanks to google and slightly modified to fit my needs.  Please don't judge me based on the beauty of the scripts I post.

BIOSMode (From Mike Terrill – UEFI or Legacy)

Drive (C: Drive Space)

SecureBoot (From Mike Terrill – Enabled or Not)

VolumeFree (C: Drive – Free Space)


Registry, these were keys I created during the TS by stamping TS Variables to Key Values.

These are stamped to the WinPE registry, as that is the OS running when this is displaying.  In my TS, I don’t have any additional BGinfo / Images display once it’s out of PE, after that’s it’s finishing the OSD with the windows setup black screen, so I only needed this info to display during the WinPE stage, which made writing it to the registry the perfect solution for my purposes.

The Variables are set using a FrontEnd or Collection Variables.  I use the Now Micro front end in my lab. Link HERE, scroll down to the FrontEnd Link.  The AD OU is a direct relation to the "Branch" Chosen and auto populated. In this front end, everything in the top area is auto generated based on Queries, or other imput, the only field that can be modifed is teh Computer Name, either leave the auto generated one, or modify for the deployment.  If doing a "Refresh" all of the variables are set on my collections, %OSDComputerName% is the name the computer already has,  so the settings (variables) would be reapplied automatically during a Reimage with no need for the front end.  This is just an example, basically you can put anything you want into BGInfo, just need to be a little creative.

Note, if you're creating variables and registry keys to use in BGInfo, I know this seems obvious, but make sure you run the steps to create the variables and keys before you run the step for BGInfo! (Set Status 2 - Which is a native MDT Step auto generated) The Step is calling the ztibackground.wsf file, which gathers information (architecture, etc) uses that to call the correct version of bginfo (x86 or x64) then pull the additional files (templates, Images, scripts) from the x86 folder, even on x64 machines.

Once you’ve added all of your Custom Fields, you can then add them into your bginfo template, and play around with that, it’s basically like working with wordpad from windows 95.

Once you have your desired layout, save the template and overwrite the default.  Then update the MDT Package in ConfigMgr.

Here is my Template File & VBS files, over write the ones in the x86 folder.

Coming up next, taking this and applying it to in-place upgrade.

Please comment with additional .vbs scripts or things you've found handy to add.  Feedback is always welcome.

Bitlocker on Hyper-V Virtual Machine

Update 2017.11.29 - Thanks to for the idea, I was able to get FDE working using a pass-through disk, see bottom of post for more info.

Short post to go over something I found while researching Bitlocker Full Disk Encryption on Hyper-V virtual machines.

I was testing Enabling Bitlocker during our Task Sequence, and I didn’t have any physical machines to test on, no problem right?  With Hyper-V, you can now enable virtual TPM on Gen2 VMs, and have all the yummy goodness of UEFI, Secureboot, Bitlocker, Credential Guard all on your VM!  So I started testing, everything worked!  But when I checked the Bitlocker Status (manage-bde –status), it showed I was only encrypting Used Space.  While this would be fine for a Virtual Machine, I was confused because I told it to use Full Disk, NOT used space.  I ran many tests, trying several different things, but in the end, it never came out as I expected, with Full Disk.  Even post OSD, if I decrypted, ensured policy was set for Full Disk, it would only encrypt Used Space.  Finally, I gained access to a physical test machine, ran the exact same Task Sequence, and there it was, Full Disk Encryption. – Testing done on Hosts: Win 10 1607, 1709 & Server 2016.  VM’s running 1703 and 1709. Security settings were set to Enable Secure Boot & Enable TPM, tested Dynamic expanding & fixed disks. (Not Pass-through)

To Summarize.

  • Hyper-V Virtual Machine = Used Space Encryption only with Bitlocker *Unless you can use a pass-though disk.
    • This is by Microsoft Design, Bitlocker is “Hyper-V Aware” and will only run in Used Space only mode, even if your policy is set for Full Disk
    • Remember to eject your ISO you booted from before the Bitlocker steps, or it will error
  • If you need to test your Full Disk Encryption OSD settings, do it on a physical machine. - Below I have two screen captures side by side.  Left side = Physical Machine & right side = VM on that Physical Machine.  Both machines ran same TS telling it to use FDE, but only the Physical machine actually used FDE.

How do you change your TS from doing Used Space to Doing Full Disk?

  • Disable the Pre-Provision Bitlocker Steps
  • Add Registry key to set Full Disk Encryption before “Enable Bitlocker” Step.
  • Set “Enable-Bitlocker” step to Continue on Error
    • This will set several policies settings, like save the key to AD, and which way you want to deploy bitlocker (TPM only, etc)
  • Add Additional Manage-Bde Step: manage-bde -on C: -RecoveryPassword

Here are the details for the steps in my TS, as you can see, I also set it to use XTS AES 256 (except for flash media, which I use older type so it's more backwards compatible with other Windows computers)



2017.11.29 - Getting FDE to work using Pass-Though

Using an Offline Disk on the Host, and setting that as the drive on the VM, FDE works.


Thanks Paul, can now test FDE on VM!

Clean Up Storage Pre Upgrade

Just another group of tasks to add to your arsenal.  We run a Check Readiness step before our upgrades, with a minimum of 20GB Free. We have many clients that do not meet this minimum requirement and fail, and then have to remediate. While we have long term plans to automate much of this, and prevent the Task sequence from ever running on machines that don’t reach these pre-reqs, for now, a Band-Aid.


Step Breakdown “Storage Cleanup” Group
Run only if FreeSpace < 20GB

This same query is placed on several steps.  If the step that is cleaning up is successful at getting FreeSpace above 20GB, then lets continue on.  Otherwise, the last step that will run if still under 20GB is the restart, to help flush things from the previous steps.

  1. Cleanup User Temp Folders
  2. Cleanup c:\Windows\Temp
  3. Delete user Profiles over X Days inactive

    This requires that the delprof2.exe file from Helge Klein's site. (It is in the download, as I have permission to redistribute it)
    You can change the day to any number you want and run this steps as many times as you want.  My idea was that I would start at a high number, then slowly lower it, 360, 180, 90, 60, 45, 30, 20,15,10,5, and have the wmi query on it, so as soon as it dumped enough old profiles, to get 20GB Free, it could continue on leaving newer profiles.  The script also looks up the top console user, and excludes that from the deletions, so even if the primary user hasn't logged in for awhile (on leave), it won't delete that profile (as long as it's still the top console user, and not some tech's account).  This is a powerful step, be careful with it, as you could accidentally remove a profile you didn't want to. If you have some profiles you don't ever want to delete, you can exclude them by adding an /ed:user in the script (look to Helge's documentation for more info).
  4. Cleanup WinSXS folder
  5. CleanMgr – All Options
    This was borrowed directly from stealthpuppy.  I had written something, but then found this and it was just easier to use this.
  6. Restart Computer
    The restart only happens if there still isn't 20GB Free Space.This will be added to the Task Sequence Module Download HERE.

ConfigMgr Task Sequence Collection

This is my "Clip Show" blog post, but hopefully you still find it useful.

I've been building out a Task Sequence that is just a collection of Task Sequence sections, or handy steps.  I'll use this TS to pull sections from when I create new Task Sequences, and add / modify as I test in "Real" deployment Task Sequences. DOWNLOAD HERE *Note, this is not an actual Deployment TS, it's meant to be imported and then have parts copied into your own TS.  All content, including some not used directly in this TS is included.

I have several sections, also a few handy steps for pause, wait, copying CMTrace local, and so on.  Many of these are borrowed from great community leaders such as Mike Terrill, Jason Sandys, Jörgen Nilsson, Mark Godfrey, and others (Sorry if I missed anyone)

  • Power Settings, CCMEXEC Change & Revert - This section will grab your current power settings, place in variable, set system to high performance, then restore them at the end of your TS.  It also has steps for changing the CCMEXEC service to auto start, instead of delayed, and back.
  • Upgrade Lockscreen - This section will change your lockscreen, designed for the Win10 In place upgrades.
  • User Lockouts - This section will use local group policy to block any users, either via AD Group, or users from local machine
  • AutoLogon - This adds account and keys for auto logon (for testing in lab)
  • Enable Mouse Support - This will enable the mouse cursor in the Windows 10 TS after WinPE steps are complete.
  • Windows 10 Tweaks - Several sub-sections of Customization gathered over the past years, many demo'd @ MMS2017

Power Settings info:


CCMExec Sevice to Auto & Back:


Upgrade LockScreen & User Lockout :
I’ve made a few modifications since the post about this, moving the cleanup to a scheduled tasks, that will run during the upgrade deleting the Lock Screen images / Keys & cleaning up the Locked Out users, so users can log back in after.  It will also clean up the scheduled tasks.  I’ve left in the steps for you to add after the upgrade to do clean up as well, leaving you many options on how to implement this idea.  Each step has detailed notes in the descriptions.



Nothing changed from the blog post, just a reminder, don’t do this in production.


Enable Mouse Support:
or Microsoft's Official Post 13 days later:


Reset (Disable)


Windows 10 Customizations / Tweaks


Most of this section is straight from MMS:
Windows 10 Features, enable or disable some “features” in win10
OEM Info, allows you to set the information that is displayed in “System”
Explorer Tweaks – Covers things that modify things displayed on Desktop or Explorer


Group Branding includes changing the Lock Screen, Wall Papers, User Icons, Start Menu
Default Profile are tweaks that apply only at the user level, so these are added to the default profile.


Remove Default Apps, either a script to remove everything (That is specified in the script, not actually everything) at once, or a line by line option to be granular.