Securing Windows 365 Enterprise with Azure Firewall

Configuring Azure Firewall in combination with Windows 365

To increase security on your Windows 365 hosts you might want to put your Windows 365 clients behind a firewall. There are several options but one of the options that you have is to use the Azure Firewall. The Azure firewall is a powerful SaaS solution of Microsoft, but also an expensive one. Recently Microsoft announced the preview of a new Firewall sku, the Azure Firewall basic. The solution is more aimed to midsized companies. It lacks the advanced features of the Standard and premium Firewall but is does provide you with enough features to better secure your environment. Besides it also in a lower price range so it should be more attractive to midsized companies.

  • Azure Firewall Premium is recommended to secure highly sensitive applications (such as payment processing). It supports advanced threat protection capabilities like malware and TLS inspection.
  • Azure Firewall Standard is recommended for customers looking for Layer 3–Layer 7 firewall and needs auto-scaling to handle peak traffic periods of up to 30 Gbps. It supports enterprise features like threat intelligence, DNS proxy, custom DNS, and web categories.
  • Azure Firewall Basic is recommended for SMB customers with throughput needs of less than 250 Mbps.

In this blog I will show you the basics of setting up the new Azure Firewall Basic sku in combination with Windows 365 Enterprise. Unfortunately, Windows 365 Business is not suitable for Azure Firewall because you will need to redirect the traffic through the Azure Firewall. With Windows 365 business you do not have any control over the networking, since it’s managed by Microsoft. The article builds upon the blog series of Windows 365, so if you need information on how to set up Windows 365, I recommend reading through those articles first.

Azure Firewall

This feature is in preview, so you might need to register the new Azure Firewall Basic Provider. To do so:

  • Connect-AzAccount
  • Select-AzSubscription -Subscription “subscription_id or subscription_name”
  • Register-AzProviderFeature -FeatureName AzureFirewallBasic -ProviderNamespace Microsoft.Network
  • Check Registration: Get-AzProviderFeature -FeatureName AzureFirewallBasic -ProviderNamespace Microsoft.Network  
  • Wait until the provider is registered

From a networking perspective an Azure Basic Firewall needs 3 subnets within a vnet. It needs a management subnet, Azure firewall subnet and a subnet workload subnet. The management and the Azure firewall subnet need specific names otherwise you won’t be able to deploy the Firewall. So, in your vnet you need to create 3 subnets:

  1. Subnet : AzureFirewallSubnet, in my case I am using a subnet
  2. Subnet: AzureFirewallManagementSubnet, in my case I am using a subnet
  3. Subnet: Workload subnet
Required subnets

In production environments it is considered better to create a hub spoke network topology where you Firewall is in a separate Vnet than your workload. You connect your Vnets via network peering. The functionality doesn’t change is you have 1 or multiple Vnets.

Now you have set up the subnets in your Vnet its time to deploy the Azure Firewall. Sign into the Azure Portal and search for Firewalls and select Create.

To set up Azure Firewall sign into the Azure Portal and search for Firewalls and select Create.

  • Subscription. Where the Azure firewall will be deployed. This needs to be the same subscription as where your vnet is created.
  • Resource Group. Select or create a resource group to deploy the Firewall
  • Name. Give you Firewall a name.
  • Region. Select the region for your Firewall. This also needs to be the same as the region of you vnet.
  • Availability zone. If the region supports availability zones you can select a zone or leave it to none
  • Firewall SKU. Select Basic, or a higher sku.
  • Firewall management. Is greyed out is you choose Basic
  • Firewall Policy. Create a new policy. This also needs to be deployed in the same region.
  • Virtual network. Choose a virtual network. Pick the network where you want to deploy the Firewall. If you did not create the necessary subnets, you will get an error.
  • Public IP address. Create a new Public IP address
  • Management public IP address. The basic sku also needs a public management IP. You won’t be able to connect to this IP, but it is necessary for Microsoft to manage your Firewall.
Azure Firewall deployment

Choose review and create. The deployment will start and can take up to 30 min, so go grab yourself a cup of coffee.

While waiting for the deployment we can already create a route table. With a route table we can redirect network traffic within Azure. Otherwise the Windows 365 clients network traffic will leave Azure without passing through the Firewall.

