3 Simple Steps to Deploying Win32 Applications with your MDM

Application management for Windows is hard. There is so much variation in the types of application packages that need to be deployed, moving from a PCLM tool to a modern tool like Workspace One can feel like TOO big of a job to do all at once.

Photo by JESHOOTS.com on Pexels.com

Never fear! All problems can be solved if you look at them in meaningful chunks.

There are three segments of the application deployment process that need to be addressed if you are going to make the move to Modern Management:

  1. Packaging
  2. Install Context
  3. Logging

Depending on how mature your organization is on these three aspects of application deployment, you may find moving to Modern Management easier than you thought.

Packaging

In our organization, we already had a very mature capability for Packaging our hundreds of natively installed applications.

What do I mean by mature? In our case, the bits that needed to be installed were wrapped in a script (e.g.- VBS, Powershell) which performs a series of pre-execution checks (for example – is the app already installed), executes the required installation command(s) in a specific sequence, and produces a log file. A standard format README file is also created for each package to indicate details such as installation command line, how to know when the installation is completed, installation context, reboot required, etc.

This consistency allows every application whether a single MSI, Executable, or combination or series including transforms and patches to be installed in a consisten and repeatable way. The process is executed the same way every single time.

Our MDM toolset is able to deploy application in ZIP format which aligns perfectly with the package approach that I just described. Please note that NOT ALL MDMs are able to deploy ZIP format. If you are using an MDM that does not support deploying ZIP format, then you will need to create a format that is supported by your MDM. A word of caution, creating a format such as MSI or EXE may or may not be supported by the vendor so ZIP is really a nice format to be able to use.

Install Context

The vast majority of applications should be installed in the System Context rather than the User Context. This eliminates concerns around whether the user of the PC has Administrative rights for installation of applications. It also ensure that the application is installed for All Users on the PC instead of for a single user. If you need to manually test whether the application successfully installs in System context, you will want to use PSEXEC to execute the installation. I will share more in a future post about how to use PSEXEC to install in System context manually.

95% or more of our application packages were built for installation in the System Context so that made our move to Modern Management easy. For situations where existing packages were being installed as User Context, we revised the packages to eliminate the need. In some cases, it was just a matter of deleting unnecessary code. In other cases, we leveraged Active Setup to copy needed files to user directories. If the packages could not be revised, then we leveraged a third-party tool to provide automatic elevation for User Context package installation on our PCs.

Logging

I am a very lazy coder so it is pretty funny for me to identify logging as the last item in the must haves list. It is important that the installation logs that are created by your packages write to a consistent location and that the location is easily accessible by a Standard User on the PC. No matter how great a package you have created, when you begin deploying a package with an Electronic Software Distribution tool you will see errors in installations and you will need quick access to the logs on a PC in order to determine the issue (which is typically within the package and not very often due to an issue with the tool).

I can’t tell you how many times I ‘ve been told, I tested in on my PC and it worked by an App Owner. The reality is that when you take that package and install it on 1,000 PCs you are going to run into scenarios that you did not account for in your package. Logging is essential to identifying these scenarios.

So that’s all that I wanted to share on this topic today. We were able to reuse hundreds of packages that were originally prepared for distribution using a PCLM tool and successfully deploy them with our MDM tens of thousands of times on Windows 10.

Create a Custom ADMX Policy

If your MDM does not provide a method for running scripts, you may want to create a Custom ADMX Policy to apply registry settings to your Windows 10 devices for situations where there are not CSPs available.

There are some limitations to what registry settings you can apply via Custom ADMX Policy. Policies are not allowed to write to locations within the System, Software\Microsoft, and Software\Policies\Microsoft keys, except for the following locations (Note – the following locations are ALLOWED):

  • Software\Policies\Microsoft\Office\
  • Software\Microsoft\Office\
  • Software\Microsoft\Windows\CurrentVersion\Explorer\
  • Software\Microsoft\Internet Explorer\
  • software\policies\microsoft\shared tools\proofing tools\
  • software\policies\microsoft\imejp\
  • software\policies\microsoft\ime\shared\
  • software\policies\microsoft\shared tools\graphics filters\
  • software\policies\microsoft\windows\currentversion\explorer\
  • software\policies\microsoft\softwareprotectionplatform\
  • software\policies\microsoft\officesoftwareprotectionplatform\
  • software\policies\microsoft\windows\windows search\preferences\
  • software\policies\microsoft\exchange\
  • software\microsoft\shared tools\proofing tools\
  • software\microsoft\shared tools\graphics filters\
  • software\microsoft\windows\windows search\preferences\
  • software\microsoft\exchange\
  • software\policies\microsoft\vba\security\
  • software\microsoft\onedrive

