Using Enterprise Mode in Microsoft Edge and Internet Explorer 11

Enterprise Mode is a feature that shipped in Internet Explorer 11 for Windows 10, and was also introduced to Internet Explorer 11 in Windows 7 and 8.1 in April 2014 that should be seriously considered by any organisation still hoping to complete their Windows 10 migrations before end of support in January 2020, but are worried that their older web applications may not work in the latest version of Internet Explorer.

Enterprise Mode has two functions depending on which browser you are using; In Microsoft Edge it can be used to automatically redirect certain website to IE11 (Edge itself does not do any compatibility rendering, it simply shifts you over to IE11 to do that). In IE11, it can be used to open specified sites in certain document modes or in IE8 or IE7 Enterprise Mode which offers greater emulation of those browsers.

To start, you must enable Enterprise Mode in both Edge and IE11 separately. Yes, there are two places in Group Policy where you have to enable this feature to fully utilise it.

For Microsoft Edge:
Computer Configuration > Policies > Administrative Templates > Windows Components > Microsoft Edge > Configure the Enterprise Mode Site List

For Internet Explorer 11:
Computer Configuration > Policies > Administrative Templates > Windows Components > Internet Explorer > Use the Enterprise Mode IE website list

When you have enabled them, you are also required to enter a path where your site list can be found. This can either be a URL (if you have an internal web server to host it) or a file share location (such as \\fileserver.domain.com\SiteList\sitelist.xml).

To create your site list, start by downloading the Enterprise Mode Site List Manager tool. That is assuming you are working with Windows 10 clients. If you are working with Windows 7 or 8.1 clients, download this tool instead. Once you’ve installed it you are given an easy interface to generate a valid XML file for the site list. Just for fun, let’s take my site and configure Edge to open it in IE11, and IE11 to render it in IE8 compatibility mode:

Adding my site to Enterprise Mode

Let’s see what that looks like in the resulting XML:

Adding my site to Enterprise Mode XML

A few things to take away from this:

1) The site list is on version 2. This matters because if this does not increment each time you make a change, Edge and IE11 will not honour the change.
2) The site URL is just the main domain and does not include the https:// or any subdomains. In this case, any URL containing kevinstreet.co.uk will redirect to IE11 (for example, https://reallyoldapp.kevinstreet.co.uk or https://kevinstreet.co.uk/reallyoldapp will redirect to IE11). If you only want a specific subdomain to redirect to IE11 then you should specify that subdomain.
3) The selected compatibility is IE8 Enterprise Mode.
4) The site will be opened in IE11. If a user tries to open it in Microsoft Edge, IE11 will automatically open and navigate to the page.

With the site populated with sites (presumably not actually with my site!) and the site list XML saved to the location you specified in the GPO, open Microsoft Edge and test browsing to the site you specified. It may not work immediately! Edge takes approximately 60 seconds from the time it is opened to check for a new version of the site list and apply it (as does IE11).

Super handy tip: If you want to confirm that your site list is working, in both Edge and IE11, type about:compat in the URL to get a list of websites and their prescribed behaviour. You even get a Force update button to speed up the process of updating the site list. Very useful if you are in the process of adding sites and want to quickly test that your configuration is working.

Compatibility Settings

Once you’re sure both Edge and IE11 are using the latest version of the site list, retry browsing to a URL you specified. In Edge, it should automatically open in IE11 and open in the specified compatibility mode.

My site in Internet Explorer Enterprise Mode
Gosh my site looks pretty bad being rendered as if it was open in Internet Explorer 8!

As you can see from the image above, the site has loaded in Enterprise Mode (this is clear because the of the little blue icon that appears next to the URL). This icon only appears when you select Enterprise Mode as a compatibility mode, it does not appear if you select a document mode. You can still confirm that it has worked by browsing to the site and pressing F12 to open the Developer Tools, then selecting the Emulation tab. In here you will see that the Document mode and Browser profile are configured as you specified in the site list.

Bonus cool stuff: Google Chrome also has a version of this, called Legacy Browser Support. This is particularly cool because you can configure it with Group Policy and it can use the same site list as Edge and IE11, so no need to maintain separate lists! Click here to learn more about Google Chrome Legacy Browser Support for Windows.

