Auto shutdown AVD Personal Host Pools

Auto shutdown AVD personal desktop host pools

Update (22/12/2021): Since Managed Identities for Automation accounts is now GA. I have updated the script to make use of this. This way the Automation account requires less permissions to run.

If you’re using Azure Virtual Desktop in a pooled scenario you are properly using the scaling script that Microsoft has provided . This script works great, but what about personal host pools. The scaling script doesn’t have support for this type of host pool. This is a shame because you can also save considerably amount of money if your personal session hosts would only be running if they are being used. Especially now that Start Virtual Machine on Connect is now generally available.  This means that users can power on the machines when they start working. However the machines are only turned on, and not deallocated. Which is only half of the solution…

In order to deallocate machines that are not being used I’ve create a PowerShell script that can be run in an Automation Account. The script does the following:

  • Checks if the host pool is set to personal, pooled is not supported
  • Checks if start on Connect is enabled. Link to how to configure this https://docs.microsoft.com/en-us/azure/virtual-desktop/start-virtual-machine-connect
  • Collects all the Session Hosts in the host pool
  • If the Session Host is running it checks if there is an active session, if there are no active sessions the Session Host will be Deallocated.
  • You can exclude machines from the script by using a tag

The script is available in my GitHub Repo. You can import the script into an automation account and set it up yourself. Or if you would like to use the script you can use the following script that will set everything up for you. This script is a slightly adjusted version of Microsoft’s script which is used for the scaling script itself.

The DeployAutomationAccount.ps1 script will:

  • Checks if you have the appropriate permissions
  • Checks if you have the correct modules installed on your computer
  • Deploys a new resource group for the automation account (if needed)
  • Deploys a new Automation Account (if needed) and imports the necessary modules and runbook
  • Creates an Automation Schedule which runs every 1 hour
  • Connects the Runbook to the Schedule so it will start
  • Validates if an Run As Account is present
  • Creates a managed identity with the required permissions

To deploy the automation account with the AVD-PersonalAUtoShutdown.ps1 script you first download the script:

New-Item -ItemType Directory -Path "C:\Temp" -Force
Set-Location -Path "C:\Temp"
$Uri = "https://raw.githubusercontent.com/stephanvandekruis/AVD/main/PersonalScaling/DeployAutomationAccount.ps1"
# Download the script
Invoke-WebRequest -Uri $Uri -OutFile ".\DeployAutomationAccount.ps1"

Also download the Custom Role Definition for the role assignments

$Uri = "https://raw.githubusercontent.com/stephanvandekruis/AVD/main/PersonalScaling/Automation-RoleDefinition.json"
# Download the script
Invoke-WebRequest -Uri $Uri -OutFile ".\Automation-RoleDefinition.json"

Log in to your environment

Login-AzAccount

Run the following cmdlet to execute the script and create the Automation Account. You can fill in the values or comment them out to use their default values.

$Params = @{
    "AADTenantId"               = "<Azure_Active_Directory_tenant_ID>"
    "SubscriptionId"            = "<Azure_subscription_ID>" 
    "AutomationRG"              = "<ResourceGroup of the Automation Account>" # Optional. Default: rgAVDAutoShutdown
    "AutomationAccountName"     = "<Automation Account Name>" # Optional. Default: AVDAutoScaleAccount
    "AutomationScheduleName"    = "<Automation Schedule Name>" # Optional. Default: AVDShutdownSchedule
    "AVDrg"                     = "<AVD resource group which holds the Host Pool Object>"
    "SessionHostrg"             = "<Resource group which contains the VMs of the session hosts>"
    "HostPoolName"              = "<Host pool Name>"
    "SkipTag"                   = "<Name of the tag to skip the vm from processing>" # Optional. Default: SkipAutoShutdown
    "TimeDifference"            = "<Time difference from UTC (e.g. +2:00) >" # Optional. Default: +2:00
    "Location"                  = "<Location of deployment (e.g West Europe)>" # Optional. Default: West Europe
}

.\DeployAutomationAccount.ps1 @Params

The deployment will kick off and the automation account with the AVD-PeronalAutoShutdown.ps1 script will be created.

The one thing that I will not do for you is the creation of an Run As Account. To create the Run as Account:

  1. In the Azure portal, select All services. In the list of resources, enter and select Automation accounts.
  2. On the Automation accounts page, select the name of your Azure Automation account. The default value is AVDAutoShutdownAutomationAccount
  3. In the pane on the left side of the window, select Run As accounts under the Account Settings section.
  4. Select Azure Run As account. When the Add Azure Run As account pane appears, review the overview information, and then select Create to start the account creation process.
  5. Wait for the deployment to complete

During the deployment of the Automation account a schedule as also created. This schedule will trigger the runbook every hour and will do so for the next 5 years. You can adjust the schedule to your requirements.

To view the out put of the AVD-PersonalShutdown script you:

  1. Go to the Automation account that hosts the script (default is AVDAutoShutdownAutomationAccount)
  2. Under Process Automation you find Jobs
  3. Select the top job, which is the latest.
  4. Select the tab Output. Here you will find all the output information that the script generated.

To exclude a machine from begin processed you can simply add a tag to the VM and the script will skip that practically machine, the default value for this is SkipAutoShutdown

Wrapping up

You can find the scripts and additional information in my GitHub Repo.

If you are using the script and liking it, I would love to read about it in the comments! Or if you have any suggestions on how to improve the script, I would love the read your suggestions as well!

Win32 Application Supersedence

HOW TO: Update Win32 apps with Endpoint Manager

Updating Win32 applications with Endpoint Manger is a cumbersome task.  Newer versions of applications wont install if a previous versions of the application is present on the device. The first step is to remove the application from the device and then creating a new deployment. This could result that the user isn’t able to use a particular application since the admin had to wait for the uninstall deployment to complete. Or maybe you created some custom installation which would remove the application and then install the newer version of that application. Either way the process was not easy..

Microsoft has now introduced a new function called Win32 app Supersedence, which enables you to easily update or supersede newer applications. This article will describe the new functionality and how to use it in your environment. At the moment of writing this article the functionality is still in preview, so it might be subject to change.

Scenario

Let’s say you have deployed the Citrix Receiver application via a Win32 Endpoint Manager deployment. The Citrix Receiver applications is being replaced by the new Citrix Workspace application and you need to deploy the Citrix Workspace application to the devices which are being managed by Endpoint Manger.

