PowerShell

Get-StaleDevices

Identifies devices inactive for a configurable threshold across Intune, Entra ID, and on-premises Active Directory. Outputs CSV and HTML reports with remediation actions.

IntuneEntra IDActive DirectoryReportingReal-world script

Overview

Get-StaleDevices identifies devices that have not checked in within a configurable threshold across Intune, Microsoft Entra ID, and on-premises Active Directory. Output includes CSV and HTML reports with per-device remediation recommendations.

Stale device cleanup is an underappreciated security hygiene task. Inactive device records create noise in compliance reports, consume Intune licences, and can be used by attackers who recover old hardware with a valid certificate or token cache.

This script is read-only. It queries data sources and produces reports. It does not delete, disable, or modify any device records. Remediation actions shown in the report require separate deliberate steps.

Tested environment: Windows 11 24H2 management workstation, Microsoft Graph PowerShell SDK 2.x, Intune and Entra ID tenants on April 2026 service release.

Prerequisites

The script requires the following before running:

  1. Microsoft Graph PowerShell SDK — install if not present:
PowerShell
Install-Module Microsoft.Graph -Scope CurrentUser -Repository PSGallery -Force
  1. Entra ID app registration with the following Application (not Delegated) permissions:

    • Device.Read.All
    • DeviceManagementManagedDevices.Read.All

    Grant admin consent for both permissions after creating the registration.

  2. RSAT Active Directory module — for on-premises AD queries:

PowerShell
# Windows 11 / Windows 10 2004+
Add-WindowsCapability -Online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0
  1. The account running the script needs read access to Active Directory. Domain User is sufficient for AD queries.

Parameters

ParameterTypeDescription
-StaleThresholdDays[int]Days since last check-in to classify as stale. Default: 90
-Sources[string[]]Sources to query: Intune, EntraID, ActiveDirectory. Default: all three
-OutputPath[string]Directory for CSV and HTML report output. Created if it does not exist
-GraphCredential[PSCredential]Service principal credentials for unattended Graph API access
-IncludeRemediation[switch]Add recommended action column to the report

Usage Examples

Basic interactive run — 90-day threshold, prompt for Graph credentials:

PowerShell
Get-StaleDevices -StaleThresholdDays 90 -OutputPath C:\Reports\StaleDevices

Query Intune and Entra ID only (no on-premises AD required):

PowerShell
Get-StaleDevices -Sources @('Intune', 'EntraID') -StaleThresholdDays 60 -OutputPath C:\Reports

Unattended run with service principal — for scheduled task or pipeline use:

PowerShell
$appId     = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
$appSecret = ConvertTo-SecureString 'YOUR_SECRET' -AsPlainText -Force
$cred      = New-Object PSCredential($appId, $appSecret)

Get-StaleDevices -GraphCredential $cred -StaleThresholdDays 90 -IncludeRemediation -OutputPath C:\Reports

Output

The script writes two files per run to the specified -OutputPath:

FileFormatUse
StaleDevices-YYYYMMDD.csvCSVPower BI import, pipeline processing, ticket creation
StaleDevices-YYYYMMDD.htmlHTMLHuman review, management reporting

Remediation recommendations

When -IncludeRemediation is specified, each device row includes a RecommendedAction column:

ConditionRecommended Action
Stale in all sources (>180 days)Delete from all directories; revoke certificates and tokens
Stale in Intune only, active in ADInvestigate — device may have been re-imaged without re-enrolling in Intune
Active in Intune, stale in Entra IDSync Entra ID device record; check hybrid join connector health
Active in Intune, missing from ADLikely cloud-only device; verify Autopilot registration is current
Stale in AD onlyCheck if device was decommissioned but AD record not cleaned up

Do not bulk-delete devices based solely on this report without a manual review pass. Active devices with clock drift, offline periods, or VPN-only connectivity can appear stale with a 60–90 day threshold.

Validation

After running, verify the report looks complete:

PowerShell
# Count devices in the CSV
(Import-Csv C:\Reports\StaleDevices\StaleDevices-$(Get-Date -Format yyyyMMdd).csv).Count

# Spot-check a known stale device name — confirm it appears in the report
Import-Csv C:\Reports\StaleDevices\StaleDevices-$(Get-Date -Format yyyyMMdd).csv |
    Where-Object { $_.DeviceName -eq 'LAPTOP-OLD-01' }

Cross-reference the total device count in the CSV against the device count visible in the Intune portal (Devices > All devices) to confirm the Graph query returned a full result set and was not truncated.

Common Errors

Connect-MgGraph : Insufficient privileges The app registration is missing the required Graph permissions, or admin consent has not been granted. Navigate to Entra admin centre → App registrations → [your app] → API permissions and confirm both permissions show "Granted for [tenant]".

Get-ADComputer : The server is not operational The script cannot reach a domain controller. Ensure the management workstation is domain-joined, or run from a machine with line of sight to an AD DC. Use -Sources @('Intune', 'EntraID') to skip the AD query if on-premises AD is not accessible.

Invoke-MgGraphRequest : Response status code does not indicate success: 429 (Too Many Requests) The Graph API is throttling the request. The script should retry automatically, but for large tenants (50,000+ devices) add a -ThrottleDelay value or break the run into source-specific queries to reduce concurrent request volume.

Report contains 0 devices Verify the -StaleThresholdDays value. A threshold of 7 days in an active fleet may return 0 stale devices legitimately. Confirm the app registration has Device.Read.All with admin consent, not just Delegated permissions.

Security Notes

  • The script is read-only across all data sources.
  • When using a service principal (-GraphCredential), store the client secret in a secrets vault (Azure Key Vault, Windows Credential Manager) rather than hardcoding it in scripts or scheduled task arguments.
  • The output CSV and HTML files contain device names, last check-in dates, and compliance states. Treat them as internal data — do not share publicly or store in unprotected locations.
  • Do not automate device deletion based on this report without a human review step. Automated deletion of devices that are merely inactive can remove valid hardware from management.

Senior Enterprise Sysadmin · 12+ Years Windows & Intune

I've spent 12+ years managing Windows fleets, Intune tenants, and Active Directory environments for enterprise clients across finance, logistics, and professional services. AdminSignal exists because I got tired of docs that stop at "click Apply." Everything here is tested in production before it goes on the page.

AdminSignal content is produced independently. Editorial policy