Making iSBEM and Jet Reports work in Windows 10

This may be quite a niche post, but if it helps just one person overcome a “run-time error 5” whenever they try to run one of the iSBEM databases or an “Access Denied”1 error when trying to run a report powered by Jet Reports then it’s worth it!

In Windows 10 the built-in antimalware solution, Windows Defender, has a feature known as Windows Defender Exploit Guard. You can read up about this feature in more detail here, but one of its features in particular, the attack surface reduction rules, can sometimes prevent certain behaviour working in Microsoft Office applications.

Looking more closely at the attack surface reduction rules, you can see that a few of them are tailored specifically at Microsoft Office applications. In my experience the rule “Block all Office applications from creating child processes” can prevent the external processes needed by iSBEM and Jet Reports from running, which causes the errors mentioned above. You can quite easily check if this is the case by attempting to run an iSBEM database or Jet Report and getting the error, then open the Event Viewer and navigate to Applications and Services Logs > Microsoft > Windows > Windows Defender > Operational and looking for any warning or error level events that indicate that Windows Defender blocked the process from running.

If you do find the block event in the Event Viewer, you can create an exclusion to prevent it from being blocked. This can either be done in Group Policy or PowerShell. Open Group Policy editor and navigate to Computer Configuration > Administrative Templates > Windows Components > Windows Defender Antivirus > Windows Defender Exploit Guard > Attack Surface Reduction. In here, one of the policies that can be configured is “Exclude files and paths from Attack Surface Reduction rules”, and you can use this to add your exclusions. You can use wildcards and environment variables to ensure the exclusions you add will work regardless of where they apply (for more details on that see this article). Try to make your exclusions as specific as possible so that you still get as much protection from Windows Defender Exploit Guard as possible!

If you wish to add exclusions using PowerShell, you should use the following command:

Add-MpPreference -AttackSurfaceReductionOnlyExclusions "Path to exclude"

For example, to unblock the iSBEM database you may use the following exclusion:

Add-MpPreference -AttackSurfaceReductionOnlyExclusions "%SYSTEMDRIVE%\NCM\iSBEM_v5.6.a\iSBEM_v5.6.a.mdb"

With that in place, test running the database again and continue to monitor the logs in  Event Viewer until all blocks have been identified and exclusions created.

1Of course an error like Access Denied isn’t necessarily being caused by Windows Defender, it could actually be a permission issue.

Download Window 10 Enterprise 1903 with the Media Creation Tool (including en-GB and other language versions)

The March (or that May?) 2019 version of Windows 10 is now availabe to download using the Media Creation Tool. Using the GUI you can download the consumer ISO which contains the Home, Professional and Education SKUs of Windows 10.

If you want to download the Enterprise version of Windows 10, but don’t have access to Microsoft VLSC, Visual Studio or Action Pack subscriptions, it is possible to download it using the Media Creation Tool if you know the right command line switches.

To download Windows 10 Enterprise 1903 using the Media Creation Tool, log in with a local administrator account (for some reason it isn’t good enough to run the tool using Run as administrator, you actually do have to be logged in as an administrator) and download the tool. Open a CMD prompt and change directory to the directory you saved the Media Creation Tool in, and enter the following command:

MediaCreationTool1903.exe /Eula Accept /Retail /MediaArch x64 /MediaEdition Enterprise

When you’re prompted for a product key, you can use the Windows 10 Enterprise KMS client key from this site on Microsoft Docs.

This will download an ISO that contains the various Enterprise SKUs (Enterprise, Enterprise N,  Education, Education N, Professional and Professional N) with en-US installed and set to default. If you’d prefer to get en-GB, use the following command:

MediaCreationTool1903.exe /Eula Accept /Retail /MediaLangCode en-GB /MediaArch x64 /MediaEdition Enterprise

This will download an ISO containing the same SKUs as above, but with en-GB installed and set to default.

As far as I can tell, this works for any of the language pack region tags listed on this site. So for example, to download Windows 10 Enterprise 1903 with French installed and set to the default language, you can use this command:

MediaCreationTool1903.exe /Eula Accept /Retail /MediaLangCode fr-FR /MediaArch x64 /MediaEdition Enterprise

If you want to download the 32-bit version of Windows 10 Enterprise instead, you should change /MediaArch to x86.

When you have downloaded the ISO you may unpack it to find that the it does not contain an install.wim, but instead contains install.esd in the sources directory. Depending on what you are doing, you may need the .wim file (for example, if you’re planning to use it with SCCM). Thankfully obtaining a .wim file from the .esd is quite straightforward using DISM.

Open a CMD prompt and use the following command (changing the path for /WimFile to match where your install.esd file is):

dism.exe /Get-WimInfo /WimFile:C:\Temp\Windows10_1903\sources\install.esd

This will list each of the SKUs in the install.esd file. Make a note of the index of the SKU you want (in my case, I want the Enterprise SKU which is index 3).

DISM Get-WimInfo

Now use the following command to create an install.wim file which contains the SKU you want:

dism.exe /Export-Image /SourceImageFile:C:\Temp\Windows10_1903\sources\install.esd /SourceIndex:3 /DestinationImageFile:C:\Temp\Windows10_1903\sources\install.wim /Compress:max /CheckIntegrity

Make sure the path for /SourceImageFile and /DestinationImageFile are correct for you and change the /SourceIndex to match the index you noted earlier.

dism.exe /Export-Image /SourceImageFile:C:TempWindows10_1903sourcesinstall.esd /SourceIndex:3 /DestinationImageFile:C:TempWindows10_1903sourcesinstall.wim /Compress:max /CheckIntegrity

 

Once that is done you can delete the install.esd file if you want, to save space.

This process also works with earlier versions of Windows 10.

Installing Remote Server Administration Tools (RSAT) for Windows 10 1809 (including SCCM deployment) (Part 2)

In the first part of this guide I stated that in order to install RSAT in Windows 10 1809 and above, Windows needs to be able to reach the Internet to download the source files. This is due to RSAT being a feature-on-demand in 1809 and above, so the files are not included on the disk but instead hosted online and downloaded when required.

Well it turns out the source files can be downloaded, if you have access to Microsoft Volume Licensing Service Center or Visual Studio downloads. Search for “features on demand” and make sure you download the latest ones for 1809 (in my Visual Studio downloads portal it is listed as “Windows 10 Features on Demand, version 1809 (Updated Sept 2018)”).

Once you have downloaded the ISO, you can use it as the source location when installing RSAT with PowerShell. Say, for example, you mount the ISO as the F: drive, you would use the following command:

Get-WindowsCapability -Online | Where-Object {($_.State -notmatch 'Installed') -and ($_.Name -match 'RSAT')} | %{Add-WindowsCapability -Online -LimitAccess -Name $_.Name -Source F:\ }

However, there is a lot more on that disk than just the files required for RSAT, and if you wish to use this in an SCCM package you will want to sanitise it a bit. The whole disk contains 4.6 GB of files, however the ones we need for RSAT are only about 500 MB.

To create a package using only the files you need for RSAT, create a folder somewhere called RSATSource and copy the files with the following names (there will be multiple files per search, you need all of them):

