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:


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. I’ve also uploaded this script to my GitHub repository for your convenience.


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.

    Enable Credential Guard on Windows 10 during OS Deployment with ConfigMgr

    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.



    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

    FileName:    Enable-CredentialGuard.ps1
    Author:      Nickolaj Andersen
    Contact:     @NickolajA
    Created:     2016-06-08
    Updated:     2016-08-10
    Version:     1.0.1
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 {
		    [parameter(Mandatory=$true, HelpMessage="Value added to the smsts.log file.")]

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

		    [parameter(Mandatory=$false, HelpMessage="Name of the log file that the entry will written to.")]
		    [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=""DynamicApplicationsList"" 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 smsts.log file"

    function Invoke-Executable {
            [parameter(Mandatory=$true, HelpMessage="Specify the name of the executable to be invoked including the extension")]

            [parameter(Mandatory=$false, HelpMessage="Specify arguments that will be passed to the executable")]

        if ([System.String]::IsNullOrEmpty($Arguments)) {
            try {
                $ReturnValue = Start-Process -FilePath $Name -NoNewWindow -Passthru -Wait -ErrorAction Stop
            catch [System.Exception] {
                Write-Warning -Message $_.Exception.Message ; break
        else {
            try {
                $ReturnValue = Start-Process -FilePath $Name -ArgumentList $Arguments -NoNewWindow -Passthru -Wait -ErrorAction Stop
            catch [System.Exception] {
                Write-Warning -Message $_.Exception.Message ; break

        # Return exit code from executable
        return $ReturnValue.ExitCode

    # Write beginning of log file
    Write-CMLogEntry -Value "Starting configuration for Credential Guard" -Severity 1

    # Enable required Windows Features for Credential Guard
    $FeatureHyperVisor = Invoke-Executable -Name dism.exe -Arguments "/Online /Enable-Feature /FeatureName:Microsoft-Hyper-V-HyperVisor /All /LimitAccess /NoRestart"
    if ($FeatureHyperVisor -in @(0, 3010)) {
        Write-CMLogEntry -Value "Successfully enabled Microsoft-Hyper-V-HyperVisor feature" -Severity 1    
    else {
        Write-CMLogEntry -Value "When enabling Microsoft-Hyper-V-HyperVisor feature, an unexpected exit code of $($FeatureHyperVisor) was returned" -Severity 3

    # For version older than Windows 10 version 1607 (build 14939), add the IsolatedUserMode feature as well
    if ([int](Get-WmiObject -Class Win32_OperatingSystem).BuildNumber -lt 14393) {
        $FeatureIsolatedUserMode = Invoke-Executable -Name dism.exe -Arguments "/Online /Enable-Feature /FeatureName:IsolatedUserMode /LimitAccess /NoRestart"
        if ($FeatureIsolatedUserMode -in @(0, 3010)) {
            Write-CMLogEntry -Value "Successfully enabled IsolatedUserMode feature" -Severity 1    
        else {
            Write-CMLogEntry -Value "When enabling IsolatedUserMode feature, an unexpected exit code of $($FeatureIsolatedUserMode) was returned" -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:
5. At the very top of your task sequence, add a Set Task Sequence Variable step and configure it like in the picture below:
6. Save the changes and start deploying!


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:
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:
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.



  1. Aaron

    Seems to be failing in 1607 deployments

    1. Bill Moore

      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.

  2. Bill Moore

    Haha. Should read *now* part of the hypervisor. Apologies.

  3. Steve Whitcher

    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?


Leave a Comment

Your email address will not be published. Required fields are marked *