Initial Deployment

For the initial deployment an IntuneWin package was created (if you’re interested in how to create one view this article) and deployed via Endpoint Manger. The applications were successfully installed on all the clients.

One topic that has now become more important is the ability to know what version is installed. How can one identity which version that is active on the client. The key in this whole process is the ability to identify an unique value that determines the version of the application. Maybe the version number can be found within the name of the .exe or can the version be found in the registry. For Citrix the version can be found in the registry. In the path Computer\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Citrix\InstallDetect\{A9852000-047D-11DD-95FF-0800200C9A66} there is the value DisplayVersion which holds the value of the installed Citrix Receiver. This value can be used in the Detection rules to validate whether or not the application is installed. So when deploying your applications put some extra time in detecting the version of your application, which will make your life easier in the long run. How to use these detections rules I will show later on.

Supersedence

You have created a new package for the Citrix Workspace application and are ready to deploy the package via Endpoint Manger. Go to Endpoint.microsoft.com >Choose Apps > Windows > Add > For app type select Windows app (Win32)

Select your new package and fill out the necessary app information.

At the program settings fill in your install and uninstall commands. Make sure the also the uninstall command works as expected. This uninstall command can be used by the Supersedence functionality depending on your update strategy. I will explain this behavior later on in this article.

The detection rules are used to determine if an application is installed. As mentioned earlier it would be wise to use a value that the unique for the application and the version of that application. If there is no distinct difference between the two versions Endpoint Manger won’t be able to determine which application to install. For this article I’m using the registry detection rule.

  • Key path: Computer\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Citrix\InstallDetect\{A9852000-047D-11DD-95FF-0800200C9A66}
  • Value name: DisplayVersion
  • Detection Method: String comparison
  • Operator: Equals
  • Value: 19.9.0.21

We will skip the Dependencies tab and go straight to the new Supersedence tab. Here you will be able to select the application that is being superseded by the new application. In our case this is the Citrix receiver version 14.12.0.18020.

600

You now have the option to select yes or no at the Uninstall previous version. When to use what option? When you choose to uninstall the previous application Endpoint Manger will use the uninstall command configured in your Endpoint Manger Deployed, in the example uninstall.cmd. This option can be used if you completely replace the application with a new application, let’s say Citrix Receiver with the Windows Virtual Desktop client. Or you can use the uninstall feature to completely reconfigure the new application. In the Supersedence configuration this option is referred as Replace. If you enabled toast notifications the user will also be informed that the application is begin uninstalled and the new application is begin installed.

If you chose not to uninstall the application Endpoint Manger will try to update the application with the newer version. For this to function the application installer needs to be able to update from an older version. This way any configured settings should be honored as long as the application support this. In the Supersedence configuration this option is referred as Update. If you enabled toast notifications the user will also be informed that the application is begin updated and the new application is begin installed.

What option to choose really depends on your application. In many cases updating the application would be preferable, but replacing the applications can also have its advantages. As always the answer would be, it depends. So make sure to test and validate before going into production with the new application.

More information

MSIX App Attach with CIM

HOW TO: Use CIM for WVD App Attach

To use MSIX App Attach you need to extract an MSIX package to a VHD or a VHDx format to then mount the drive to the Virtual Machine. But there’s a third format that can be used, namely Composite Image Files System or .CIM in short. This is a new file system introduced by Microsoft to use in combination with MSIX App Attach. Why need a new file system? CIM provides better performance when compared to VHD(x). Microsoft preformed a comparison test between VHDX and CIM where they mounted 500 files in each format, each file being 300 MB. With the following results:

SpecsVHDCimFS
Average mount time356 ms255 ms
Average unmount time1615 ms36 ms
Memory consumptions6% (of 8 GB)2% (of 8 GB)
CPU (count spike)Maxed out multiple timesNo impact

As you can see the load on the machine with CIMFS is significantly lower than when compared to the mounting of VHD’s. This information was shared during the Windows Virtual Desktop masterclass. Microsoft host these sessions every few month and are free to follow, so make sure to sign up for the next one! The sessions are always packed with information and new announcements. That begin said let see how to create a CIM file.

Prerequisites

Creating CIM file

The MSIXMGR tool has some handy functionalities backed in. Extracting a MSIX to a VHDx there were many steps involved like creating a VHDx file, mounting and extracting the MSIX and dismounting the disk again. The MSIXMGR tool automates these steps. Now we are going to generate the CIM files but the same steps can be used for the creation of VHD(x) files.

  • Open Command prompt in elevated mode
  • Navigate to the MSIXMGR location (c:\temp\msixmgr)
  • Run the following command
msixmgr.exe -Unpack -packagePath "C:\Users\Stephan\Desktop\ CitrixReceiver_3.0.1.0_x64__v1hrd262mcs5e.msix" -destination c:\temp\output\CitrixReceiver_3.0.1.0_x64.cim -applyacls -create -vhdSize 100 -filetype “CIM” -rootDirectory apps

In c:\temp\output you will find all the different .cim files. You will need all the files for in order to make this work.

If you don’t want to use CIM and just a VHDx file you can use the same command but simply replace cim with VHD(x).

msixmgr.exe -Unpack -packagePath "C:\Users\Stephan\Desktop\ CitrixReceiver_3.0.1.0_x64__v1hrd262mcs5e.msix" -destination c:\temp\output\CitrixReceiver_3.0.1.0_x64.vhdx -applyacls -create -vhdSize 100 -filetype “VHDX” -rootDirectory apps

MSIX App Attach

Copy all the .cim files you created to the file share that have been set up for MSIX App Attach.

In the Azure Portal go to your host pool and select MSIX Packages. Choose Add and provide the UNC path to the cim file. In my case this is \\man-0\appattach\CitrixReceiver_3.0.1.0_x64.cim. Make sure to put the State on Active.

640640Add MSIX App Attach Package

Go to your Application Group settings. Here you have two options. The first option is to include the application in the Default Desktop application group. The application will be available to the users when he signs in. Or you can create a remote application group which will only provide the remote app. In my case I will be using the default desktop group. So select the group, choose Applications and choose Add. From the dropdown you can select the newly added application. In my case this is Citrix Workspace. Make sure the assign the application group to you users.

To test sign in on the host pool where you should now see the newly added application based!

Other resources

Endpoint Manager and Windows Defender Application Guard

HOW TO: Deploy Windows Defender Application Guard with Endpoint Manager

In part 2 of the series, I will be taking a closer look at Windows Defender Application Guard (WDAG), specifically for Edge. Not to confused with Windows Defender Application Control (WDAC). Essentially WDAG runs application in a virtualized environment on your Windows 10 device. This way the operating system is protected from any applications that try to interfere with the system.

For Edge, WDAG helps to isolate untrusted websites. By isolating browsers users can safely browse the web without having to worry that they accidently end up on a site that they are not supposed to be on. This isolation happens within a Hyper-V-enabled container. This container is separate from the host operating system. Meaning that if a website turns out to be malicious the host device is protected, and the attacker cannot get the data.

Today this article is about Edge, more specifically the new Chromium version, but these same settings also work for the older Edge and even Internet Explorer. This level of isolation is also available for Microsoft Office, but this will not be covered today.

Other articles in the series:

  1. Windows Defender Application Control
  2. Windows Defender Application Guard
  3. Windows Defender Credential Guard
  4. Windows Defender Device Guard

Prerequisites

  1. A physical test client (64-bit, Virtualization options, minimum of 8GB), joined and enrolled in Endpoint Manager
  2. Windows 10 Enterprise currently supported version
  3. Microsoft subscription with Endpoint Manager

Enable Windows Defender Application Guard

To enable WDAG go to endpoint.microsoft.com, select Devices > Configuration Profiles > New Profile and select Windows 10 and later. For profile select Endpoint Protection.

Fill out the basic information and continue to the next step. Select Microsoft Defender Application Guard to reveal the options. I have applied the following settings, tailor them to your need if needed. In the link you can find the explication of all these settings. If you want to provide a nice experience for your users make sure to enable retain user generated browser data. This way cookies and preferences are saved. Finally apply the policy to a group.

Network boundaries

The next question is how to control what sites are blocked and what site are considered as trusted. The documentation of Microsoft is not particularly clear on this point, but is hidden way in one of the lines of text. Within Endpoint manager you have the options to create a Configuration Profile specifically for network boundaries.

To create a profile go to Devices > Configuration Profiles > New Profile and select Windows 10 and later. For profile select Network boundary. Depending on what you want to whitelist there are special rules and formats you need to apply by.  Also take into account if you want to use wildcards or specific domains. See the explication of Microsoft how to whitelist certain domains. See the explination on how to whitelist domains:

ValueNumbers of dots to the leftMeaning
contoso.com0Trust only the literal value of contoso.com.
www.contoso.com0Trust only the literal value of www.contoso.com.
.contoso.com1Trust any domain that ends with the text contoso.com. Matching sites include spearphishingcontoso.com, contoso.com, and www.contoso.com.
..contoso.com2Trust all levels of the domain hierarchy that are to the left of the dot. Matching sites include shop.contoso.com, us.shop.contoso.com, www.us.shop.contoso.com, but NOT contoso.com itself.

Here are some boundaries that I have added for this article. Most of the resources are Microsoft cloud services, but of course I also added my own website as a safe website.

Network boundary
Cloud Resourcesportal.office.com|tasks.office.com|protection.office.com|meet.lync.com|teams.microsoft.com
Cloud Resourcesoutlook.office.com|outlook.office365.com|portal.office.com
Cloud Resources/*AppCompat*/
Cloud Resourcescontoso.sharepoint.com| contoso-my.sharepoint.com| contoso-files.sharepoint.com
Neutral Resourceslogin.windows.net,login.microsoftonline.com
Neutral Resources.stephanvdkruis.com,.microsoft.com

Final result:

So now you configured WDAG, but what is happening on the background? By enabling WDAG the Windows Defender Application Guard feature is installed on the client. This installation requires a restart so the next time a user turns off its device the feature will be installed. After the feature is live users can start their browser and at first nothing is different then what they are used to. If they immediately start their browser, they might see an initialization popup meaning that the container is being provisioned.

They can go to any trusted site or cloud resources that have been defined as trusted in the boundary policy. However as soon as they try to go to an untrusted website a secure isolated browser is started. See the example below when we browse to google.com.

Endpoint Manager and Windows Defender Application Control

HOW TO: Deploy Windows Defender Application Control with Microsoft Endpoint Manager

Windows 10 has a variety of security features build in. These features are not enabled by default, but if configured correctly they can significantly increase the security of the devices. The main advantage of Windows 10 Enterprise are the security features. These security features ‘harden’ the operating system. By hardening your OS, you protect yourself and the Enterprise against viruses, ransomware, and possible hackers. This blog series explains the different “Defender” functionalities that are available in Windows 10 Enterprise and how to configure them by using Microsofts Endpoint Manager (Intune).  

Microsoft always likes to rebrand their functionalities, and the name defender is now used generally for all the security features, not only covering Windows 10. You can think of Defender for Endpoint, Defender for Azure etc. This is also true for the functionalities of this blog series. Windows Defender Application Control is the new name for services which were once called Application Control Guard, or even Configurable Code Integrity (CCI).

This series touches upon the following subjects:

  1. Windows Defender Application Control
  2. Windows Defender Application Guard
  3. Windows Defender Credential Guard
  4. Windows Defender Device Guard

Prerequisites

  1. A physical test client with Windows 10
  2. Microsoft subscription with Endpoint Manager

Windows Defender Application Control

Simply stated: Windows Defender Application Control (WDAC) controls whether an application may or may not run on a Windows 10 device. If the application is trusted the application can run, otherwise the application is blocked. There is a lot more to it of course but in essence this is what is does. Some may remember AppLocker which was introduced in Windows 7 and it allowed organization to control which applications could run on a device. If stated like this the functionalities of AppLocker and WDAC are very alike, but WDAC takes it a lot further. Not only does WDAC now has the capability to also control drivers, it can also make use of Microsoft’s Intelligent Security Graph. By using the Intelligent Security Graph, you do not have to whitelist applications individually, but you automatically trust the application is Microsoft trusts the application. This will save you a lot of time maintaining the WDAC policies. Furthermore, you have the option to automatically approve applications that have been deployed by using software distribution solutions, such as Microsoft Endpoint Manger.

Securing your environment by building and maintaining WDAC policies or any other security solution will take time. The policies you create will change over time since applications and other software change. You should understand that this is not a one-time configuration, and this should be evaluated on a regular basis. Before you start implementing WDAC I would recommend to start by reading and understanding the documentation of Microsoft. Make sure that the requirements of your business needs are clear.

There are so many variables that go into designing this solution that it is impossible to cover all the steps. This series of articles should give you a basic understanding on how to use these security features to your advantage. What are the high level steps in this article:

  1. Create a baseline policy
  2. Update baseline policy
  3. Test a WDAC policy
  4. Deploy a WDAC Policy
  5. Monitor your WDAC Policy
  6. Enforcing WDAC policy

In this article we create a policy for a fully managed device. You can also create policies for lightly managed devices. The difference between the two is that with fully managed devices all the software installed on the device is managed by IT and users cannot install any applications. On lightly managed devices users can install applications. If you are planning to start with WDAC it is recommended to start by treating your devices as if they are lightly managed. After that slowly build up the security around the device until they are “fully managed”.

1.      Create a baseline policy

You start with a baseline. Creating a baseline policy depends on what type of device you are using. Each type of device has its own drivers and specifications, depending on the manufacturer of the device. So, it is important to capture baseline policies for each type of device. If you have multiple types of devices you can use each baseline for the specific device type, or you can merge the baseline into one baseline policy which you can then use for all of them. Microsoft has provided some example policies in C:\Windows\schemas\CodeIntegrity\ExamplePolicies. For this article we start from scratch.

Take a Windows 10 device which is as clean as possible to start the inventorying phase. To start use the following PowerShell command. This command will scan the entire device and creates a baseline XML. This will take some time to complete.

$CIPolicyXML = "C:\temp\WDAC_Policy_DellLatitude5500.xml" 
New-CIPolicy -MultiplePolicyFormat -filePath $CIPolicyXML -ScanPath C: -level FilePublisher -UserPEs -Fallback Hash 

Powershell Explained:

-MultiplePolicyFormatYou can add the -MultiplePolicyFormat parameter when creating policies which will be deployed to computers which are running Windows build 1903+.
-filePathWhere to save the xml
-ScanPath C:What directory do you want to scan
-level FilePublisherSpecifies the primary level of detail for generated rules
-UserPEsCommand scans for user-mode executables (applications) along with kernel-mode binaries such as drivers and creates rules at the Publisher level.
-Fallback HashTo catch any applications not discovered using the primary file rule level specified by the -Level parameter

2. Update baseline policy

Scanning your device will take a considerable time. When the scanning is complete you can add extra rules to the XML file. Understand WDAC policy rules and file rules (Windows 10) – Windows security | Microsoft Docs

  • Option 13 is used so that applications installed by a software distribution solution are automatically allowed.
  • Option 14 enables the use of the Microsoft Intelligent Security Graph so that well known applications are automatically approved.
  • Option 16, so no reboot is required when applying WDAC policies.
  • Option 17, so you can combine policies.
  • Activating Hardware Virtualized Code Integrity and set it to enabled. To be used with care, some applications and drivers are incompatible with HVCI and can cause software malfunction and blue screens.
Set-RuleOption -FilePath $CIPolicyfileXML -Option 13
Set-RuleOption -FilePath $CIPolicyfileXML -Option 14
Set-RuleOption -FilePath $CIPolicyfileXML -Option 16
Set-RuleOption -FilePath $CIPolicyfileXML -Option 17
Set-HVCIOptions -Enabled -FilePath $ CIPolicyXML

3. Test a WDAC policy

When your XML has finished building you can convert the XML to a CIP file. First open the XML file and copy the <PolicyID> , this can be found at the bottom of the XML file and looks something like {DF4B2E6F-F05F-4D3C-AE70-000F6CCD445C}. The name of the CIP file must match the Policy GUID. To create a CIP file run:

ConvertFrom-CIPolicy -XmlFilePath $CIPolicyXML -BinaryFilePath “C:\temp\{DF4B2E6F-F05F-4D3C-AE70-000F6CCD445C}.cip”

The CIP file is now ready to be tested. Copy the CIP file to C:\Windows\System32\CodeIntegrity\CIPolicies\Active and reboot the machine.

The WDAC policy was created  in audit mode, meaning that no applications will be blocked. However, the event log will show if an application would have been blocked if the policy were being enforced. In the Event Viewer under Applications and Services Logs > Microsoft > Windows > Code Integrity > Operational you will see all the warnings. Make sure to run different application and check the event viewer for warnings and errors.

4. Deploy WDAC policy – pilot

Before this section explains how to deploy WDAC policies with Endpoint Manager, a little side step. I was preparing this blog by reading documentation and trying to the deploy the WDAC policy in my lab. I’ve followed the documentation from Microsoft Deploy Windows Defender Application Control (WDAC) policies by using Microsoft Intune (Windows 10) – Windows security | Microsoft Docs. Everything went fine until I was not able to upload the bin file that was created. Every time I tried to create the policy I received the error: Unable to save due to invalid data. Update your data then try again: Exception has been thrown by the target of an invocation. After a while I found this article stating that OMA-URI policies with payload over 350k bytes were no longer supported Support Tip: Custom OMA-URI’s not always applying to Windows 10 Devices – Microsoft Tech Community . Well the payload for a WDAC policy is way bigger then 350k bytes so that would explain why I wasn’t able to add the policy. Even by stripping a WDAC policy to its bear minimum it would still be bigger than 350k bytes… I’m hoping this will be resolved in the future, so I will leave the original procedure in place, but also provide an alternative method to deploy the WDAC policy.

Original method

You have created a baseline policy and tested the policy on a device. Ideally you want to test the policy on multiple devices which are being used by multiple people within your organization. Running a pilot will better determine if your baseline policy fits the business needs. So, its time to deploy the policy to several devices by using Configuration Manager.

To deploy the policy with Endpoint manager the policy first must be converted to a bin file.

