Security Posture

Validate status of Windows 10 security settings

I’ve created a Powershell-script for detecting status of different security related device features and settings related to Windows 10. The ambition with this script is to be able to check the current setting of different features in a quick way without utilizing any portals. Currently the script detects the status of:

  • Operating System (Edition, Architecture, Version, and Buildnumber)
  • TPM
  • Bitlocker
  • UEFI
  • SecureBoot
  • Defender (Antivirus, Antispyware, Realtime Protection, Tamper Protection, IOAV Protection, Network Protection, PUAProtection)
  • CloudProtectionService (MAPS for Defender)
  • DefenderATP
  • ApplicationGuard
  • Windows Sandbox
  • Credential Guard
  • Device Guard
  • Attack Surface Reduction
  • Controlled Folder Access

The script will write entries to a log file residing at the client (C:\Windows\Temp\Client-SecurityPosture.log) which preferably is read using CMTrace or OneTrace.

Install the Script
The script itself can be found at Powershell Gallery and installed using:
Install-Script -Name SecurityPosture -force  

Or you can download it manually from my Github.

Running the Script
Security Posture has support for running individual functions (switches), let’s try and check the Operating System and the status of UEFI and Secure Boot as an example:

Next thing to try is running the script querying every function in it:

The status of more functions and features will be displayed:

As I stated in the beginning of this post. the script will write entries to a log file residing at the client at C:\Windows\Temp\Client-SecurityPosture.log which preferably is read using CMTrace or OneTrace.


More detailed information can be found in the description of the script. I’m planning on upgrading it to a module in the future with more visible help related to each function. I have a project for the script listed on my Github. Feel free to comment or DM me suggestions/ideas or errors you may encounter.

Manage authentication method (MFA in AzureAD, telephone-number)

Finally some new capabilites for us in regards to displaying, changing and turning off MFA-configurations for users. My past post regarding MFA-status can be read here which utilized Get-Msoluser. Now, Microsoft has released a new set of commands in the MSGraph api for Azure Multi-factor authentication which I’ll briefly go through in this post. Note that this is only in beta right now and more features will be added later.

First, let’s see what we can do as stated here:

“The new APIs we’ve released in this wave give you the ability to:

  • Read, add, update, and remove a user’s authentication phones.
  • Reset a user’s password.
  • Turn on and off SMS sign-in.”

Sweet, let’s try it out. We’ll start by navigating to Microsoft Graph and consent to the required permissions. For this example, be sure to use an account who is Global Administrator or Authentication Administrator.

Enter this information (change UPN to a test-user in your tenant):

Now select “Modify permissions” and be sure to consent to the permission UserAuthenticationMethod.ReadWrite.All 

Note that I’ve specified GET (fetch information) and when I press Run Query now, the result:

No value, which was expected in my case since my test-user does not have any phone number registered as authentication method for MFA. So let’s now try to POST the information instead and give the user a registered telephone number.

Change GET to POST

In the request Body, enter the following entries with your chosen values:

“phoneType”: “mobile”,
“phoneNumber”: “+46234567890”


Press Run Query again.. Success!

If you would like to verify the setting, change POST to GET again to fetch the same users Authentication Methods and now you’ll see the phone number:

The information can also be verified in AzureAD of course under Authentication Methods:

As Microsoft has stated here, more methods will be added in the future for these API-calls which will be much appreciated by many of us out there.

ABM – Invalid Profile during enrollment (Default Enrollment Restriction)

I stumbled upon a pretty dazzling error the other day where the solution wasn’t too obvious for me so I thought I would share my findings.

Prerequisites which all were in place:
– Apple Business Manager configured and Apple-devices where transmitted from reseller.
– Integration with Intune in place and devices successfully synced to my Intune-tenant.
– ABM-profile assigned to the successfully synced devices with User Affinity-setting configured.

During the provisioning of the device when the iPhone or iPad is turned on after the device has connected to cellular or WiFi, the ABM-profile is about to be downloaded to the device. But this time it only got prompted with “Invalid Profile”.

I tried deleting the device from Intune and re-synced ABM, I also tried modifying the settings for the ABM-profile and redeployed the ABM-token in Intune. I even tried resetting the whole ABM-integration between Intune and ABM but nothing solved my issue. The solution was instead, related to my Enrollment Restriction setup. You can find your enrollment restrictions in Endpoint Manager by going here and navigating to Devices/Enroll Devices and then Enrollment Restrictions.

