Skip to content

Conversation

@nicolonsky
Copy link
Contributor

@nicolonsky nicolonsky commented Nov 20, 2025

Description

  • Adding Intune license check to decide whether Intune checks are applicable
  • Adding multiple Microsoft Intune checks:
    • MT.1090 - Global administrator role should not be added as local administrator on the device during Microsoft Entra join
    • MT.1091 - Registering user should not be added as local administrator on the device during Microsoft Entra join
    • MT.1092 - Intune APNS certificate should be valid for more than 30 days
    • MT.1093 - Apple Automated Device Enrollment Tokens should be valid for more than 30 days
    • MT.1094 - Apple Volume Purchase Program Tokens should be valid for more than 30 days
    • MT.1095 - Android Enterprise account connection should be healthy
    • MT.1096 - Ensure at least one Intune Multi Admin Approval policy is configured
    • MT.1097 - Ensure all Intune Certificate Connectors are healthy and running supported versions
    • MT.1098 - Mobile Threat Defense Connectors should be healthy
    • MT.1099 - Windows Diagnostic Data Processing should be enabled
    • MT.1100 - Intune Diagnostic Settings should include Audit Logs
    • MT.1101 - Default Branding Profile should be customized
    • MT.1102 - Windows Feature Update Policy Settings should not reference end of support builds
    • MT.1103 - Ensure Intune RBAC groups are protected by Restricted Management Administrative Units or Role Assignable groups
    • MT.1105 - Ensure MDM Authority is set to Intune

Contribution Checklist

Before submitting this PR, please confirm you have completed the following:

  • 📖 Read the guidelines for contributing to this repository.
  • 🧪 Ensure the build and unit tests pass by running /powershell/tests/pester.ps1 on your local system.

 

Join us at the Maester repository discussions 💬 or Entra Discord 🧑‍💻 for more help and conversations!

@nicolonsky nicolonsky marked this pull request as ready for review November 20, 2025 15:10
@nicolonsky nicolonsky requested review from a team as code owners November 20, 2025 15:10
@SamErde SamErde requested a review from Copilot November 20, 2025 18:55
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds comprehensive Microsoft Intune health checks and monitoring capabilities to the Maester framework. It introduces license validation for Intune and implements 16 new security and operational checks covering device enrollment policies, certificate management, connector health, and platform configurations.

Key changes:

  • Added Intune license detection in Get-MtLicenseInformation with support for multiple Intune service plan SKUs
  • Implemented 16 new test functions covering Apple/Android integrations, certificate connectors, compliance settings, and administrative policies
  • Added DeviceManagementRBAC.Read.All permission requirement for RBAC group protection checks

Reviewed Changes

