Don't have a package yet?
Run Collect-IntuneDiagnostics.ps1 in an
elevated PowerShell on the device. It collects MDM logs,
event logs, registry exports, identity/network info and the IME logs, and
writes IntuneDiag-<device>-<timestamp>.zip to
C:\Temp. Upload that zip above.
Download Collect-IntuneDiagnostics.ps1
View script source
<#
.SYNOPSIS
Collects a complete diagnostics package from an Intune-managed Windows device.
.DESCRIPTION
Mimics the Intune "Collect diagnostics" action and extends it with:
- MDM logs via mdmdiagnosticstool.exe (all registered areas)
- Relevant Event Logs (MDM, Entra/AAD, Device Registration, ESP/Shell-Core)
- Registry exports (Enrollments, PolicyManager, IME, Autopilot)
- Identity status (dsregcmd), certificates, network info
- Intune Management Extension (IME) logs
- Defender support files, Windows Update logs, system reports
- Status of relevant services and scheduled tasks
Result: a single zip file in C:\Temp (or a custom path).
.PARAMETER OutputPath
Folder where the zip file will be created. Default: C:\Temp
.EXAMPLE
.\Collect-IntuneDiagnostics.ps1
.\Collect-IntuneDiagnostics.ps1 -OutputPath D:\Diag
.NOTES
Run as Administrator (elevated PowerShell).
#>
[CmdletBinding()]
param(
[string]$OutputPath = 'C:\Temp'
)
# ============================================================
# 0. Preparation
# ============================================================
# Admin check
$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()
).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if (-not $isAdmin) {
Write-Error 'This script must be run as Administrator. Start an elevated PowerShell session and try again.'
exit 1
}
$timestamp = Get-Date -Format 'yyyyMMdd-HHmmss'
$work = Join-Path $OutputPath "IntuneDiag-$env:COMPUTERNAME-$timestamp"
$zipFile = "$work.zip"
$folders = @('MDM','EventLogs','Registry','Identity','Network','Apps-IME','System','Defender','WindowsUpdate','Autopilot')
foreach ($f in $folders) {
New-Item -ItemType Directory -Path (Join-Path $work $f) -Force | Out-Null
}
$transcript = Join-Path $work 'CollectionTranscript.log'
Start-Transcript -Path $transcript -Force | Out-Null
function Write-Step { param([string]$Msg) Write-Host "[$(Get-Date -Format 'HH:mm:ss')] $Msg" -ForegroundColor Cyan }
function Invoke-Safe {
param([string]$Name, [scriptblock]$Action)
Write-Step $Name
try { & $Action } catch { Write-Warning " Failed: $($_.Exception.Message)" }
}
# ============================================================
# 1. MDM logs (mdmdiagnosticstool, all areas)
# ============================================================
Invoke-Safe 'MDM diagnostics (all areas)...' {
$areaKey = 'HKLM:\SOFTWARE\Microsoft\MdmDiagnostics\Area'
if (Test-Path $areaKey) {
$areas = (Get-ChildItem $areaKey).PSChildName -join ';'
Write-Host " Areas found: $areas"
& "$env:windir\system32\mdmdiagnosticstool.exe" -area $areas -zip (Join-Path $work 'MDM\MDMDiag-AllAreas.zip') | Out-Null
}
# Always also generate the default report (HTML + XML + registry dump)
& "$env:windir\system32\mdmdiagnosticstool.exe" -out (Join-Path $work 'MDM\DefaultReport') | Out-Null
}
# ============================================================
# 2. Event Logs
# ============================================================
$eventLogs = @{
'DeviceManagement-Admin' = 'Microsoft-Windows-DeviceManagement-Enterprise-Diagnostics-Provider/Admin'
'DeviceManagement-Operational'= 'Microsoft-Windows-DeviceManagement-Enterprise-Diagnostics-Provider/Operational'
'AAD-Operational' = 'Microsoft-Windows-AAD/Operational'
'UserDeviceRegistration' = 'Microsoft-Windows-User Device Registration/Admin'
'Shell-Core' = 'Microsoft-Windows-Shell-Core/Operational'
'ModernDeployment-Autopilot' = 'Microsoft-Windows-ModernDeployment-Diagnostics-Provider/Autopilot'
'ModernDeployment-Diagnostics'= 'Microsoft-Windows-ModernDeployment-Diagnostics-Provider/ManagementService'
'Provisioning-Diagnostics' = 'Microsoft-Windows-Provisioning-Diagnostics-Provider/Admin'
'CodeIntegrity' = 'Microsoft-Windows-CodeIntegrity/Operational'
'TaskScheduler' = 'Microsoft-Windows-TaskScheduler/Operational'
'Application' = 'Application'
'System' = 'System'
}
foreach ($entry in $eventLogs.GetEnumerator()) {
Invoke-Safe "Event log: $($entry.Key)..." {
$dest = Join-Path $work "EventLogs\$($entry.Key).evtx"
wevtutil epl $entry.Value $dest /ow:true 2>$null
if (Test-Path $dest) {
# Also create a readable text summary of errors/warnings (last 200 events)
Get-WinEvent -LogName $entry.Value -MaxEvents 200 -ErrorAction SilentlyContinue |
Where-Object { $_.Level -in 1,2,3 } |
Select-Object TimeCreated, Id, LevelDisplayName, Message |
Format-List | Out-File (Join-Path $work "EventLogs\$($entry.Key)-ErrorsWarnings.txt") -Width 250
}
}
}
# ============================================================
# 3. Registry exports
# ============================================================
$regKeys = @{
'Enrollments' = 'HKLM\SOFTWARE\Microsoft\Enrollments'
'PolicyManager-Current' = 'HKLM\SOFTWARE\Microsoft\PolicyManager\current'
'PolicyManager-Providers' = 'HKLM\SOFTWARE\Microsoft\PolicyManager\Providers'
'IntuneManagementExtension'= 'HKLM\SOFTWARE\Microsoft\IntuneManagementExtension'
'Win32Apps' = 'HKLM\SOFTWARE\Microsoft\IntuneManagementExtension\Win32Apps'
'Autopilot' = 'HKLM\SOFTWARE\Microsoft\Provisioning\Diagnostics\AutoPilot'
'Autopilot-EstablishedCorr'= 'HKLM\SOFTWARE\Microsoft\Provisioning\AutopilotSettings'
'EnrollmentStatusTracking' = 'HKLM\SOFTWARE\Microsoft\Windows\Autopilot\EnrollmentStatusTracking'
'FirstSync' = 'HKLM\SOFTWARE\Microsoft\Windows\Autopilot'
'CloudDomainJoin' = 'HKLM\SYSTEM\CurrentControlSet\Control\CloudDomainJoin'
'MDM-Uninstall' = 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
'InternetSettings' = 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings'
}
foreach ($entry in $regKeys.GetEnumerator()) {
Invoke-Safe "Registry: $($entry.Key)..." {
reg export $entry.Value (Join-Path $work "Registry\$($entry.Key).reg") /y 2>$null | Out-Null
}
}
# ============================================================
# 4. Identity & certificates
# ============================================================
Invoke-Safe 'dsregcmd /status...' {
dsregcmd /status | Out-File (Join-Path $work 'Identity\dsregcmd-status.txt')
}
Invoke-Safe 'Certificates (machine + user)...' {
certutil -store MY | Out-File (Join-Path $work 'Identity\certs-machine-MY.txt')
certutil -store -user MY | Out-File (Join-Path $work 'Identity\certs-user-MY.txt')
# Highlight the machine certificates, including the Intune MDM device cert
Get-ChildItem Cert:\LocalMachine\My |
Select-Object Subject, Issuer, NotBefore, NotAfter, Thumbprint, @{n='Expired';e={$_.NotAfter -lt (Get-Date)}} |
Format-List | Out-File (Join-Path $work 'Identity\certs-machine-overview.txt')
}
# ============================================================
# 5. Network
# ============================================================
Invoke-Safe 'Network configuration...' {
ipconfig /all | Out-File (Join-Path $work 'Network\ipconfig.txt')
netsh advfirewall show allprofiles | Out-File (Join-Path $work 'Network\firewall-profiles.txt')
netsh advfirewall show global | Out-File (Join-Path $work 'Network\firewall-global.txt')
netsh winhttp show proxy | Out-File (Join-Path $work 'Network\winhttp-proxy.txt')
netsh wlan show profiles | Out-File (Join-Path $work 'Network\wlan-profiles.txt')
route print | Out-File (Join-Path $work 'Network\routes.txt')
Get-DnsClientServerAddress | Format-Table -AutoSize | Out-File (Join-Path $work 'Network\dns-servers.txt')
}
Invoke-Safe 'Connectivity test to Intune/Entra endpoints...' {
$endpoints = @(
'login.microsoftonline.com',
'enterpriseregistration.windows.net',
'enrollment.manage.microsoft.com',
'portal.manage.microsoft.com',
'fef.msuc03.manage.microsoft.com',
'graph.microsoft.com'
)
$results = foreach ($ep in $endpoints) {
$t = Test-NetConnection -ComputerName $ep -Port 443 -WarningAction SilentlyContinue
[pscustomobject]@{
Endpoint = $ep
Reachable = $t.TcpTestSucceeded
RemoteIP = $t.RemoteAddress
}
}
$results | Format-Table -AutoSize | Out-File (Join-Path $work 'Network\endpoint-connectivity.txt')
}
# ============================================================
# 6. Apps / Intune Management Extension
# ============================================================
Invoke-Safe 'Copying IME logs...' {
$imeLogs = "$env:ProgramData\Microsoft\IntuneManagementExtension\Logs"
if (Test-Path $imeLogs) {
Copy-Item $imeLogs (Join-Path $work 'Apps-IME\Logs') -Recurse -Force
}
}
Invoke-Safe 'IME service status...' {
Get-Service -Name 'IntuneManagementExtension','Microsoft Intune Management Extension' -ErrorAction SilentlyContinue |
Select-Object Name, Status, StartType |
Format-Table -AutoSize | Out-File (Join-Path $work 'Apps-IME\service-status.txt')
}
Invoke-Safe 'Inventorying installed apps...' {
$paths = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*',
'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
Get-ItemProperty $paths -ErrorAction SilentlyContinue |
Where-Object DisplayName |
Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
Sort-Object DisplayName |
Format-Table -AutoSize | Out-File (Join-Path $work 'Apps-IME\installed-apps.txt') -Width 250
}
# ============================================================
# 7. System
# ============================================================
Invoke-Safe 'msinfo32 report (this may take a while)...' {
Start-Process msinfo32 -ArgumentList "/report `"$(Join-Path $work 'System\msinfo32.log')`"" -Wait
}
Invoke-Safe 'Drivers, battery, OS info...' {
pnputil /enum-drivers | Out-File (Join-Path $work 'System\drivers.txt')
powercfg /batteryreport /output (Join-Path $work 'System\battery-report.html') 2>$null
Get-ComputerInfo | Out-File (Join-Path $work 'System\computerinfo.txt')
Get-HotFix | Sort-Object InstalledOn -Descending |
Format-Table -AutoSize | Out-File (Join-Path $work 'System\hotfixes.txt')
}
Invoke-Safe 'Relevant scheduled tasks...' {
Get-ScheduledTask -TaskPath '\Microsoft\Windows\EnterpriseMgmt\*' -ErrorAction SilentlyContinue |
Select-Object TaskPath, TaskName, State |
Format-Table -AutoSize | Out-File (Join-Path $work 'System\enterprisemgmt-tasks.txt') -Width 250
}
# ============================================================
# 8. Defender
# ============================================================
Invoke-Safe 'Defender support files...' {
$mpcmd = "$env:ProgramFiles\Windows Defender\mpcmdrun.exe"
if (Test-Path $mpcmd) {
& $mpcmd -GetFiles | Out-Null
Copy-Item "$env:ProgramData\Microsoft\Windows Defender\Support\MpSupportFiles.cab" `
(Join-Path $work 'Defender') -Force -ErrorAction SilentlyContinue
}
Get-MpComputerStatus -ErrorAction SilentlyContinue |
Out-File (Join-Path $work 'Defender\mp-status.txt')
}
# ============================================================
# 9. Windows Update
# ============================================================
Invoke-Safe 'Windows Update log (this may take a while)...' {
Get-WindowsUpdateLog -LogPath (Join-Path $work 'WindowsUpdate\WindowsUpdate.log') -ErrorAction SilentlyContinue | Out-Null
Copy-Item "$env:ProgramData\USOShared\Logs\System\*.etl" (Join-Path $work 'WindowsUpdate') -Force -ErrorAction SilentlyContinue
}
# ============================================================
# 10. Autopilot / ESP extras
# ============================================================
Invoke-Safe 'Autopilot/ESP files...' {
Copy-Item "$env:windir\Logs\Panther\unattendgc\setupact.log" (Join-Path $work 'Autopilot') -Force -ErrorAction SilentlyContinue
Copy-Item "$env:ProgramData\Microsoft\Provisioning\*.log" (Join-Path $work 'Autopilot') -Force -ErrorAction SilentlyContinue
}
# ============================================================
# 11. Generate summary
# ============================================================
Invoke-Safe 'Generating summary...' {
$dsreg = dsregcmd /status
$aadJoined = ($dsreg | Select-String 'AzureAdJoined\s*:\s*(\w+)').Matches.Groups[1].Value
$prt = ($dsreg | Select-String 'AzureAdPrt\s*:\s*(\w+)').Matches.Groups[1].Value
$mdmUrl = ($dsreg | Select-String 'MdmUrl\s*:\s*(.+)').Matches.Groups[1].Value
$imeService = (Get-Service -Name 'IntuneManagementExtension' -ErrorAction SilentlyContinue).Status
$recentErrors = Get-WinEvent -LogName 'Microsoft-Windows-DeviceManagement-Enterprise-Diagnostics-Provider/Admin' -MaxEvents 500 -ErrorAction SilentlyContinue |
Where-Object Level -eq 2 |
Select-Object -First 10 TimeCreated, Id, Message
$summary = @"
==========================================================
INTUNE DIAGNOSTICS SUMMARY
Device : $env:COMPUTERNAME
Date : $(Get-Date)
User : $env:USERNAME
==========================================================
[Identity]
AzureAdJoined : $aadJoined
AzureAdPrt : $prt
MDM URL : $mdmUrl
[Services]
IntuneManagementExtension : $imeService
[Last 10 MDM errors (DeviceManagement Admin log)]
$($recentErrors | Format-List | Out-String)
See the subfolders for all details:
MDM\ - mdmdiagnosticstool output (HTML report, registry dump, evtx)
EventLogs\ - evtx exports + errors/warnings as text
Registry\ - Enrollments, PolicyManager, IME, Autopilot
Identity\ - dsregcmd, certificates
Network\ - ipconfig, proxy, firewall, endpoint connectivity
Apps-IME\ - IME logs, app inventory
System\ - msinfo32, drivers, hotfixes, scheduled tasks
Defender\ - MpSupportFiles.cab, status
WindowsUpdate\ - WindowsUpdate.log, USO etl files
Autopilot\ - setupact.log, provisioning logs
==========================================================
"@
$summary | Out-File (Join-Path $work '_SUMMARY.txt')
Write-Host $summary
}
# ============================================================
# 12. Package everything
# ============================================================
Stop-Transcript | Out-Null
Write-Step 'Packaging everything...'
Compress-Archive -Path "$work\*" -DestinationPath $zipFile -Force
Remove-Item $work -Recurse -Force
Write-Host ''
Write-Host "Done! Diagnostics package: $zipFile" -ForegroundColor Green