Check out your Default restriction targeting All Users, and be sure to note the description of it:
This is the default Device Type Restriction applied with lowest priority to all users regardless of group membership.”

That’s what I had missed. I had made another Device type restriction with priority 1, that targeted my Intune Users and in that restriction iOS were allowed for enrollment. Beneath that one, in the Default restriction iOS was blocked. The result is that manual user driven Intune-enrollment for a mobile device works for users who are members of my Intune-Users group but the automatic enrollment by Apple Business Manager did not.

Conclusion: in other words, my bad! I had modified the default one way before the ABM-integration was in place and the regular iPhone-enrollments worked flawlessly. So be sure to double check your Enrollment Restrictions if you stumble upon any ABM Invalid Profile related errors.

Post a policy to Intune using Intune PowerShell SDK

In my last post regarding the MSGraph and the Intune PowerShell SDK I demonstrated how you installed the Intune PowerShell SDK and connected to the Graph Explorer to query information in your tenant of choice.

Today I will demonstrate how you can monitor (by the help of your web-browser) which json-values are produced when you create a Compliance Policy in Intune which you then in turn can use to create the same policy in Powershell to a tenant of your choice by the help of Intune PowerShell SDK. In my example I used Microsoft Edge as browser.

Start by logging in to your tenant of choice:
Navigate to Devices/Windows/Compliance Policies.
Press F12 to start recording Network Activity in your Microsoft Edge browser.

To see in the recording what actually gets sent to the backend when you create something in Microsoft Endpoint Manager (Intune), let’s create a policy. In my example I chose a Compliance policy for Windows 10. Choose a name and a value for Minimum OS version. I used these values:
Name: Windows10-Compliance
Minimum OS version: 10.0.18363.778

When you have created your policy, you probably noticed that many things happened in the backend (to your right in the browser) during the recording of the network activity. To filter some of the results out you can type in “Devicecompliancepolicies” in the filter-field. Browse through the different entries until you find a POST entry with the graph URL under ‘General’ which is the one we are after right now.
Request URL: https:/
Request Method: POST

As you see above, the information which got posted to the Graph is expandable.

Now, to the fun part. You can use the Intune Powershell SDK to post these values into a tenant of your choice. To do this, install (if you haven’t already), import the Microsoft.Graph.Intune module and then authenticate using Connect-MSGraph.