You can also choose to use existing ADMX group policies that are available for software packages such as Google Chrome and Microsoft Office. I have used both. Just be sure to encode the policy before applying them.

Here is an example of a custom ADMX policy that I created in order to apply the following registry setting:

HKCU:\Control Panel\International\User Profile

HttpAcceptLanguageOptOut

This is the Custom ADMX Policy that must be pushed to your device first before applying the actual policy setting:

Note carefully that I didn’t both to edit anything that wasn’t 100% necessary. Most of you will probably want to pretty up the category and policy names so that it is prettier. I am more of a minimalist 🙂 or maybe just a little bit lazy!

The only thing that is really important is that you:

  1. Specify which registry location and key you need to set
  2. Specify whether it is a “User” policy or a “Machine” policy
  3. Make note of the Policy Name that you are going to need to reference when applying the policy

Now that I have my policy applied, I want to set the registry key value to “1” (aka enabled). The next step is to push the following policy to the device to actual add the registry key with the correct value:

If you navigate to the registry of the device, you will see the custom ADMX Policy in this location:

HKLM:\Software\Microsoft\PolicyManager\ADMXDefault

You will also see the applied policy, in this location:

HKLM:\Software\Microsoft\PolicyManager\Current

and, of course, the destination registry key that we intended to set is now successfully applied.

Here is a really good article with video about how Custom Policies are created and applied –> https://docs.microsoft.com/en-us/windows/client-management/mdm/win32-and-centennial-app-policy-configuration

I used the article to figure out how to do this the first time, but it was a pain so I hope that my example will be helpful to you if you are looking to create a custom policy for the first time.

Using CDATA within an MDM Policy

There is a lot written on MDM policy including references to using CDATA. Here is a real life example of a policy ( InternetExplorer\AllowAddons ) written with CDATA vs. encoded:

CDATA

ENCODED

CDATA is much easier to read so if your MDM supports it, obviously you would want to use it. My personal experience is the VMWare Workspace One supports CDATA.

Please comment if the MDM that you use, supports CDATA also!

Create a Local Administrator Account

It is common to use a local Administrator account to provide Administrative access for technicians when they are imaging or configuring PCs. It would be bad form, security-wise to leave this type of account in place so it is typically deleted at the end of the build process.

If you ever find yourself in a situation where you need to re-add a local account, you can do it with OMA-DM using Accounts CSP with the following Custom XML:

Note – only Add is available with this CSP so your MDM provider will need to provide scripting support in order to provide full account management features.

Confirming that MDM Policies have been applied

It is really difficult to feel confident about the move from GPO to MDM Policy, when you don’t know how to confirm that a policy has been successfully applied. I can’t tell you how many times over the past two years, people have raised concerns that they can’t see our MDM policies in the Group Policy editor 🙂

This post is all about sharing what I’ve learned over the past two years about how to confirm that an MDM policy has been successfully applied using tools that are built into the Windows 10 client.

For the most part (there are some exceptions like Firewall and Applocker), there are three tools built into the Windows 10 client that you can use to confirm that an MDM policy has been applied:

  1. Event Viewer
  2. Registry Editor
  3. MDM Report

Using the Event Viewer

When you push a policy from the MDM of your choice, logs for the event are stored in the following log:

Microsoft-Windows-DeviceManagement-Enterprise-Diagnostics-Provider/Admin

Using the Registry Editor

In order to use the registry editor to monitor the application of MDM policies, I first wanted to share a diagram that shows at a very high level how policies are processed.

MDM policies are processed by the OMA-DM client and ultimately the destination registry settings that are impacted by the application of MDM policies are identical (there are of course exceptions) to the destination registry settings for Group Policy.

The Intermediate Registry Setting for a policy can be found in the following location:

HKLM:\Software\Microsoft\PolicyManager\Current (tells you which policies have been applied, but not always the value for the policy that was applied)

and

HKLM:\Software\Microsoft\PolicyManager\Provider\<provider ID for your device-MDM relationship> (tells you which policies have been applied, and the value of the policy)

The Destination Registry Setting for ADMX policies can be found in the following location:

HKLM:\Software\Microsoft\PolicyManager\Default

RegKeyPathRedirect

RegValueNameRedirect

I have had the most luck identifying the Destination Registry Setting for non-ADMX policies by searching the internet, but in another post, I will share a list of non-ADMX destination registry setting locations that I have already identified.

The most important thing to remember is that your destination registry settings can be modified by user’s directly if they are Administrators or via GPO so if you don’t reapply MDM policies the actual value of the policy on your clients can drift. In our situation, we have chosen to leverage an API feature of our MDM which allows us to identify drift in the destination registry settings and reapply the MDM policy to remediate.

Using the Advanced Diagnostic Report

The MDM Report can also be used to verify that MDM settings have been applied. To use the MDM report on a device, perform the following steps:

  1. Search for Access work or school
  2. Click on the resource that ends with “MDM” then click Info
  3. Scroll down to the bottom of the page
  4. Click Create Report
  5. Click Export
  6. The report can be retrieved from C:\Users\Public\Documents\MDM Diagnostics

I hope that you found this post useful. Feel free to comment or message me if you have any additional questions or if you have additional information that you would like to share on this topic.

My CSP Playlist

Photo by Pixabay on Pexels.com

I worked really, really hard to learn to play the piano accompaniment at mass. It took me a whole year to be able to play the entire mass. I started by playing just 1 song for each mass because 1 song was all that I was comfortable learning and then playing within a single week. Thankfully, the music director was extremely supportive; she would play the rest of the songs each week to make this scenario possible. I doubt that there are very many music directors out there that would be willing to do that.

Over time, I became comfortable learning and playing 2 songs in a week; then finally 3 songs. Eventually, I was able to play 4 songs in a week not because I could learn 4 songs in a week, but rather it was because I already knew 1 of the songs. Over time, I knew so many songs that I could play the whole mass each week!

That same music director suggested to me that I could earn extra money playing wedding and funeral masses if I had a playlist that I could provide to people of songs that I could play. I never did monetize my piano skills, but I did create the playlist that she suggested. By the time that I stopped playing at mass, I had more than 100 songs in my playlist 🙂

This is a long-winded way of telling you where this playlist concept came from and how it applies to Microsoft CSPs. I’m not sure what people out there want to know about how to successfully apply the policies, so I figured that if I posted my playlist, then people could send me a note or comment and tell me which policies they are having issues with so that I can share my experience on how to successfully apply them.

It is probably obvious from my posts so far that I strongly perfer using custom XML to configure Windows 10 devices because of the level of control that you have over the application and removal of each individual setting.

That said, here is my Playlist – please do let me know which ones you are having trouble with!! I will include links to any posts that I have written on these topics.

Every CSP I Have Ever Used

Custom ADMX Policies

AboveLock\AllowCortanaAboveLock

AboveLock\AllowToasts

Accounts\AllowAddingNonMicrosoftAccountsManually

Accounts\AllowMicrosoftAccountConnection

Accounts\Domain

Accounts\Users

ApplicationManagement\AllowAllTrustedApps

ApplicationManagement\AllowDeveloperUnlock

ApplicationManagement\AllowGameDVR

ApplicationManagement\MSIAllowUserControlOverInstall

Applocker\ApplicationLaunchRestrictions

AppRuntime\AllowMicrosoftAccountsToBeOptional

Autoplay\DisallowAutoplayForNonVolumeDevices

Autoplay\SetDefaultAutoRunBehavior

Autoplay\TurnOffAutoPlay

Bitlocker\EncryptionMethodByDriveType

Browser\AllowPasswordManager

Browser\AllowPopups

Browser\ConfigureHomeButton

Browser\ConfigureOpenMicrosoftEdgeWith

Browser\DisableLockdownOfStartPages

Browser\EnterpriseModeSiteList

Browser\HomePages

