public/Remove-EntraDevice.ps1

function Remove-EntraDevice {
<#
.SYNOPSIS
    Removes Entra ID (Azure AD) device objects by matching AzureAdDeviceId from managed devices.

.PARAMETER FromManagedDevice
    Managed device objects whose AzureAdDeviceId will be used to find Entra devices.

.PARAMETER EntraDevice
    You can also pass Entra device objects directly (with Id/DeviceId).

.EXAMPLE
    $stale = Get-StaleIntuneDevice
    Remove-EntraDevice -FromManagedDevice $stale -WhatIf
#>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')]
    param(
        [Parameter(ValueFromPipelineByPropertyName)]
        [object[]]$FromManagedDevice,

        [Parameter(ValueFromPipeline)]
        [object[]]$EntraDevice
    )
    begin {
        $resolved = @()
    }
    process {
        if ($FromManagedDevice) {
            $aadIds = $FromManagedDevice | ForEach-Object { $_.AzureAdDeviceId ?? $_.AzureADDeviceId } | Where-Object { $_ } | Select-Object -Unique
            if ($aadIds) {
                $all = Get-MgDevice -All -ErrorAction Stop
                $resolved += $all | Where-Object {
                    ($_.DeviceId -and ($_.DeviceId -in $aadIds)) -or
                    ($_.Id -and ($_.Id -in $aadIds))
                }
            }
        }
        if ($EntraDevice) { $resolved += $EntraDevice }
    }
    end {
        foreach ($d in ($resolved | Select-Object -Unique)) {
            $target = "{0} (Id: {1})" -f ($d.DisplayName ?? $d.Id), $d.Id
            if ($PSCmdlet.ShouldProcess("Entra ID Device","Remove $target")) {
                try {
                    Remove-MgDevice -DeviceId $d.Id -Confirm:$false -ErrorAction Stop
                    Write-Verbose "Removed Entra device $target"
                } catch {
                    Write-Warning "Failed to remove Entra device $target. $_"
                }
            }
        }
    }
}