How to decode Intune Win32 App Packages

The new Intune Win32 app management is a great way to deploy Win32 apps with Microsoft Intune. Imagine you have a kind of source share for all the .intunewin files you have created. At some point in time you like to modify a package but you do not have the source files right now, only the .intunwin package. Wouldn’t it be nice to convert the .intunewin package back to an unencrypted package? Additionally what is if you lost your complete sources, can we get them back directly from the Intune tenant?

As a quick reminder, the packaging workflow is like this:

  1. Compressing the source folder of the Win32 apps and its files to a sub folder ‘Contents’ with the new extension .intunewin
  2. Encrypting the compressed file
  3. Computing a SHA265 hash
  4. Generating a detection.xml file in a sub folder ‘Metadata’
  5. Compressing complete working folder and create again an .intunewin file
.intunewin compressed file – internal folder structure

As described in my previous post “Part 3, Deep dive Microsoft Intune Management Extension – Win32 apps” the portal and the Intune service gets all necessary information from the detection.xml file to deal with the Win32 app. The EncryptionInfo in the detection.xml file is stored with your Intune tenant to gain access to the uploaded encrypted .intunewin package. The encrypted .intunewin (located in the contents folder) can be distributed safely by Microsoft to the Intune back-end services responsible for content distribution without getting exposed to others, only the tenant who uploaded the file has the EncryptionInfo and can decrypt the file. The clients will get this information also when they are requesting Win32 apps for installation via policy.

If we try to open the inner encrypted .intunewin file with 7-Zip, it is expected to be not working. We will see the following error message:

I’m using the fact that the encryption information is stored along with the package before uploading. As long as this information is available we can make use of it. I wrote a small .net tool “IntuneWinAppUtilDecoder” to extract the .intunewin file content, read the EncryptionInfo from the detection.xml file to get the encryption key and initialization vector and decrypt the inner .intunewin package from the contents folder back to an unencrypted .intunewin package. Et voila – we have an unencrypted .intunewin.decoded file, which we can open with our favorite archiver like 7-Zip.

The IntuneWinAppUtilDecoder is available on my GitHub account here:

https://github.com/okieselbach/Intune/tree/master/IntuneWinAppUtilDecoder

The direct download link to the zipped binary file is here.

Let’s have a look how the tool looks like when running. The command line utility is pretty simple to use, just point to the path of the .intunewin file and optionally you can run it in silent mode to prevent output. If you already have the encrypted .intunewin, and the encryption key, and the Initialization Vector you can provide these information on the command line as well:

IntuneWinAppUtilDecoder.exe <FullPathToIntunewinFile> [/s | /silent]
[/key:base64encodedKey /iv:base64encodedIV]

In my following example I’m decrypting an Adobe Acrobat Reader DC package:

As you can see the tool will ask for any overwrite and cleanup of extracted files before proceeding. Sometimes it is useful to keep the extracted content for further inspection. For easy proceeding just hit enter and let the tool do the cleanup of the extracted .intunewin content. After successful decryption we have now an additional .intunewin.decoded file in the same directory as the original .intunewin file:

This .decoded file can be opened with 7-Zip and easily extracted and here we have back the original sources:

When running the tool in silent mode /silent it will not ask for overwrite or cleanup, the overwrite of existing .decoded file and the cleanup of the extracted files is always done in silent mode.

How to get the sources back from the Intune tenant directly?

I discovered that all relevant download and decryption information to get the sources back from your tenant are in the regular log files of the Intune Management Agent here:
C:\ProgramData\Microsoft\IntuneManagementExtension\Logs\IntuneManagementExtension.log

So I wrote a small PowerShell script to parse the logfile and extract all relevant information of the already installed .intunewin files (otherwise we would not have the log file entry :-)). This is an example of that log file entry:

<![LOG[Get content info from service,ret = {
"odata.metadata":"https://fef.msub03.manage.microsoft.com/SideCar/StatelessSideCarGatewayService/$metadata#SideCarGatewaySessions/@Element","odata.id":...
LOG]!>

Basically I’m searching for this particular log entry which I then decode with the certificates on the device as they include decryption information of the installed .intunewin file. The installed .intunewin file is encrypted and can only be decrypted by your device with the right certificate. The log entry does include the download location also. It would be possible to write a tool to request the file from Intune directly to get to this information but in fact then I would write lots of the parts of the agent my self again. Getting tokens for requests, dealing with discovery, decryption, etc. So I decided to not do that and let the agent to its job and grab the necessary information from the log files. In case of missing entries you can simply enroll a device and install all software via Company Portal on it to get all log entries and then parse this info for further usage.

So in the log entry we have everything we need. If we run the script provided below on an Azure AD joined device with Intune enrollment you can successfully decrypt the encryption information which you get from the Intune GatewayService to decrypt and download the encrypted .intunewin file. The agent itself does nothing else during a normal install. It requests a policy which includes the package info, content info and decryption info. I decode this as well and provide it as plain text to you, or we can simply pass this to the IntuneWinUtilDecoder as parameters for instant decryption.

The script can also be found on my GitHub account here: https://github.com/okieselbach/Intune/blob/master/Get-DecryptInfoFromSideCarLogFiles.ps1

Here the script in action, downloading an app discovered in the log entry (yellow is the download URL, cyan is the encryption info highlighted) and in the end decoding it:

I hope this small utility and script is as useful for you as for me as I deal with a lot of test deployments in my lab and miss from time to time my source files. With the IntuneWinAppUtilDecoder and the script I’m now able to simply extract my source files again in any case.

Have fun at decrypting 🙂 your .intunewin files!

Deploying Win32 app BGInfo with Intune

Deploying BGInfo to quickly find your test devices or provide easy VM access during trainings with more visibility of the available user permissions.

Deploying the well known Sysinternals tool BGInfo is popular since a very long time. Often people use it for more visibility of vital OS parameter to end users. It is used mostly to support in-house help desk personal. Today I’m using this approach, to provide a handy solution for your development or test environment to quickly identify your devices and logged on user including their permissions (local admin or standard user) in that session like this:

The undiscovered need for this was there all the time, e.g. during intensive testing in my development environments with a lot of virtual test devices and during class room training’s to make student life’s easier. I often test various features so Windows Version and Edition is important to know for me. As a nice addition I added the local permissions of the logged on user. Following an user logged on to an Autopilot device with standard user permission and a device without Autopilot and local administrator permissions:

Now you know my intention for this blog post. I was inspired by Nick Hogarth blog post (Intune – Win32 app Deploying BGInfo) about this and re-discovered my need 🙂 and took his solution and developed it a little further for my needs (thanks Nick!). I can recommend to read his blog as well as he has a nice walk through how to create and upload the Intunewin package for Intune and trace the installation itself. Like Nick I only focus on the x64 Edition of BGInfo64 as I’m not dealing with x86 devices for a long time now.

First I had to came up with a way to identify if the user is a local admin. BGInfo supports various ways to get OS information and one option is to use vbs scripts. So I wrote a short vbs script to verify local Administrators group membership. To handle this in a way to be language independent I’m resolving the local Administrators group SID S-1-5-32-544 (read about well known SIDs here) to the localized display name to finally enumerate account membership. 

GitHub Listing – CheckAdmin.vbs

The vbs script is dynamically written by the install script as CheckAdmin.vbs to the BGInfo install folder (C:\Program Files\BGInfo) during install. This way I do not have to maintain several files, only my install script. I followed the same way and created an install.ps1 to install BGInfo64.exe with the custom background information file custom.bgi. In addition I modified the startup shortcut creation to create the shortcut with the ActiveX object WScript.Shell in the PowerShell install script. The startup shortcut is needed to always have actual information on the background. Following the complete install.ps1:

GitHub Listing – install.ps1

To also provide uninstall capabilities I created the small uninstall.ps1 as well:

GitHub Listing – uninstall.ps1

The custom background information file custom.bgi was adjusted to present all information needed. Especially the CheckAdmin.vbs is referenced to get the user permission information:

For completeness I list the two registry keys I used for displaying the complete Version string e.g. 10.0.17763.194 (1809) 

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ReleaseId

-> Windows Release e.g. 1809

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\UBR

 -> Patchlevel e.g. 194

All files for the complete Intune Win32 app package can be found in my GitHub account here:
https://github.com/okieselbach/Intune/tree/master/Win32/BGInfo64

As always when dealing with Intune Win32 apps we need to package it as .intunewin and upload the package to Intune. Use the Packaging tool from here: https://github.com/Microsoft/Intune-Win32-App-Packaging-Tool. The complete conversion can be done in an one liner when the conversion tool is in the same folder structure level as the BGInfo folder with all needed files:

.\IntuneWinAppUtil -c .\BGInfo -s Bginfo64.exe -o .\ -q

For more details regarding packaging see my post: Part 3 Deep Dive Microsoft Intune Management Extension Win32 Apps. As soon as we have the BGInfo64.intunewin package we can upload it and specify the install and uninstall command lines with the install behavior System:

powershell -ex bypass -file install.ps1
powershell -ex bypass -file uninstall.ps1

As the detection rule we use a simple file exists for BGInfo64.exe in the install folder:

C:\Program Files\BGInfo
Bginfo64.exe

Finally you can assign it to your devices or users. I assigned it to all my devices as I like to have it on all my test devices:

If successfully installed you should see the following files:

Because it is installed in System context we need to logon once to trigger the startup shortcut to finally execute BGInfo in user context and create the background information. If everything runs fine you should get nice information about the device you are currently using and in which context you are running (admin or user permission).

I hope it may help you as it helps me and gives you an idea how to dynamically get OS parameters for BGInfo and display them.

Happy tattooing you backgrounds!

Ignite 2018 – My wrap up

First of all, what an amazing experience to attend Microsoft Ignite 2018 in Orlando. All started off with a keynote by Satya Nadella followed by general announcement sessions and technical deep dive sessions. The key message was about “Tech Intensity”. This is described by changing your cultural mindset and your processes. Ultimately leading to a better digital transformation by tearing down silos in your organization and bringing teams and technology closer together. Creating close feedback loops to generate advantage of valuable insights. Technology will cover every aspect of our life sometime and it is time now to start to align yourself to this. Time to disrupt yourself, modernize your own business model. Everyone has to find ways to leverage technology to optimize their businesses otherwise others will have a significant advantage in a short amount of time. It’s time for a culture of adoption.

The biggest announcement for me as an Enterprise Mobility MVP is by far the Win32 app support in Microsoft Intune.

IntuneWin32Announcement

Microsoft delivers the functionality to wrap your apps (all kind of installers like setup.exe etc) in a container (zip) format and allows distribution via Intune. This is a game changer for Microsoft Intune as it was one of the missing parts and blocker for customers to fully adopted the modern management approach. Customers who are wiling to modernize and are going for a full modern management approach are now able to install their Line-of-business applications directly via Intune. This functionality is powered by the Microsoft Management Extension (see my deep dives Part 1 and Part 2) which was used for PowerShell script execution with Intune already in the past. I will provide some technical deep dive insights into the Win32 capabilities in the following days.

For Windows Autopilot they announced Hybrid Azure AD join and the capability to harvest Autopilot data. The Hybrid Azure AD join might be good for some people but I really encourage everyone to check out Azure AD join as it also supports accessing local AD resources with Kerberos authentication. Harvesting Autopilot information of existing devices in an easy way is great and simplifies the steps to a modern infrastructure where all devices even in a reinstall/reset scenario are using a simplified setup powered by Windows Autopilot. For Intune they delivered great Sessions regarding the availability of Intune Security Baselines and Desktop Analytics. The Intune Security Baselines are provided to fill configuration gaps which companies currently see when transitioning from a local AD and Group Policy environment to a Azure AD/MDM environment. The goal is to have all required security settings available in the MDM environment to easily transition. In addition to the Security Baseline settings, Intune gets support for Administrative Templates to further simplify the configurations of policy settings for Office and Windows. It frees us to handle the complex way of admx ingestion by providing the most needed settings in the portal. Not only the settings administration is made simple they also released the Intune PowerShell SDK to easily automate tasks within Intune. With Desktop Analytics we get tighter integration of the telemetry data from Windows Analytics into Intune to build piloting rings based on telemetry to ensure good coverage of your LOB apps in the piloting rings.

A lot of changes happening in the IT world right now and Microsoft builds out his platforms to be even more mature to support us in every aspect. This starts with the Microsoft 365 story by bringing real cross platform functionality like Information Protection availability in every product like Outlook, Word etc. for Windows, iOS/macOS, and Android. They also announced the OneDrive feature “Files on Demand” for macOS now. There is a very big focus on Security on everything what Microsoft is doing right now. More than 3500 full time security professionals are working at Microsoft to power the security platforms also with the help of AI to generate insights for the Intelligent Security Graph. To fight the world of passwords they announced Azure AD password less sign-in. A very good simplification of the portals is coming up also to provide consistency in the handling. This simplification includes a common URL scheme like devicemanagement.microsoft.comadmin.microsoft.com, security.microsoft.com, or compliance.microsoft.com. Even a Windows Virtual Desktop in the cloud was announced. Another highlight to mention is that Microsoft will bring up a new offer called Microsoft Managed Desktop where Microsoft will completely manage your devices. In the Office world we got Microsoft Ideas which helps you to find great layouts and even the interesting data in your Excel spreadsheet powered by AI.

Beside these great announcements I’ve taken the chance to meet with a lot of the Product Group members and had great conversations with them. Also I met a lot of my fellow MVPs which was a great experience. Really looking forward for the next one in Orlando at November 4-8. If you like to pre-register follow this link.

See you in Orlando next time! 👍

 

 

Automation of gathering and importing Windows Autopilot information

Complete process automation of gathering and upload of a device Autopilot information to the Windows Autopilot service with an Azure Automation Runbook.

AzureAutomation


On one of my previous blog post Gather Windows 10 Autopilot info in azure blob storage during wipe and reload, I described the gathering of Autopilot information during operating system deployment in a wipe and reload scenario with MDT. Just a short recap of the problem and my initial solution:

If we purchase a new device, the OEM vendor takes care of installing Windows 10 with a signature edition or provisioning ready installation including all necessary drivers. If we buy new hardware the information for Autopilot can be synced into our tenant from the OEM vendor (Lenovo is already capable of doing that and others will follow). We will get the device information in Intune and we can start to assign an Autopilot Deployment Profile and start to enroll the devices.

What if we have a bunch of Windows 7 devices in the environment?

A way to handle this is that we are playing the role of the OEM vendor and do the install of a Windows 10 signature edition on the existing Windows 7 devices, gathering Autopilot information, and let Windows 10 start in the Out of Box Experience (OOBE) again for user enrollment. Depending what is available we can use ConfigMgr or MDT for this. My example uses MDT.

Now imagine a situation where a rollout team is preparing a lot of machines. We would end up in a lot of .csv files on different devices. To make this a little easier for IT to import the hardware information of new devices into the Autopilot service, we build up the following logic:

  1. Gather hardware information via PowerShell Script Get-WindowsAutoPilotInfo during wipe and reload
  2. Upload .csv file via AzCopy to an Azure Blob Storage
  3. Gather .csv files from Azure Blob Storage and combine them into a single combined.csv file
    This was a manual step in my previous solution
  4. Upload combined .csv file to Autopilot and assign Deployment Profiles
    This was a manual step in my previous solution
  5. Device can be delivered to the end user like it where shipped by the OEM vendor

You can read more about the initial solution here: Gather Windows 10 Autopilot info in azure blob storage during wipe and reload

This blog post is all about automating these two steps – gathering and upload of Autopilot information to Intune.

Architecture

First, I will explain the architecture and how it works and then I’m going to describe the way to implement it. The overall architecture is based on an Azure Automation Runbook and looks like this:

AutoPilotImportArchitectureOverview

The new procedure including the enhanced logic for a complete automation of the import is now as follows (modified steps for complete automation):

  1. Gather hardware information via PowerShell Script Get-WindowsAutoPilotInfo during wipe and reload scenario
  2. Upload .csv file via AzCopy to an Azure Blob Storage
  3. Gather .csv files from Azure Blob Storage and combine them into a single .csv file with the help of a scheduled Azure Runbook
  4. Upload combined .csv file information to Windows Autopilot Service via PowerShell Script WindowsAutoPilotIntune running in an Azure Automation Runbook 
  5. Cleanup Azure Blob Storage (delete all .csv files of successfully imported devices and delete all .csv files of already imported devices)
  6. Generate import notification and summary and post it to a Microsoft Teams channel
  7. Autopilot information is available for the OOBE user enrollment scenario with Autopilot. The Autopilot profile gets automatically assigned by a dynamic AzureAD device group membership.
  8. Device can be delivered to the end user like it where shipped by the OEM vendor

I’ve still chosen the copy via AzCopy of individual .csv files to the Azure Blob Storage approach as we can then limit the access quite well via shared access signature and we can easily limit permission to write blob objects only. No need to provide credentials or Blob Storage keys on the client side. Sure, we could build up a more advanced HTTP endpoint to gather device information, but this approach is quick and simple. I’m pretty sure that the complete solution of this automation task is something which we do not need in future when devices are Windows 10 migrated and we then buy Autopilot ready hardware only.

Guide to build the new solution

The Autopilot Graph API is an API with focus on batch processing. This means we import new device information into a kind of staging area and Windows Autopilot service will pick up the new device information and starts importing it. This process varies in the amount of time it takes and we have to check the status of all devices to get the import result. As soon as the devices are processed we can clean up the staging area and the import is done. Normally we would do this by wrapping the Graph API calls (REST) into some PowerShell functions and build the logic for the described process. Luckily Microsoft released a new PowerShell Module WindowsAutoPilotIntune (thx to @mniehaus) based on the Graph API to import new AutoPilot information into Intune.

In my previous blog post about Process automation for Intune and Azure AD with Azure Automation, I created a Runbook to delete old devices from Intune via Graph API and demonstrated how to do an unattended authentication within the Runbook. All the details how this can be achieved are explained there. Please follow the guide to setup the Azure Automation account. I use the same unattended authentication technique to utilize the PowerShell Module WindowsAutoPilotIntune to import the device information into Autopilot service in the following Runbook. Additionally, the Runbook is built to protect concurrent execution (thx to Tao Yang, I used his implementation for it) to ensure a sequential processing and to keep track of current running imports. If we would design this as a concurrent solution it would get much harder in terms of monitoring and reporting in the end. In addition, there is a max import of 175 devices into the staging area of the API which we are taking care of by limiting the Runbook import to 175 devices during one run.

If the requirements are implemented based on the previous blog post (especially the Intune native app and the automation service account) we simply need to extend the permissions to “Read and write Microsoft Intune configuration” of the automation account which was created during the setup of Process automation for Intune and Azure AD with Azure Automation in section Building the solution.

IntuneNativeAppPermission

For the concurrent execution protection, we need our automation credential to have Reader permission and for Blob Storage access we need Contributor permissions on the subscription. As the result we grant Contributor permission to the automation account:

SubscriptionPermissions

Finally, we can implement the complete Runbook which can be found on my GitHub account here:

The Runbook is written in PowerShell and follows the logic described in the beginning of this post – section architecture.

Create a PowerShell Runbook and paste-in the code.

CreateNewRunbook
PowerShellRunbook

To make sure the Runbook successfully runs we need to define some additional variables. I assume that the IntuneClientId and Tenant variable are defined as described in the previous blog post.

AzureAutomationVariables

Additional variables needed for Azure Blob Storage access:

ContainerName: <your-blob-storage-containername>
StorageAccountName:
<your-blob-storage-account>
StorageKey: <your-blob-storage-secret-key> * as encrypted variable

Additional variables needed for Microsoft Teams Channel notification:

SubscriptionUrl: <your-subscription-url>

The subscription URL can be found as shown below. Please do not copy the /overview end of the URL. The URL should end with the subscription GUID only (like highlighted):

AzureSubscriptionsUrl

TeamsWebHookUrl: <your-ms-teams-webhook-url>

Open MS Teams and choose a Channel where the Autopilot notification from the Azure Runbook should be displayed. Click on the three dots and choose Connectors:

TeamsConnectors

Look for Incoming Webhook and click Configure

incomingwebhook.png

Type in the details and upload a icon and click Create

ConnectorDetails

Finally copy the Webhook URL:

ConnectorWebHookUrl

Paste it into the Azure Automation variable TeamsWebHookUrl and set encrypted value to Yes

TeamsWebHookVarEncrypted

This is necessary to get Microsoft Teams notifications with some statistics and information to troubleshoot errors. Below is an example of an import notification in Microsoft Teams:

AutoPiloImportTeamsNotification

We have some statistics, detailed error list with device information and a link to the Runbook itself in Azure. All based on Adaptive Cards JSON code. This can be easily modified to fulfill personal needs. Have a look at the Adaptive Cards Designer (https://acdesignerbeta.azurewebsites.net) for experimenting with layouts and adjust the Runbook code.

Enhanced client-side script part

I my previous blog post about Gather Windows 10 Autopilot info in azure blob storage during wipe and reload I have described how to setup the Azure Blob Storage to gather the “<hostname>.csv” files during MDT operating system installation. Please follow the previous guide to setup the Azure Blob Storage and the integration in MDT.

I have an enhanced version of the gather script now which can be found on my GitHub account and is also shown below. The enhanced version does not have the dependency on AzCopy.exe (incl. dependency files) and Get-WindowsAutoPilotInfo.ps1 in the script directory. If they are not available, they are downloaded from an additional Blob Storage container named resources. The additional container resources must be created and the AzCopy.zip and Get-WindowsAutoPilotInfo.ps1 must be uploaded there to successfully run the script:

BlobStorageResources
BlobStorageResourcesContent

The enhanced Get-WindowsAutoPilotInfoAndUpload.ps1 version:

Replace ZZZZ with your Blob Storage account name and ZZZZ with your SAS signature in the script above. See here Delegating Access with a Shared Access Signature for more SAS signature details.

This version can also be used to be executed via Microsoft Intune Management Extension to run it on existing Windows 10 devices. It is possible to collect all targeted device information and the Runbook will import the device information. Already imported devices will be skipped. This way we can make sure every device is imported to the Autopilot service.

SideCarAutoPilotScript

Sample output of the Runbook

AutoPiloImportRunbookOutput

If a device information <hostname>.csv is successfully imported the .csv files will be deleted from the Azure Blob Storage. In case of an error it will be left there untouched but reported via Runbook output and Teams notification. There is one case where the Runbook will delete the .csv file from the Azure Blob Storage also. This is if the Runbook detects an error 806 – ZtdDeviceAlreadyAssigned. In that case we can delete the .csv as it has no consequences. In every other error situation someone needs to resolve the error manually. The Teams notification is only generated if there is some device information in the Azure Blob Storage. The normal procedure would be if operations gets an import notification it should check and in case of errors they should be resolved manually.

AutoPiloImportTeamsNotification

Important observations during testing

The Autopilot import via Graph API takes some time and it may also timeout. So, it is not a typical request response REST API in this case. Remember all device information is staged and then the devices are monitored for their success or error state. This led to situations where I had to wait up to 1 hour to get a successful import, even when the UI in Intune tells us it takes up to 15 min. So be prepared that it might take longer or fails during the run. I chose this approach as it is the same procedure as the Azure Portal does the import. In fact, we really automated the import process in Intune but did not invent a complete different process which might cause different problems of device tracking or concurrency and so on. Depending on the use case you can run the Runbook on a recurring schedule. My normal use case for this scenario is to support people who are preparing older devices when they are getting reinstalled from Windows 7 to Windows 10. If someone expects immediate availability of Autopilot information after such a reinstall this might be problematic as the API is not designed for this. Another fact is that the Autopilot Deployment Profile assignment using Intune does take some time also at the moment. I observed that it took several hours sometimes. I suggest to re-arrange the operational processes and hand out reinstalled Windows 10 devices after some additional time and not directly after reinstalling, as this increases the possibility that the Autopilot information is not imported and profile assigned yet.

To run the Runbook on a recurring schedule just go to the Runbook and add a schedule. The max recurrence is limited to every hour.

AddRunbookSchedule

Just define a schedule (max once per hour) and monitor the recent job overview if it works:

AzureRunbookSchedule

The schedule can even be enhanced by using a simple Logic App and not using the Azure Automation Runbook schedule at all:

LogicAppTriggerRunbook

Please see Stefan Strangers post for detailed instructions how to implement a simple Logic App to trigger an Azure Automation Runbook:

In case something goes wrong I have created a second Runbook to clean up the staging area of the Autopilot Graph API. Get it from my GitHub account and run it in case of fatal errors where you might want to clean up the staging area:

Here is a sample output of the Cleanup Runbook:

CleanupRunbookOutput

UPDATE:
There is a way to gather AutoPilot profiles for existing devices in the meantime (see screenshot below), but this would not give you the AutoPilot Experience during initial setup.

For the initial AutoPilot experience without true registering upfront via this automation or via the OEM vendor you can deploy a AutoPilotConfiguration.json file to C:\windows\provisioning\Autopilot. See a more detailed docs article here: https://docs.microsoft.com/en-us/windows/deployment/windows-autopilot/existing-devices

Further information

Azure Logic Apps – Schedule your Runbooks more often than every hour
https://blogs.technet.microsoft.com/stefan_stranger/2017/06/23/azur-logic-apps-schedule-your-runbooks-more-often-than-every-hour

Preventing Azure Automation Concurrent Jobs In the Runbook
https://blog.tyang.org/2017/07/03/preventing-azure-automation-concurrent-jobs-in-the-runbook

Post notifications to Microsoft Teams using PowerShell
https://blogs.technet.microsoft.com/privatecloud/2016/11/02/post-notifications-to-microsoft-teams-using-powershell

importedWindowsAutopilotDeviceIdentity resource type
https://developer.microsoft.com/en-us/graph/docs/api-reference/beta/resources/intune_enrollment_importedwindowsautopilotdeviceidentity

Autopilot profile assignment using Intune
https://blogs.technet.microsoft.com/mniehaus/2018/06/13/autopilot-profile-assignment-using-intune

Adaptive Cards Designer
https://acdesignerbeta.azurewebsites.net

I published the same article on SCConfigMgr in a more step-by-step guide version, meaning there are not so many cross references to my other articles:

Automation of gathering and importing Windows Autopilot information
http://www.scconfigmgr.com/2018/07/23/automation-of-gathering-and-importing-windows-autopilot-information

I hope this can increase your throughput on the way to an Autopilot Windows 10 modern management environment.

When someone finds bugs or problems with the solution let me know and leave a comment. I will do my best to fix them as it should be a reliable part during preparing old devices with Windows 10.

Intune Managed Browser (MAM) with Azure AD Application Proxy and Conditional Access

Recently Microsoft enhanced the Intune Managed Browser experience with Mobile Application Management (MAM) and app-based Conditional Access (CA) a lot. It is integrated into the Conditional Access story as an approved app and supports the Azure AD Application Proxy very well now.

 

What does this allow us to do now?

We are now able to design a solution to publish our internal websites externally with minimal effort and then allow access to it from our mobile devices only by the Intune Managed Browser protected by Intune app protection policy. This ensures the information is safeguarded in our containerized Intune MAM solution. This gives most companies enough trust to actually do the publishing of internal resources for usage on mobile devices and support the bring your own device (BYOD) solution.

Please read the How does Application Proxy work? documentation from Microsoft to get a better understanding what we are going to do in the next section with the Azure AD Application Proxy. The Azure AD Application Proxy architecture is shown in the figure below:

ArchitectureAADAP

One of the nice things is it will not require us to open up any inbound firewall ports. As long as we are allowed to make outbound connections we can publish internal websites easily to external. The solution even supports various authentication scenarios inclusive Single Sign-On (SSO).

 

Here is a walkthrough of a demo setup to show it in action

The walkthrough of the demo scenario should get you a deeper understanding of the new possibility. Assuming we have some internal websites e.g. intranet and expenses and they are available in the internal network only. To simulate that, I have setup an IIS server hosting the two simple websites, intranet and expenses within a private network. They are reachable on the IIS server via http://localhost for intranet and http://localhost:81 for expenses. In addition I have a link from intranet pointing to expenses website (link target is: http://localhost:81, compare screenshot with html source code). I built the two demo sites to also demonstrate link translation with Azure AD Application Proxy later on.

AADAPIntranetSites

AADAPIntranetSitesHtml

 

How do we get the internal websites published now?

First of all we need to switch off the IE Enhanced Security Configuration on the Windows Server otherwise we are not able to complete the login prompt of the Azure AD Application Proxy during setup procedure. Then we are downloading the Azure AD Application Proxy on our demo IIS server and run the msi installer. It’s a very lightweight installer and the only thing we need to provide is the Global Administrator credential during setup to finish the process.

AzureADAppProxyDownload

The next step after installing the connector is to enable it by clicking Enable application proxy. After it is enabled the UI switches to “Disable application proxy” (shown in screenshot as step 3). Once enabled we have the Connector group default and our server listed there. It is possible to install more then one connector and build connector groups to support better reliability of the publishing (in fact this is recommended). The connector does not need to be installed on the IIS as I have done it in my demo setup, it should be on a dedicated Windows Server 2016 for example. I needed to run it on the IIS for simplicity of my setup and to use the internal address of http://localhost during publishing later on.

The official documentation for the Azure AD Application Proxy from Microsoft is found here https://docs.microsoft.com/en-us/azure/active-directory/active-directory-application-proxy-enable or you follow the link on the application proxy blade “Learn more about Application Proxy“.

With an up and running connector we can publish the websites now. It is the best to follow the detailed step-by-step guide from Microsoft https://docs.microsoft.com/en-us/azure/active-directory/application-proxy-publish-azure-portal and make both available. I published my both sites as an Enterprise Application as described and used no custom domain, but enabled link translation in the application body.

Published internal websites:

AzureADAppProxyPublishedWebsites

Details of the website intranet with internal URL http://localhost

AzureADAppProxyIntranet

Details of the website expenses with internal URL http://localhost:81

AzureADAppProxyExpenses

Now I can open up my published intranet from external and the intranet link originally pointing to http://localhost:81 was replaced by the application proxy because we enabled link translation on the application body (compare screenshot below). This works only if we publish both websites as the application proxy must find a published website for http://localhost:81 to do the translation.

AADAPIntranetSitesExternal

In a real world implementation I would recommend to use a custom domain for publishing to maintain your links. For example if we have mydomain.com as Active Directory (AD) and I publish via Azure AD Application Proxy with the custom domain mydomain.com I can reach the website internally and externally with the same URL. To set this up follow the instructions here:

Working with custom domains in Azure AD Application Proxy
https://docs.microsoft.com/en-us/azure/active-directory/active-directory-application-proxy-custom-domains

 

Securing our Intune mobile apps with Intune application protection policies

Now we need to add a MAM policy – app protection policy to secure the Intune Managed Browser and Mobile Outlook. To do that we open Intune > Mobile apps > App protection policies > Add a policy

MAMPolicyAdd

After adding the policy we make sure Outlook and the Managed Browser is in the targeted apps and of course we adjust the individual Policy setting to meet our corporate standard and to realize the containerization (e.g. let apps only transfer data to other managed apps, encrypt data and so on…).

MAMPolicyTarget

For the policy setting we need to make sure the setting Restrict web content to display in the Managed Browser is set to Yes. This makes sure internal links in emails are opened in the Intune Managed Browser. Even better because of the Azure AD Application Proxy publishing we make sure that internal links get translated and opened successful in Intune Managed Browser. We will do that by assigning an additional app configuration policy in the next step.

MAMPolicySettings

As last configuration we assign the app protection policy to our AAD user group we want to target.

To configure the Intune Managed Browser to work hand in hand with the Azure AD Application Proxy and translate internal URLs to the published URLs we need to configure an app configuration policy for the managed browser.

AppConfigurationAppProxyRedirection

AppConfigurationAppProxyRedirectionTarget

Now the important piece of configuration is to configure:

Key: com.microsoft.intune.mam.managedbrowser.AppProxyRedirection
Value: true

The screenshot below does not display the complete string!

AppConfigurationAppProxyRedirectionSetting

Again as last configuration we assign the app configuration policy to our AAD user group we want to target.

 

Controlling access to the internal websites with app-based Conditional Access

Now we need to make sure our internal published website can only be accessed by Intune approved apps which are protected by app protection policy.

To do that we create the following Conditional Access policy in Intune or in the Azure AD portal. We assign our AAD user group, target All cloud apps, and include iOS and Android devices, and select Browser and Mobile apps desktop clients

CAMAMBrowserAndDesktopApps

As access control we grant access for approved client apps by choosing the option Require approved client app

CAMAMApprovedApps

 

How about the user experience?

Everything is in place and we assume someone in the company sent us an internal link to the new intranet site http://localhost. We open up mobile Outlook on iOS in this example:

OutlookIntranetMail

If we now click on the internal link, Outlook is configured to Restrict web content to display in the Managed Browser and will open the link in the Intune Managed Browser for us. The Intune Managed Browser is then instructed for AppProxyRedirection = true. This will redirect us to the external published URL instead of the internal URL as shown below and shows us the demo intranet site:

ManagedBrowserIntranet

Even the link within the demo intranet site is translated and will open the published demo expenses website:

ManagedBrowserExpenses

To make sure that the published intranet site is only accessible by the Intune Managed Browser we open up Safari and open the published intranet site by typing in the external URL and we will check if access if blocked:

SafariBlockInternalWebsite

As we see the access is blocked and we get a nice feedback to use the Intune Managed Browser instead and we can directly use the blue link button to open the Intune Managed Browser.

 

Summary

We have seen how to publish internal websites via Azure AD Application Proxy easily. Then we configured our mobile apps to use an Intune app protection policy and instructed the Intune Managed Browser to use Azure AD proxy redirection to translate internal links and open them successfully. We achieve protection of the published internal website to prevent data leakage.

 

Further information

The Intune Managed Browser now supports Azure AD SSO and Conditional Access!
https://cloudblogs.microsoft.com/enterprisemobility/2018/03/15/the-intune-managed-browser-now-supports-azure-ad-sso-and-conditional-access/

Better together: Intune and Azure Active Directory team up to improve user access
https://cloudblogs.microsoft.com/enterprisemobility/2017/07/06/better-together-intune-and-azure-active-directory-team-up-to-improve-user-access/

Manage Internet access using Managed Browser policies with Microsoft Intune
https://docs.microsoft.com/en-us/intune/app-configuration-managed-browser

How to create and assign app protection policies
https://docs.microsoft.com/en-us/intune/app-protection-policies

 

My advice to all, give it a try and start to play with MAM and app-based Conditional Access as it might be a quick win for your company and finally allow the usage of BYOD as company data can be protected very well in this scenario.

Happy publishing and protecting 🙂