Browser\PreventCertErrorOverrides

Browser\PreventFirstRunPage

Browser\SetHomeButtonURL

Browser\SyncFavoritesBetweenIEAndMicrosoftEdge

Connectivity\DisableDownloadingOfPrintDriversOverHTTP

Connectivity\DisableInternetDownloadForWebPublishingAndOnlineOrderingWizards

Connectivity\HardenedUNCPaths

ControlPolicyConflict\MDMWinsOverGP

CredentialProviders\BlockPicturePassword

CredentialsDelegation\RemoteHostAllowsDelegationOfNonExportableCredentials

CredentialsUI\EnumerateAdministrators

DataProtection\AllowAzureRMSForEDP

DataProtection\AllowDirectMemoryAccess

DataProtection\EDPShowIcons

DataProtection\RevokeOnMDMHandoff

DataProtection\RevokeOnUnenroll

DeliveryOptimization\DODownloadMode

DeviceGuard\ConfigureSystemGuardLaunch

DeviceGuard\EnableVirtualizationBasedSecurity

DeviceGuard\LsaCfgFlags

DeviceGuard\RequirePlatformSecurityFeatures

DeviceLock\AllowSimpleDevicePassword

DeviceLock\AlphanumericDevicePasswordRequired

DeviceLock\DevicePasswordEnabled

DeviceLock\DevicePasswordExpiration

DeviceLock\DevicePasswordHistory

DeviceLock\MaxDevicePasswordFailedAttempts

DeviceLock\MaxInactivityTimeDeviceLock

DeviceLock\MinDevicePasswordComplexCharacters

DeviceLock\MinDevicePasswordLength

DeviceLock\MinimumPasswordAge

DeviceLock\PreventLockScreenSlideShow

EventLogService\SpecifyMaximumFileSizeApplicationLog

EventLogService\SpecifyMaximumFileSizeSecurityLog

EventLogService\SpecifyMaximumFileSizeSystemLog

Experience\AllowManualMDMUnenrollment

Experience\AllowWindowsConsumerFeatures

Experience\AllowThirdPartySuggestionsInWindowsSpotlight

FileExplorer\TurnOffDataExecutionPreventionForExplorer

FileExplorer\TurnOffHeapTerminationOnCorruption

Firewall

InternetExplorer\AllowAddonlist

InternetExplorer\AllowAutoComplete

InternetExplorer\AllowEnterpriseModeSiteList

InternetExplorer\AllowSiteToZoneAssignmentList

InternetExplorer\CheckServerCertificateRevocation

InternetExplorer\DisableFirstRunWizard

InternetExplorer\DisableHomePageChange

InternetExplorer\DisableSecondaryHomePageChange

InternetExplorer\DoNotAllowUsersToAddSites

InternetExplorer\DoNotAllowUsersToChangePolicies

InternetExplorer\DoNotBlockOutdatedActiveXControls

InternetExplorer\IncludeAllLocalSites

InternetExplorer\IncludeAllNetworkPaths

InternetExplorer\InternetZoneAllowAccessToDataSources

InternetExplorer\InternetZoneAllowAutomaticPromptingForActiveXControls

InternetExplorer\InternetZoneAllowAutomaticPromptingForFileDownloads

InternetExplorer\InternetZoneAllowCopyPasteViaScript

InternetExplorer\InternetZoneAllowDragAndDropCopyAndPasteFiles

InternetExplorer\InternetZoneAllowFontDownloads

InternetExplorer\InternetZoneAllowLessPrivilegedSites

InternetExplorer\InternetZoneAllowScriptInitiatedWindows

InternetExplorer\InternetZoneAllowUserDataPersistence

InternetExplorer\InternetZoneDownloadSignedActiveXControls

InternetExplorer\InternetZoneDownloadUnsignedActiveXControls

InternetExplorer\InternetZoneEnableMIMESniffing

InternetExplorer\InternetZoneInitializeAndScriptActiveXControls

InternetExplorer\InternetZoneJavaPermissions

InternetExplorer\InternetZoneLaunchingApplicationsAndFilesInIFRAME

InternetExplorer\InternetZoneLogonOptions

InternetExplorer\InternetZoneNavigateWindowsAndFrames

