Part 2, Deep dive Microsoft Intune Management Extension – PowerShell Scripts

Because of the popularity of my first blog post Deep dive Microsoft Intune Management Extension – PowerShell Scripts, I’ve decided to write a second post regarding Intune Management Extension to further explain some architecture behind this feature and upcoming question from the community. A deeper understanding helps to successful troubleshoot the feature.

Table of content for easy navigation

 

Details of the MSI deployment of the Intune Management Extension agent?

Please read the first article Deep dive Microsoft Intune Management Extension – PowerShell Scripts, to get an understanding of the MSI install job.

The EnterpriseDesktopAppManagement CSP takes care of this task and delivers the MSI to the device and starts the execution. The CSP provides some helpful information in registry for troubleshooting.

In the registry at HKLM\SOFTWARE\Microsoft\EnterpriseDesktopAppManagement\<SID>\<MSI-ProductCode> you can find helpful information for troubleshooting:

EnterpriseDesktopAppManagementCspRegistry

Highlighted value names are described in detail here:

CurrentDownloadUrl: URL to the MSI install file.

EnforcementRetryCount: The number of times the download and installation operation will be retried before the installation will be marked as failed.

EnforcementRetryIndex: The current number of retry.

EnforcementRetryInterval: Amount of time, in minutes between retry operations.

EnforcementStartTime: Start time of enforcement.

EnforcementTimeout: Amount of time, in minutes that the installation process can run before the installer considers the installation may have failed and no longer monitors the installation operation.

LastError: Error after last execution.

Status: The Status can have the following values according to the EnterpriseDesktopAppManagement CSP documentation:

Value = Status
10 = Initialized
20 = Download In Progress
25 = Pending Download Retry
30 = Download Failed
40 = Download Completed
48 = Pending User Session
50 = Enforcement In Progress
55= Pending Enforcement Retry
60 = Enforcement Failed
70 = Enforcement Completed

In case of no sidecar agent on the device the status may indicate an error or it is still in progress of downloading. Try to figure out this status. Correlate the status with your device and environment. There may be a proxy issue?

According to the screenshot above the CSP will try it 3 times with a timeout of 10 min and then it will be marked as failed. Is there a retry after x days, I assume yes but I don’t have some documentation for it. As soon as I have more information I will update the article accordingly.

 

Be aware of the log files regarding sensitive data!

The following script below will create a local user account with a specified static password. It is a working script, but be aware that it should not be used in production! The whole script content will be logged to the IntuneManagementExtension.log file. There you will find the clear text static password as defined in the script. As an example I have copied and marked the particular log file entries below the script to show that. Disk encryption technologies like BitLocker are lowering the risks a bit, but even then this is not a concept to be used in production environments! An attacker can read the log files with standard user permissions and get the sensitive data. Without BitLocker encryption this can be done even offline!

Again: I do NOT recommend transferring sensitive data like passwords via this approach! I know it’s often done. There is a similar approach for on-prem AD which is often used. The GPO preferences for local user management tasks uses a simple xml file with passwords base64 encoded -> this is not secure! Please consider something that was build for that purpose. Admin account management should be done via LAPS or other third party. I know there is no equivalent solution like LAPS for a cloud only environment right now from Microsoft.

# Author: Oliver Kieselbach
# Date: 01/03/2018
# Description: Create a local user account.

# REMARK: DO NOT USE IN PRODUCTION, Password will not be unique and be visible in clear text in log file!

# The script is provided "AS IS" with no warranties.

Param([switch]$Is64Bit = $false)

