I was working with a customer who was facing following issue.

Allowed 15 devices per user to enroll in Intune. This eventually ended up enrolling lots of devices in Intune by end-users. This is actually not an issue unless they stop using enrolled devices proactively and keep them turned off. This is a big problem for admins to meet their compliance.

What’s the solution?

Enrollment Limit: The obvious solution is to ensure that not more than 2 or 3 devices should be allowed. Obvious exceptions can be there. Also, the number of allowed devices depends on IT admis appetite to manage the devices. Allow the number where you really find the balance between escalations during enrollment vs escalations for compliance. I have also seen educating the end users using some SOAP solution works alot.

Device cleanup rules: Set device cleanup rules in Intune to delete the devices if they are inactive for certain number of days.

If you are also inventorying devices in Microsoft Entra ID, you should cleanup those records as well. Unfortunately, Intune cleanup rule does not do that. However, you can use following script to perform the mobile device cleanup and thank me later 😉.

The idea here is to identify devices inactive for X number of days. If last contact day is more than X days, mark that device Disabled. Yes, it’s not a good idea to delete a device directly unless you are sure about it.

We are then deleting the devices Disabled for Y number of days. Or, we can say, we are deleting devices in X+Y number or days since it was inactive.

Also, we have provision to run this script in demo mode and logging too.

Just make sure declare Number of days of inactivity to disable. Then number of days of inactivity to delete. Also, do not forget to mention Demo mode option and logging location where you have permissions.

Hope this helps.

#############################################
#Please provide the number of days of inactivity after which we can declare a mobile device as stale. We will disable Stale device.
$DisableAfter=90

#Please provide the number of days of inactivity after which we can delete the mobile device after disabling it.
$DeleteAfter=120

#Are you running in Demo Mode? 1=Yes, 2=No.
$demo=1
#############################################
<#
.COPYRIGHT

Copyright (c) Microsoft Corporation. All rights reserved.

.SYNOPSIS 

This script is created to delete the inactive mobile device records.

AUTHOR
Bindusar Kushwaha

Version 1.8.
Added Pop-up before deleting the records.


.EXAMPLE

.PARAMETER

#>

<#
DISCLAIMER STARTS 
This Sample Code is provided for the purpose of illustration only and is not intended to be used in a 
production environment.
THIS SAMPLE CODE AND ANY RELATED INFORMATION ARE PROVIDED "AS IS"
WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. We 
grant You a nonexclusive, royalty-free right to use and modify the Sample Code and to reproduce and 
distribute the object code form of the Sample Code, provided that You agree:
(i) to not use Our name, logo, or trademarks to market Your software product in which the Sample Code is embedded; 
(ii) to #include a valid copyright notice on Your software product in which the Sample Code is embedded; and 
(iii) to indemnify, hold harmless, and defend Us and Our suppliers from and against any claims or lawsuits,including attorneys’ fees,
that arise or result from the use or distribution of the Sample Code."  
DISCLAIMER ENDS 
#>

Function Write-Host()
{
    <#
    .SYNOPSIS
    This function is used to configure the logging.
    .DESCRIPTION
    This function is used to configure the logging.
    .EXAMPLE
    Logging -Message "Starting installation" -severity 1 -component "Installation"
    Logging -Message "Something went wrong" -severity 2 -component "Installation"
    Logging -Message "BIG Error Message" -severity 3 -component "Installation"
    .NOTES
    NAME: Logging
    #>
    PARAM(
        [Parameter(Mandatory=$true)]$Message,
         [int]$severity=1,
         [string]$component="StaleDeviceHandling"
         )

         $logdir="C:\Temp\Logs"

        If(!(Test-Path $logdir))
        {
            $null = New-Item -Path $logdir -ItemType Directory -Force -ErrorAction SilentlyContinue
        }
        
        $StartTime = Get-Date -Format "dd-MM-yyyy"
        [String]$Path = "$Logdir\StaleMobileDevices_$StartTime.log"
        
        $today=Get-Date -Format yyyyMMdd-HH
        $TimeZoneBias = Get-CimInstance -Query "Select Bias from Win32_TimeZone"
        $Date = Get-Date -Format "HH:mm:ss.fff"
        $Date2 = Get-Date -Format "MM-dd-yyyy"
        #$type =1

         "<![LOG[$Message]LOG]!><time=$([char]34)$date$($TimeZoneBias.bias)$([char]34) date=$([char]34)$date2$([char]34) component=$([char]34)$component$([char]34) context=$([char]34)$([char]34) type=$([char]34)$severity$([char]34) thread=$([char]34)$([char]34) file=$([char]34)$([char]34)>"| Out-File -FilePath $Path -Append -NoClobber -Encoding default 

}