Microsoft-Windows-ActiveDirectory-DS-LDS-Tools-FoD-Package~31bf3856ad364e35~amd64~
Microsoft-Windows-BitLocker-Recovery-Tools-FoD-Package~31bf3856ad364e35~amd64~
Microsoft-Windows-CertificateServices-Tools-FoD-Package~31bf3856ad364e35~amd64~
Microsoft-Windows-DHCP-Tools-FoD-Package~31bf3856ad364e35~amd64~
Microsoft-Windows-DNS-Tools-FoD-Package~31bf3856ad364e35~amd64~
Microsoft-Windows-FailoverCluster-Management-Tools-FOD-Package~31bf3856ad364e35~amd64~
Microsoft-Windows-FileServices-Tools-FoD-Package~31bf3856ad364e35~amd64~
Microsoft-Windows-GroupPolicy-Management-Tools-FoD-Package~31bf3856ad364e35~amd64~
Microsoft-Windows-IPAM-Client-FoD-Package~31bf3856ad364e35~amd64~
Microsoft-Windows-LLDP-Tools-FoD-Package~31bf3856ad364e35~amd64~
Microsoft-Windows-NetworkController-Tools-FoD-Package~31bf3856ad364e35~amd64~
Microsoft-Windows-NetworkLoadBalancing-Tools-FoD-Package~31bf3856ad364e35~amd64~
Microsoft-Windows-RemoteAccess-Management-Tools-FoD-Package~31bf3856ad364e35~amd64~
Microsoft-Windows-RemoteDesktop-Services-Tools-FoD-Package~31bf3856ad364e35~amd64~
Microsoft-Windows-ServerManager-Tools-FoD-Package~31bf3856ad364e35~amd64~
Microsoft-Windows-Shielded-VM-Tools-FoD-Package~31bf3856ad364e35~amd64~
Microsoft-Windows-StorageMigrationService-Management-Tools-FOD-Package~31bf3856ad364e35~amd64~
Microsoft-Windows-StorageReplica-Tools-FoD-Package~31bf3856ad364e35~amd64~
Microsoft-Windows-SystemInsights-Management-Tools-FOD-Package~31bf3856ad364e35~amd64~
Microsoft-Windows-VolumeActivation-Tools-FoD-Package~31bf3856ad364e35~amd64~

You will also need to copy the “metadata” folder and the file “FoDMetadata_Client.cab”. With these files copied into their own folder, you can change the PowerShell to:

Get-WindowsCapability -Online | Where-Object {($_.State -notmatch 'Installed') -and ($_.Name -match 'RSAT')} | %{Add-WindowsCapability -Online -LimitAccess -Name $_.Name -Source C:\RSATSource }

Obviously replace C:\RSATSource with the location of the source folder you copied all those files into.

Creating an SCCM application to deploy RSAT

Since I already wrote this up in Part 1 of this guide, this part is mostly just a rehash of that. However, there is one change to the script so that it now uses the local packaged source, rather than going online to download the source.

To create an application in SCCM you will need three things: An install command, an uninstall command and a detection method. To cover the install and uninstall command, let’s create a PowerShell script with an install and uninstall function that can be called from the command line. The following PowerShell script is used to install and uninstall all RSAT components; if you want to pick and choose the ones you install or uninstall, modify it accordingly.

## Install all RSAT components

Function InstallRSAT {
    
Get-WindowsCapability -Online | Where-Object {($_.State -notmatch         'Installed') -and ($_.Name -match 'RSAT')} | %{Add-WindowsCapability -Online -LimitAccess -Name $_.Name -Source $PSScriptRoot\RSATSource}

}



## Uninstall each RSAT component so that no dependancies are left behind

Function UninstallRSAT {
    
Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.BitLocker.Recovery.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.CertificateServices.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.DHCP.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.Dns.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.FailoverCluster.Management.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.FileServices.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.IPAM.Client.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.LLDP.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.NetworkController.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.NetworkLoadBalancing.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.RemoteAccess.Management.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.RemoteDesktop.Services.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.Shielded.VM.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.StorageMigrationService.Management.Tools')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.StorageReplica.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.SystemInsights.Management.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.VolumeActivation.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.WSUS.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.ServerManager.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}

}



## Get the parameter passed to the script

$DeploymentType=$args[0]



## Run the install or uninstall function

if ($DeploymentType -eq "Uninstall") {
    
UninstallRSAT
}


else {
    
InstallRSAT
}

Copy that script and save it as Install-RSAT.ps1. Create your application in SCCM and go through the wizard, giving it a name, publisher and version. The source will be the location where you saved Install-RSAT.ps1. Don’t forget to also copy your RSATSource folder to this location! When you get to the install and uninstall commands in the wizard, you can use the following commands:

To install:
powershell.exe -ExecutionPolicy Bypass -File .\Install-RSAT.ps1 -DeploymentType Install

To uninstall:
powershell.exe -ExecutionPolicy Bypass -File .\Install-RSAT.ps1 -DeploymentType Uninstall