ConvertFrom-CIPolicy -XmlFilePath $CIPolicyXML -BinaryFilePath “C:\temp\{DF4B2E6F-F05F-4D3C-AE70-000F6CCD445C}.bin”
  • In Endpoint Manager go to Configuration Profiles and add a new policy. For platform select Windows 10 and later for profile select Custom.
  • Give your policy a name, and go to the next step
  • In configuration settings Add a new OMA-URI setting
    • Provide a clear name
    • OMA-URI is ./Vendor/MSFT/ApplicationControl/Policies/<POLICYID> /Policy. Here you replace <POLICYID> with the value of the policy ID without the brackets
    • For Data type select Base64 (file) and upload the bin file
  • Assign the deployment to a group with test devices / users

Alternative Method

For the alternative distribution method, we are going to use the IntuneWinAppUtil.exe utility from Microsoft. The goal is to copy the CIP file to C:\Windows\System32\CodeIntegrity\CIPolicies\Active folder. However this brings on a new problem, because in order to copy something in that directory you need administrative permissions. Even though the account installing the application should have this permissions, it is not permitted to copy files to that location. Or I haven’t found a good way of doing this, if you know the solution please let me know because I haven’t found a better way. I did however found one way of completing this and it seems a little bit devious, but if it works it works. It involves creating a scheduled task which then copies the files to the right location.. In order to make it work all the necessary information is wrapped into a Win32 Intune package to deploy it to the device. The tool for doing this will also be used for the monitoring agent later on in this blog. To learn and read more about this packaging method check out my previous blog.

To start create a folder containing the following:

-Your CIP file
– A Powershell script to Deploy the CIPolicy  (Deploy-CIP.ps1 Adjust the script to match your CIPolicy id.)


#Create CIP directory
New-Item -Path "c:\" -Name "CIP" -ItemType "directory"

#Start logging
$logfile = 'c:\CIP\CopyCIPolicy.txt'
Start-Transcript $logfile -force

#Copy items to CIP directory
Copy-Item -Path ".\{DF4B2E6F-F05F-4C3D-AE70-000F6CCD445C}.cip" -Destination "C:\CIP" -Force
Copy-Item -Path ".\Copy-CIP.ps1" -Destination "C:\CIP" -Force

#Create scheduled task
$Time = New-ScheduledTaskTrigger -Once -At 12:00
$User = "SYSTEM"
$Action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-ExecutionPolicy Bypass -file `"C:\CIP\Copy-CIP.ps1`""
Register-ScheduledTask -TaskName "CopyCIPolicy" -Trigger $Time -User $User -Action $Action -Force
Start-ScheduledTask -TaskName "CopyCIPolicy"

Stop-Transcript

#Exit code
Return 0

– A Powershell script to Copy the CIPolicy  (Copy-CIP.ps1 Adjust the script to match your CIPolicy id.)

Copy-Item -Path "C:\CIP\{DF4B2E6F-F05F-4C3D-AE70-000F6CCD445C}.cip" -Destination "C:\Windows\System32\CodeIntegrity\CiPolicies\Active" -Force