In the Azure portal search for Route Table and create a new Route table

  • Subscription. Same subscription as the vnet to which you want to connect to route table
  • Resource Group. A resource group of your choosing.
  • Region. Select the same region of your vnet
  • Name. A clear name, such as route-to-fw
  • Propagate gateway routes. Depending on your config, but you can leave it on yes.

When your route table has been created go to the route table and select Routes and select Add

Add route

Add the following to the new route:

  • Route name. A clear descriptive name
  • Address prefix destination. Choose IP Addresses
  • Destination IP addresses/CIDR ranges. Enter this way all traffic will be forwared.
  • Next hop. Choose Virtual Applicance
  • Next hop address. This is the IP of the Azure firewall. This is the first available IP in the AzureFirewallSubnet. In my case the range is so the first available IP will be You can also check this by going to the Firewall.

The next step is to associate the route table to a subnet, this way all devices in that subnet will use the route defined in the table. Be aware that associating the route table will result in disconnecting your Windows 365 user sessions. You need to configure the firewall as described in the next section. To associate the route table, select subnets and choose associate. You can there select the Vnet and the subnet of where your workload is deployed.

Configuring Azure Firewall

You now have a firewall and you route all the Windows 365 traffic through that firewall. This also means that the traffic that is required for users to connect to the Windows 365 machine is also blocked. So if a user tries to connect to its machine it will get the following message. So if you are deploying the firewall to a production environment wait with applying the route table otherwise your users won’t be able to connect to their machines.

Unable to connect to Windows 365

You will need to make some firewall rules. Unfortunately, there is no official Microsoft documentation of which firewall rules you need to create in order for Windows 365 to work (At least I haven’t found it). There is however documentation available on firewall rules for Azure Virtual Desktop. The two basically share the same connection method so that should give us a good starting point. You can find the AVD documentation here . In the Azure Portal search for Firewall Policies. A policy was created when you deployed the Firewall so there should be at least one policy there. Open that policy and let’s start with Application rules. In the Application rules you have to have at least one rule collection. A rule collection is a logical set of rules that allow or deny traffic. Select Add a rule collection. Give the collection a name, for example Windows365Applicationrules. For type use Application and give the collection a priority. The priority determines the order of the collection to be deployed. If you don’t know how many rule collections you are going to have pick a number witch gives you flexibility in deploying higher of low collections. So don’t start with 100 since that is the highest priority. For Rule collection group you can leave the DefaultApplicationRuleCollectionGroup for now. Next you can define the rules.

Enter the following rules. The source is my subnet range where I deployed my Windows 365 machines.

NameSource TypeSourceProtocolDestination TypeDestination
Login Microsoft OnlineIP Address10.2.2.0/
AVDIP Address10.2.2.0/24Https:443FQDN*
W365 MonitorIP Address10.2.2.0/24Https:443FQDN*
catalogartifactIP Address10.2.2.0/
W365 MonitoringIP Address10.2.2.0/
W365 blob storageIP Address10.2.2.0/
MicrosoftIP Address10.2.2.0/24http:80,
Application rules
Application rules

Next go to Network rules. Here also select Add a rule collection. Give the collection a name, select for rule collection type Network. Give a priority and for Rule collection action select Allow. For rule collection rule group select DefaultNetworkRuleCollectionGroup. Enter the following rules:

NameSource typeSourceProtocolDestination PortsDestination TypeDestination
Azure ServicesIP Address10.2.2.0/24TCP80IP Address169.254.169.254,
AVD ServicesIP Address10.2.2.0/24TCP443Service tagsSelect WindowsVirtualDesktop, AzureFrontDoor.Frontend, AzureMonitor
DNSIP Address10.2.2.0/24TCP, UDP53IP Address* Address10.2.2.0/24TCP1688IP Address20.118.99.224, Address10.2.2.0/24TCP1688IP Address23.102.135.246
 IP Address10.2.2.0/24TCP   
 IP Address10.2.2.0/24TCP   
Network rules
Network rules