Next up is the detection method. For this, you will need to use a PowerShell detection method. The PowerShell will simply check that the RSAT optional components have their install state set to Installed:

$installed = Get-WindowsCapability -Online | where name -like RSAT* | where state -like Installed | select name

if ($installed) {
    return $true
}

That should be all you need! Deploy that to a Windows 10 1809 device and the user should be able to install RSAT from Software Center.

Windows Vista Ultimate Signature Edition

On January 30th, 2007 Microsoft released their much-delayed successor to Windows XP, Windows Vista. It released with far too many editions, which Microsoft slowly whittled down to just a few over the years leading up to the release of Windows 10.

One of the lesser known editions that Microsoft released was Windows Vista Ultimate Signature Edition. This was unique among the special signed / event orientated releases of Windows in that it was commercially available for anyone to purchase rather than being limited to handouts at the launch event. It was available in the US and cost $10 more than the regular Ultimate edition, getting you exactly $0 worth of additional stuff, unless you really like boxes with a print of Bill Gates’ signature on them.

Windows Vista Ultimate Signature Edtion front

This was limited to 25,000 copies, and, like the Windows 95 Special Edition, only got you an upgrade license of Windows Vista – not even a full license! Like the Windows 95 Special Edition there is a printed note from Bill Gates on the inside cover of the box that reads:

I’ve always been inspired by the limitless potential of technology. And I believe that its definition is never fixed, but instead is an ongoing collaboration among technical professionals and enthusiasts – a group of people who are inspired by the challenge of testing the limits of technology, redefining its boundaries, and setting new standards for innovation and progress. At Microsoft, we feel very fortunate to be a part of this effort. And so, as thanks, we hope you will enjoy this Signature Edition of Windows Vista Ultimate. It represents both our best work and our vision of what the future might hold.

Bill Gates

This wasn’t the only special edition of Windows Vista that Microsoft released. They also released a (PRODUCT) RED edition in support of raising awareness and helping to eliminate AIDS in Africa. This was originally a Dell exclusive that only shipped with certain Dell PCs but got its own boxed release that was available from December 15th, 2008. This edition came with some additional desktop wallpapers, a screensaver, two Sidebar gadgets and a DreamScene wallpaper (remember those things?)

If you’re interested in any other special Windows editions please check out my article about Windows 95 Special Edition and Windows 7 Ultimate Signature Edition.

Switch from Legacy BIOS to UEFI on existing installs of Windows Server 2016 (and 2012 / 2012 R2)

With most modern servers now shipping with UEFI enabled by default and many virtual hypervisor platforms supporting it for guest VMs as well, you may wish to switch your existing installations of Windows Server 2012, 2012 R2 or 2016 from booting with legacy BIOS to booting with UEFI. Thanks to a small tool introduced by Microsoft in Windows 10 1703, MBR2GPT.EXE, this can be done very easily.

You will need to download a copy of Windows 10 1703 or later in order to follow this guide as you need a copy of MBR2GPT.EXE and you need to boot your server into the version of WinPE that comes with these releases of Windows 10. You cannot run the tool in versions of Windows prior to 1703 (which, technically, Window Server 2016 is as it uses the same codebase Windows 10 1607).

Make certain your platform supports UEFI booting before continuing with this guide. If it does not, you will no longer be able to boot into Windows after you have changed the partition table from MBR to GPT.

If this process fails it has the potential to make your server unbootable, corrupt your data and cause lengthy downtime. Make certain you have an adequate backup of your server and a restoration process in place before proceeding.

Okay, with the big scary warnings out of the way, let’s get going!

First start by loading the Window 10 1703 (or later) ISO onto a USB drive, DVD, or if you’re following this process on a VM, mount it directly on the VM. Restart your server and boot the server from the Windows installation media. Click Next on the language selection screen and on the next screen click Repair your computer.

When the options screen comes up select Troubleshoot, and in Advanced Options select Command Prompt. You’ll find yourself at the command prompt in X:\Sources. Change directory to X:\Windows\system32 and start diskpart. Type list disk to list the disks attached to the system and note down the one that contains the OS. This will likely to be disk 0 but may not be depending on your servers’ disk layout.