Write-Host "====================Starting the Script $($MyInvocation.MyCommand.Name)"
Write-Host "Running as: $([char]34)$(whoami)$([char]34)"
Write-Host "Running under: $([char]34)$((Get-WMIObject -Class Win32_ComputerSystem -ErrorAction SilentlyContinue).UserName)$([char]34)"
Write-Host "Running on: $([char]34)$(hostname)$([char]34)"


Write-Host "Connecting to Graph..."
Connect-MgGraph

$dt = (Get-Date).AddDays(-$DisableAfter)
Write-Host "Disabling Devices older than $dt"

$params = @{
	accountEnabled = $false
}

$Devs=Get-MgDevice -All | Where {($_.ApproximateLastSignInDateTime -le $dt) -and (($_.OperatingSystem -eq 'IPhone') -or ($_.OperatingSystem -eq 'AndroidForWork') -or ($_.OperatingSystem -eq 'IPad'))} | select-object -Property AccountEnabled, id, DeviceId, OperatingSystem, DisplayName, ApproximateLastSignInDateTime

#Disabling the accounts which are older than 90 days for iOS, iPadOS, Android.
foreach ($Dev in $Devs)
{
    Write-Host "Disabling Device named $($Dev.DisplayName) as its last log sign in time is $($dev.ApproximateLastSignInDateTime)."
    Update-MgDevice -DeviceId $Dev.ID -BodyParameter $params
}

#Display a Warning about devices about to be deleted.

$dt1 = (Get-Date).AddDays(-$DeleteAfter)
$Devices = Get-MgDevice -All | Where {($_.ApproximateLastSignInDateTime -le $dt1) -and ($_.AccountEnabled -eq $false) -and (($_.OperatingSystem -eq 'IPhone') -or ($_.OperatingSystem -eq 'AndroidForWork') -or ($_.OperatingSystem -eq 'IPad'))}
foreach ($Device in $Devices)
{
   $Action=[System.Windows.MessageBox]::Show("Device named $($device.DisplayName) will be deleted?",'Device Deletion','YesNoCancel','Warning')
   If($Action -eq 'Yes')
   {
        If($demo -eq 0)
        {
            Remove-MgDevice -DeviceId $Device.Id
            Write-Host "Logged on User mentioned above selected YES. Device $($device.DisplayName) removed."
        }
        else
        {
            Write-Host "Logged on User mentioned above selected YES. Device $($device.DisplayName) should have been removed if not in DEMO."
        }
   }
   ElseIf($Action -eq 'No')
   {
        Write-Host "Logged on User denied deleting the record. Device $($device.DisplayName) is NOT removed."
   }
   Else
   {
        Write-Host "Logged on User cancelled the prompt. No action taken for $($device.DisplayName)"
   }
}
Write-Host "====================Ending the Script $($MyInvocation.MyCommand.Name)"
#############################################

Leave a comment

I’m Bindusar

Welcome to BINLABS, my cozy corner of the internet dedicated to IT admins and their daily encounter. Here, I invite you to join me for daily challenges with solution faced by admins using scripts. Let’s script together!

Let’s connect