After the policies are applied (and you have applied the route table) you should be able to sign in to your Windows 365 environment. However, browsing through the firewall logging ( you can enable this in the diagnostic settings of your firewall) I was still getting a lot of deny hits for Microsoft services. Even though I was able to connect to the Windows 365 machine, Windows 365 is depending on more services. For example it also communicates to Intune. So I have also added the following application rules:

NameSource TypeSourceProtocolDestination TypeDestination Address10.2.2.0/24Https:443FQDN* Address10.2.2.0/
.azure-devices.netIP Address10.2.2.0/24Https:443FQDN*
Application rules

The Firewall logging seemed a lot better after adding the extra rules. You now have configured the bare minimum for allowing the Windows 365 services to you hosts. But that doesn’t mean you are ready. Users are still not able to browse the internet of access any of the other Microsoft 365 services. So, you will need to configure additional rules. We did create a rule to browse to, but if you want to go to your connection will be blocked. The next step would be op further configure the firewall rules depending on the needs of your organization.

I hope this blog was helpful, if you have any questions or some parts needs additional clarification please let me know in the comments.

Windows 365 Enterprise – AAD Join

Setting up Windows 365 AAD Join step by step

Windows 365 Enterprise – AAD Join

As we have seen in Getting Started with Windows 365 Business setting up Windows 365 Business is pretty straight forward. With Windows 365 Enterprise you will see you get a lot more options. This makes setting up Windows 365 Enterprise a bit more complicated, because you have more design decisions to make.

