Configuration Manager Dynamic Drivers & BIOS Management with Total Control Part 2

In Configuration Manager Dynamic Drivers & BIOS Management with Total Control Part 1, I talked about the requirements for the various scenarios when coming up with a solution for driver and BIOS management. I also gave a glimpse of what the Task Sequence steps look like once the solution is in place. In Part 2, I am going to show what it takes to get the solution step up and running (at first glance it looks complicated, but it is actually pretty easy, especially if you download the templates below).

Video summary:

Before getting started, there are a few assumptions:
1. Configuration Manager is already running Current Branch
2. Windows ADK is Windows 10 Creators Update (1703) (required for MBR2GPT)
3. Microsoft Deployment Toolkit (MDT) 8443 is integrated with Configuration Manager
4. A MDT Toolkit package is available in Configuration Manager
5. A MDT database is setup and configured

If you do not already have MDT installed and configured, please see this excellent guide at windows-noob.com (just make sure to use the MDT 8443 release): How can I deploy Windows 10 with MDT 2013 Update 2 integrated with System Center Configuration Manager (Current Branch): https://www.windows-noob.com/forums/topic/14057-how-can-i-deploy-windows-10-with-mdt-2013-update-2-integrated-with-system-center-configuration-manager-current-branch/
For setting up the MDT database, see Use the MDT database to stage Windows 10 deployment information: https://docs.microsoft.com/en-us/windows/deployment/deploy-windows-mdt/use-the-mdt-database-to-stage-windows-10-deployment-information

Starting off, there will be a one time modification of the MDT database, extending the database to include some custom fields that we are going to define.

1. Add the following columns to the dbo.Settings table: TARGETBIOSDATE, FLASHBIOSCMD, BIOSPACKAGE, W10X64DRIVERPACKAGE, W7X64DRIVERPACKAGE. If you manage 32-bit operating systems, you can add columns for those as well. Also, as of now, there should not be a need for a build specific Windows 10 driver package (like one for 1607 and another for 1703), but if that changes then additional columns can be added to support them in the future. BIOS stepping – this is where you need to apply one or more BIOS versions to get to the latest version. Some older models require this and additional BIOSPACKAGE columns can be created to support this. This is not going to be covered in this blog, but if there is enough interest I will cover it in a future blog.
image

There is already a great blog called How to extend the MDT 2010 database with custom settings that is still applicable to MDT 8443 and can be used as a reference. Be sure to refresh the views after adding the columns.

2. Create BIOS Packages and Driver Packages for each make/model. If you do not already have them for each of the models you support or if you want to get the updated releases, then check out the Driver Automation Tool the awesome guys over at SCConfigMgr have created. This is a great tool and will save you a ton of time.

3. Define each make/model in the MDT database. I do not cover Lenovo systems in this blog, so if you manage those systems then check out The Deployment Bunny’s blog Modelalias User Exit for Microsoft Deployment Toolkit 2010/2012.

4. On the Details tab, scroll down to the bottom where the custom properties are listed and enter the Package IDs, Target BIOS Date and Flash BIOS command. The Target BIOS date is that that shows up in WMI for the BIOS version (also seen in msinfo32) in YYYYMMDD format.

For the Custom Settings and the Task Sequences, feel free to save some time and download them here:
Dynamic BIOS and Drivers Blog.zip

Disclaimer:                                                                                                                                                                                 Your use of these example Task Sequences is at your sole risk. This information is provided “as-is”, without any warranty, whether express or implied, of accuracy, completeness, fitness for a particular purpose, title or non-infringement. I shall not be liable for any damages you may sustain by using these examples, whether direct, indirect, special, incidental or consequential.

5. Create the following custom settings file and add it to an existing reference settings package or create a new one (feel free to replace SQL connection with a webservice of your choice):

[Settings]
Priority=CSettings,MMSettings,Default
Properties=TARGETBIOSDATE,FLASHBIOSCMD,BIOSPACKAGE,W7X64DRIVERPACKAGE,W10X64DRIVERPACKAGE

[Default]

[CSettings]
SQLServer=CM02
Database=MDT
Netlib=DBNMPNTW
SQLShare=DeploymentShare$
Table=ComputerSettings
Parameters=UUID, AssetTag, SerialNumber, MacAddress
ParameterCondition=OR

