Remove inactive devices in Intune automatically using Microsoft Graph API and Powershell (and a scheduled task)


Just like we do in Configuration Manager, Active Directory, Exchange and anywhere else (where possible), It’s a good idea to keep things clean (at least I think so). Clean in terms of removing inactive computers, objects, mailboxes and so forth. This brings me to Microsoft Intune and how we can leverage Microsoft Graph API through Powershell to automatically remove inactive devices, and doing so on a schedule through a scheduled task. Curious? Read on 🙂

Example of devices that haven’t checked in for 30 days

Read more…

Upgrading Configuration Manager Current Branch to version 1802 (A real example from a real production environment)


I know. There are tons of similar post explaining how to upgrade Configuration Manager Current Branch to the latest version, but that’s not a valid reason not to do another one (:D). Also, mine is exactly how I did it in our production environment, from beginning till end, and not in a lab where you usually (I do) almost blindfolded click next and accept everything, without any precautions.

This is a stand-alone primary site in an enterprise environment of a midsize company in Denmark, running on Windows Server 2016 (I most recently did an in place upgrade of the OS from 2012. Another blog post incoming soon), and for your inspiration, this is the exact steps I went through. Curious? Read on 🙂

Read more…

Provide Internet access to your private lab in Hyper-V using a Windows Server 2016 router


This is a post on a subject I’m usually not addressing on my blog, but I think having a lab is crucial and super important for any IT pro. A lab for testing and screwing up before screwing up in production is key!

In my example, I’m running a lab in a private and isolated network, but I’m still very interested in providing Internet access for the servers and workstations running inside the lab. This is how to do just that, using the routing feature within Windows Server 2016. (I’m aware that Hyper-V in Server 2016/Windows 10 has a new NAT feature which can do this too, where a router is preferred in a more complex lab with several networks).

Read more…

Change device ownership in Microsoft Intune standalone using Microsoft Graph API and Powershell


When enrolling devices into Microsoft Intune using the Company Portal, the devices end up enrolling as personal owned. This can be changed manually on each device directly in the Intune portal after enrollment. Making sure that all devices are company owned refines management and identification, as well as enabling Intune to perform additional management tasks. Also, for additional security, you can configure device restrictions to block enrollment of devices that are not company owned.

But what if we don’t like to do stuff manually and have hundreds or thousands of devices? Automation through Microsoft Graph API and Powershell to the rescue.

Read more…

How to Conditional Access for Exchange Online OWA (Webmail) using Intune


While brewing on a much more detailed post on how I moved my devices from Intune Hybrid with ConfigMgr to Intune standalone, I thought I’d share how you can offer webmail for your users, while requiring MFA (Multifactor Authentication) if not coming from a company device, using Conditional Access.

In this post I will only cover the actual steps in Intune, but for this to work, you will have to have your Windows devices registered with Azure AD. There will be some requirement for your on-prem AD and for your ADFS, if that’s how you federate with Azure/O365. These requirements are explained in details in this Microsoft article:


  • Intune is now fully accessible through the Azure portal on – head over there and sign in
  • When signed in, look for More services in the menu and search for Intune

  • In the Intune section of the Azure portal, click on the Conditional Access menu button

  • Create a new Conditional Access policy on New policy and give it a name f.i. Conditional Access – OWA

  • Assign the new CA policy to a group consisting of users. For your inspiration, I’m syncing an on-premise security group consisting of users already assigned an EMS license, as Conditional Access in Intune requires an EMS license. This will probably vary depending on your needs, setup and design goals, but I recommend that there is some synergy between whom is assigned EMS licenses, and whom you are targeting with policies in Intune (for the sake of doing proper IT 🙂

  • Select Exchange Online in Cloud apps

  • As conditions, make sure that all device platforms are selected (as we’d like to target any browser on any platform) and select Browser in the Client apps menu.

  • In Access controls, select 1) Require MFA, 2) Require device to be compliant and 3) Require domain joined (hybrid Azure AD) and select that only one of these controls needs to be satisfied. Doing exactly this configuration, will make sure that if you are coming from a private device (hence not compliant and not domain joined) will trigger MFA when accessing webmail. On the other hand, coming from an Intune enrolled AND compliant device OR a domain joined PC will not require MFA.


Before enabling the policy, I recommend that you take a closer look at the new preview feature for Conditional Access, WhatIf. It will let you know the impact of your new CA policy by setting the desired conditions. It will also tell you, if you have configured any legacy CA policies in the old silverlight Intune portal which might interfere with your new CA policies.

Now, when signing into from my private computer, I’m required to approve the sign in request through my prefered MFA method.

Enjoy your new Conditional Access policy requiring MFA when signing into webmail (OWA) on a private device. 🙂


Create required registry key for Intel vulnerability (#Meltdown #ADV180002) using Compliance Settings in ConfigMgr


Unless you have been hiding under a rock since Christmas, you should have heard about the new CPU vulnerability found in Intel and AMD chips:

Long story short, following this vulnerability Microsoft instantly made changes to their OS, requiring all AV (Antivirus) products to be compatible with these new changes.

Everything in details in this link: 

What the article also mentions is that any Windows OS won’t be offered the January Security Updates (and any subsequent) until a very specific registry key is present on the systems. This is seen, when computers in your environment doesn’t request the update when you expect it to, and when compliance reports in ConfigMgr tells you that the update show up as Not Required when you know it is.

Most AV products by this time do create the registry key already, but what if you do not use any AV (for whatever reason that may be), and what if you want to make sure the registry key is there already and always is. Use Compliance Settings in ConfigMgr. Usually for on-prem domain joined computers, I would stick to Group Policies, but for this in particular, Compliance Settings in ConfigMgr does a way better job in regards to remediation and reporting of compliance.


  • Create a new Configuration Item in ConfigMgr following these snippets (Assets and Compliance tab)

  • Add the newly created Configuration Item to Configuration Baseline, and deploy the baseline to selected collections.


Go to the Monitoring tab of the ConfigMgr console and expand Reporting -> Reports -> Compliance and Settings Management and find the report: Summary compliance by configuration baseline and lean back and watch how your clients are reporting back compliance. (Might take a while depending on your Client Policy Settings)


Updating Office 365 ProPlus. A custom alternative (Using Powershell App Deployment Toolkit and ConfigMgr)


First off, this is probably not for everyone. ConfigMgr and WSUS can deploy updates to the O365 ProPlus client just fine and most needs are probably satisfied this way. However, if you are interested in more visibility before, during and after deploying O365 updates to your users – read on!

After updating ConfigMgr to 1706 (from 1610 and 1702) something changed in the behavior of installing O365 ProPlus updates. Previously, in 1610 and 1702, the behavior was actually quite transparent for the end user: A restart flag is set and the update is installed after the computer restarts. This actually meant that you could deploy any update to o365 ProPlus and not worry about notifying your users about anything but the coming restart (which is somewhat similar to the behavior of standard software updates for Windows)

Coming ConfigMgr 1706, this changed dramatically to in-app notifications as well as forced shutdown of apps (and potential loss of unsaved work) if the right circumstances was in place. Also, when the apps are shut down, nothing is being displayed to notify the user about the progress, so most users will re-open the Office apps right away creating even more problems.

The Microsoft Docs article for the change in behavior is outlined right here:

I urge anyone managing O365 updates with ConfigMgr to give it a read and take notes of all the possible outcomes when deploying O365 updates this way. To quote the important ones (note all the maybe’s, which makes the experience really inconsistent):

  • A pop-up notification might not display until the user clicks the icon in the notification area. In addition, if the notification area has minimal space, the notification icon might not be visible unless the user opens or expands the notification area
  • If the deadline is in the past or configured to start as soon as possible, running Office apps might be forced to close without notifications (they do – yay)
  • The in-app notification bar does not display on an Office app that is running before the update is downloaded. After the update is downloaded, the in-app notification displays only for newly opened apps (the yellow in-app bar is inconsistent. Sometimes it shows, sometimes it doesn’t. Reopening apps or not)

So, enough with the ranting. Above is the facts about the poor user experience when running ConfigMgr 1706. Below will be how I used something totally different to create visibility for our users.

Powershell App Deployment Toolkit!

We all know the infamous Powershell App Deployment Toolkit: (And if you don’t, that’s another day and another blog post 🙂

Below is exactly how (and along the lines, why) I chose to leverage the use of the Powershell Deployment Toolkit and the ODT to deploy O365 updates in my organization.


Create the Office Deployment Tool .xml file (Update.xml)

The ODT relies on a .xml file. That is whether you want to update or downgrade your Office 365 ProPlus installation. In this scenario I want to update, and for this I can specify exactly what build I want to update to. If you don’t specify a version, you will be updated to the latest build in your channel. A lot of the content in the .xml is optional, and something you also can manage through ConfigMgr or GPOs.

This is exactly the .xml file I’m using to update my Monthly Channel (previously called Current Channel) clients to the latest build. I manage the channel through GPOs, which is why you don’t see the channel being set in my .xml.

Create the folder structure

This is optional and just an illustration of how I do it. I have a complete folder structure in my source file library equal to something similar to this:

8431.2107 and 8730.2127 are build numbers and is respectively version 1708 and 1711. Complete list of all the builds numbers and release dates for Monthly and Semi-Annual channel, look here!

Inside each build number, I have the Powershell Deployment Toolkit:

Inside the Files folder, I put my newly created Update.xml along side the Setup.exe from the ODT and a Update.bat file (which is what we will have the PS Deployment Toolkit running) containing following:

@echo off
“%~dp0setup.exe” /configure “%~dp0Update.xml”

I’m using a batch file to wrap the installation into, for the diversity and simplicity. If needed I can quickly edit the batch file, update DPs and move on (opposed to edit the PowerShell script)

Roll-back and downgrade

If needed, you can have the ODT (Setup.exe) to downgrade the version of Office 365 ProPlus as well. This is also done configuring the proper settings in an .xml file.

Below is my .xml file used to downgrade Office 365 ProPlus. Notice ForceDowngrade=”True” which is required if you are moving backwards (a SaaS like this, is meant to move forward 🙂 Again, take a look at this page for knowledge about the different versions/builds for your channel: here!

This I wrap into a Downgrade.bat as well inside the Files folder of the Powershell Deployment Toolkit. (In a separate folder. For a separate package in ConfigMgr.)

@echo off
“%~dp0setup.exe” /configure “%~dp0Downgrade.xml”

The above configurations is made to actually download the differences in bits directly from the Office CDN. This is also something to consider if using this method. However, you can specify SourcePath=”” to let the installation grab the bits from a local source if desired. Microsoft has specified the download sizes in this post here!


With all of above in place, you will be ready for deployment with ConfigMgr. Note that I assume that you know your way around the Powershell Deployment Toolkit.

To target the update of Office to the proper computers, I use collections. ConfigMgr is able to inventory a lot of useful information regarding the Office 365 ProPlus client which includes the current version, channel etc:

This query example will give you all computers that: Has Office 365 ProPlus installed, runs on Current Channel set through GPO and is NOT already on the latest 1711 build. (This should probably be altered to fit your needs and environment, depending on various factors)

With this in place, you will have isolated the computers in need of being a target for your Office 365 ProPlus update.


Now there’s only a few steps left, but I assume you already know how to:

  • Customize your Powershell Deployment Toolkit to your needs
    • Close the Office apps, and keep them closed (prevent users from starting any, until the installation is done)
    • Keep the user notified during the entire process through custom dialogs
    • Show a friendly restart dialog, prompting the user to restart within allotted time
  • Create a package in ConfigMgr, distribute to your favorite DPs
  • Test the deployment
  • Deploy to your users
  • Be happy about the process being a lot smoother in regards to user friendliness.

GIF of everything in action: Installation running, user trying to open Word and the dialogs that follow.

Detect vulnerability in TPM (ADV170012) using ConfigMgr Compliance Settings


Coming Patch Tuesday this month, Microsoft revealed a whooping vulnerability in some infineon TPM chips; ADV170012

In the above article, Microsoft gives us some insight on the vulnerability itself, as well as how to detect and counter the vulnerability.

As how to detect the vulnerability, they released a patch which writes an entry to the event log and highlights the vulnerability in TPM.msc.

They also released a Powershell script, which they in turn – unfortunately – don’t go into much details about. They tells us to use PSremoting to query multiple computers and nothing else.

So, how about using ConfigMgr to detect whether our computers are vulnerable or not? Compliance Settings to the rescue!

I rewrote their script to instead return $true or $false, and make it usable to detect compliance or non-compliance.

So, following is my edition of the script, and how to setup the CI in ConfigMgr


  • Create a new CI. Give it a name and enable it to run on all Windows Desktops and Servers (Custom)

  • At the Specify settings for this OS page, click New

  • In the Create Setting page, select Script and Boolean. Insert my script from above in Edit Script

  • In the Create Rule page, select the newly created CI

  • Add the completed Configuration Item to a Configuration Baseline and deploy to selected collections


  • Taking a closer look directly on the client on the Configurations tab of the ConfigMgr client, you will either notice a compliant or non-compliant state

  • For a better summary of compliance, I personally like to create collections. Go to the deployment of the Configuration Baseline, and right click. Below is your options to create additional collections

  • The net result is a set of collections which memberships clearly tells the compliance state of the TPM vulnerability

Download my CI and baseline here:

Enjoy 😎


Switch Office 365 ProPlus update channel (through Software Center)


Following is a post on how I let (some) of our users decide whether they want to roll on the Current Channel (now called Monthly) or the Deferral Channel (Now called Semi-Annual and Broad) for Office 365 ProPlus.

According to numerous blogs on the www, there are several ways of doing this; modifying registry, GPO, reinstalling Office or to rerun setup.exe from the Office Deployment Tool (ODT).

I’ve chosen to go with the last option, and modify the channel through setup.exe coming from ODT. (I spent some time on GPO and modifying the registry without the expected results. However using setup.exe gives you visibility and a method that yields the results right away)


  • Go ahead and download Microsoft Deployment Tool (ODT) if you haven’t already. Link: Download Office 2016 Deployment Tool
  • Create two new .xml files containing following content (one for each channel switch)

Semi-Annual channel (also called Deferred or broad):

Monthly channel (also called current):

  • Put the .xml files in folder next to setup.exe from the Microsoft Deployment Tool (ODT)
  • Create two .bat files containing following content (one for each channel switch)
    • I’m deleting the current regkeys responsible for setting the channel prior to making the actual switch. This is due to some weirdness I’ve been seeing where the values are not properly updated.



  • Put the two .bat files into the same folder and copy the content to your content library used in ConfigMgr (Whereever that may be. This is pretty standard, so I’m not going into details here)
  • Create two new Applications in ConfigMgr with a Deployment Type set to Script Installer. Below the snippets from the Create New Application process.

  • Set the previously created .bat files as the installation program (SetDeferred.bat)

  • Detection rules for the applications will be the corresponding registry keys. The value of the below registry key is changing upon switching channels.

Monthly Channel:

Deferred Channel:

  • Distribute the content of the newly created applications to your preferred distribution points (groups), and deploy the applications.


Running the applications will result in either an upgrade or downgrade of Office 365 ProPlus.  This should be followed by a series of windows which will take you through the process for the new channel that you have switched to.

This is something I have deployed internally in the IT department, enabling them to easily switch between the channels.

Enjoy! 😎


Converting from BIOS to UEFI with Powershell (During OSD using ConfigMgr on Lenovo laptops)

Following my previous post, this is an quick example on how to use my Powershell script to convert from BIOS to UEFI in a bare metal scenario. (Again, only Lenovo laptops is working with this script)

Most of the magic lies within the Task Sequence itself, so I will break it down in pieces:

  • Create a group in your Task Sequence called “Prepare Computer (BIOS)” with the condition _SMSTSBootUEFI not equals true (This will make sure the content of the group only runs if UEFI is not enabled already)

  • Next step, format the disk with following settings (Step: Format and Partition Disk (BIOS))
    • Disk type: Standard (MBR)
    • Partition type: Primary
    • 100% remaining disk
    • File system: NTFS

  • Next step, create a new group called Config Lenovo BIOS with following condition: SELECT * FROM Win32_BIOS WHERE Manufacturer = “Lenovo” (This will make sure the step only runs on a Lenovo computer)

  • Next step, run my Powershell script directly from a package like shown below. The parameter -EnableSecureBoot will also enforce UEFI to be enabled.

  • Next step, format the disk with following settings (Step: Format and Partition Disk (BIOS to UEFI))
    • Disk type: GPT
    • Partition type: Primary
    • Size: 600Mb
    • File System: FAT32
    • Variable: TSUEFIDrive
  • Add another partition:
    • Partition type: Primary
    • Size: 100% of remaining space
    • File system: NTFS
    • Variable: None

  • Next step, one final reboot to the boot image currently assigned to this task sequence. When the task sequence returns from the reboot, the Lenovo BIOS will be set to SecureBoot AND UEFI and Windows will continue installing.

Ultimately, you can have 2 steps to take care of when the computer is coming with either BIOS setting or UEFI, and act accordingly. Se below snippet for inspiration.

Enjoy! 🙂