diskpart List Disk

Exit diskpart and type MBR2GPT.exe /validate /disk:0. This will run the MBR2GPT tool on your OS disk to validate that it is ready for the conversion. If it is successful, run MBR2GPT.exe /convert /disk:0 and wait for the conversion to complete – it should not take long.

MBR2GPT Convert

That’s it for the conversion. Now restart your server, enter setup and enable UEFI booting. Save and exit and Windows should boot right up without any issues.

Now there is some optional clean up you can do. How optional it is depends on if you’ll ever want to extend the size of the drive. On a physical server it is unlikely your partition doesn’t already use the full size of the drive, however on a VM where it is possible to increase the size of the disk, you may have need to extend it in the future. It also depends on if you use BitLocker or not – more on that in a moment.

Here’s the deal. In Windows, open a command prompt and start diskpart. Type select disk 0 and then list partition. You will see three partitions – a 500 MB recovery partition, your OS partition and a 100 MB EFI system partition. That 500 MB partition is no longer in use since you no longer have an MBR partition. The new system partition is that 100 MB one at the end, and because it is at the end it will block you extending your OS partition. Fortunately, you can reuse that 500 MB of space and put the EFI system partition there instead.

If you use BitLocker to encrypt your drive the 500 MB partition also contains the unencrypted system files needed to start your computer. In this case, you cannot delete the partition. If you really need to be able to extend your partition in the future you can either unencrypt your drive, move the partition and then re-encrypt it, or use a third-party partitioning tool to move the EFI system partition to the front of the disk.

If you want to complete the partition clean up, here’s what to do. First, reboot the server and use the same steps as earlier with your Windows 10 installation media to end up back at the command prompt. From here, enter diskpart and type select disk 0 and then list partition. Note down which partitions are the 500 MB recovery partition and 100 MB system partition (typically these will be partition 1 and partition 3). Proceed to delete these partitions by first selecting them and then deleting them, using the commands select partition 1 followed by delete partition override and then select partition 3 followed by delete partition override.

diskpart Delete Partitions

Now create a new EFI system partition at the front of the disk using the command create partition efi size=100, format it using format quick fs=fat32 and assign it a drive letter using assign letter=s. Next, use the list volume command to get a list of volumes and make a note of the drive letter your OS drive is on (very likely C).

diskpartListVolume

Exit diskpart and type bcdboot C:\Windows /s S: to copy the necessary system files to the new EFI system partition.

Finally, enter diskpart one last time, type select disk 0 and then select partition 2 and then type extend to reclaim that 100 MB of space at the end of the drive (may as well, right?) This will leave you with 2 partitions – the 100 MB EFI system partition at the beginning of the drive and your OS partition. Exit diskpart and restart your server.

diskpartExtendPartition

And that’s it, the server now boots with UEFI and the partitions are all tidied up1.

1The astute among you will have realised that actually, the partitions aren’t quite as clean as you might like. Due to the old system partition being 500 MB and the new one being 100 MB, there is now 400 MB of unused space between the system partition and the OS partition. You have a few options here. The first, and simplest, is to actually create the new EFI partition with 500 MB of space rather than 100 MB. It doesn’t need that much space, but it will look better in Disk Management not having that random unused space between the partitions. Your second option is to simply leave it there, which could be beneficial in the future. If you ever turn on BitLocker it will need to create a 350 MB partition to store the unencrypted system files needed to boot your computer, and it can do so inside that 400 MB of space. Your third option is to use a third-party partitioning tool which is capable of extending your OS partition into the space in front of it, which is something that diskpart cannot do.

Installing Remote Server Administration Tools (RSAT) for Windows 10 1809 (including SCCM deployment) (Part 1)

Update, February 2019: Since writing this in October 2018 I have learnt that it is possible to download the files needed if you have access to certain Microsoft resources. If you do not, this guide is still relevant. However you may wish to read this and Part 2 before taking any action.

Starting in Windows 10 1809 and continuing in future versions of Windows 10, the Remote Server Administration Tools are an optional feature that can be installed from within the OS, rather than you having to download them from Microsoft separately. This new approach fixes the issue that the tools would be uninstalled every time you install a Windows 10 feature update.