Install-Module -Name Microsoft.Graph.Intune -force
Import-Module -Name Microsoft.Graph.Intune -verbose
view raw gistfile1.txt hosted with ❤ by GitHub
When your UPN and your TenantID appears in Powershell, you’re successfully authenticated to the tenant and the module is now being operational.
#Windows 10 Compliance
$Windows10Compliance = New-IntuneDeviceCompliancePolicy `
-windows10CompliancePolicy `
-displayName "Windows10-Compliance" `
-osMinimumVersion 10.0.18363.778 `
-scheduledActionsForRule `
(New-DeviceComplianceScheduledActionForRuleObject `
-ruleName PasswordRequired `
-scheduledActionConfigurations `
(New-DeviceComplianceActionItemObject `
-gracePeriodHours 0 `
-actionType block `
-notificationTemplateId "" `
) `
view raw gistfile1.txt hosted with ❤ by GitHub

When you are connected to your tenant in your session, copy the code above to your current Powershell-window and run it to post a Windows 10 Compliance Policy to your tenant.

Guide: Advanced Installer

Packaging of a basic MSI-installer using Advanced Installer (Free Edition)
Recently I’ve been using Advanced Installer (Free edition) for basic packaging of different application installers. I work mainly with Microsoft Intune when it comes to application deployment so in between the newly released Win32-App-Packaging-Tool I’ve found a spot for preparation and packaging of install-files using Advanced Installer. Following below is a easy to follow guide for how you utilize the software and re-package your first MSI-installer.

The version of Advanced Installer I’m currently using is version 1.6.5, the Free Edition which can be downloaded here. Download and install it, start the application and then create a New Project. Be sure to change the project to “Simple” since that’s the version we are going to use here.

When the Project is provisioned, be sure to navigate to Resources and then Files and Folders. When this is done, drag your MSI-file from any location to the “Application Folder”. As you can see on the screenshot above the source-location of this file also get’s listed.

Next step is to customize the name, version and publisher of your package. Press Product Details under Product Information. To the right on “Version” of the product, press and then select your newly imported MSI-installer. This will automatically provision the version of the application to your package.

I have then chosen to call the application Edge Beta and Publisher will be my made up company “Virtual Company”.

After pressing OK, at this point press “Keep existing” since we don’t need to generate a new Product Code at this time.

After this is done, press Build to save your project and generate the newly configured installer. I’ll save mine locally to C:\Temp\Edge.

Wait until the build finishes and then press OK. As you see in the screenshot above, you’ll see where the newly generated package resides (C:\Temp\Edge\Edge Beta-SetupFiles\Edge Beta.msi).

Viewing the MSI-Installer show all the properties we just configured. Well done.

Advanced Installer also comes with a enterprise-looking template for the installation of packaged installers, see below for my screenshots from the user experience regarding manual installation of the application.

User experience using the installer

Check MFA-Status of Users (Powershell)

Finding information about MFA on a user in Azure Active Directory can be achieved in mutiple ways. Here, I will describe an easy way of finding MFA-information (registered, and by which method) by using Powershell, the cmdlet Get-Msoluser and its related property StrongAuthenticationMethods.

Install the powershell Module MSOnline:
Install-Module MSOnline
Then, connect to the service in Powershell by:

When authenticated, query all users who have MFA activated using the following code:
Get-MsolUser -All | where {$_.StrongAuthenticationMethods -ne $null} | Select-Object -Property UserPrincipalName

Now, let’s expand the property StrongAuthenticationMethods to get more information about MFA’s state, and which MFA-method the user has configured MFA with:
Get-MsolUser -All | Where {$_.UserPrincipalName} | Select UserPrincipalName, DisplayName, @{n=”Status”; e={$_.StrongAuthenticationRequirements.State}}, @{n=”Methods”; e={($_.StrongAuthenticationMethods).MethodType}}, @{n=”Chosen Method”; e={($_.StrongAuthenticationMethods).IsDefault}} | Out-GridView

Useful result when working with Microsoft 365 and MFA. As you see above, allowed methods in my tenant is PhoneAppOTP and PhoneAppNotification (Microsoft Authenticator). The chosen method for this users MFA is PhoneAppNotification. The reason why the Status-field is empty is because this user activated MFA via a Conditional Access Policy and the MFA is not enabled/Enforced via the old MFA-portal.

MDT – Client failed TFTP Download

Client fails to download TFTP, Event 4101 (MDT, WDS, DHCP and IP-Helper)

Operating systems affected: Windows Server 2016 (Monthly CU 2019/03 KB:
KB4489889) and Windows Server 2019 (Monthly CU 2019/04 KB4493509)

Solution: uncheck the setting “Enable Variable Window Extension” on the WDS-server.
Go to Windows Deployment Services > Servers > Right click the server name and then choose Properties. The setting is found under “TFTP” as can be seen below:

Install the Intune Powershell Module

The Intune Powershell Module is a great addition to the current
Device Management-portal when it comes to Intune management.
Note: An account with the role Global Administrator is required for the authentication and the consent of this module for your tenant.

1. Start Powershell as an administrator and install the Intune Powershell Module typing in the command: Install-Module -Name Microsoft.Graph.Intune
Confirm the install by clicking Yes to all.

2. Then we need to authenticate to the tenant of your choice.
Do this by typing in the command: Connect-MSGraph

3. Sign with your account, enter your credentials and then press Sign in

3. An account with the role Global administrator is required since the module needs to be delegated some rights on behalf of the organizaton. Check “Consent on behalf of your organization” and then press Accept.

5. When your UPN and your TenantID appears in Powershell, you’re successfully authenticated to the tenant and the module is now being operational.

6. To show all the commands the module has to offer, type in:
Get-Command -Module Microsoft.Graph.Intune

7. There are plenty of commands you can utilize from this module, as of right now the total count is 914.

To count all the commands which are currently included in the module, enter:
(Get-Command -Module Microsoft.Graph.Intune).count

Autopilot Resources

Autopilot on Reddit

Get Hardware details

Microsoft Store for Business (AutoPilot-devices)

AutoPilot Hyrbid AzureADJoin

Manage Intune Graph API/Intune Powershell Module rights

Autopilot Demo/Test

Assigning Dynamic Profiles

Assigning Profiles by Exception

Offline Deployment Profile

Configuring Windows 10 defaults via Windows Autopilot using an MSI

Autopilot Virtual Machine


MDT Autopilot (no hardware hash)

Autopilot MDT

Autopilot SCCM (Existing Devices)

Speeding upp Autopilot for Existing Devices