[MMSettings]
SQLServer=CM02
Database=MDT
Netlib=DBNMPNTW
SQLShare=DeploymentShare$
Table=MakeModelSettings
Parameters=Make, Model
ParameterCondition=AND

The following section is for a Wipe-n-Load Task Sequence

6. Create a MDT Gather step in the Task Sequence that uses the custom settings created above. This gather step will get the above entries that have been populated in the MDT database.

NOTE: Be sure to suspend BitLocker before flashing the BIOS in order to prevent being prompted for the recovery key. Also, if BIOS passwords are used, they will either need to be turned off or passed to the flash BIOS command line.

7. Create the Update BIOS Group with the following steps and conditions:

8. Set the BIOSUpdate Task Sequence variable. This variable will determine if a BIOS update is necessary based on the BIOS release date and also if TARGETBIOSDATE, FLASHBIOSCMD and BIOSPACKAGE exist.

9. Create a Flash BIOS group. The conditions on this group are if BIOSUPDATE is TRUE and IsOnBattery is False. Since many BIOS update utilities require AC, we do not even want to try to update the BIOS if it is running on battery. The IsOnBattery variable is set by the MDT Gather step. It also should be checked as part of pre-flight checks, but by also keeping it in the Update BIOS group, we keep it modular and this group can be used in a Software Distribution Task Sequence to update the bios existing clients.

10. Set BIOS Variables is where part of the magic happens and is a Set Dynamic Variables Task Sequence step. This is where we set the following variables: OSDDownloadDestinationLocationType, OSDDownloadContinueDownloadOnError, OSDDownloadDownloadPackages and OSDDownloadDestinationVariable. I talked about these variables in my Hacking the Task Sequence 2017 session at the Midwest Management Summit and they may lead to a future blog post. But for now, just understand that they work with the Download Package Content step executable. We are downloading the package found in the BIOSPACKAGE variable and we are going to store the download location in a base variable called BIOS. Since there is only one package, the location will get stored in the variable BIOS01. DISCLAIMER: Although these Task Sequence variables are not read only (meaning they do not start with an “_”), they are not publicly documented, which translates to “use at your own risk”.

11. The Download BIOS step is a Run Command Line step that calls OSDDownloadContent.exe. This exe is tied to the Download Package Content Task Sequence step and will consume and use the variables set in the previous step. This step is also part of the magic as it will do a dynamic content location request for the package and then download it to the TS Cache.



[Update] Directly after the Download BIOS step, it is important to insert a Reset Variables step. Since the variables are being set outside of the Download Package Content step, the variables do not get deleted. Resetting them to blank will allow any subsequent Download Package Content steps outside of this process to work normally if inserted into the Task Sequence.

12. The Flash BIOS step is another Run Command Line step that executes the command stored in the FLASHBIOSCMD variable. It also sets the working directory to the location where the BIOS package was downloaded (BIOS01). Use Continue on error or define the exit return codes so the Task Sequence does not fail.

13. The Flashing BIOS… step is also another Run Command Line step that executes timeout.exe for 60 seconds. Timeout.exe is not part of the MDT Toolkit Package, so you will need to add the correct versions (x86/x64) to your MDT Toolkit Package if you want to use it. The Windows 10 version of timeout.exe will not run on Windows 7. However, the Windows 7 version of timeout.exe will run on Windows 10. The alternatively, simply include timeout.exe in the path on your Boot Images and then it will run regardless of the operating system. Otherwise, I have seen ping commands being used to create a sleep cycle. The reason I do this is because some vendors recommend not rebooting right away (even though the main process finished). Therefore, I stick it in there for good measure.

14. Once the first phase of the BIOS update has run, the system needs to be rebooted so that the second phase can run. Since this is for a Wipe-n-Load Task Sequence, we will go ahead and reboot into the Boot Image after the BIOS update has completed. Provide the end user a message like “A new BIOS is being installed. DO NOT Power Off or unplug the system during this process. The computer must restart to continue.”

15. Directly below the Apply Network Settings step, create a new group called Apply Drivers. The condition on this group is if W10X64DRIVERPACKAGE exists. If the variable does not exist, then it was not populated in the MDT db and this group will be skipped. This is by design for the scenario where a model does not have a Windows 10 Driver Package and/or the out of the box Windows 10 drivers work just fine.

16. Set Driver Variables (similar to the Set BIOS Variables) is where part of the magic happens and is a Set Dynamic Variables Task Sequence step. This is where we also set the following variables: OSDDownloadDestinationLocationType, OSDDownloadContinueDownloadOnError, OSDDownloadDownloadPackages and OSDDownloadDestinationVariable. Here, we are downloading the package found in the W10X64DRIVERPACKAGE variable and we are going to store the download location in a base variable called DRIVERS. Since there is only one package, the location will get stored in the variable DRIVERS01.

17. The Download Driver Package step is a Run Command Line step that calls OSDDownloadContent.exe. This exe is tied to the Download Package Content Task Sequence step and will consume and use the variables set in the previous step. This step is also part of the magic as it will do a dynamic content location request for the package and then download it to the TS Cache.

[Update] Directly after the Download Driver Package step, it is important to insert a Reset Variables step. Since the variables are being set outside of the Download Package Content step, the variables do not get deleted. Resetting them to blank will allow subsequent Download Package Content steps outside of this process to work normally if inserted into the Task Sequence.

18. The Apply Driver Package step is another Run Command Line step that simply executes DISM to apply the drivers to the Windows installation contained in the OSDisk variable (which is set in the Format and Partition Disk step).

The following section is for an In-Place Upgrade Task Sequence

The same approach can be used for an In-Place Upgrade Task Sequence with a few changes.

[Update] Directly after the Download BIOS step, it is important to insert a Reset Variables step. Since the variables are being set outside of the Download Package Content step, the variables do not get deleted. Resetting them to blank will allow subsequent Download Package Content steps to work normally if inserted into the Task Sequence.

19. After the Flashing BIOS… step, change the Restart Computer step to restart to the currently installed default operating system. Provide the end user a message like “A new BIOS is being installed. DO NOT Power Off or unplug the system during this process. The computer must restart to continue.” NOTE: After the reboot, if using BitLocker on Windows 7, you will need to disable/suspend it again since the built-in Configuration Manager step only suspends it for one reboot.

20. Create a group called Download Drivers with the condition that the variable W10X64DRIVERPACKAGE exists (similar to the Apply Drivers group created above for the Wipe-n-Load Task Sequence).

21. The Set Driver Variables step is the same as Step 16 above.

22. The Download Driver Package step is the same as Step 17 above.

[Update] Directly after the Download Driver step, it is important to insert a Reset Variables step. Since the variables are being set outside of the Download Package Content step, the variables do not get deleted. Resetting them to blank will allow subsequent Download Package Content steps outside of this process to work normally if inserted into the Task Sequence.

23. Now we need to inform the Update Operating System step the location of the drivers. Enable the “Provide the following driver content to Windows Setup during upgrade” option and enter %DRIVERS01% for the “Staged content” location. Since we only want this to run when the Driver Package exists, add the condition Task Sequence Variable DRIVERS01 exists.

24. In the case that the Driver Package does not exist, duplicate the previous step, clear the “Provide the following driver content to Windows Setup during upgrade” option and add the condition Task Sequence Variable DRIVERS01 not exists. This can be reduced to using one step by using the undocumented variable OSDUpgradeStagedContent variable that Johan Arwidmark talks about in his blog post Improving the ConfigMgr Inplace-Upgrade Task Sequence.

25. Chances are, there will be a need to have more than BIOS Package or Driver Package in the production environment for a given model. As new BIOS updates and drivers are released, they can be pilot tested in the environment using the same exact Task Sequences without modification. There is no need to setup different Task Sequences, simply define your pilot systems in the MDT database under the Computers node.

26. This can be done by adding a new record in the MDT database using the Asset tag, UUID, Serial number or MAC address.

27. The same extended fields show up on the Details tab for the computer record. Add in the new BIOS package and Driver package information and the next time the system is built it will use these packages. Once the packages have passed the pilot testing phase and have been deemed production worthy, simply change the BIOS package and Driver package information in the Make and Model node for that particular model.

Lastly, as new models enter the environment, simply create the BIOS and Driver Packages in Configuration Manager and then create the entry in MDT for the new model – once again, all done without modifying either Task Sequence. In summary, this solution meets all of the five requirements that I defined in Part 1:
1. Runs in Full OS and WinPE
2. Same method works across baremetal, refresh and in-place upgrade Task Sequences
3. Dynamic without the need to edit the TS or scripts
4. Supports Production and Pre-Production in the same TS
5. Intuitive and easy to use

Now, who would like to see this functionality built into Configuration Manager out of the box?
And, who would like to see the hardware vendors publish the BIOS WMI date stamp so that it can be consumed electronically?

Originally posted on https://miketerrill.net/

Configuration Manager Dynamic Drivers & BIOS Management with Total Control Part 1

When approaching any solution, it is a good idea to come up with a list of requirements that the solution needs to be able to meet. This way you will be sure to start off on the right foot and not have to rip and replace, add to, or redo over the solution in the future. In terms of Driver & BIOS management, I have come up with the following requirements that need to be met in order to have the best solution possible that can be used in multiple scenarios:

1. Runs in Full OS and WinPE
2. Same method works across baremetal, refresh and in-place upgrade Task Sequences
3. Dynamic without the need to edit the TS or scripts
4. Supports Production and Pre-Production in the same TS
5. Intuitive and easy to use

There are a lot of blogs out there on how to manage drivers and BIOS updates with Configuration Manager, however, each of them fall short of the above requirements in one way or another. I first started out on this quest back in 2015 when I was investigating what it would take to go from BIOS to UEFI. Long story short, you need to use the vendor utilities (or methods) to change the firmware settings and they worked the best when the BIOS was running the latest version. I wanted to be able to flash the BIOS in the full OS, as well as WinPE (requirement #1). This meant that Configuration Manager Packages needed to be used since Applications cannot be used in WinPE. This way, the same process could be used regardless if the system was bare metal from the vendor or an existing machine that was getting a refresh or in-place upgrade Task Sequence (requirement #2). By the way, some vendors still have limitations on flashing the BIOS in WinPE x64, but a lot of models now support this for the most part.

Another goal was to be able to do this without having a 5 mile long Task Sequence that needs to be edited every time there was a new model, new BIOS version or new Driver Package (requirement #3). Every time a Task Sequence changes, it has the possibility of stopping imaging for the environment while replication takes place. If you have a small environment, this may be okay, but in a large environment it can be like stopping a production assembly line (not good). Next, the solution needs to be able to support BIOS versions and Driver Packages that are marked as production, as well as support BIOS versions and Driver Packages that are pre-production (requirement #4). This way a proper Test > QA > Pilot > Production methodology can be carried out using the current production Task Sequence (this is the Total Control part). If you look at the BIOS releases or driver releases over the past two years, you will notice that the hardware vendors have been busy releasing updates. As newer versions of Windows 10 get released, the vendors usually release new drivers starting a month after the CB release. Lastly, the solution needs to be intuitive and easy to use so that it can be managed by junior level administrators (requirement #5).

At the 2016 Midwest Management Summit, I had come up with a solution that covered most of the above requirements for doing the BIOS updates. At the time, I had split each of the vendors because it made it more modular, but also because some vendors (to remain nameless) at the time did not support flashing under WinPE x64. The only thing that I did not have figured out was how to do the dynamic content location request. In the Task Sequence below, I was cheating by creating a dummy group handle the CLR (the dummy group is one that does not execute but the TS does not know it and will still do the CLR at the start of the TS).

image

Little did I know, the step that I was using to get the content locations for the BIOS packages (Download Package Content), actually can do a dynamic content location request (I learned this during a trip to Redmond last November). Fast forward a bit and this is what the Flash BIOS portion of the Task Sequence looks like now:

image

Now, ‘how do drivers fit into this?’ you say. Well, the same concepts can be applied – in fact, drivers are even easier. For a Wipe-n-Load Task Sequence, we can now do driver management in three easy steps:

image

And for an In-Place Upgrade Task Sequence, driver management can be done in two easy steps all using the same process:

image

So by now you are probably thinking that this is all too good to be true and there has to be a catch. No catch – it is really this simple. In Configuration Manager Dynamic Drivers & BIOS Management with Total Control Part 2, I go into detail on how to set up, configure and use the solution.

Originally posted on https://miketerrill.net/

Windows 10 BIOS to UEFI In-place Upgrade Task Sequence using MBR2GPT

At the Midwest Management Summit 2017, I gave a session called Building the Ultimate Windows 10 UEFI Task Sequence. In this session, I covered both types of BIOS to UEFI Task Sequences – Wipe-and-Load and In-place Upgrade. This blog is going to cover the In-place Upgrade version of the BIOS to UEFI Task Sequence. This Task Sequence will use variables that I previously wrote about in the blog posts: BIOS and Secure Boot State Detection during a Task Sequence Part 1 & Part 2, as the goal is to have a single Task Sequence that covers the various scenarios. In addition, this blog also replaces the original blog I wrote, Using MBR2GPT with Configuration Manager OSD, when I first discovered MBR2GPT in one of the Windows Insider builds.

NOTE: See my blog Configuration Manager Dynamic Drivers & BIOS Management with Total Control Part 2 for a downloadable Task Sequence Template for the following Task Sequence.

When converting from BIOS to UEFI, it is best to do this after the system has been upgraded to Windows 10. The version of Windows 10 does not matter, although, it should be a version that is still supported. Also, even though MBR2GPT will run in the full OS (starting with Windows 10 1703), it is a best practice recommendation to run it from WinPE (version 1703 or later). The reason for this is that there can be other applications on the system that use filter drivers for disk access (antivirus, antimalware, 3rd party disk encryption and other 3rd party p2p solutions). These applications could interfere with the disk conversion and potentially cause a failure, therefore, always run MBR2GPT in WinPE for best results.

Typically, a Boot Image is not assigned to an In-place Upgrade Task Sequence. However, since we are going to use WinPE as part of our Task Sequence, a WinPE 1703 (or later) Boot Image should be assigned to the Task Sequence. Also, it is important to use the 64-bit Boot Image when running on a 64-bit UEFI System.

The basic flow goes like this after the OS has been upgraded:
Disable BitLocker
Set BIOS and Secure Boot Variables
Restart into WinPE (if running Legacy BIOS)
BIOS to UEFI
Run MBR2GPT (if running Legacy BIOS)
Configure BIOS Firmware Settings
Restart into Windows
Re-enable BitLocker

If you are not using BitLocker, then you can skip the two BitLocker groups. Also, even though this process works with BitLocker using earlier algorithms, if you are coming from a version of Windows before Windows 10 1511 (like when coming from Windows 7), then you might want to consider the new encryption type AES-XTS (see the blog BitLocker: AES-XTS new encryption type for more information). Moving to the new encryption type will require decryption/re-encryption of the drive.

Disable BitLocker

The reason for putting this Group in after the OS has upgraded is to cover the scenario when coming from Windows 7. As I mentioned in my blog How to detect, suspend, and re-enable BitLocker during a Task Sequence, the built in Disable BitLocker Task Sequence step on suspends BitLocker for one reboot. Therefore, I run this Group one more time just incase BitLocker was re-enabled after the In-place Upgrade.

Set BIOS and Secure Boot Variables

I cover these steps in detail in the two blogs mentioned above, but the two variables that get used in the BIOS to UEFI Group are BIOSMode and SecureBootState.

Restart into WinPE (if running Legacy BIOS)

On this step, we only need to reboot if the system is running in Legacy BIOS Mode. If it is running in UEFI Hybrid or UEFI Native without Secure Boot, the disk will already be configured for GPT. On the Options tab, add the condition: Task Sequence Variable BIOSMode equals “LegacyBIOS” (Note: you could also use _SMSTSBootUEFI equals FALSE, but having LegacyBIOS is easier to find in log files, status messages and is easier for help desk personal to understand). Also add the hardware manufacturers that you want to support. This is important because you cannot convert BIOS to UEFI on a GEN 1 Hyper-V VM and you will probably want to test the rest of the Task Sequence on a VM outside of the BIOS to UEFI steps.

BIOS to UEFI

On this Group, we only need to perform BIOS to UEFI or BIOS Firmware Settings if the system is running Legacy BIOS, UEFI Hybrid or UEFI Native without Secure Boot. On the Options tab, add the condition: Task Sequence Variable SecureBootState not equals “Enabled”. Once again, also add the hardware manufacturers that you want to support.

MBR2GPT (if running Legacy BIOS)

I like to run this step prior to configuring the BIOS settings. Secure Boot can be programmatically enabled, however per the specification it cannot be programmatically disabled. If you enable Secure Boot prior to running converting the disk and MBR2GPT is not able to convert the disk for some reason (like too many MBR partitions, see my blog Configuration Manager OSD, Recovery Partitions and MBR2GPT), then the machine will require a desk side visit to reset the BIOS settings and manually disable Secure Boot.

This step will run under WinPE. MBR2GPT can be called directly using a Run Command Line step since it is in the path in WinPE. If dealing with systems that do not install the OS on disk 0, then you will need to create multiple steps and put the necessary conditions on each. MBR2GPT will generate useful log files and I like to save them in the Task Sequence log directory (_SMSTSLogPath). This way they will be available after the Task Sequence runs. On the Option tab, add the condition: Task Sequence Variable BIOSMode equals “LegacyBIOS. This will ensure that this step only runs under this condition. Note: we could have also used and/or added _SMSTSinWinPE equals “TRUE”. Also enable Continue on error. This is important because we do not necessarily want the entire In-Place Upgrade to fail just because MBR2GPT was not able to run. If it is a hard failure, then the Task Sequence will definitely not continue as the system will probably no longer boot up.

Configure BIOS Firmware Settings

In the Firmware Settings Group, you will add your own BIOS settings commands, utilities or tools. These commands, utilities and tools can run in a full OS or WinPE. If you use Dell systems, please see my previous blog post Automating Dell BIOS-UEFI Standards for Windows 10 for the commands (and order) of switching the UEFI settings using the Dell CCTK (aka Command Monitor). On the Option tab, add the condition: Task Sequence Variable _SMSTSLastActionSucceeded equals “TRUE”. This will ensure that this group is only entered if the previous step that runs was successful. In the case of a Legacy BIOS system, if MBR2GPT is not successful, we want the Task Sequence to continue, but we do not want to flip the BIOS settings to UEFI and enable Secure Boot. In the other case of a system running UEFI Hybrid or UEFI Native without Secure Boot, it will run if the previous non-skipped step was successful. NOTE: It is important to be running the latest BIOS version and BIOS utilities for best results. Also, be sure to account for BIOS passwords if used in your environment. It is best to disable the BIOS passwords and then re-enable them at the end of the process.

Restart into Windows

After the Firmware Settings are changed, a system reboot is required for them to be applied. This restart will boot the system back into Windows 10.

Re-enable BitLocker

Once the system has been configured for UEFI Native with Secure Boot and booted back up into Windows 10, it is time to re-enable BitLocker. The Re-enable BitLocker Group will run in a full OS and only if the OSDBitLockerStatus equals “Protected”. This variable gets set earlier in the Task Sequence before the operating system is upgrade. For more information, see my blog How to detect, suspend, and re-enable BitLocker during a Task Sequence.

MBR2GPT and BitLocker

If you read the Microsoft documentation for using MBR2GPT, they only tell you that you need to delete the existing protectors and recreate them (they don’t mention that you need to reset the Windows Recovery Environment to generate a new reagent.xml and update the bcd). They do not really give any clear guidance on how to do this.

Reset Windows Recovery Environment

Resetting the Windows Recovery Environment only needs to be done when using MBR2GPT with BitLocker. On the Option tab, add the condition: Task Sequence Variable BIOSMode equals “LegacyBIOS”.

I have seen some forum posts on the internet that talk about deleting the ReAgent.xml file (found in C:Windows\System32\Recovery). Windows will re-create this file on the next reboot and it should modify the bcd file accordingly. However, I prefer to update it (and the bcd) by simply disabling WinRE and re-enabling it. I also display the status after re-enabling it. Each of these commands will pipe output to the smsts.log and also CM Status Messages. For clarity they are split in three different steps.

Reset BitLocker Protectors for MBR2GPT

Just like Resetting the Windows Recovery Environment, resetting the BitLocker Protectors only needs to be done when using MBR2GPT with BitLocker. On the Option tab, add the condition: Task Sequence Variable BIOSMode equals “LegacyBIOS”.

Now we just need to delete the BitLocker protectors. This can be done by running the following command: manage-bde -protectors -delete c:

It is extremely important to perform a restart after deleting the BitLocker protectors and before enabling BitLocker. If it is not done in this order, the system will prompt for the BitLocker recovery key on the next reboot.

Enable BitLocker

The last thing to do in the Re-enable BitLocker Group is to enable the BitLocker protectors. This can be done using the native Enable BitLocker Task Sequence step. Since the operating system drive is already encrypted, just the BitLocker protectors are being created and/or enabled (depending on the scenario).

In summary, this approach will cover multiple upgrade scenarios, including BIOS to UEFI, when performing an in-place upgrade to Windows 10.

Originally posted on https://miketerrill.net/