InternetExplorer\InternetZoneRunNETFrameworkReliantComponentsSignedWithAuthenticode

InternetExplorer\InternetZoneUsePopupBlocker

InternetExplorer\IntranetZoneJavaPermissions

InternetExplorer\TrustedSitesZoneAllowAccessToDataSources

InternetExplorer\TrustedSitesZoneAllowAutomaticPromptingForActiveXControls

InternetExplorer\TrustedSitesZoneAllowFontDownloads

InternetExplorer\TrustedSitesZoneAllowNETFrameworkReliantComponents

InternetExplorer\TrustedSitesZoneJavaPermissions

InternetExplorer\TrustedSitesZoneNavigateWindowsAndFrames

LanmanWorkstation\EnableInsecureGuestLogons

LocalPoliciesSecurityOptions\Accounts_BlockMicrosoftAccounts

LocalPoliciesSecurityOptions\Accounts_EnableAdministratorAccountStatus

LocalPoliciesSecurityOptions\Accounts_EnableGuestAccountStatus

LocalPoliciesSecurityOptions\Accounts\LimitLocalAccountUseOfBlankPasswordsToConsoleLogonOnly

LocalPoliciesSecurityOptions\Accounts_RenameAdministratorAccount

LocalPoliciesSecurityOptions\InteractiveLogon_DoNotDisplayLastSignedIn

LocalPoliciesSecurityOptions\InteractiveLogon_DoNotRequireCTRLALTDEL

LocalPoliciesSecurityOptions\InteractiveLogon_MachineInactivityLimit

LocalPoliciesSecurityOptions\InteractiveLogon_MessageTextForUsersAttemptingToLogOn

LocalPoliciesSecurityOptions\InteractiveLogon_MessageTitleForUsersAttemptingToLogOn

LocalPoliciesSecurityOptions\MicrosoftNetworkClient_DigitallySignCommunicationsAlways

LocalPoliciesSecurityOptions\MicrosoftNetworkClient_SendUnencryptedPasswordToThirdPartySMBServers

LocalPoliciesSecurityOptions\MicrosoftNetworkServer_DigitallySignCommunicationsAlways

LocalPoliciesSecurityOptions\NetworkAccess_DoNotAllowAnonymousEnumerationOfSAMAccounts

LocalPoliciesSecurityOptions\NetworkAccess_DoNotAllowAnonymousEnumerationOfSamAccountsAndShares

LocalPoliciesSecurityOptions\NetworkAccess_RestrictAnonymousAccessToNamedPipesAndShares

LocalPoliciesSecurityOptions\NetworkAccess_RestrictClientsAllowedToMakeRemoteCallsToSAM

LocalPoliciesSecurityOptions\NetworkSecurity_DoNotStoreLANManagerHashValueOnNextPasswordChange

LocalPoliciesSecurityOptions\NetworkSecurity_LANManagerAuthenticationLevel

LocalPoliciesSecurityOptions\NetworkSecurity_MinimumSessionSecurityForNTLMSSPBasedClients

LocalPoliciesSecurityOptions\NetworkSecurity_MinimumSessionSecurityForNTLMSSPBasedServers

LocalPoliciesSecurityOptions\UserAccountControl_BehaviorOfTheElevationPromptForAdministrators

LocalPoliciesSecurityOptions\UserAccountControl_BehaviorOfTheElevationPromptForStandardUsers

LocalPoliciesSecurityOptions\UserAccountControl_RunAllAdministratorsInAdminApprovalMode

LocalPoliciesSecurityOptions\UserAccountControl_UseAdminApprovalMode

LocalPoliciesSecurityOptions\UserAccountControl_VirtualizeFileAndRegistryWriteFailuresToPerUserLocations

MSSecurityGuide\ApplyUACRestrictionsToLocalAccountsOnNetworkLogon

MSSecurityGuide\ConfigureSMBV1ClientDriver

MSSecurityGuide\ConfigureSMBV1Server

MSSecurityGuide\EnableStructuredExceptionHandlingOverwriteProtection

MSSecurityGuide\WDigestAuthentication

MSLegacy\AllowICMPRedirectsToOverrideOSPFGeneratedRoutes

MSLegacy\AllowTheComputerToIgnoreNetBIOSNameReleaseRequestsExceptFromWINSServers

MSLegacy\IPSourceRoutingProtectionLevel

MSLegacy\IPv6SourceRoutingProtectionLevel

NetworkProxy

Office

PassportForWork

Personalization\DesktopImageUrl

Power\AllowStandbyStatesWhenSleepingOnBattery

Power\RequirePasswordWhenComputerWakesOnBattery

Power\RequirePasswordWhenComputerWakesPluggedIn

Power\StandbyTimeoutOnBattery

Power\StandbyTimeoutPluggedIn

Printers\PublishPrinters

Reboot\Schedule

RemoteAssitance\SolicitedRemoteAssistance

RemoteDesktopServices\ClientConnectionEncryptionLevel

RemoteDesktopServices\DoNotAllowDriveRedirection

RemoteDesktopServices\DoNotAllowPasswordSaving

RemoteDesktopServices\PromptForPasswordUponConnection

RemoteDesktopServices\RequireSecureRPCCommunication

RemoteManagement\AllowBasicAuthentication_Client

RemoteManagement\AllowBasicAuthentication_Service

RemoteManagement\AllowUnencryptedTraffic_Client

RemoteManagement\AllowUnencryptedTraffic_Service

RemoteManagement\DisallowDigestAuthentication

RemoteManagement\DisallowStoringOfRunAsCredentials

RemoteProcedureCall\RestrictUnauthenticatedRPCClients

Restricted Groups

Search\AllowIndexingEncryptedStoresOrItems

Security\AllowAutomaticDeviceEncryptionForAzureADJoinedDevices

Settings\AllowAutoPlay

Settings\PageVisibilityList

Start\ImportEdgeAssets

Start\StartLayout

Storage\RemovableDiskDenyWriteAccess

System\AllowStorageCard

System\AllowTelemetry

Update\AllowAutoUpdate

Update\AllowMUUpdateService

Update\AutoRestartDeadlinePeriodInDays

Update\AutoRestartNotificationSchedule

Update\AutoRestartRequiredNotificationDismissal

Update\BranchReadinessLevel

Update\DeferFeatureUpdatesPeriodInDays

Update\DeferQualityUpdatesPeriodInDays

Update\EngagedRestartDeadline

Update\EngagedRestartSnoozeSchedule

Update\EngagedRestartTransitionSchedule

Update\PauseFeatureUpdates

Update\PauseQualityUpdates

Wifi\AllowAutoConnectToWiFiSenseHotspots

Wifi\AllowInternetSharin

WiFi\Profile

WindowsConnectionManager\PohitConnectionToNonDomainNetworksWhenConnectedToDomainAuthenticatedNetwork

WindowsDefenderSecurityCenter\DisableEnhancedNotifications

WindowsDefenderSecurityCenter\DisableNotifications

WindowsInkWorkspace\AllowWindowsInkWorkspace

WindowsLogon\HideFastUserSwitching

WindowsLogon\SignInLastInteractiveUserAutomaticallyAfterASystemInitiatedRestart

WindowsPowerShell\TurnOnPowerShellScriptBlockLogging

WiredNetwork\LanXML

Creating WlanXML

Assuming that you are using a Custom Policy, there are two steps to creating the XML to place within the <Data></Data> for the WiFi CSP WlanXML node:

  1. Export XML from an existing profile
  2. Encode the XML so that it can be processed by the OMA-DM client

Export XML from an existing profile

If you are migrating from Group Policy management to MDM management, then you probably already have a device configured with the needed WiFi profile that you can use to export the XML.

To export XML from an existing profile, perform the following steps from an existing GPO-managed device:

  1. Open Command Prompt
  2. Type netsh wlan export profile name=enter the name of the interface here

Encode the XML so that it can be processed by the OMA-DM client

  1. Open the exported XML with Notepad++ or the XML editor of your choice
  2. While there are a lot of fancier ways to handle the encoding, the simplest way is to do a replace all for the following three items –
    1. < is replaced with <
    2. > is replaced with >
    3. is replaced with

If you are using Custom XML, paste the resultant XML between the <Data></Data> and push the policy via the MDM of your choice.

In a separate post, I will share information about where to confirm that your policies have been applied.