– A Powershell script to remove the CIPolicy (Remove-CIP.ps1 Adjust the script to match your CIPolicy id

#Cleaning up resources

Stop-ScheduledTask -TaskName "CopyCIPolicy"
Unregister-ScheduledTask -TaskName "CopyCIPolicy" -Confirm:$false
Remove-Item -Path "c:\CIP" -Recurse -Force 

#remove policy from C:\Windows\System32\CodeIntegrity\CiPolicies\Active

Remove-Item -Path "C:\Windows\System32\CodeIntegrity\CiPolicies\Active\{DF4B2E6F-F05F-4C3D-AE70-000F6CCD445C}.cip" -Force


#Exit code
Return 0
  • Run the IntuneWinAppUtil.exe and specify:
    • The source folder location
    • The setup file, which is Deploy-CiPolicy.ps1
    • Output folder
    • You do not need a catalog folder

To deploy the application use endpoint.microsoft.com:

  • Add and new Windows app (Win32)
  • Fill in the app information
  • For the install command use powershell.exe -ExecutionPolicy Bypass .\Deploy-CIP.ps1
  • For the uninstall use powershell.exe -ExecutionPolicy Bypass .\Remove-CIP.ps1
  • Run as system
  • Specify your requirements
  • For Detection rules make use of a File manually detection rule. Here you can use C:\Windows\system32\CodeIntegrity\CiPolicies\Active and for File use {DF4B2E6F-F05F-4C3D-AE70-000F6CCD445C}.cip (change the name to your CIP policy), detection method File or folder exists

5. Monitor your WDAC Policy

As mentioned previously in this blog you can view the Event Viewer to check if applications are blocked. In larger deployments this is not really practical to check each individually device for events.  Ideally you want to have a central location for all the Event logs. For this you can use a Log Analytics Workspace.

To create a Log Analytics Workspace follow these steps Create a Log Analytics workspace in the Azure portal – Azure Monitor | Microsoft Docs. Then open the workspace and select Advanced Settings and Data. Search for Microsoft-Windows-CodeIntegrity and add both, also add Operations Manager. Do not forget to save the configuration.

After you have a Workspace enable logging in endpoint.microsoft.com by going to Reports and selecting Diagnostics settings. Select Add diagnostic setting. Select all the different log types and for destination details select Send to Log Analytics Workspace and select your subscription and Workspace.

Enable logging Endpoint Manager

Go back to the Analytics Workspace and now go to Agents Management. Here you can download the log agent and make sure to note the Workspace ID and the Primary key.

The downloaded Analytics agents needs to be repackaged using the IntuneWinAppUtil.exe. Check out my previous blog for more in-depth information.  The first step is to extract the contents of the AnalyticsAgent.exe.

  • Place the downloaded MMASetup-AMD64.exe into a folder
  • Run .\ MMASetup-AMD64.exe /c and specify a folder location on where to put the extracted data.
  • Run the IntuneWinAppUtil.exe and specify:
    • The source folder location
    • The setup file, which is setup.exe
    • Output folder
    • You do not need a catalog folder
  • You now have the monitoring app packaged into the Intune format

To deploy the application use endpoint.microsoft.com:

  • Add and new Windows app (Win32)
  • Fill in the app information
  • For the install command use setup.exe /qn NOAPM=0 ADD_OPINSIGHTS_WORKSPACE=1 OPINSIGHTS_WORKSPACE_ID=”<WORKSPACEID>” OPINSIGHTS_WORKSPACE_KEY=”<PRIMARYKEY>” OPINSIGHTS_WORKSPACE_AZURE_CLOUD_TYPE=0   AcceptEndUserLicenseAgreement=1″
    You need the Workspace ID and the Primary key from your workspace. View the reference in the docs Install Log Analytics agent on Windows computers – Azure Monitor | Microsoft Docs
  • SPecify your requirements
  • For Detection rules make use of a Registry manually detection rule. Here you can use Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HealthService\Parameters\Management Groups\AOI-<WORKSPACEID> where you change WORKSPACEID to your Workspace ID
  • Assign your application to a group

After the deployment is finished the Monitor Agent starts uploading Event logs to the Workspace. To view the Event Logs open the Workspace and select Logs. Here you can enter Query based on Kusto Query Language to search the Event Viewer logs. For example you can use the following query to display all the logs with a Warning or Error in the Code Integrity Events category.

Event
| where Source == "Microsoft-Windows-CodeIntegrity"
| where EventLevelName == "Warning" or EventLevelName == "Error"
| project TimeGenerated, Computer, RenderedDescription
| sort by TimeGenerated desc 

6. No more testing, time for enforced mode

When your done with testing and you have validated everything to work as expected it is time to turn on the enforced mode. To enforce the policy option 3 is removed from the XML which is the configuration for audit mode.

$CIPolicyXML = "C:\temp\WDAC_Policy_DellLatitude5500.xml"
Set-RuleOption -FilePath $CIPolicyXML -Delete -Option 3

After the audit mode is removed repackage the XML to a CIP for local testing or to a bin file if you deploy the policy with Endpoint Manager.  

Endpoint Manager Win32 App Deployment (MSI and EXE)

HOW TO: deploy Win32 application using Endpoint Manager.

With Endpoint Manger you can deploy a variety of different applications to Windows clients.  I have made blog posts about using MSIX packages to provide a modern way to distribute applications. Sometimes MSIX might not be the right solution for you. This blog is about deploying Win32 applications using the Windows App (Win32) capabilities. This form of distributing gives you a lot of control on how and when an application should be installed.

A note of caution, if you start to use Windows App (Win32) app deployment for your environment it is highly recommended that you do not combine Windows App (Win32) with Line-of-Buisiness app installations. Especially if you are planning to use Microsoft Autopilot, the combination of Win32 apps and Line-of-Business apps will cause installations to fail. So, if you decide to use Windows App (Win32), use it for all your applications.

Before you can upload a Win32  application to Endpoint Manager you will need to prepare the application. Essentially you repackage the application and all the dependent files into an .IntuneWin package, which can then be uploaded to Endpoint Manger. To package an application you will need to download the Win32 Content Prep Tool from GitHub.

You will then need to gather all required media to install the application and place them into one folder. I have created two examples, one for .exe applications and one for .msi application. For both types of installations, it is recommended to create two batch files, one for installation and one for the uninstallation. This will provide better control when deploying the application.

For the Citrix Workspace, which is an .exe I have created the following batch files: install.cmd and uninstall.cmd and placed them in a folder togheter with the exe installation file.

Install.cmd:

@ECHO OFF
PUSHD "%~dp0"
"CitrixWorkspaceApp.exe" /silent /noreboot /forceinstall

uninstall.cmd

@ECHO OFF
PUSHD "%~dp0"
"CitrixWorkspaceApp.exe" /silent /uninstall
Citrix Workspace package content

For Acrobat Reader, which is an .msi I have also created the following batch files: install.cmd and uninstall.cmd. These files are added to the installation files.

msiexec /i "%~dp0AcroRead.msi" ALLUSERS=1 /qn /norestart
msiexec /x "%~dp0AcroRead.msi" /q
Acrobat Reader package content

Once you have gathered all the necessary installation media and you have validated that your batch files are working, by running the install.cmd and uninstall.cmd files you are ready to package. To package the applications run IntuneWinAppUtil.exe from an elevated PowerShell prompt. You are prompted for the source folder, which is the folder that contains all the installation files. The setup file is the actual executable and you need to specify an output folder where the .IntuneWin  file will be saved. At this point we do not need a Catalog folder. After the Utillity is ready you will end up with an .IntuneWin file.

Endpoint Manager

Now its time to distribute the application using Endpoint Manger. Login to endpoint.microsoft.com and select Apps and all Apps to Add a new application. Make sure to choose Windows app (Win32) as an app type. The first step is to select your .IntuneWin file and to provide information about the application. I will first start with Citrix Workspace and then add Acrobat Reader.

Application information

The second step specifies how to install the application. For the install and uninstall commands you will need to enter the batch files you created in the beginning. In my case the Install command is install.cmd and the uninstall command is uninstall.cmd. For installation behavior you can choose between system and user. This will determine where the application will be installed, either in the system context or in the user profile, this depends on your application.

Application installation controls

Choosing a restart behavior after the application is installed. Of course, this all depends on your application and whether it requires a reboot. Depending on your needs the following actions are explained:

Determine behavior based on return codes – The device will restart bases on the configured return code.
No specific action – Will suppress a restart during the installation of Win32 apps.
App install may force a device restart – This option means that the Win32 app installation can complete without suppressing restarts. With this configuration a Hard reboot return code will notify the user that a restart of the device will be triggered in 120 minutes. A Soft reboot return code will notify the user that a restart is required to finish the installation.
Intune will force a mandatory device restart – After a successful Win32 app installation the device will be rebooted immediately with no notification.

You get several default return codes. In most cases these return codes will work for you application . . The code configures the post-installation behavior of the Win32 app. If your application uses different access codes, you can use them here. The actions are explained:

Failed – The Failed return code indicates that the Win32 app installation failed.
Hard reboot – The Hard reboot return code indicates that the device is required to restart to complete the installation. Additional Win32 apps cannot be installed on the device without restart. The user will be notified about the required restart.
Soft reboot – The Soft reboot return code indicates that the next Win32 app can be installed without requiring a restart, but a restart is necessary to complete the installation of the installed Win32 app. The user will be notified about the restart.
Retry – The Retry return code indicates that the Win32 app installation is retried three times. The installation will wait for 5 minutes between each attempt.
Success – The Success return code indicates the Win32 app installation was successful.

The third step in the process is to specify the requirements. For the most part these are self-explanatory. You can however use custom requirement types such as specific files, registry settings or even scripts to determine whether an application should be installed or not. I will not be going into detail in this blog. For now, I only choose to install on 64-bit machines with a minimum operating system of Windows 10 1903.

Installation requirements

The fourth step are the detection rules. The detection rules are used to check if the application is present on the device. If the rules are not met Endpoint Manager will try to install the application on the device.

For .exe installations you might decide to just validate if the application is present. In my case I just check if SelfService.exe is present, in the path C:\Program Files (x86)\Citrix\ICA Client\SelfServicePlugin\.

EXE Application detection rule

The fifth step is to create dependency rules. Software dependencies are applications that must be installed before this application can be installed.  Specifically, the device must install the dependent apps before it installs the Win32 app. You can add Win32 app dependencies only after your Win32 app has been added and uploaded to Intune. After your Win32 app has been added, you will see the Dependencies option on the pane for your Win32 app. Any Win32 app dependency needs to also be a Win32 app. It does not support depending on other app types, such as single MSI LOB apps or Microsoft Store apps.

Since this is the first Win 32 app there is no option to create any dependencies. After Citrix Workspace is added a dependency will be created with Acrobat Reader. So, I just select next and I assign the application to a user group, as required.

For Acrobat Reader the steps are the same with a few exceptions. For the detection rules I will use a MSI rule type instead of a file location. Normally the MSI product code is filled in automatically. If this is not the case, you can check your registry settings. For 64-bit machines browse to HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall. Here you will find an overview of all the installed applications. In my case for Acrobat Reader I can find the MSI GUID.

MSI application detection rule
Find the MSI GUID in the Registry settings

Since Citrix Workspace has been added to Endpoint Manger this can be used as a dependency. Acrobat Reader and Citrix are do not require each other to function, this is purely for demonstration purposes. To add a dependency simply select to add a dependency and select the application, in this case CitrixWorkspace.exe. By creating dependencies means that before Acrobat Reader is installed the Citrix Workspace application must be present. If Citrix Workspace is not present Endpoint Manager will install it first.

Application dependencies

Now the configuration is ready, and the applications start deploying to the clients. What happens on the client? Well first the Intune Management Extensions is installed on the client. This extension is used for the installation as well as the deployment of custom PowerShell scripts on devices. You can use the extension for troubleshooting purposes. The log file IntuneManagementExtension.log can be found in C:\ProgramData\Microsoft\IntuneManagementExtension\Logs.

User notification

MSIX App Attach on Windows Virtual Desktop

Windows Virtual Desktops App Attach has just gone into Public Preview. A new major step in delevering and optimizing Windows Virtual Desktop application management. This blog will cover to steps on how to set it up.

MSIX_appAttach
Wndows Virtual Desktop, Fslogix and App Attach

But first what is MSIX App Attach and why it’s going to help you with your WVD environment. When maintaining your environment there are generally three components that you manage. Namely the OS, User Profiles and Applications. On a laptop for example all these components are on a single device and the components stored on a single disk. This works fine for the laptop but if you have non-persistent environments you have a challenge. In an ideal situation you want to separate the user data, application data and OS data.

Fslogix

Separating the user information is something that has long been used and is especially handy when you work on non persistent environments. With Fslogix there is no need anymore for the User Profile Disk, which comes with all its limitations and performance issues. It works great for non persistent environments. This way the user data is seperated from the OS and the Application data and is stored seperatly.

MSIX App Attach

With MSIX App Attach you can separate the applications from the Operating System, the same way that you would use Fslogix to separate the user data from the OS. This way you will have three different entities that you can mange independently of each other. So if you would have to update an application you wouldn’t have to create a new golden image for example, but would only modify or create a new application package. This makes the deployment and updates management of your environment much easier.

Let`s get started

Here’s what I’ll be covering:

  • Create Share
  • Convert MSIX to VHDX
  • Configure MSIX App attach

There are a couple of thing you will need:

  1. A certificate to sign your MSIX package, this certificate also needs to be installed on the WVD session hosts. Check out my previous blog on how to to this; Deploy MSIX with Intune.
  2. Applications that are already packaged in the MSIX format. Also check out Deploy MSIX with Intune on how to set this up.
  3. For now your subscription needs to be white listed for MSIX app attach. Fill out the Microsoft form, with your subscription ID. Approval of request can take up to 24 hours.
  4. A Windows Virtual Desktop environment with session hosts which are based on Windows version 2004. Make sure that you set this host pool to an evaluation environment.

Create Network Share

To deploy the MISX packages to the Session hosts you will need a network share. This network share needs to be accessible for users AND to computers. So create two groups, one containing your users, one containing your WVD session hosts. All is needed are Read rights.

Prepare WVD hosts

First the automatic updates for MSIX app attach applications needs to be disabled. In a elevated command prompt run:

rem Disable Store auto update:

reg add HKLM\Software\Policies\Microsoft\WindowsStore /v AutoDownload /t REG_DWORD /d 0 /f
Schtasks /Change /Tn "\Microsoft\Windows\WindowsUpdate\Automatic app update" /Disable
Schtasks /Change /Tn "\Microsoft\Windows\WindowsUpdate\Scheduled Start" /Disable

rem Disable Content Delivery auto download apps that they want to promote to users:

reg add HKCU\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager /v PreInstalledAppsEnabled /t REG_DWORD /d 0 /f

reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager\Debug /v ContentDeliveryAllowedOverride /t REG_DWORD /d 0x2 /f

rem Disable Windows Update:

sc config wuauserv start=disabled

Furthermore Hyper-V needs to be enabled on the VM. To install Hyper-V run

Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All

Convert MSIX to VHDX

Before you can use the MSIX package, you will need to convert them to VHD(x) files (or .Cim but we won’t cover this today). Using the Microsoft docs, this is how you convert the MSIX.

  1. You will need the Hyper-V management tools. Install them by using
    Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
  2. Download the msixmgr tool.
  3. Unzip the files
  4. Run the following Powershell commands to create a VHDx. Adjust the command s to your needs
New-VHD -SizeBytes 1000MB -Path c:\temp\chrome.vhdx -Dynamic -Confirm:$false
$vhdObject = Mount-VHD c:\temp\chrome.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

5. Create a parent folder. In my case I will name it GoogleChrome
6. Run the msixmgr to expand the MSIX package.
.\msixmgr.exe -Unpack -packagePath “C:\Temp\Appattach\GoogleChrome_68.46.88.0_x64__v1hrd262mcs5e.msix” -destination “D:\GoogleChrome” -applyacls
The destination is the folder you created in step 4 and 5
7. Detach the VHDX and your are ready to place the VHDX to your packages location

WVD Portal

With the preparations in place we can now add the MSIX packages to our hosts pool. Because the feature is still in preview you will need to use the following link to access MIX package feature https://preview.portal.azure.com/?feature.msixapplications=true#home. Go to your WVD app attach host pool, here you will see a new option, MSIX packages.

MSIX app attach

Select MSIX packages and Add to add a new package.
– Enter the UNC path to the VHDX file
– Enter a display name
– Set the state to Active

Add msix package
Add MSIX package

Now that the package is added you will need to assign the application to users. In you Host pool select Application groups. By default there should be at least one application group named after your host pool name followed by -DAG. To assign the application group to users go to assignment and add the users that need access to the host pool.

To add the MSIX package to the host pool go to Applications and select add:
– For MSIX Package select your added package
– Provide a Name
– Select Save

Add MSIX application

To check your work log in to the WVD host pool as a user and you should see the application that was added via MSIX app attach!

MSIX app attach final result

More info

Hopefully the information provided was helpful to you. You can also checkout the following sites for additional information:

MSIX Filetype Association

Today I received a message from Richard regarding File Associations and MSIX packages. Great question, lets figure it out.

Hi Stephan,

I created an MSIX app attach for Workspace App and deployed/attached it to my WvD servers.

The Workspace app is visible/available when i login to WvD , i can launch the Citrix Workspace app so it is working. But….. if I connect to a citrix storefront server I get a .ICA file from the server but seems there is no extention relationship with the Workspace App……. and if i search for an app to my computer to open the ICA file the Workspace app does not appear in the available App list??

Richard

So its true that by default an MSIX package doesn’t have file associations by default. In this case installing Citrix workspace using my previous article won’t allow you to open .ica files. Furthermore, you wont be able to associate Workspace with any file extension.

.ica file association with Citrix workspace

So how to fix this? In order to associate your MSIX packages with file extensions you will need to edit the MSIX so called Manifest file. The Manifest file can be edited during the creation of the MSIX package, or you can edit your existing package. When you choose to edit the existing package you will see the option under Package information.

By opening the file you will see an XML file containing information about your package. In order to create file associations such as .ica association you will need to add additional information. Microsoft has created some documentation on how to do this. In our case this means adding the following config in the <Applications> section. Copy the xml code and paste it just before </Application>.

[cc lang=”xml”]




.ica




[/cc]

so it looks like this:

MSIX Manifest file

If you would redeploy your Citrix Workplace, you now should be able to open the .ica file.

Final result

Of course this will work for any file type associations that you would want to make in combination with any application you would want to use.

Windows Virtual Desktop as trusted location for Conditional Access

When using Windows Virtual Desktop the public IP of which you are NATed to the internet changes consistently. In some cases you would want to have the traffic origination the WVD hosts to use the same public IP adress. So that it can be whitelisted to use some external service, or so that it can be used as a trusted location for Conditional Access. This way users can connect to Windows Virtual Desktop and be prompted for MFA, but once they are signed in, in a managed environment they aren’t prompted for MFA again.

Traditionally you could accomplish this setup by using an Azure Load Balancer. I didn’t find this very easy to implement, luckily Microsoft introduced a new service called Virtual NAT Gateway which make this a lot easier to implement. By using a Virtual NAT Gateway you can NAT your outbound connections through one, or more Public IP addresses. This way all the VM’s within a certain subnet of your virtual network will use a dedicated public IP to make outbound connections.

Please note that the Virtual NAT Gateway is still in preview, so I wouldn’t recommend using this in production environments.

To get started you will need a Virtual Network with some subnets, with a Virtual Machine deployed in that Virtual Network.

To create a NAT gateway, you select create resource and look for NAT Gateway.

Select your subscription, resource group and give the NAT Gateway a name and continue to the next step.

Here you can create or select a public IP address, if you need more one PIP you can also choose to create a whole range of PIPs. Notice that the SKU and assignment are Standard and Static, this means that the PIP you select won’t change over time.

Select a virtual network with the subnet(s) you want to associate the NAT Gateway, add tags and Create the NAT Gateway.

After the deployment is ready you can verify your settings by logging into the VM and checking your public IP on a website like https://www.myip.com/

You could then add this IP as a trusted location to use with Conditional Access so users wont have to two-factor authenticate within a WVD session.

Update MSIX package with Intune

In my previous blog I showed how easy it was to package and deploy an application using MSIX and Intune. In this blog I want to show how easy it is to update and application. Applications evolve and time to time they get updated with the latest patches or security updates. To update applications with Intune can be challenging. Sometime you have to create a new deployment of an application. This requires you to first uninstall the application, otherwise you would get conflicts.

So for this blog I have the following situation. I have deployed the Citrix Receiver application to my users. The Citrix receiver was been updated and is now the Citrix Workspace application. I want to remove Citrix Receiver and replace this with the new Citrix Workspace application. Let me show you how easy this process is when you use MSIX.

So I have my test machines on which the Citrix Receiver MSIX is deployed.

CitrixReceiver

The fist step is to create a new MSIX package for the Citrix Workspace application. I wont go over all the steps (check out the previous blog). But here it is important that you name your package the same as the application you want to replace. So if you previously deployed an application with the name CitrixReceiver, create a new package with the name CitrixReceiver. Furthermore it is important that you increment the version of your package.

Update_MSIX
Update Name and Versions

When your MSIX package is ready and tested, you can upload it to Intune. Simply go to your previous deployment. In my case this was the CitrixReceiver deployment. Select Properties and go to App package File. Here you can select and upload the new version of your application.

Upload new version of your MSIX package

When the application is finished uploading Intune will redeploy the application to your clients.

MSIX updating to Workspace
Citrix Workspace App is finished updating

Recap

I showed you how easy it was for you to update an existing MSIX application with Intune, by simply redeploying it. Knowing how easy your application management can be, I would encourage everyone to give MSIX a try.