How do you get smarter in MDM & Group Policy?

Upcoming Training Classes

With Jeremy Moskowitz

To consult about an on-site (Private) Group Policy class or the Group Policy Health Check, please call Laura Rubinstein at 215-391-0096 or email laura[[att]]

To purchase seats in a LIVE or ONLINE training class, contact Laura Rubinstein at 215-391-0096 or email laura[[att]]

Get serious, and perform “Best Practices” around Group Policy management. Take back control and get your IT life back!

Dates Class Actions
11 / 20 / 2019 Chicago2019 Learn More

How do you get smarter in MDM & Group Policy?

Jul 2020

Windows 10 (and Server) Event Logs to Azure Log Analytics Walkthru

It’s a Cloud, Cloud, Cloud, Cloud, Cloud, Cloud world. Except actually most of your stuff is still likely mostly on-prem, or acts that way. Take Windows 10 for instance. Windows 10 has events in the event logs, and maybe you already know about on-prem Event Forwarding.

Tip: If you want to learn more about on-prem Event Forwarding, you can see my Walkthrough of that here video and text.

But how do we take on-prem events from Windows 10 (or Windows Server) and get the up to the cloud for later analysis? If you have 24, 250, or 25,000 domain joined (or even NON-domain joined) machines, say with Windows Intune or PolicyPak Cloud… how can you do the equivalent of event forwarding to some central place?

That is the job of Azure Log Analytics. I’m going to call it “LA” for short.

LA had an original name, OMS which stood for Operations Management Suite, but as near as I can tell, that’s over. But its good to know LA’s original name, because you’ll see OMS pop up from time to time in the walkthrough, docs, and software. Additionally, it’s also good to know that what you’ll see here is build upon the original System Center Microsoft Operations Manager (SCOM); but I won’t be using that function.

The official documentation for LA can be found here; but I had a few stumbles. Some tips o’ the hat to Travis Roberts’ video and blog which also helped give me a leg up. The blog is here and the helpful video series on Azure Log Analytics (though a little old now because of the name and UI changes) can be found at:

My goal in researching this project was to give some PolicyPak MDM Customers a quick guide to research interesting events that PolicyPak automatically logs to its own event log. But in this guide, I’m also going to show you how to collect some standard and also some extra event logs.

To get started you need a Log Workspace. This is basically a security block between this collection of logs, and say another collection of logs. Each Log Workspace has a GUID based Workspace ID and two keys (Primary and Secondary.) You’ll use these to send, say, YOUR Windows 10 machines’ event logs to your workspace. And the other Azure admins … you know, those SQL server people or Exchange or whatever … they’ll send their event logs to their workspaces.

To get started use the big search thingie to find “Log Analytics workspaces” like what’s seen here.

Then, there’s a little Wizard (not shown) to help you get started. Basically it’s asking you for names and which Azure region you want to keep the data in. Then after it gets going you’ll see “Your deployment is underway” like what’s seen here.

Then you should be thrown into the Advanced settings like what’s seen here. If not, find the Workspace you just created and click Advanced in the left-side menu. It should get you to this place. Note then the “WORKSPACE ID” and “PRIMARY KEY” like what’s seen here. Hang on to those, you’ll need these in a bit. Then also download the Windows Agent 64-bit or 32-bit to get started for your example machines.

In this example, we’ll be installing the LA Agent by hand on a test machine. In real life you could use, say Windows Intune to deploy it with command line options to just chuck in your Workspace ID and Primary Keys and do the whole thing silently and automatically.