Function Restart-As64BitProcess
{
If ([System.Environment]::Is64BitProcess) { return }
$Invocation = $($MyInvocation.PSCommandPath)
if ($Invocation -eq $null) { return }
$sysNativePath = $psHome.ToLower().Replace("syswow64", "sysnative")
Start-Process "$sysNativePath\powershell.exe" -ArgumentList "-ex bypass -file `"$Invocation`" -Is64Bit" -WindowStyle Hidden -Wait
}

if (!$Is64Bit) { Restart-As64BitProcess }
else
{
Start-Transcript -Path "$env:temp\CreateLocalUser.log"

$password = ConvertTo-SecureString "SecretP@ssw0rd!" -AsPlainText -Force
New-LocalUser "John" -AccountNeverExpires:$true -FullName "John Doe" -Password $password

Stop-Transcript
}

To demonstrate the problem with this approach, here is the corresponding log file part after script execution with the complete script and static password in clear text:

sensitivedatainlogfile.png

 

Getting content of scripts once they are uploaded to Intune?

The Intune Azure Portal does not provide any UI element to show the uploaded script again. Thanks to the GitHub repository Intune PowerShell Samples we do not script something by our own. We can use a script provided from there called DeviceManagementScripts_Get.ps1. It will get all uploaded scripts, including script content, and details from the Intune API via Microsoft Graph API.

Get it from here:
https://github.com/microsoftgraph/powershell-intune-samples/blob/master/DeviceConfiguration/DeviceManagementScripts_Get.ps1

Save it locally and run it with PowerShell and provide your Intune Administrator credentials when asked for:

IntuneManagementExtensionScriptContent

 

What about return codes (exit codes) of PowerShell scripts?

At the moment the Intune Management Extension will gather various results, but the Intune Azure portal does not show them in an UI element (if it will change in the future and we have something available, I will update the post accordingly). As for now scripts can be executed through the Intune agent and the Intune UI will show just the execution state success or failure. The status is related to successful agent execution, like no hash mismatch, no script content problem, and no error output… it does not reflect the script exit code.

Scripts like this, I called it “failscript.ps1” are handled as success at the moment:

[Environment]::Exit(-1)

See here the results in Intune Azure Portal:

IntuneAgentFailscriptStatus

Perhaps Intune will show us script exit codes in the UI sometime, then we could verify this easily with the failscript from above.

If we use Write-Error cmdlet in our scripts then Intune will pick up the error output. Here an example:

Write-Error -Message "Could not write regsitry value" -Category OperationStopped

This gives us a failed status in the monitoring section of the PowerShell scripts:

IntuneAgentWriteErrorScriptStatus

 

 

Where can I find a helpful PowerShell script template to start with?

I have made a simple script template which:

  1. Enforces execution in x64 PowerShell (restart of PowerShell as x64 process)
  2. Generates a log file in C:\Windows\temp when run in system context
    or %LocalAppData%\temp when run in user context
  3. Has exit code handling (exit code is even gathered when restarted as x64 process)
  4. Uses Write-Error to signal Intune a failed execution and makes sure we have reporting reflecting our script execution success (standard error is even gathered when restarted as x64 process)

For ongoing maintenance it is provided via GitHub Gist:

 

Script execution retry interval when failed?

The PowerShell scripts are executed via agent on the target device. If an execution fails, the agent tries to run the script again during next check-in. Current check-in interval is every 60 minutes. This procedure is limited to 3 attempts!

This is tracked in registry at:

HKLM\SOFTWARE\Microsoft\IntuneManagementExtension\Policies\UserGUID\ScriptGUID

The DownloadCount also means execution count and the result is tracked as Success or Failed.

IntuneManagementExtensionScriptRegistry

If we change the run as account (user/system), signature check or script content, the DownloadCount will be reset, and the agent will try another 3 attempts to execute the script.

 

Can we schedule scripts?

No we do not have a run schedule at the moment. For example the agent does not execute the script every x hours. The agent checks every 60 minutes for new policies in the backend – during this no re-run of scripts occurs once a script is successful executed. If scheduling of scripts is needed I suggest to register the script as a scheduled tasks via PS commands. That’s the only way at the moment (as soon as we have something available for scheduling I will update the post accordingly).

Below a script to copy the scheduled script to a certain folder like C:\ProgramData\CustomScripts\myScript.ps1 and then register a scheduled task to run it periodically:

# Author: Oliver Kieselbach
# Date: 01/31/2018
# Description: install ps script and register scheduled task

# The script is provided "AS IS" with no warranties.

# define your PS script here
$content = @"
Out-File -FilePath "C:\Windows\Temp\test.txt" -Encoding unicode -Force -InputObject "Hello World!"
"@

# create custom folder and write PS script
$path = $(Join-Path $env:ProgramData CustomScripts)
if (!(Test-Path $path))
{
 New-Item -Path $path -ItemType Directory -Force -Confirm:$false
}
Out-File -FilePath $(Join-Path $env:ProgramData CustomScripts\myScript.ps1) -Encoding unicode -Force -InputObject $content -Confirm:$false

# register script as scheduled task
$Time = New-ScheduledTaskTrigger -At 12:00 -Daily
$User = "SYSTEM"
$Action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-ex bypass -file `"C:\ProgramData\CustomScripts\myScript.ps1`""
Register-ScheduledTask -TaskName "RunCustomScriptDaily" -Trigger $Time -User $User -Action $Action -Force

Here some documentation regarding PowerShell and scheduled tasks:
https://docs.microsoft.com/en-us/powershell/module/scheduledtasks/register-scheduledtask?view=win10-ps

But you need to think about a strategy how to track all this or how to modify in the future. Once set you may want to have a modification script to change schedules or even delete it from the device again.

 

Integrated HealthCheck of Intune Management Extension agent?

The Intune Management Extension creates a scheduled task which will run a Health Check once a day.

IntuneManagementExtensionHealthCheck

If familiar with ConfigMgr and the ConfigMgr agent, there we have the same concept. The health check involves 4 files:

ClientHealthEval.exe and ClientHealthEval.exe.config: The binary which runs the health check.

HealthCheck.xml: The xml with all rules to run to perform the health check.

HealthReport.json: The json report with results of the rules defined by the xml.

The tests are defined in the xml file to check the agent registered service, startup type, service status and memory usage.

 

User interaction and timeout?

When using a scripts with the typical user interaction (like shown as an example in my first article Deep dive Microsoft Intune Management Extension – PowerShell Scripts), be advised that this script is getting executed and showing a dialog which blocks the script from finishing, until the user interacts with the dialog and then let the script finish. This can lead to timeouts and then scripts are getting marked as failed even when successfully ran.

The current default script timeout is 10 minutes for execution which is currently not adjustable.

 

If you find something missing or changed feel free to leave a comment. Thanks!

How to “Push-button reset” Windows 10

The “push-button reset” (PBR) is the way to do a “factory reset” on Windows 10. It constructs a fresh Windows 10 installation and we can start over again.

Implementing a Microsoft 365 powered device mobility concept for a modern workplace with Windows 10, makes usage of Windows as a Service and provides new ways of self enrollment. Wherever we are, we service the OS from the cloud (Windows Update for Business) and manage it from the cloud (Intune).

In case of failure there are primarily two options:

  • Get a new device and enroll the device to Azure AD again
  • Start push-button reset to run a factory reset and start over again

In case of failure or if we want to re-purpose the device (back into stock or hand over to another employee) we use the push-button reset in this concept.

 

How is push-button reset triggered from the client?

First of all we need to distinguish between a device where the user is local administrator and a device where the user is standard user.

In case of local administrator the push-button reset can be triggered from Settings > Update & Security > Recovery > Reset this PC > Get started

PBR Settings Local Administrator

As shown there are two options available:

  • Keep my files
  • Remove everything

When choosing “Remove everything” we have the following two additional options:

PBRResetEverything

Be aware if “Remove files and clean the drive” is chosen it will really take a long time to complete!

 

In case of standard user we do not have the reset option in settings available. This is relevant when using AutoPilot and a profile with “Disable local admin account creation on the device” as shown below:

AutoPilotProfileSfB

As a standard user the settings are shown with no reset option in the recovery menu:

PBRSettingsStandardUser

For Microsoft 365 powered devices managed by Intune we can deploy the Company Portal and use it to trigger the reset. Open the deployed Company Portal > choose device > … (menu in the upper right) > Reset

PBRCompanyPortal

PBRCompanyPortalDialog

 

How is push-button reset triggered from Intune?

We need to open the Intune portal portal.azure.com and navigate to Intune > Devices > All Devices > pick the particular device > Factory reset

IntuneFactoryReset

as shown in the screenshot there is the additional option to “Retain the enrollment state and user account”.

For detailed description what is retained please refer to: https://docs.microsoft.com/en-us/intune/devices-wipe#factory-reset

If the device is on and connected, it takes less than 15 minutes for a factory reset command to propagate across all device types.

 

What is the “Fresh Start” available in Intune?

The Fresh Start device action removes any apps that were installed on a Windows 10 PC running the Creators Update, then automatically updates the PC to the latest version of Windows. This can be used to help remove pre-installed (OEM) apps that are often delivered with a new PC. You can configure if user data is retained when this device action is issued. In this case, apps and settings are removed, but the contents of the users Home folder are retained.

IntuneFreshStart

IntuneFreshStartDialog

If the device is on and connected, it takes less than 15 minutes for a factory reset command to propagate across all device types.

 

Reset in Action

When a reset is triggered the device will end up rebooting and the reset will occur.

Windows10Resetting

After finishing the reset the device will start in OOBE again for new enrollment or at the logon screen when enrollment was retained.

 

Issues with Lenovo devices and the troubleshooting

During tests I observed Lenovo devices which ran into an error after resetting and starting into OOBE again. Shortly after language and keyboard selection I got this:

OOBESomethingWentWrong

After some debugging I found out that the license.rtf file was not available in C:\Windows\System32 and this blocked the OOBE from displaying the EULA and resulted in the “Something went wrong” error screen. Click on “Try again” generated a loop.

I could solve this problem with a small customization of the PBR. The PBR has options to add a script to the PBR routine. More details see here: https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/add-a-script-to-push-button-reset-features

I prepared a script which copies the license.rtf file back to C:\Windows\System32 folder if it is missing after the reset. We need to prepare 2 files and we need the license.rtf from a running Windows 10 device.

EnableCustomizations.cmd

rem EnableCustomizations.cmd

rem Define %TARGETOS% as the Windows folder (This later becomes C:\Windows)
for /F "tokens=1,2,3 delims= " %%A in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\RecoveryEnvironment" /v TargetOS') DO SET TARGETOS=%%C

rem Define %TARGETOSDRIVE% as the Windows partition (This later becomes C:)
for /F "tokens=1 delims=\" %%A in ('Echo %TARGETOS%') DO SET TARGETOSDRIVE=%%A

rem Add back license.rtf file if missing
IF NOT EXIST "%TARGETOS%\System32\license.rtf" (
copy "%TARGETOSDRIVE%\Recovery\OEM\license.rtf" "%TARGETOS%\System32\license.rtf" /y
)
exit /b 0

ResetConfig.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- ResetConfig.xml -->
<Reset>
 <Run Phase="BasicReset_AfterImageApply">
 <Path>EnableCustomizations.cmd</Path>
 <Duration>2</Duration>
 </Run>
 <Run Phase="FactoryReset_AfterImageApply">
 <Path>EnableCustomizations.cmd</Path>
 <Duration>2</Duration>
 </Run>
</Reset>

In the end copy EnableCustomizations.cmd, ResetConfig.xml and the license.rtf to the folder:

C:\Recovery\OEM

After deploying the custom PBR fix for the Lenovo devices the push button reset runs smoothly.

 

Further information

Remove devices by using factory reset or remove company data
https://docs.microsoft.com/en-us/intune/devices-wipe

Push-button reset
https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/push-button-reset-overview

Add a script to push-button reset features
https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/add-a-script-to-push-button-reset-features

 

Happy resetting!

 

Configure Delivery Optimization with Intune for Windows Update for Business

When using the Modern IT approach and building Microsoft 365 powered devices it is a combination of the following cloud services for Modern Management:

WUfB

To support the Windows as a Service strategy with cloud services we rely on the well known Windows Update service, but with the controls for business usage. This is called Windows Update for Business (WUfB). That means our content is provided by Microsoft Update servers and we define the installation behavior like deferrals or even pause of feature or quality updates. The WUfB settings can be configured in Intune via Software Udpates. This article will not show details of the WUfB settings.

For successful servicing we need to make sure an internet break out with proper bandwidth capacity is available to support our devices. To prevent internet traffic congestion we can utilize Peer 2 Peer technologies like BranchCache and Delivery Optimization to optimize Windows 10 update delivery. In case of Windows Update for Business we need to focus on Delivery Optimization (DO).

You can use Delivery Optimization to reduce bandwidth consumption by sharing the work of downloading these packages among multiple devices in your deployment. Delivery Optimization can accomplish this because it is a self-organizing distributed cache that allows clients to download those packages from alternate sources (such as other peers on the network) in addition to the traditional Internet-based Windows Update servers.

How does Delivery Optimization work in detail?

First of all the published content must be chunked and hashed. Currently Microsoft supports the following content:

  • Windows Updates (Feature/Quality)
  • Drivers
  • Store Apps

The basic procedure is:

  1. Client A checks for Updates
  2. Client A gets download sources (MS content server and additional clients (peers) B, C, …
  3. Client A requests chunks from MS content server and peers B, C, …
  4. Client A verifies hashes of chunks and builds file from chunks
  5. Client A verifies complete file via hash

The clients will check-in to the Delivery Optimization cloud service as long as the content is valid in its cache. This is necessary to let DO service keep track of devices and let it distribute peer info to requesting clients.

The Delivery Optimization has multiple Download Modes and this is an important part for successful utilization of DO. It configures the logical grouping of devices based on certain criteria. In this example we set Download Mode to Group and we use a custom group ID. This custom Group ID can be delivered by DHCP as an Option ID with code 234 when using upcoming Windows 10 Version 1803.

Group download mode is the recommended option for most organizations looking to achieve the best bandwidth optimization with Delivery Optimization.

The custom group id delivered by DHCP for scoped devices will let us take control over the grouping. We can assign multiple DHCP scopes the same Group ID or different Group IDs. That’s how we build our device collections and control the peer 2 peer traffic even across NATs.

The DO Peer 2 Peer traffic is a direct TCP/UDP connection on port 7680.

DOFirewall

Now we can build effective groups aligned with our networking infrastructure to restrict P2P traffic to physical sites, multiple sites, subnets, what ever we want.

 

How to configure DO with Intune?

At time of this writing I’m using the Insider Preview for the upcoming Windows 10 Version 1803 to test and include settings which are really worth to mention in this context.

I won’t get into details about every available setting but I will show a complete setup to test DHCP Option ID as source for Group ID.

The custom group ID can be generated by PowerShell:

[guid]::NewGuid()

The custom OMA-URI to configure Download Mode to Group is:

Name: DODownloadMode
OMA-URI: ./Vendor/MSFT/Policy/Config/DeliveryOptimization/DODownloadMode
Data type: integer
Value: 2 (group)

With Windows 10 Version 1803 we can provide the Group ID as a DHCP Option ID with code 234. To configure the client to use DHCP option ID we need to configure the following OMA-URI:

Name: DOGroupIdSource
OMA-URI: ./Vendor/MSFT/Policy/Config/DeliveryOptimization/DOGroupIdSource
Data type: integer
Value: 3 (DHCP Option ID)

Now we need to configure our DHCP infrastructure to provide the DHCP Option ID to our clients. In my example I use a Microsoft DHCP Server:

1. Set Predefined Options

 

MSDHCPpredefinedOptions

2. Configure the Predefined Options

MSDHCPpredefinedoptionsAdd

3. Confirm with OK

MSDHCPGroupIdValue

4. Configure Scope Options

MSDHCPScopeOptions

5. Set Custom Group ID as Option ID 234

MSDHCPScopeOptionsGroupId

6. Verify new Scope Option 234 DOGroupID

MSDHCPGroupIdOptionInScope

This would be enough to let all clients in the same DHCP scope group together and allow P2P traffic.

When testing DO in Virtual Machines I encourage you to configure the following additional settings:

  • DOMinFileSizeToCache to 1 MB to ensure caching with even small downloads
  • DOMinRAMAllowedToPeer to 1 GB to let VMs with small amount of RAM P2P
  • DOPercentageMaxForeDownloadBandwidth to limit manual Store download Bandwith (this will not restrict peer traffic) *
  • DODelayForegroundDownloadFromHttp to 30 seconds to give time to find other peers *

* Windows 10 Version 1803 is needed

Custom OMA-URIs:

./Vendor/MSFT/Policy/Config/DeliveryOptimization/DOMinFileSizeToCache = 1 (Integer, in MB)

./Vendor/MSFT/Policy/Config/DeliveryOptimization/DOMinRAMAllowedToPeer = 1 (Integer, in GB)

./Vendor/MSFT/Policy/Config/DeliveryOptimization/DOPercentageMaxForeDownloadBandwidth = 10 (Integer, in %)

./Vendor/MSFT/Policy/Config/DeliveryOptimization/DODelayForegroundDownloadFromHttp = 30 (Integer, in Sec.)

A test environment configuration may look like this:

DOMDMSettings

For production environments please review all available MDM Delivery Optimization settings and adjust as needed for your environment. For example DOMaxCacheAge, DOMinBackgroundQoS and DOPercentageMaxBackDownloadBandwidth might be from interest for production environments. Remember to check for new settings with every new Version of Windows 10!

 

Test to verify everything works as expected!

Make sure the settings are applied to the test devices. Generate a advanced diagnostic report:

Open Settings > Accounts > Access work or school > Connected to TenantName’s Azure AD > Info > scroll down to the bottom and click “Create report”

AdvancedDiagnosticsReport

Important settings to verify:

DOMDMReport

Test procedure:

On Client A start a download from the Store with 100MB+ download size and wait for finish. You should observe a throttled download when using VMs with setting DOPercentageMaxForeDownloadBandwidth.

On Client B start the same download from the Store and wait for finish. You should notice a significant faster download on Client B, as it will receive data from local peer without restrictions when tested with VMs and mentioned settings above.

Since Windows 10 Version 1803 we can generate a DO log file to trace the behavior:

Get-DeliveryOptimizationLog | ft -Wrap | Out-File -FilePath $env:temp\DOLogs.txt ; notepad $env:temp\DOLogs.txt

Get the log files from Client A and B and look for entry “Using groupID”, here you must find the DHCP Group ID in both logs:

DOLogFileGroupId

On Client B you will find stats regarding communication with Peer Client A on port 7680:

DOLogfilePeerUsage

If you like to test again you can use disk cleanup utility to clean the DO cache:

DODiskCleanup

Then uninstall the Store app and start the test over again.

 

Further information

 

Happy caching and a good P2P utilization!

How to disable SMBv1 with Intune [deep dive analysis]

I recently got motivated to research a bit about new MDM settings available in the latest Windows 10 Insider Build (17074) and how to configure them. Settings available in preview Windows 10 versions normally do not have a lot of technical documentation for it or there is even no documentation for a particular feature and corresponding setting at preview release time.

In this post I would like to show how to get the right pieces of information to configure an ADMX-backed policy setting in Windows 10 via Intune OMA-URIs with no technical documentation for it. We need to get all implementation details by our self. My goal is to show some of the inner workings how parts of the MDM policies are implemented and how we can get a deeper understanding of them.

I’ll demonstrate my analysis with some new Windows 10 latest Insider build settings (at time of writing build version 17074) derived from MSSecurityGuide to control SMBv1 on the device. The two settings are:

  • ConfigureSMBV1ClientDriver
  • ConfigureSMBV1Server

These settings control the SMB 1.0/CIFS File Sharing Support

Optional Feature SMBv1

 

How do we get to know this new available settings?

First we have a look at the registry. There is a new place where you can find MDM Policy CSP settings. Group Policy settings are stored in the Policies registry key and MDM Policy CSP settings can be found in the PolicyManager key here:

HKLM\SOFTWARE\Mircosoft\PolicyManager

As we see in the screenshot below there are two different sub keys. One current key and a default key.

Within the current key we find all settings configured for this device by Policy CSP via MDM like Intune. Within the default key we find all available settings for the particular Windows 10 release.

RegistryPolicyManagerDefault

As mentioned the latest Windows 10 version (at time of writing build version 17074) has a sub key for MSSecurityGuide with additional sub keys for ConfigureSMBV1ClientDriver and ConfigureSMBV1Server.

RegistryPolicyManagerSMBv1

If we have a look at the details, for example of ConfigureSMBV1ClientDriver we see the value name admxMetadataDevice. This gives us a hint that this particular policy is an ADMX-backed policy.

SMBv1ADMXHint

 

How do we configure it if we don’t know the input values for it?

The way Microsoft implemented the feature ADMX-backed policies is as follows:

A defined set of the default policies which come with the OS in the path C:\Windows\PolicyDefinitions are parsed at OS build time and stored in the MDM store as converted MDM policies. The second way is to ingest custom ADMX files after OS shipment which are then also parsed and stored in the MDM store as MDM policies. I wrote an ADMX file ingestion article for a custom OneDrive ADMX file here: Deep dive ADMX ingestion to configure SilentAccountConfig with OneDrive.

For a thorough understanding everyone should read the Background section of the Microsoft docs article Understanding ADMX-backed policies.

With all that in mind we need to find the original ADMX file for the policy and then we can derive the actual values for configuration because ADMX-backed policies are configured by a schema derived from the ADMX xml file structure.

Luckily I know that the MSSecurityGuide is provided by Microsoft through the Microsoft Security Compliance Toolkit 1.0 and within that package is the Windows 10 Version 1709 Security Baseline.zip. This includes the SecGuide.admx in the subfolder Templates.

SecGuideAdmx

Due to public knowledge how to configure ADMX-backed policies we can derive the configuration input values from the SecGuide.admx file. To derive the input values we need to study the article Understanding ADMX-backed policies especially the sections ADMX-backed policy examples and Sample SyncML for various ADMX elements.

To create the OMA-URI we append the registry key MSSecurityGuide and the sub key ConfigureSMBV1ClientDriver to ./Vendor/MSFT/Policy/Config/

./Vendor/MSFT/Policy/Config/MSSecurityGuide/ConfigureSMBV1ClientDriver

Now we need to follow the Sample SyncML for various ADMX elements for proper Enum usage as input value to disable the SMBv1 Client driver

  1. find enum
  2. get name from id attribute
  3. choose value for disable

SecGuideAdmxXml

construct the xml data element with derived values for id and value:

<data id="Pol_SecGuide_SMB1ClientDriver" value="4"/>

The result is the following custom OMA-URI setting:

Name: ConfigureSMBV1ClientDriver
OMA-URI: ./Vendor/MSFT/Policy/Config/MSSecurityGuide/ConfigureSMBV1ClientDriver
Data type: string 
Value:
<enabled/>
<data id="Pol_SecGuide_SMB1ClientDriver" value="4"/>

 

According to How to detect, enable and disable SMBv1, SMBv2, and SMBv3 in Windows and Windows Server the SMBv1 Server can be controlled by this registry key:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters
Registry entry: SMB1 REG_DWORD: 0 = Disabled

To disable the SMBv1 Server we need to set the registry value SMB10 and this is the disabled value in the SecGuide.admx xml file.

SecGuideAdmxXml2

The result is the following custom OMA-URI setting:

Name: ConfigureSMBV1Server
OMA-URI: ./Vendor/MSFT/Policy/Config/MSSecurityGuide/ConfigureSMBV1Server
Data type: string 
Value: <disabled/>

Now we configure this as a custom OMA-URI in Intune and target it to our user group with Windows 10 Insider builds

SMBv1MDMOMAURI

 

How to verify if the settings are correctly deployed?

First of all we can generate a MDM Advanced Diagnostics Report:

Open Settings > Accounts > Access work or school > Connected to TenantName’s Azure AD > Info > scroll down to the bottom and click “Create report”

AdvancedDiagnosticsReport

open the Report MDMDiagReport.html it in Edge and look for:

MDMReport

Second we can check the registry for MDM applied settings:

SMBv1MDMSetting

Third we can verify the SMBv1 LanmanServer > Parameters > SMB1 = 0:

SMBv1ServerSetting

We can query the Windows feature if not enabled via PowerShell:

Get-WindowsOptionalFeature -Online -FeatureName SMB1Protocol

SMBv1WindowsFeature

We can verify the SMBv1 Client and Server component via PowerShell:

Get-SmbServerConfiguration | Select EnableSMB1Protocol, EnableSMB2Protocol

SMBv1ServerConfig

sc.exe query MRXSMB10

SMBv1ClientConfig

Congratulations you successfully disabled the SMBv1 protocol as recommended in the Security Baseline for Windows 10!

Important note

SMBv1 is not installed by default in Windows 10 Fall Creators Update and Windows Server, version 1709
https://support.microsoft.com/en-us/help/4034314/smbv1-is-not-installed-windows-10-and-windows-server-version-1709

If a Windows 10 Version was upgraded from an earlier edition like RS2 to RS3, SMBv1 is not deactivated, the install state is migrated. SMBv1 will not be installed for fresh RS3 installations. The setting above would enforce uninstall of SMBv1 for migrated devices.

Further information

Configuring Windows Defender Credential Guard with Intune

The Windows Defender Credential Guard is a feature to protect NTLM, Kerberos and Sign-on credentials. Windows 10 Enterprise provides the capability to isolate certain Operating System (OS) pieces via so called virtualization-based security (VBS). NTLM and Kerberos credentials are normally stored in the Local Security Authority (LSA). Once VBS is enabled the LSASS process will be split into an isolated process (protected by virtualization based security)  called LSAiso and the LSASS process. The LSAiso process can not be accessed by other OS components than the LSASS. This approach protects credentials from malicious tools which gained system context access. A well known tool to accomplish extraction of credentials from LSASS in system context is Mimikatz. This will not work after enabling Windows Defender Credential Guard as the only process validated to gain access to LSAiso process is LSASS.

With that in mind Credential Guard can protect an attack vector used by a lot of bad guys trying to steal sensitive information. It’s really worth considering to turn this protection on for Windows 10 Enterprise x64 (no support for x86) devices.

CredentialGuardDesign

Further information of Credential Guard:
https://docs.microsoft.com/en-us/windows/access-protection/credential-guard/credential-guard-how-it-works

 

How do we configure this via Modern Management in Intune?

Since Windows 10 Version 1709 Microsoft provides Policy CSP support to configure Credential Guard via custom OMA-URIs. We can create a custom device profile:

CreateDeviceProfile

and then choose Profile type: custom

CredentialGuardDeviceProfile

Here we add the following OMA-URIs to configure Credential Guard with default settings and additional DMA Protection:

Name: DeviceGuard/EnableVirtualizationBasedSecurity
OMA-URI: ./Vendor/MSFT/Policy/Config/DeviceGuard/EnableVirtualizationBasedSecurity
Data type: integer
Value: 1 (enable virtualization based security)

Name: DeviceGuard/EnableVirtualizationBasedSecurity
OMA-URI: ./Vendor/MSFT/Policy/Config/DeviceGuard/LsaCfgFlags
Data type: integer
Value: 1 (Enabled with UEFI lock)

Name: DeviceGuard/EnableVirtualizationBasedSecurity
OMA-URI: ./Vendor/MSFT/Policy/Config/DeviceGuard/RequirePlatformSecurityFeatures
Data type: integer
Value: 3 (Turns on VBS with Secure Boot and direct memory access (DMA). DMA requires hardware support.)

Further information regarding Policy CSP values:
https://docs.microsoft.com/en-us/windows/client-management/mdm/policy-csp-deviceguard

As a last step we assign the new device configuration profile to our user group we want to provide the additional Credential Guard protection.

 

How to verify successful configuration?

First of all we verify if Intune applied the configuration successfully:

CredentialGuardDeploymentStatus

Then you can verify the applied registry settings on the target device of the user:

CredentialGuardRegistrySettings

Further information regarding registry settings:
https://docs.microsoft.com/en-us/windows/access-protection/credential-guard/credential-guard-manage

Make sure the device was restarted after successful configuration! This is needed as Credential Guard relies on Hyper-V technology for virtualization-based security and therefore it will enable the feature Hyper-V Hypervisor component.

We can have a look for the LsaIso.exe process in task manager:

CredentialGuardProcess

Finally we open up msinfo32.exe and verify if virtualization-based security is running and Credential Guard is activated:

CredentialGuardMsinfo32

If everything went well your machine is now protected against stealing of password secrets (hashes) which can be used by attackers for Pass-The-Hash (PTH) attacks. Keep in mind that this will not protect against attacks like key loggers. The solution is an effective way to protect credential stealing from memory.

 

How to test this in a Hyper-V Virtual Machine?

When using Microsoft Hyper-V you can enable nested virtualization on the VM and enable the Trusted Platform Module. Now you can test Credential Guard in your Hyper-V VM.

Enabling nested virtualization on Hyper-V VM:

Set-VMProcessor -VMName <VMName> -ExposeVirtualizationExtensions $true

Further information on nested virtualization:
https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/user-guide/nested-virtualization

Enabling the TPM on Hyper-V VM:

HyperVTPM

 

Additional things to consider?

The target hardware must support Credential Guard
https://docs.microsoft.com/en-us/windows/access-protection/credential-guard/credential-guard-requirements

Compatibility problems
https://docs.microsoft.com/en-us/windows/access-protection/credential-guard/credential-guard-considerations

Limitation in protection
https://docs.microsoft.com/en-us/windows/access-protection/credential-guard/credential-guard-protection-limits

 

UPDATE

Virtualization based security (VBS) will be available for non-Enterprise SKUs and starting with RS4+ VBS will be automatically enabled for clean installs!

 

If you are using Windows 10 please try Credential Guard in your environment as it is a really big security enhancement of Windows 10 Enterprise.