This does have a downside though, which is that Windows must go out to an update source to get the source files for RSAT (they are not included in the /Sources/sxs directory like the .NET 3 Framework source files are). This means you may have to allow clients to go out to Windows Update if they are installing RSAT!

The quick and dirty way to install all RSAT components is to open an administrative PowerShell window and use the command:

Get-WindowsCapability -Online | Where-Object {($_.State -notmatch 'Installed') -and ($_.Name -match 'RSAT')} | %{Add-WindowsCapability -Name $_.Name -Online }

This will look for all features that have RSAT in the name and install them.

If you get an error 0800f0954 it means the source location could not be reached. This may be because the machine you’re attempting to install RSAT on doesn’t have internet access or is configured to go to a WSUS or SCCM server for updates. If it’s the latter, you can enable a GPO which allows Windows to go to Windows Update for optional component installations only (while still getting regular updates from WSUS or SCCM). This GPO is in:

Computer Configuration > Administrative Templates > System > Specify settings for optional component installation and component repair

Tick the Download repair content and optional features directly from Windows Update instead of Windows Server Update Services (WSUS) and click OK to set the GPO. You can test this with local group policy to make sure it fixes the issue before deploying it to everyone!

Each of the RSAT components can also be installed individually if you don’t wish to install all of them. The list of RSAT components can be found on this Microsoft Docs page. Use the following PowerShell command to install the component you want, changing the name to match the component you want to install (these are listed as capability names on the linked Microsoft Docs page):

Get-WindowsCapability -Online | Where-Object {($_.State -notmatch 'Installed') -and ($_.Name -match 'Rsat.BitLocker.Recovery.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}

You can install multiple components by simply duplicating the command and changing the name to match another component.

Uninstalling is a little more complicated as you cannot simply use the same catch-all PowerShell command to uninstall as you can to install. This is because some of the RSAT components have dependencies and if you try to uninstall them all the dependancies  will remain installed. To get around this, you can uninstall them in a specific order to ensure that all the dependant components are removed first.

I use the following order:

Get-WindowsCapability -Online | Where-Object {($_.State -notmatch 'Installed') -and ($_.Name -match 'Rsat.BitLocker.Recovery.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}

Get-WindowsCapability -Online | Where-Object {($_.State -notmatch 'Installed') -and ($_.Name -match 'Rsat.CertificateServices.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}

Get-WindowsCapability -Online | Where-Object {($_.State -notmatch 'Installed') -and ($_.Name -match 'Rsat.DHCP.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}

Get-WindowsCapability -Online | Where-Object {($_.State -notmatch 'Installed') -and ($_.Name -match 'Rsat.Dns.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}

Get-WindowsCapability -Online | Where-Object {($_.State -notmatch 'Installed') -and ($_.Name -match 'Rsat.FailoverCluster.Management.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}

Get-WindowsCapability -Online | Where-Object {($_.State -notmatch 'Installed') -and ($_.Name -match 'Rsat.FileServices.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}

Get-WindowsCapability -Online | Where-Object {($_.State -notmatch 'Installed') -and ($_.Name -match 'Rsat.IPAM.Client.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}

Get-WindowsCapability -Online | Where-Object {($_.State -notmatch 'Installed') -and ($_.Name -match 'Rsat.LLDP.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}

Get-WindowsCapability -Online | Where-Object {($_.State -notmatch 'Installed') -and ($_.Name -match 'Rsat.NetworkController.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}

Get-WindowsCapability -Online | Where-Object {($_.State -notmatch 'Installed') -and ($_.Name -match 'Rsat.NetworkLoadBalancing.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}

Get-WindowsCapability -Online | Where-Object {($_.State -notmatch 'Installed') -and ($_.Name -match 'Rsat.RemoteAccess.Management.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}

Get-WindowsCapability -Online | Where-Object {($_.State -notmatch 'Installed') -and ($_.Name -match 'Rsat.RemoteDesktop.Services.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}

Get-WindowsCapability -Online | Where-Object {($_.State -notmatch 'Installed') -and ($_.Name -match 'Rsat.Shielded.VM.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}

Get-WindowsCapability -Online | Where-Object {($_.State -notmatch 'Installed') -and ($_.Name -match 'Rsat.StorageMigrationService.Management.Tools')} | %{Remove-WindowsCapability -Name $_.Name -Online}

Get-WindowsCapability -Online | Where-Object {($_.State -notmatch 'Installed') -and ($_.Name -match 'Rsat.StorageReplica.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}

Get-WindowsCapability -Online | Where-Object {($_.State -notmatch 'Installed') -and ($_.Name -match 'Rsat.SystemInsights.Management.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}

Get-WindowsCapability -Online | Where-Object {($_.State -notmatch 'Installed') -and ($_.Name -match 'Rsat.VolumeActivation.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}

Get-WindowsCapability -Online | Where-Object {($_.State -notmatch 'Installed') -and ($_.Name -match 'Rsat.WSUS.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}

Get-WindowsCapability -Online | Where-Object {($_.State -notmatch 'Installed') -and ($_.Name -match 'Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}

Get-WindowsCapability -Online | Where-Object {($_.State -notmatch 'Installed') -and ($_.Name -match 'Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}

Get-WindowsCapability -Online | Where-Object {($_.State -notmatch 'Installed') -and ($_.Name -match 'Rsat.ServerManager.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}

Making sure that the last three are Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0, Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0 and Rsat.ServerManager.Tools~~~~0.0.1.0 seems to fix issues with dependant components.

Creating an SCCM application to deploy RSAT

To create an application in SCCM you will need three things: An install command, an uninstall command and a detection method. To cover the install and uninstall command, let’s create a PowerShell script with an install and uninstall function that can be called from the command line. The following PowerShell script is used to install and uninstall all RSAT components; if you want to pick and chose the ones you install or uninstall, modify it accordingly.

## Install all RSAT components
Function InstallRSAT {
    Get-WindowsCapability -Online | Where-Object {($_.State -notmatch 'Installed') -and ($_.Name -match 'RSAT')} | %{Add-WindowsCapability -Name $_.Name -Online}
}

## Uninstall each RSAT component so that no dependancies are left behind
Function UninstallRSAT {
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.BitLocker.Recovery.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.CertificateServices.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.DHCP.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.Dns.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.FailoverCluster.Management.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.FileServices.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.IPAM.Client.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.LLDP.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.NetworkController.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.NetworkLoadBalancing.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.RemoteAccess.Management.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.RemoteDesktop.Services.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.Shielded.VM.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.StorageMigrationService.Management.Tools')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.StorageReplica.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.SystemInsights.Management.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.VolumeActivation.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.WSUS.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
    Get-WindowsCapability -Online | Where-Object {($_.State -match 'Installed') -and ($_.Name -match 'Rsat.ServerManager.Tools~~~~0.0.1.0')} | %{Remove-WindowsCapability -Name $_.Name -Online}
}

## Get the parameter passed to the script
$DeploymentType=$args[0]

## Run the install or uninstall function
if ($DeploymentType -eq "Uninstall") {
    UninstallRSAT
}

else {
    InstallRSAT
}

Copy that script and save it as Install-RSAT.ps1. Create your application in SCCM and go through the wizard, giving it a name, publisher and version. The source will be the location where you saved Install-RSAT.ps1. When you get to the install and uninstall commands in the wizard, you can use the following commands:

To install:
powershell.exe -ExecutionPolicy Bypass -File .\Install-RSAT.ps1 -DeploymentType Install

To uninstall:
powershell.exe -ExecutionPolicy Bypass -File .\Install-RSAT.ps1 -DeploymentType Uninstall

Next up is the detection method. For this, you will need to use a PowerShell detection method. The PowerShell will simply check that the RSAT optional components have their install state set to Installed:

$installed = Get-WindowsCapability -Online | where name -like RSAT* | where state -like Installed | select name
if ($installed) {
    return $true
}

That should be all you need! Deploy that to a Windows 10 1809 device and the user should be able to install RSAT from Software Center… as long as their device can go online to reach the source files.