Once you have the download, get it over to your test machine. Machine can be real or virtual. Note that you shouldn’t do this (nor do you need to) for WVD virtual machines. Those have a magical connector to accept event logs to LA; and you shouldn’t need to use this method. (Docs: and a blog

Then, Up, Up and away. Launch the agent.. which requires admin rights. (Or, pro tip: Use PolicyPak Scripts to install it automatically where the script is elevated. )

You’ll need to select “Connect the agent to Azure Log Analytics (OMS)” like what’s seen here.

Then, it’s time to chuck in your Workspace ID and Workspace Key. And you’ll likely keep the default of Azure Cloud: Azure Commercial. Pull the pulldown if you have something unusual to select here.

Yes, you want to check for updates when MS Update kicks in….

And.. you’re basically done.

Now let’s make sure we’re talking in both directions. The Microsoft Monitoring Agent is found in Control Panel… which is a weird place, but, hey… that’s okay.

Then click the Azure Log Analytics (OMS) tab and … see you’re talking outbound.

Back in Azure, in the Advanced Settings page, the zero should be one !

Now it’s time to add in the actual event logs you want to capture. Note that the more you capture, the more you pay. Strictly speaking for the PolicyPak customer I made this blog entry for, he only needed to capture the PolicyPak log (which I do last.) But just for completeness and testing, I’ll capture some more too, since you might not have the PolicyPak Log. (And, why don’t you!? Come on over and check out PolicyPak for Pete’s sake. Really, your sake to be honest.)

So just type Application then +. Then System and + and bingo. Those are “well known” logs which LA knows about and pre-populates this list. But PolicyPak? Not as common.. (Yet !) Therefore you could take a guess that our event logs are named PolicyPak (they are…). But how would you know?

The trick is to find the log you want to capture in Windows, and go to its properties and get its Full Name like what’s seen here. Yeah, this one was easy.

But some are harder. I also wanted to capture the MDM event log which has a goofy and weird name. To get it, I went into an Event inside that log and captured its name microsoft-windows-devicemanagement-enterprise-diagnostics-provider/Operational and its brother microsoft-windows-devicemanagement-enterprise-diagnostics-provider/admin.

You can see that second log here…

Once I pasted in all the logs and added them, I clicked Save and got this !

Data.. data? Do we have data ? Click on Logs and close the sample queries. Let’s just see what have. All of it (which shouldn’t be much.)

In the top box, type
Then click Run. Bingo.. out should pop all the events that have been captured. You can change the Display Time to make sure that you’re getting the right events, right now.

It took a little while for the non-well-known logs to show up. But maybe it will work faster for you than for me. If you want to give it a shot and try your non-well-known logs, like this, give it a go.
Event | where Eventlog == "PolicyPak"
Then click Run again.
Pow! Here come your logs.

Then I can also dig into an event, and … hey look ! EastSalesUser1 ran Procmon, and PolicyPak did the elevation ! Amazeballs !

That’s it. Well, that’s basics anyway.

Remember this blog is a simple walkthrough / getting started. This isn’t “Magic Tricks with Windows Analytics.” But if I had this guide, I would have been up and running about 10x faster. So I hope this helps you out and shows how you can take on-prem or “Always on the go” Windows 10 machines and record their logs, then sort thru them for actionable items and trends.

Jun 2020

ADMX Windows 2020 and GPPreferences Escalation Bug CVE-2020-1317 Fixed

There were two big news items this week in GP-land:


1. The Windows "May 2020 Release" for ADMX templates is out.  You can get them here. Martin Briklmann on gHacks.Net already did a breakdown of what's new in the ADMX templates, so I don't have to. That review / overview is here. Nice job.


2. A research team uncovered a flaw in GPPrefs CSE User Based items.The basic gist is that GPPrefs User Side items (were) storing user policies in a user-writable %localappdata%\Microsoft\Group Policy\History directory when Remove this Item when it is no longer applied option is enabled. When GPupdate is called, the contents are read. If "evil" contents are present, the GPupdate process will perform the processing of those evil contents. As such, Microsoft fixed this in CVE-2020-1317. More reading about it and the direct download links to the patches can be found here.


This isn't an underlying problem in GP "the engine" itself; but rather GPPrefs and then specifically the user-side policies, and specifically, the printer policies. The patch will then change the location from user-space to ProgramData space when GPPrefs User side stores these values.


Hope this helps you out !

Jun 2020

Establishing Edge v83 Security Baselines with Group Policy

MDM administrators that utilize Microsoft Endpoint Management (Intune) are familiar with the concept of Security Baselines.  A security baseline is a collection of Microsoft recommended configuration settings that help secure and protect enterprise users and devices.  For instance, MEM offers security baselines for Windows 10, Microsoft Defender ATP and Edge.  Security baselines are an easy and effective way for admins to ensure that they are consistently enforcing a minimum security level that will address fundamental security and compliance issues.  Some admins may be surprised that security baselines are available for Group Policy as well.

The Benefits of Using Security Baselines

While it is perfectly ok to configure your own MDM profile or GPO to select and configure available settings, baselines are a quick and easy way to enforce a default baseline that prevents users from making changes that will result in an insecure state.  There are a number of benefits of using security baselines offered by Microsoft.

  • They are already configured by Microsoft security experts
  • They enforce settings that mitigates contemporary security threats.
  • Baseline settings have been pretested to ensure that they do not cause operational issues that are worse than the risks they mitigate
  • They ensure that users and device configuration settings are compliant with the baseline

Security Baselines are not just for MDM

Microsoft has been releasing Security baselines since the Windows XP days.  Because Group Policy offers far more settings than MDM, the simplification that they offer for AD environments is even more of a benefit.  For instance, there are more than 200 Microsoft Edge Group Policy settings for Windows, but only some of these are security related.   By implementing Microsoft Edge baselines, you can rest assure that you are deploying the most up-to-date security settings for Microsoft Edge using your GPO environment.

Security Baseline for Microsoft Edge v83

Microsoft just recently announced the release of the Microsoft v83 of Microsoft Edge.  Microsoft continues to release new versions and settings for the new Chromium Edge browser.  Version 83 includes 19 new computer and user based settings.  The accumulated total of Edge settings currently stands at 311 Computer policy settings and 286 User configuration policy settings.  The current baseline involves 12 of these settings which are identical to the v80 security baseline.

To obtain the security baseline for Microsoft Edge, you need to download the Security Compliance Kit.  The compliance kit the following:

  • Importable GPOs
  • A script to apply the GPOs to local policy
  • A script to import the GPOs into Active Directory Group Policy
  • A spreadsheet documenting all recommended settings in spreadsheet form
  • Policy Analyzer rules
  • GP Reports
  • Documentation

Implementing the Baseline into your AD Environment

Keep in mind that you must have the Edge v83 ADMX files contained within your Central Store as a prerequisite.  Once you download the toolkit, open the Scripts folder and run either the local policy script or the AD import script as shown below.

In this example we using the Baseline-ADimport script.  The script will then import a GPO called MSFT Edge version 80 – Computer that involves the following Administrative Templates.

Some of the configured settings include the following:

The toolkit includes a GP Reports Folder that contains an HTML report of GPO templates available in the baseline.

It is recommended that you stay current with the latest security baselines of Edge and Windows 10.  You can keep abreast of future baselines as they become available through the Microsoft website.   

You can learn about the newest policy settings available with Edge v83 on the Microsoft website


Jun 2020

MSIX App Attach:  Walkthru (Walk Before You Run)

MSIX App Attach: How do you do it?  Find out in this blog.

That being said, let's first understand the problem MSIX App Attach tries to solve: 

For a long time, golden images were used with a myriad of applications... leading to a myriad of golden images.

NOT a great way to streamline. Images can quickly become bloated and the task of updating and maintaining them is cumbersome and overly time consuming.  VDI and application streaming has been another alternative, but these require complex infrastructure that has to be implemented and maintained. Now with remote work on everyone's mind, we need an easier way deliver applications. 

As such, Microsoft recently unveiled their new MSIX App Attach solution and is positioning it as their main technology for modern application packaging and provisioning.  As its name implies, it allows you to attach an application to the OS.  Some of the benefits of MSIX App Attach include:

  • No special deployment servers are needed
  • No agents: Everything is just "built into Windows" natively.
  • You can use existing MSIX packages without altering or repackaging them.
  • There is ultra-low / no performance impact.
  • Can be used on-premise or cloud

To help you get started with this new methodology approach to application delivery, I have composed a called “MSIX: Walk before you run” to help you get familiar with the basic approach of how it works.  To keep things simple, we aren’t going to create any MSIX packages here but will use existing ones just to show how to implement an MSIX App Attach solution.

Then you can use the material below to "follow along" and try this yourself.

Step 1: Get a compatible OS

So first and foremost, you need an OS that supports it all.  That means getting a copy of Windows 2004 which is the latest version of Windows 10.  Then you need to upgrade to Build 19631 which at this time may require you to utilize the Windows Insider Program to get it.

Step 2: Get MSIX packages

So of course we need some MSIX packages.  Now we could use the MSIX Packaging Tool that you can download from Microsoft, but I am skipping that step for take advantage of some existing packages already available.  There is a great Microsoft repository site called Github Winget Package Manifest Page that features all types of prepackaged applications.  Pull the page up in a browser and do a search for MSIX.  In my video, I then chose MSIX Commander as my feature application and copied it’s URL in order to download it.  Now I have an MSIX package that I can use for my example.  Place it and all other downloads in a separate folder.  In my video, I am using a directory called “Demo.”

Step 3:  Using the Script

I went and logged on my local my machine as a domain admin in order to perform the remaining tasks.  Throughout my video I refer to a conglomerated script that I pieced together for you.  I obtained the script from several sources.  I got some from the official Microsoft Setup Document which guides you along in much the same format that I take in the video.  I also used several scripts made available by Tom Hickling’s Github page.  I then cobbled all of these scripts together and I have included the final script in its entirety at the end of this blog. Now let’s go through the script.

Step 4: Create a VHD Package

While you see MSIX App Attach associated with Azure and WVD a lot, keep in mind that what we are doing can be performed on local desktops or laptops as well as VDI and WVD machines.  I am doing everything locally in this video.  You will need to download the MSIXMGR Tool and place it in the same directory as your MSIX file (in my case MSIX Commander).  Now we need to utilize the script to create the VHD.  To do this, I used Tom Hickling’s script.  Since he was using VLC as his package, I modified it to accommodate MSIX Commander.  Go create the VHD, I am using the section titled “Make an MSIX into a VHD”

Open an elevated PowerShell session and go to the directory that contains all of the required files I mentioned earlier.  Then paste the VHD script and let PowerShell do its thing.  Now your MSIX VHD file is created with your MSIX file expanded into the VHD.  The VHD will already be mounted.  In my case it mounted as drive E so you can browser its contents.  Be sure to view the package name and copy that name and paste it into Notepad for future reference.  You will also need to know the Volume ID of the VHD file which you can find by using the “mountvol” command.  Then paste in your Notepad as well.

Step 5: Package Staging

In this video, I chose to skip the Certificate section for simplicity which takes us to the next step called Staging.  First go ahead and unmount the VHD.  You will find that the Stage section of the script is broken down into regions.  I advise you to paste the script into PowerShell region by region.  For first region, you will need to modify the VHD name, package name and volume ID you recorded earlier.  Below is what my first region looked like:

$parentFolder = "MSIXCOMMANDER"
$packageName = "PascalBerger.MSIXCommander_1.0.7.5_x64__ajjbhed1xnq88" 
$parentFolder = "\" + $parentFolder + "\"
$volumeGuid = "5f51883c-6f50-4c6a-9afb-9513c6e7c565"
#NOTE: GET VOLUMEGUID after mounting VHD then use MOUNTVOL command to get volume GUID. Remove {}
$msixJunction = "C:\temp\AppAttach\" 

The second region will mount the disk and the third region will perform what is called the junction.  The final “stage region” will perform the actual attaching.

Step 6: Register Script

So now we have attached the app, but we don’t have it within the user space.  I have the variables assigned to the values I mentioned earlier to run MSIX Commander so let’s copy the Register region and paste it into PS.  Once completed, you will then see MSIX Commander in the Windows Start Menu like in the video.  If I log on another user, in this case a standard user, I can’t see the MSIX app because the register script only applied to the user account I was logged on at the time.  So for this demonstration, I will simply open PowerShell logged on as a standard user and paste the Register region script in once again.  While I may have to dig a little through the Start menu to see it, it now appears for the user at hand.

Step 7:  Undoing the MSIX App Attach Environment

Any MSIX package that can be registered can be deregistered as well.  To do so, simply copy the De-Reregister region of the script and paste it into PowerShell and run it.  Now the app will disappear from the start menu.  In the video, I switched over to my original domain admin account and ran the deregistering process as well.  The final step of undoing everything will be to de-stage it so it cannot be applied to users any longer.

That completes the demonstration.  Go ahead and use the script I have included.  Just remember to modify the mentioned variables within the script when working with other MSIX files and such.  With a few run-throughs, you will be running in no time.

Jeremy’s Compiled Script below for reference... !


Make an MSIX into a VHD

#Go and package your app using the MSIX App packager

#Generate a VHD or VHDX package for MSIX


new-vhd -sizebytes 2048MB -path C:\ApplicationVHDs\MSICOMMANDER.vhdx -dynamic -confirm:$false

$vhdObject = Mount-VHD C:\ApplicationVHDs\MSIXCOMMANDER.vhdx -Passthru

$disk = Initialize-Disk -Passthru -Number $vhdObject.Number

$partition = New-Partition -AssignDriveLetter -UseMaximumSize -DiskNumber $disk.Number

Format-Volume -FileSystem NTFS -Confirm:$false -DriveLetter $partition.DriveLetter -Force

#Create a folder with your Appname as the name of the folder in root drive mounted above

new-item -path 'E:\MSIXCOMMANDER' -ItemType Directory

#Expand MSIX in CMD in Admin cmd prompt - Get the full package name

.\msixmgr.exe -Unpack -packagePath ".\MSIX Commander-x64.msix" -destination "E:\MSIXCOMMANDER" -applyacls


New-SelfSignedCertificate -Type CodeSigningCert -Subject "CN=JeremyTest"



$parentFolder = "MSIXCOMMANDER"
$packageName = "PascalBerger.MSIXCommander_1.0.7.5_x64__ajjbhed1xnq88" 
$parentFolder = "\" + $parentFolder + "\"
$volumeGuid = "5f51883c-6f50-4c6a-9afb-9513c6e7c565"
#NOTE: GET VOLUMEGUID after mounting VHD then use MOUNTVOL command to get volume GUID. Remove {}
$msixJunction = "C:\temp\AppAttach\" 
#region mountvhd
    Mount-Diskimage -ImagePath $vhdSrc -NoDriveLetter -Access ReadOnly                 
    Write-Host ("Mounting of " + $vhdSrc + " was completed!") -BackgroundColor Green 
    Write-Host ("Mounting of " + $vhdSrc + " has failed!") -BackgroundColor Red
#region makelink
$msixDest = "\\?\Volume{" + $volumeGuid + "}\"
if (!(Test-Path $msixJunction)) 
    md $msixJunction
$msixJunction = $msixJunction + $packageName
cmd.exe /c mklink /j $msixJunction $msixDest
#region stage
[Windows.Management.Deployment.PackageManager,Windows.Management.Deployment,ContentType=WindowsRuntime] | Out-Null
Add-Type -AssemblyName System.Runtime.WindowsRuntime
$asTask = ([System.WindowsRuntimeSystemExtensions].GetMethods() | Where { $_.ToString() -eq 'System.Threading.Tasks.Task`1[TResult] AsTask[TResult,TProgress](Windows.Foundation.IAsyncOperationWithProgress`2[TResult,TProgress])'})[0]
$asTaskAsyncOperation = $asTask.MakeGenericMethod([Windows.Management.Deployment.DeploymentResult], [Windows.Management.Deployment.DeploymentProgress])
$packageManager = [Windows.Management.Deployment.PackageManager]::new()  
$path = $msixJunction + $parentFolder + $packageName # needed if we do the pbisigned.vhd
$path = ([System.Uri]$path).AbsoluteUri
  $asyncOperation = $packageManager.StagePackageAsync($path, $null, "StageInPlace")                                                                                                                
$task = $asTaskAsyncOperation.Invoke($null, @($asyncOperation))    


#MSIX app attach registration sample
#region variables 
#$packageName = "PowerBI_1.0.0.0_x64__74tjgdb1s5w2y"
$packageName = "PascalBerger.MSIXCommander_1.0.7.5_x64__ajjbhed1xnq88" 
$path = "C:\Program Files\WindowsApps\" + $packageName + "\AppxManifest.xml"
#$path = "E:\VLC\" + $packageName + "\AppxManifest.xml"
#region register
Add-AppxPackage -Path $path -DisableDevelopmentMode -Register


#MSIX app attach deregistration sample
#region variables
$packageName = "PascalBerger.MSIXCommander_1.0.7.5_x64__ajjbhed1xnq88"
#region deregister
Remove-AppxPackage -PreserveRoamableApplicationData $packageName


4. De-stage
#MSIX app attach de staging sample
#region variables
$packageName = "PascalBerger.MSIXCommander_1.0.7.5_x64__ajjbhed1xnq88"
$msixJunction = "C:\temp\AppAttach\"
#region deregister
Remove-AppxPackage -AllUsers -Package $packageName
cd $msixJunction
rmdir $packageName -Force -Verbose