Copilot reviewed 43 out of 43 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
website/docs/sections/permissions.md Added DeviceManagementRBAC.Read.All permission
tests/maester-config.json Added metadata for 16 new Intune checks (MT.1090-MT.1105)
tests/Maester/Intune/Test-MtIntunePlatform.Tests.ps1 Added 6 new platform-level Intune tests
tests/Maester/Intune/Test-MtIntuneConnectorHealth.Tests.ps1 New file with 5 connector health validation tests
tests/Maester/Entra/Test-MtEntraDeviceRegistrationPolicy.Tests.ps1 Consolidated device registration and local admin tests
powershell/public/maester/intune/*.ps1 Implemented 13 new test functions with license checking
powershell/public/maester/entra/*.ps1 Added 2 device registration local admin validation functions
powershell/public/Get-MtLicenseInformation.ps1 Added Intune license detection support
powershell/public/Get-MtGraphScope.ps1 Added DeviceManagementRBAC.Read.All scope
powershell/public/Add-MtTestResultDetail.ps1 Added NotLicensedIntune skip reason
powershell/internal/Get-MtSkippedReason.ps1 Added Intune licensing message
powershell/Maester.psd1 Exported 13 new test functions

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 43 out of 43 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 43 out of 43 changed files in this pull request and generated 13 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@f-bader
Copy link
Contributor

f-bader commented Nov 21, 2025

Thank you @nicolonsky for this submission. I will review this over the weekend

Copy link
Contributor

@merill merill left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nicolonsky this is amazing. Thank you for all the tests you are contributing.

In my tenant, which has intune license but not much configured a lot of the tests are erroring out.

Please see comments.

Thanks

Comment on lines 1 to 52
<#
.SYNOPSIS
Check the validity of the Apple Automated Device Enrollment (ADE) token for Intune.
.DESCRIPTION
The Apple Automated Device Enrollment (ADE) token is required to synchronize Apple devices with Microsoft Intune. This command checks if the ADE token is valid and not expired.

.EXAMPLE
Test-MtAppleAutomatedDeviceEnrollmentToken

Returns true if the ADE token is valid for more than 30 days, false if it is expired or expiring soon.

.LINK
https://maester.dev/docs/commands/Test-MtAppleAutomatedDeviceEnrollmentToken
#>
function Test-MtAppleAutomatedDeviceEnrollmentToken {
[CmdletBinding()]
[OutputType([bool])]
param()

if (-not (Get-MtLicenseInformation -Product Intune)) {
Add-MtTestResultDetail -SkippedBecause NotLicensedIntune
return $null
}

try {
Write-Verbose 'Retrieving Apple Automated Device Enrollment token status...'
$expirationThresholdDays = 30
$automatedDeviceEnrollmentTokens = @(Invoke-MtGraphRequest -RelativeUri 'deviceManagement/depOnboardingSettings' -ApiVersion beta)

$testResultMarkdown = "Intune Automated Device Enrollment Token Status:`n"
$testResultMarkdown += "| Name | TokenExpirationDateTime | LastSuccessfulSyncDateTime | LastSyncErrorCode |`n"
$testResultMarkdown += "| --- | --- | --- | --- |`n"

$healthStatus = foreach ($token in $automatedDeviceEnrollmentTokens) {
$expiresInDays = [System.Math]::Ceiling(([datetime]$token.tokenExpirationDateTime - (Get-Date)).TotalDays)
$lastSyncDiffDays = [System.Math]::Floor(((Get-Date) - [datetime]$token.lastSuccessfulSyncDateTime).TotalDays)
$testResultMarkdown += "| $($token.tokenName) | $($token.tokenExpirationDateTime) | $($token.lastSuccessfulSyncDateTime) | $($token.lastSyncErrorCode) |`n"
Write-Output $($expiresInDays -gt $expirationThresholdDays -and $lastSyncDiffDays -eq 0)
}

$testResultMarkdown += '```' + "`n"
$testResultMarkdown += $automatedDeviceEnrollmentTokens | ConvertTo-Json
$testResultMarkdown += "`n"
$testResultMarkdown += '```'

Add-MtTestResultDetail -Result $testResultMarkdown
return $healthStatus -notcontains $false
} catch {
Add-MtTestResultDetail -SkippedBecause Error -SkippedError $_
return $null
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm seeing the following error in my tenant.

InvalidArgument: /Users/merill/GitHub/maester/powershell/public/maester/intune/Test-MtAppleAutomatedDeviceEnrollmentToken.ps1:35
Line |
  35 |              $expiresInDays = [System.Math]::Ceiling(([datetime]$token|              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Cannot convert null to type "System.DateTime".

I dug further and can see the rest api returning

{
    "@odata.context": "https://graph.microsoft.com/beta/$metadata#deviceManagement/depOnboardingSettings",
    "@odata.count": 0,
    "@microsoft.graph.tips": "Use $select to choose only the properties your app needs, as this can lead to performance improvements. For example: GET deviceManagement/depOnboardingSettings?$select=appleIdentifier,dataSharingConsentGranted",
    "value": []
}

So in the code, it needs to read from .value

NOTE: I see the same issue with almost all the tests in this PR.

Can you confirm if these are working in your tenant?

I can see that in Test-MtIntuneRbacGroupsProtected you are reading the .value property correctly.

$diagnosticSettingsRequest = Invoke-AzRestMethod -Method GET -Path "/providers/microsoft.intune/diagnosticSettings?api-version=2017-04-01-preview"
$diagnosticSettings = $diagnosticSettingsRequest | Select-Object -ExpandProperty Content | ConvertFrom-Json | Select-Object -ExpandProperty value

$testResultMarkdown = "Intune Diagnostic Settings:`n"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The table is shown even when there are no logs. We should ideally not show an empty table with no data.

Also, It will be good to provide a relevant message when the test fails. So it says something like.

Intune diagnostic settings are not configured to include audit logs.

Image

.LINK
https://maester.dev/docs/commands/Test-MtAppleAutomatedDeviceEnrollmentToken
#>
function Test-MtAppleAutomatedDeviceEnrollmentToken {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Errors out in tenants with no ADE configured.

Similar issue with 1094, 1095, 1097, 1098,

Expected to Fail.

Image

return $null
}

try {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test passes but no values shown in table.

Image

.LINK
https://maester.dev/docs/commands/Test-MtFeatureUpdatePolicy
#>
function Test-MtFeatureUpdatePolicy {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Errors out:

Image

@nicolonsky
Copy link
Contributor Author

Hi @merill, I changed the behaviour of the failing tests and re-tested them in my tenant after deleting some of the tokens. All tests referring to a token or connector are now only performed if they exist, otherwise test execution is skipped. Based on my opinion this approach reflects the 'as-is-state' better in the test report and is more comprehensive:

image

Example test results for an individual check:

image

@nicolonsky nicolonsky requested a review from merill December 4, 2025 19:57
@merill
Copy link
Contributor

merill commented Dec 5, 2025

Awesome. Looks good now @nicolonsky !!

@merill merill merged commit 1e4d680 into maester365:main Dec 5, 2025
@SamErde SamErde added intune Microsoft Intune and removed in-progress labels Jan 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

intune Microsoft Intune

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants