smsagent.blog
  • docs.smsagent.blog
  • Custom Reporting in Microsoft Intune
    • Delivery Optimization Report
    • Windows Update for Business Custom Reporting
      • Power BI Report Walkthrough
      • Known issues / limitations
      • Change log
      • Deploy the solution
        • Create Azure Resources
        • Configure Azure Resources
        • Deploy the client-side script
        • Deploy the Azure automation runbooks
        • Configure the Power BI report
      • Adding additional language support
      • Table schema reference
    • Automating Data Exports from Microsoft Graph
      • Azure Automation account
        • Create / configure an Azure automation account
        • Grant API permissions
        • Create an Azure automation runbook
      • Azure Storage account
      • Automate Data Export to Azure Storage Account
      • Automate Data Export to Azure Monitor Logs
      • Creating / Troubleshooting Runbooks
      • Power BI
        • Connect Power BI to an Azure storage account data source
        • Connect Power BI to an Azure log analytics workspace as a data source
    • Managed Devices Report
      • Create / configure an Azure automation account
      • Grant API permissions
      • Create / configure an Azure storage account
      • Create an Azure automation runbook
      • Create a PowerBI report
      • MEM Managed Device Report template
      • Bonus! Unhealthy MEMCM Clients email report
    • Intune Assignments Report
      • Create / configure an Azure automation account
      • Grant API permissions
      • Create / configure an Azure storage account
      • Create an Azure automation runbook
      • Create a Power BI report
      • Change log
    • Patch My PC Report
      • A look at the Power BI reports
      • Change log
      • Video guides
      • Things to know
      • Create / configure an Azure automation account
      • Grant API permissions
      • Create / configure an Azure storage account
      • Create an Azure automation runbook
      • Create the Power BI report
      • Feedback
    • Windows 11 Hardware Readiness Report
    • Gathering Custom Inventory with Intune
      • Set up the Azure Resources
      • Create a Proactive remediations script package
      • Create a runbook
  • PowerShell Scripts Online Help
    • Get-AzSubscriptionActivityLog
  • Azure Solutions
    • Automated Azure Table Storage Backups
      • Change log
      • Deploy the solution
        • Create the Azure resources
        • Set the backup schedule
        • Add storage tables to the backup
        • Add role assignments to the storage account/s
        • Create a lifecycle management rule
      • Run a manual backup
      • Restore a backup
Powered by GitBook
On this page
  • Bonus!
  • Unhealthy MEMCM Clients runbook
  • Requirements

Was this helpful?

  1. Custom Reporting in Microsoft Intune
  2. Managed Devices Report

Bonus! Unhealthy MEMCM Clients email report

Bonus!

As another example of how you can export data from MS Graph, below is an Azure automation Runbook you can use to generate an email report of unhealthy co-managed MEMCM clients. Specifically, it will export a list of MEMCM co-managed devices that have synced with Intune in the last 7 days but have not synced with a MEMCM management point in the last 7 days. It will then send you the list as a CSV attachment in an email.

Unhealthy MEMCM Clients runbook

Requirements

  • Your automation account must be using a managed identity

  • The managed identity must be granted the appropriate permissions to Microsoft Graph as described in this guide

  • Outlook 365 with direct send or smtp relay configured

################################################################################
## Azure automation runbook PowerShell script to export a list of unhealthy   ##
## MEMCM clients from Microsoft Intune / Endpoint Manager and send it the CSV ##
## report as an email attachment.                                             ##
################################################################################

# Set some variables
$ProgressPreference = 'SilentlyContinue'
$EmailParams = @{
    To         = 'recipient@contoso.com'
    From       = 'azureautomation@contoso.onmicrosoft.com'
    Smtpserver = 'contoso-com.mail.protection.outlook.com'
    Port       = 25
}

# Obtain an access token for MS Graph as a Managed Identity
$url = $env:IDENTITY_ENDPOINT  
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" 
$headers.Add("X-IDENTITY-HEADER", $env:IDENTITY_HEADER) 
$headers.Add("Metadata", "True") 
$body = @{resource='https://graph.microsoft.com/' } 
$accessToken = (Invoke-RestMethod $url -Method 'POST' -Headers $headers -ContentType 'application/x-www-form-urlencoded' -Body $body ).access_token
$authHeader = @{
    'Authorization' = "Bearer $accessToken"
}

# Download data from MS Graph
$URI = "https://graph.microsoft.com/beta/deviceManagement/manageddevices?`$filter=StartsWith(operatingSystem,'Windows')&`$select=deviceName,enrolledDateTime,lastSyncDateTime,managementAgent,deviceEnrollmentType,userPrincipalName,model,serialNumber,userDisplayName,configurationManagerClientEnabledFeatures,configurationManagerClientHealthState"
$Response = Invoke-WebRequest -Uri $URI -Method Get -Headers $authHeader -UseBasicParsing 
$JsonResponse = $Response.Content | ConvertFrom-Json
$DeviceData = $JsonResponse.value
If ($JsonResponse.'@odata.nextLink')
{
    do {
        $URI = $JsonResponse.'@odata.nextLink'
        $Response = Invoke-WebRequest -Uri $URI -Method Get -Headers $authHeader -UseBasicParsing 
        $JsonResponse = $Response.Content | ConvertFrom-Json
        $DeviceData += $JsonResponse.value
    } until ($null -eq $JsonResponse.'@odata.nextLink')
}

# Organise the data as we want it displayed
$Devices = New-Object System.Collections.ArrayList
foreach ($item in $DeviceData)
{
    try {
        [void]$Devices.Add(
            [PSCustomObject]@{
                deviceName = $item.deviceName
                enrolledDateTime = $item.enrolledDateTime
                daysEnrolled = [math]::Round(((Get-Date) - ($item.enrolledDateTime | Get-Date -ErrorAction SilentlyContinue)).TotalDays,0)
                lastSyncDateTime = $item.lastSyncDateTime
                daysSinceLastSync = [math]::Round(((Get-Date) - ($item.lastSyncDateTime | Get-Date -ErrorAction SilentlyContinue)).TotalDays,0)
                managementAgent = $item.managementAgent
                deviceEnrollmentType = $item.deviceEnrollmentType
                userPrincipalName = $item.userPrincipalName
                model = $item.model
                serialNumber = $item.serialNumber
                userDisplayName = $item.userDisplayName
                memcmEnabledFeature_inventory = $item.configurationManagerClientEnabledFeatures.inventory
                memcmEnabledFeature_modernApps = $item.configurationManagerClientEnabledFeatures.modernApps
                memcmEnabledFeature_resourceAccess = $item.configurationManagerClientEnabledFeatures.resourceAccess
                memcmEnabledFeature_deviceConfiguration = $item.configurationManagerClientEnabledFeatures.deviceConfiguration 
                memcmEnabledFeature_compliancePolicy = $item.configurationManagerClientEnabledFeatures.compliancePolicy
                memcmEnabledFeature_windowsUpdateForBusiness = $item.configurationManagerClientEnabledFeatures.windowsUpdateForBusiness
                memcmEnabledFeature_endpointProtection = $item.configurationManagerClientEnabledFeatures.endpointProtection
                memcmEnabledFeature_officeApps = $item.configurationManagerClientEnabledFeatures.officeApps
                memcmClientHealth_state = $item.configurationManagerClientHealthState.state
                memcmClientHealth_errorCode = $item.configurationManagerClientHealthState.errorCode
                memcmClientHealth_lastSyncDateTime = $item.configurationManagerClientHealthState.lastSyncDateTime
                memcmClientHealth_daysSinceLastSync = [math]::Round(((Get-Date) - ($item.configurationManagerClientHealthState.lastSyncDateTime | Get-Date -ErrorAction SilentlyContinue)).TotalDays,0)
            }
        )
    }
    catch {} 
}

# Filter and export just the unhealthy clients - those that have talked to Intune but haven't talked to MEMCM in the last 7 days 
$UnhealthyMEMCMClients = $Devices | where {$_.memcmClientHealth_state -ne 'healthy' -and $_.daysSinceLastSync -le 7 -and $_.memcmClientHealth_daysSinceLastSync -gt 7}
$UnhealthyMEMCMClients | export-csv -Path $env:temp\UnhealthyMEMCMClients.csv -Force -NoTypeInformation 

# Send the email
Send-MailMessage @EmailParams -Subject "[Azure Automation] Unhealthy MEMCM Clients in Intune ($($UnhealthyMEMCMClients.Count))" -Attachments "$env:temp\UnhealthyMEMCMClients.csv"

PreviousMEM Managed Device Report templateNextIntune Assignments Report

Last updated 4 years ago

Was this helpful?