MSEndpointMgr

Enable Credential Guard in Windows 10 during OSD with ConfigMgr

When deploying Windows 10 in your organization, it’s strongly recommended to take a look at the new security features Windows brings to the table. One specific feature that I recommend all of my customers looking at Windows 10 to implement is Credential Guard. It’s a feature that uses virtualization-based security to isolate secrets so that only privileged system software can access them. Meaning, no more pass-the-hash attacks, hopefully. Anyway, we can easily turn this on during the deployment of a Windows 10 device by using PowerShell. Basically, what you need to do is to add the Hyper-V Hypervisor and Isolated User Mode features, set a couple of registry values and you’re set. In this post I’ll demonstrate how you can enable Credential Guard by running the script below and how you have to configure it in your task sequence for a successful deployment.
If you want to read up on Credential Guard, you’ll be able to find more information on the link below:
https://technet.microsoft.com/itpro/windows/keep-secure/credential-guard

Script to enable Credential Guard

I’ve put together a PowerShell script that you’ll find below that will enable Credential Guard during Windows 10 deployment.

2017-07-03 – Updated the script so that it doesn’t enable Hyper-V on Windows 10 version 1607 or higher.
2016-08-10  – With the release of Windows 10 version 1607, it’s no longer a requirement to add the Isolated User Mode feature when enabling Credential Guard, since it’s now embedded in the Hypervisor. Therefor, I’ve updated the script below to only add the Isolated User Mode feature when the BuildNumber property in Win32_OperatingSystem is less than 14393.

<#
.SYNOPSIS
    Enable Credential Guard on Windows 10 during OS Deployment with ConfigMgr
.DESCRIPTION
    This script will enable a Windows 10 device being installed through OS Deployment with ConfigMgr to leverage Credential Guard
    in order to prevent pass-the-hash attacks.
.EXAMPLE
    .\Enable-CredentialGuard.ps1
.NOTES
    Version history:
    1.0.0 - (2016-06-08) Script created
    1.0.1 - (2016-08-10) Script updated to support Windows 10 version 1607 that no longer required the Isolated User Mode feature, since it's embedded in the hypervisor
    1.0.2 - (2017-07-03) Script updated since Windows 10 version 1607 and higher no longer needs Hyper-V feature for enablind Credential Guard
.NOTES
    FileName:    Enable-CredentialGuard.ps1
    Author:      Nickolaj Andersen
    Contact:     @NickolajA
    Created:     2016-06-08
    Updated:     2017-07-03
    Version:     1.0.2
#>
Begin {
    # Construct TSEnvironment object
    try {
        $TSEnvironment = New-Object -ComObject Microsoft.SMS.TSEnvironment -ErrorAction Stop
    }
    catch [System.Exception] {
        Write-Warning -Message "Unable to construct Microsoft.SMS.TSEnvironment object" ; exit 1
    }
}
Process {
    # Functions
    function Write-CMLogEntry {
      param(
        

[parameter(Mandatory=$true, HelpMessage=”Value added to the smsts.log file.”)]

[ValidateNotNullOrEmpty()] [string]$Value,

[parameter(Mandatory=$true, HelpMessage=”Severity for the log entry. 1 for Informational, 2 for Warning and 3 for Error.”)]

[ValidateNotNullOrEmpty()] [ValidateSet(“1”, “2”, “3”)] [string]$Severity,

[parameter(Mandatory=$false, HelpMessage=”Name of the log file that the entry will written to.”)]

[ValidateNotNullOrEmpty()] [string]$FileName = “EnableCredentialGuard.log” ) # Determine log file location $LogFilePath = Join-Path -Path $Script:TSEnvironment.Value(“_SMSTSLogPath”) -ChildPath $FileName # Construct time stamp for log entry $Time = -join @((Get-Date -Format “HH:mm:ss.fff”), “+”, (Get-WmiObject -Class Win32_TimeZone | Select-Object -ExpandProperty Bias)) # Construct date for log entry $Date = (Get-Date -Format “MM-dd-yyyy”) # Construct context for log entry $Context = $([System.Security.Principal.WindowsIdentity]::GetCurrent().Name) # Construct final log entry $LogText = “<![LOG[$($Value)]LOG]!><time=””$($Time)”” date=””$($Date)”” component=””CredentialGuard”” context=””$($Context)”” type=””$($Severity)”” thread=””$($PID)”” file=””””>” # Add value to log file try { Add-Content -Value $LogText -LiteralPath $LogFilePath -ErrorAction Stop } catch [System.Exception] { Write-Warning -Message “Unable to append log entry to EnableCredentialGuard.log file” } } # Write beginning of log file Write-CMLogEntry -Value “Starting configuration for Credential Guard” -Severity 1 if ([int](Get-WmiObject -Class Win32_OperatingSystem).BuildNumber -lt 14393) { try { # For version older than Windows 10 version 1607 (build 14939), enable required Windows Features for Credential Guard Enable-WindowsOptionalFeature -FeatureName Microsoft-Hyper-V-HyperVisor -Online -All -LimitAccess -NoRestart -ErrorAction Stop Write-CMLogEntry -Value “Successfully enabled Microsoft-Hyper-V-HyperVisor feature” -Severity 1 # For version older than Windows 10 version 1607 (build 14939), add the IsolatedUserMode feature as well Enable-WindowsOptionalFeature -FeatureName IsolatedUserMode -Online -All -LimitAccess -NoRestart -ErrorAction Stop Write-CMLogEntry -Value “Successfully enabled IsolatedUserMode feature” -Severity 1 } catch [System.Exception] { Write-CMLogEntry -Value “An error occured when enabling required windows features” -Severity 3 } } # Add required registry key for Credential Guard $RegistryKeyPath = “HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard” if (-not(Test-Path -Path $RegistryKeyPath)) { Write-CMLogEntry -Value “Creating HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceGuard registry key” -Severity 1 New-Item -Path $RegistryKeyPath -ItemType Directory -Force } # Add registry value RequirePlatformSecurityFeatures – 1 for Secure Boot only, 3 for Secure Boot and DMA Protection Write-CMLogEntry -Value “Adding HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceGuard\RequirePlatformSecurityFeatures value as DWORD with data 1” -Severity 1 New-ItemProperty -Path $RegistryKeyPath -Name RequirePlatformSecurityFeatures -PropertyType DWORD -Value 1 # Add registry value EnableVirtualizationBasedSecurity – 1 for Enabled, 0 for Disabled Write-CMLogEntry -Value “Adding HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceGuard\EnableVirtualizationBasedSecurity value as DWORD with data 1” -Severity 1 New-ItemProperty -Path $RegistryKeyPath -Name EnableVirtualizationBasedSecurity -PropertyType DWORD -Value 1 # Add registry value LsaCfgFlags – 1 enables Credential Guard with UEFI lock, 2 enables Credential Guard without lock, 0 for Disabled Write-CMLogEntry -Value “Adding HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\LsaCfgFlags value as DWORD with data 1” -Severity 1 New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Control\Lsa -Name LsaCfgFlags -PropertyType DWORD -Value 1 # Write end of log file Write-CMLogEntry -Value “Successfully enabled Credential Guard” -Severity 1 }

Configure The task Sequence

Adding this script to your task sequence is no big deal really, we simply just have to call a PowerShell script with the Run PowerShell Script step and point that to a Package that contains the script file. However, there’s a catch to enabling Credential Guard during OS deployment. When adding the Windows features, by using dism.exe for example like I do in my script, an exit code of 3010 will be returned. This is not something extraordinary, but the Hyper-V Hypervisor requires an extra restart. This would eventually prevent the task sequence to break if you would add a Restart Computer step right after the step that runs the script. To work around this, we can let the script that enables Credential Guard return 3010 and enforce a restart once the task sequence has completed by using the SMSTSPostAction variable. This way, when the task sequence has successfully completed, the dual restart enforced by the Hyper-V Hypervisor feature will not break the sequence.
1. Save the above script as e.g. Enable-CredentialGuard.ps1 in folder called EnableCredentialGuard in your Content Library.
2. Create a Package without any Program and set the Data Source location to the folder you just created. Remember to distribute the content to your Distribution Points.
3. Edit your task sequence used to deploy Windows 10.
4. Add a Run PowerShell Script step somewhere at the end of your task sequence, and configure it like in the picture below:
203_1
5. At the very top of your task sequence, add a Set Task Sequence Variable step and configure it like in the picture below:
203_2
6. Save the changes and start deploying!

Results

This script will log the output of the operations if performs in a log called EnableCredentialGuard.log that is stored together with the other task sequence logs. Eventually, once the deployment has completed, you’ll find it in C:\Windows\CCM\logs. Below is how a successful deployment that enabled Credential Guard looks like:
203_4
If you’d like to verify that Credential Guard actually was enabled on the device that you’ve deployed, open msinfo32.exe and scroll down in the System Summary section. You should see that Credential Guard is present in the value section, like shown below:
203_5
That’s it, I hope that you try this out and enables Credential Guard in your Windows 10 deployment. As usual, if you have any questions, feel free to comment below or send me an email.
 

Nickolaj Andersen

Chief Technical Architect and Enterprise Mobility MVP since 2016. Nickolaj has been in the IT industry for the past 10 years specializing in Enterprise Mobility and Security, Windows devices and deployments including automation. Awarded as PowerShell Hero in 2015 by the community for his script and tools contributions. Creator of ConfigMgr Prerequisites Tool, ConfigMgr OSD FrontEnd, ConfigMgr WebService to name a few. Frequent speaker at conferences such as Microsoft Ignite, NIC Conference and IT/Dev Connections including nordic user groups.

17 comments

  • For anyone finding this blog now, you can enable Credential Guard easily with Intune via “Home-Microsoft Intune-Device configuration-Profiles-Create profile-Endpoint protection-Windows Defender Credential Guard”. It will enable VBS and Secure Boot and you can do it with or without UEFI Lock.

  • Hi Nickolaj, are your sure in not enabling Hyper-V?
    2017-07-03 – Updated the script so that it doesn’t enable Hyper-V on Windows 10 version 1607 or higher
    i tried enabling CG without installation of HyperV – Image version was 1703, rebuilt ISO from June 17 – but it doesn’t matter, CG wasn’t active yet until i enabled the Hyper-V HyperVisor manually.
    Kind regards
    Chris

  • The script enables all of Hyper-V features but is it possible to disable other features like Managements Tools and Hyper-V Services so that only Hyper-V Hypervisor is left enabled?

  • What is the obstacle of attempting to implement this on a “build and capture” TS ?

      • In my environment, we capture WIMs monthly to include updates, and consequently minimize the time it takes to build a device. Every time we have to make changes to OSD, we always consider its possibility during capture TS. Your approach involves a couple of restarts which is totally fine by me, but you know how “initializing agent…” takes a while during TS after every restart. It sounds trivial, but if I can save minutes on build time for end-users, that would be a preference for us.

      • I get your point, but as a matter of fact, with Windows 10 version 1607 and higher you don’t need to add the Hyper-V features which removes the need to restart. A final restart at the end of your task sequence is considered best practice, and even fixes a few old but known issues. All of this should be enough for enabling this in the task sequence during deployment.
        Regards,
        Nickolaj

    • Hi Steve,
      Yes, you’re correct. This is a great addition/change in the requirements for Credential Guard. It will now allow for other applications to leverage the virtualization as well and not only allow Hyper-V access.
      Regards,
      Nickolaj

  • Is it still necessary to enable the hypervisor feature in order to enable credential guard? This article has a note which seems to imply that it is not:
    https://docs.microsoft.com/en-us/windows/access-protection/credential-guard/credential-guard-manage
    “If you enable Credential Guard by using Group Policy, the steps to enable Windows features through Control Panel or DISM are not required. Group Policy will install Windows features for you.”
    It doesn’t specifically mention the Hypervisor feature, but I do seem to have computers which show credential guard as running despite not having the hypervisor feature enabled.

  • Great post, i could not remove hyper v gui/tools etc during TS so i need just hyper v hypervisor for credential guard. any idea?

  • In a domain joined scenario, is there an advantage to enabling credential guard during using this script OSD versus using a group policy to enable credential guard?

    • Just a guess. I think IsolatedUserMode is not part of the Hypervisor in 1607. I would try removing that installation section of the script to see if it’s successful.

Sponsors