One of the decisions you will have to make is how to enroll your Windows 365 clients. You have 2 options. The first option is to hybrid join the devices (see This means that you join the device to the Azure AD and the Active Directory. This functionality is also possible with normal Windows 10/11 clients. Most often this solution is used in combination with Conditional Access policies, Group policy management or SSO with on premises application. Please note that SSO is also possible to on premises application without hybrid joining the devices. In my experience most applications will SSO without the need of hybrid joining the devices. Accessing file shares and for example shared printers will work fine if you Azure AD join the devices and only sync users between Active Directory and Azure AD with AAD connect without any fancy configurations. That said, it’s always worth testing because it limits the amount of configuration you have to do for SSO. Hybrid joining devices requires extra configuration within AAD connect and line of sight to a domain controller. Only AAD joining does not require any extra configuration besides a sync with AAD connect, which in most scenarios is already present. This means that AAD joining, and Windows 365 Enterprise only requires a network connection and your good to go. Pretty easy ????

So, to demonstrate this we will deploy a Windows 365 Enterprise Azure AD joined device, that will be able to access a file share.

A small overview of my setup in Azure. I have a simple vnet containing 2 VMs, 1 domain controller which is set up to sync identities with AAD connect and a file server. The new Windows 365 machines are being joined to the same network, but in the Windows 365 subnet. In a production environment you could see that the vnet is connect to on premises resources via a vpn or Express Route, or that there is a hub spoke design with multiple vnets.

Test environment setup

Azure Network Connection

The first step would be to connect the Windows 365 services to your vnet. In order to do so go to and choose devices and Windows 365. There you select Azure network Connection.

Azure network connection

On the tab select create and choose Azure AD Join. Enter a name which tells you something about the connection, for example what the vnet is you are connecting to. Select the subscription that has the vnet and select the subnet you want your machines to join to. It’s important that your vnet is in the same region as where you want to deploy your cloud pcs as vnet are bound to a specific region.

Network details

Select next and create the connection. Make sure your account has the appropriate permissions on the subscription (Owner) and within Endpoint manager.
Microsoft will start running some checks and if all went well, you will get a checks success status.

Successful network configuration

Provisioning policies

The next step should be creating a Provisioning Policy. These policies determine how the Windows 365 pc should be created. From the Devices section select Provisioning policies and select create policy. Enter a name and description. For Join type make sure to select Azure AD Join. For network it’s important to not choose Microsoft hosted network, this way you won’t be able to integrate with your vnet and the setup is more like the Windows 365 business deployment. So, choose for Azure network connection and select the network connection you just created in the previous step.

Provisioning policy

At the image tab pick a gallery image, or a custom image if you have one. Check out this article if you’re interested in how to create a custom image. At the configuration tab select the language and region. This will automatically install the required language packs on the machine. For additional services you may choose Windows Autopatch. Windows Autopatch manages updates for you. It’s not really a Window 365 services but you can read more about it in this blog Blog | Get current and stay current with Windows Autopatch | Tech Community (

Enroll device in autopatch

Finally assign the policy to a group which contains your users. When you have finished creating the provisioning policy you are basically set. When a user has a valid license (a Windows 365 enterprise and a lisence containing Intune) and is a member of the group which is assign the provisioning policy the cloud pc will be created.

Now I assign the following licenses to my test user in order to start the provisioning of the device. My test user Pluto  has 2 licences; a Microsoft 365 E3 and the Windows 365 Enterprise 2 vCPU, 8 GB, 256 GB license.

By assigning the license the provisioning starts. Let this process complete.

provisioning finished

Connect to fileserver

Now that the provisioning is ready let’s sign in. As mentioned in the beginning of this article SSO to most of your on-premises resources will work without any extra configuration. So, in my case I have a file server (cluster) which I can connect to via \\filecl02.wvd.local\Bestanden even though I sign into the Windows 365 cloud pc with my Azure AD credentials, pretty cool.

Connect to file server

As you can see my cloud pc is only Azure AD joined and not domain joined, but still able to access on-premises resources based on my Active directory permissions.

AAD Join only

That sums up this part of the series, please continue reading at the next article, where we Hybrid Join the Windows 365 Enterprise cloud pc.

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
  • 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 = ""
# Download the script
Invoke-WebRequest -Uri $Uri -OutFile ".\DeployAutomationAccount.ps1"

Also download the Custom Role Definition for the role assignments

$Uri = ""
# Download the script
Invoke-WebRequest -Uri $Uri -OutFile ".\Automation-RoleDefinition.json"

Log in to your environment


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!

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:

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.


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

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.

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.


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

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

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.

Deploy MSIX with Intune

I think we can all agree that application deployment is probably the most challenging part of an Intune implementation. The wide variety of Line of Business applications and different installation types can give you sleepless nights. It’s true that Microsoft has made some real improvements in application deployment with the support for most applications extensions. But there are always some applications that simply can’t be deployed with Intune or are very hard to deploy and manage.

With the introduction of MSIX I dare to say that you can now practically deploy any application successfully with Intune. In this blog I describe how you can create and deploy an MSIX package with Microsoft Intune.  In this blog I will cover:

  • Create a Self-Signed Certificate (testing purposes)
  • Deploy a certificate with Intune
  • Create a MSIX package
  • Deploy the MSIX package

Please note that in order to install MSIX packages you must enable Application Sideloading.

Create a self-signed certificate

Before you can deploy a MSIX package you need a certificate to sign your package. The signing of a package is a required step in the creation of the package. This is necessary because this is the only way you can assure that package is valid and came from a trusted provider. Preferably you should use a Code Signing certificate from a 3rd party provider. For now I use a self-signed certificate so that the deployment can be tested, but for you production environment I wouldn’t recommend this.

To create a self-signed certificate, you can start PowerShell as an administrator from any VM. Enter the following cmd, where you replace <Your Organisation> with a name of your choosing:

New-SelfSignedCertificate -CertStoreLocation Cert:\CurrentUser\My -Subject “CN=<Your Organisation>” -KeyAlgorithm RSA -KeyLength 2048 -Provider “Microsoft Enhanced RSA and AES Cryptographic Provider” -KeyExportPolicy Exportable -KeyUsage DigitalSignature -Type CodeSigningCert

To Export the certificate open certmgr, your certificate is located in the Personal Certificates folder. Select the certificate –> all Tasks –> Export. Choose Next –> Yes, Export the private Key –> Choose Next –> For Encryption choose AES265 and enter a Password –> Enter a save location –> and choose Finish. You now have the certificate with a pfx extension.

Export Certificate

We also need a certificate with the cer extension, so run the export Wizard again. Select the certificate –> all Tasks –> Export. Choose Next –> No, do not export the private key –> Choose Next –>   Enter a save location –> and choose Finish.

You now have the certificate to sign your MSIX package and you have a certificate to distribute it via Intune.

Deploy Certificate Using Intune

Before you can install the MSIX package on any machine the certificate to sign the application must be trusted by the machine. Otherwise the application wont start. To install the certificate on the machine we can use Intune to distribute the certificate.

From the Intune Management Portal go to –> Device Configuration –> Profiles and choose Create Profile. Here you enter the name and description of the Profile. For the platform you choose Windows 10 and later, for Profile type select Trusted certificate. In the new blade you select the .cer certificate that you exported. After you created the Profile you than assign the profile to a group with has a test device in it.


Create a MSIX Package

For this blog I wanted to package an application that I had some trouble with in the past, the Citrix Receiver.

I have copied the Citrix Receiver installation file and the pfx certificate to the packaging VM and have launched the MSIX Packaging Tool. Here I want to create a new package, so I select ‘Application Package’.


Select Create package on this computer and choose Next.  The packaging tool will now check some prerequisites and make sure that the drivers are installed.


In the next screen select the installation file. For now, I leave the installer arguments empty. For Signing preference, I select Sign with a certificate. This step is important. If you don’t select a certificate the application won’t be able to install.


Now provide some information for you package. Give your package a Name and a Display name. The Publisher name is provided from the certificate. The display name must be the same as the certificate, if these values don’t match the application won’t install. The installation location is not a mandatory field but is recommended.


By clicking next you will now enter the installation stage. The installation of your application will now start.  You can just run through the installation as you normally would. When the installation is completed you can continue by clicking Next.


If the application requires any first launch tasks, they can now be performed otherwise press Next and continue Yes, move on. The package will now be created.


Finally provide a save location for the package and choose Create.


Deploy MSIX with Intune

Now that the MSIX package is ready we can start deploying it with Intune. Simply go to the Intune management portal –> Client apps –> Add App. Here you select Line-of-business app. Here you can upload the MSIX package you created.


When you click the app information blade you can see that most of the information is already filled out with the information from the MSIX package. After adding the app, just wait till the application is uploaded. The final step is to assign the application to a group.

After some time check your test machine to confirm that the application is deployed.



As you can see the packaging and distribution of an application with MSIX and Intune is really easy. But it doesn’t stop here, after you deployed one version of the application you might want to provide the application with an update. With MSIX this process is even easier. So in my next blog I will show you can can upgrade the Citrix Receiver application to the new Citrix Workspace application!

Windows Virtual Desktop Management Tools

Windows Virtual Desktop is probably one of the most anticipated new products of Microsoft. If you haven’t heard from it, I would suggest that you start catching up ;). With the announcement of Scott Manchester GA (General Availability) just became a little bit closer.

There are plenty of blogs about how to set up a WVD tenant and sessions hosts, so I don’ want to go into detail on how to set it up. But if you have set up a WVD tenant you must have noted the lack of management tools. Or actually the absents of management tools, you can’t even find WVD in the Azure portal. Everything is managed with PowerShell, which can be a bit challenging. Microsoft did provide some management options for you but you will have to deploy them manually. They also require you to have an App service plan, which of course will cost you money, but you won’t have to use PowerShell for you management. Nevertheless I hope Microsoft will include these managements functionalities in the Azure Portal, but for now this is your best option.

WVD Management UX

The first management tool I would like to share is the WVD Management UX. The Managment UX helps you to preform basic management tasks. In here you can:

  • Create a New Host Pool
  • Add New Hosts to a Host Pool
  • Allow or block new connections to a host.(If you would like to drain the server for maintenance)
  • Create App groups. You can create App groups for Desktops or you can create App groups for RemoteApp
  • Assign permissions to App groups

Even though this may seem somewhat limited there are some extra functions you can use. However, these basic management tasks will help you a lot in doing day to day management for WVD.

WVD Management UX

If you want to use the WVD Management UX you can deploy it via the Github repository from Microsoft. The deployment will create an App service plan S1-Standard which will cost you around 70 euro/dollar each month.

WVD Diagnostics Tool

The second tool Microsoft has provided is the Diagnostics tool and it has just been released. With the introduction of WVD Microsoft also introduced some new RDS roles. We all know the Connections broker, Gateway, Session Hosts and we all know it was very hard to troubleshoot failing connections. Therefore Microsoft introduced the new Diagnotics role, which is also fully managed by Microsoft.

New Diagnostics role in WVD

Starting with the preview it was only possible to view the diagnostics using PowerShell, luckily Microsoft has made an App so you can troubleshoot using your browser. With the new Diagnostics app you can do the following:

  • Look up diagnostic activities (management, connection, or feed) for a single user over a period of one week.
  • Gather session host information for connection activities from your Log Analytics workspace.
  • Review virtual machine (VM) performance details for a particular host.
  • See which users are signed in to the session host.
  • Send message to active users on a specific session host.
  • Sign users out of a session host.

Unfortunately these functions aren’t available in the Management UX, you’ll have to deploy another application with an new app service plan. Which will cost you 70 euro/dollar extra each month, plus the additional storage for the log files. The deployment is pretty straightforward, Microsoft will guide you through the steps.

Example of diagnostics logging
Example of VM diagnostics
Here you can log off users and send them messages.

Azure Files with ACLs

Azure files is a file share as a service that you host on Azure. You can mount the file share to a server so that you get an extra file share without having to physically extend the storage of that server. This is especially handy when you want to go through the transition of moving from IAAS to SAAS. In a cloud only environment Azure files would be preferable over and VM which is configured as a file server. Azure Files is also the preferred location for saving your FSLogix profile containers, when using Windows Virtual Desktop.

All in all this sounds pretty good, but Azure files also had a downside. Azure Files had until now no support for Access Control Lists, meaning that setting more advanced permissions on files and folders was not possible. Until now! Microsoft announced the General Availability of the support of ACL’s on Azure File shares. This enables you to set advanced permissions on files and folders.

To make this work, this is what you need:

  • Set up Azure AD Domain Services
  • A Virtual Machine that is joined to Azure Active Directory Domain Services. Active Directory is not supported!
  • A Storage Account where you enable Azure Active Directory Domain Services (Azure AD DS) for the Identity-based Directory Service for Azure File Authentication
  • Set the general permissions to the share. You can compare this with the share settings in Windows.

You need Azure AD Domain Services for you authentication, since the file share make use of Kerberos authentication and your Azure AD doesn’t support Kerberos.

Azure File authentication

You can create a new storage account or use an existing storage account. All you need to do is configure Identity-based Directory Service for Azure File Authentication to Azure Active Directory Domain Services (Azure AD DS).

Set the authentication option to AADDS

Set the Access permissions on the share. You can compare this with the share settings in Windows, where you would set global share permissions and then set NTFS permissions for more detailed permissions. Microsoft introduced three new roles for this.

  • Storage File Data SMB Share Reader allows read access in Azure Storage file shares over SMB.
  • Storage File Data SMB Share Contributor allows read, write, and delete access in Azure Storage file shares over SMB.
  • Storage File Data SMB Share Elevated Contributor allows read, write, delete and modify NTFS permissions in Azure Storage file shares over SMB.

After that just mount your share to the VM and you can set permissions!

Deploy a Azure Web App using Gitlab – Part 3

In Deploy a Azure Web App using Gitlab – Part 1 a Gitlab server was installed and some basic settings were applied. In Deploy a Azure Web App using Gitlab – Part 2  a SSL certificate was added so that HTTPS traffic could be used. In this third and final part I will start with what I intended to do; namely deploying a simple web page from Gitlab to an Azure Web App. More specific using a private Git repository so that the “code” will be safe. In short this is what’s going to happen:
1. Create a new project in Gitlab
2. Create a new App service
3. Connecting Gitlab with Azure
4. Connecting Azure with Gitlab
5. Configuring triggers or Webhooks

So creating a new project is pretty easy. Just hit the New Project button and give your project a name. I want to use a private project so that I know nobody can access the resources.

So create the new project and then we can start uploading some basic content. I like to use Visual Studio Code for this. Gitlab is kind enough to provide you with all the necessary commands to get started. These can be found at the project starting page.

[cc lang=”bash”]git clone
cd example-project
git add
git commit -m “add README”
git push -u origin master[/cc]

Continue reading “Deploy a Azure Web App using Gitlab – Part 3”