Stale devices w Entra ID i Intune — jak bezpiecznie wyczyścić nieaktywne urządzenia bez utraty kluczy BitLocker
Intune i Entra ID to dwa oddzielne systemy — wyczyszczenie urządzeń w jednym nie usuwa ich z drugiego. Pochopne usuwanie niszczy klucze BitLocker bezpowrotnie. Artykuł pokazuje bezpieczną procedurę cleanup: od eksportu inwentarza, przez ochronę Autopilota i backup BitLockera, po automatyzację całego procesu PowerShellem.

Stale devices w Entra ID i Intune — jak bezpiecznie wyczyścić nieaktywne urządzenia bez utraty kluczy BitLocker
TL;DR: Intune i Entra ID to dwa oddzielne systemy — wyczyszczenie nieaktywnych urządzeń w Intune nie usuwa ich z Entra ID automatycznie. Pominięcie tej różnicy skutkuje setkami “duchów” w katalogu, a pochopne usuwanie niszczy klucze BitLocker bezpowrotnie. W tym artykule pokazujemy jak wykryć stale devices, w jakiej kolejności je usuwać, jakie urządzenia absolutnie pomijać, i jak zautomatyzować ten proces bezpiecznie.
Problem
Masz środowisko M365 z Intune od 3 lat. Pracownicy dostają nowe laptopy, starych nikt nie wyrejestrowuje. Ktoś reinstalował Windows bez wyrejestrowania. Kilka telefonów zgubionych, kilka wymienionych przez ubezpieczenie. Po audycie okazuje się, że w Entra ID masz 340 urządzeń, w Intune 180 — a faktycznie aktywnych jest może 120.
To nie jest rzadkość. To jest norma w każdej organizacji, która nie ma formalnej procedury offboardingu sprzętu.
Skutki? Po pierwsze — helpdesk widzi pięć urządzeń o tej samej nazwie dla jednego użytkownika i nie wie, które jest aktywne. Po drugie — Microsoft Entra Connect robi writeback wszystkich tych obiektów do on-premises AD, co spowalnia synchronizację. Po trzecie — polityki Conditional Access mogą zachowywać się nieprzewidywalnie, bo zakres “managed devices” staje się nieprecyzyjny.
Ale najgroźniejszy błąd to nie brak czyszczenia — to czyszczenie bez planu. Mam kolegę admina, który napisał skrypt “usuń wszystkie urządzenia nieaktywne od 90 dni” i odpalił go bez czytania dokumentacji. Następnego ranka dwie osoby nie mogły odblokować dysków Bo klucze BitLocker zniknęły razem z obiektami urządzeń.
Dlaczego tak się dzieje
Dwa oddzielne systemy, dwie bazy danych
Pierwsza rzecz, której nie jest oczywista: Intune i Entra ID to dwa niezależne repozytoria obiektów urządzeń. Kiedy włączasz “Device cleanup rules” w Intune i ustawiasz 90 dni — Intune usunie rekord ze swojej bazy po 90 dniach nieaktywności. Obiekt w Entra ID pozostaje nienaruszony.
Odwrotnie: jeśli usuniesz urządzenie z Entra ID przez PowerShell — Intune nadal będzie go widział przez jakiś czas, dopóki nie wykona synchronizacji.
To nierozumienie tej różnicy jest źródłem 90% problemów przy cleanup.
ApproximateLastSignInDateTime — co to jest i dlaczego “approximate”
Entra ID śledzi aktywność urządzenia przez pole ApproximateLastSignInDateTime. Nie jest to dokładny timestamp ostatniego logowania — to przybliżona wartość, aktualizowana tylko w konkretnych scenariuszach:
Urządzenie pomyślnie uwierzytelniło się w kontekście polityki Conditional Access wymagającej managed device
Windows 10/11 Entra joined lub Hybrid joined był aktywny w sieci
Urządzenie zarządzane przez Intune zrobiło check-in do serwisu
Ważne: aktualizacja następuje tylko gdy różnica między starą a nową wartością przekracza 14 dni (+/-5 dni wariancji). To oznacza, że urządzenie aktywne codziennie może mieć timestamp sprzed 19 dni — i to jest normalne.
Drugi pułapka: część aktywnych urządzeń ma pusty timestamp (null/blank). Dotyczy to głównie starszych urządzeń zarejestrowanych przed wprowadzeniem tej funkcji lub urządzeń zarejestrowanych w trybie, który nie triggeruje aktualizacji. Microsoft explicite ostrzega przed tym w dokumentacji. Skrypt który filtruje po ApproximateLastSignInDateTime -le $dt i “uwzględnia” null jako datę w przeszłości — wyczyści aktywne urządzenia.
Skąd biorą się stale devices
Typowe scenariusze:
Laptop skradziony lub zgubiony — nigdy nie wyrejestrowany
Reinstalacja Windows bez wyrejestrowania z Entra ID / Intune
Wymiana urządzenia przez dział zakupów bez procedury offboardingu sprzętu
Testy urządzeń (tablety, telefony pilotażowe) — zarejestrowane, zapomniane
Odejścia pracowników bez pełnego offboardingu IT
Urządzenia zarejestrowane przez poprzednią firmę IT, o których nikt nie wie
Rozwiązanie krok po kroku
Krok 1: Eksport stanu aktualnego — najpierw dane, potem decyzje
Zanim cokolwiek dotkniesz, zrób pełny eksport. Potrzebujesz Microsoft Graph PowerShell SDK (moduł Microsoft.Graph) lub nowszego Microsoft Entra PowerShell.
# Połącz z uprawnieniami do odczytu urządzeń
Connect-MgGraph -Scopes "Device.Read.All"
# Eksport wszystkich urządzeń z kluczowymi polami
Get-MgDevice -All | Select-Object `
AccountEnabled, DeviceId, DisplayName, OperatingSystem, `
OperatingSystemVersion, TrustType, ApproximateLastSignInDateTime, `
IsCompliant, IsManaged | `
Export-Csv "$env:USERPROFILE\Desktop\entra-devices-full.csv" -NoTypeInformation -Encoding UTF8
Write-Host "Eksport gotowy: $((Get-MgDevice -All).Count) urządzeń"
Poczekaj na wynik. W dużych środowiskach (2000+ urządzeń) może to zająć kilka minut. TrustType wskaże ci typ rejestracji:
AzureAD— Entra ID joined (cloud-only)ServerAD— Hybrid Entra ID joined (on-premises + cloud)Workplace— Entra registered (BYOD)
Krok 2: Identyfikacja urządzeń Autopilot — nie usuwaj ich tak samo
To jest pułapka, o której mówi się za mało. Urządzenia zarejestrowane w Windows Autopilot mają powiązany obiekt ZTDID (Zero Touch Deployment ID). Jeśli usuniesz taki obiekt z Entra ID bez wcześniejszego usunięcia z Autopilota:
Deployment user-driven: urządzenie wróci, ale bez tagu ZTDID — nie dostanie właściwego profilu
Deployment self-deploying lub pre-provisioning: deployment się posypie z błędem ZTDID mismatch — security mechanizm zablokuje rejestrację
# Lista urządzeń zarejestrowanych w Autopilot
Connect-MgGraph -Scopes "DeviceManagementServiceConfig.Read.All"
$autopilotDevices = Get-MgDeviceManagementWindowsAutopilotDeviceIdentity -All | `
Select-Object SerialNumber, Model, GroupTag, ManagedDeviceId, AzureAdDeviceId
$autopilotDevices | Export-Csv "$env:USERPROFILE\Desktop\autopilot-devices.csv" -NoTypeInformation
Write-Host "Urządzeń Autopilot: $($autopilotDevices.Count)"
Porównaj listę Autopilot z listą stale devices przed czymkolwiek. Urządzenia Autopilot usuwa się przez portal Intune > Devices > Windows > Windows enrollment > Windows Autopilot devices, a dopiero potem czyści Entra ID.
Krok 3: Backup kluczy BitLocker — obowiązkowy przed usunięciem
Klucze BitLocker są przechowywane na obiekcie urządzenia w Entra ID. Usunięcie obiektu = bezpowrotna utrata klucza. Nie ma recovery. Nie ma supportu który ci go przywróci.
# Backup wszystkich kluczy BitLocker do CSV
Connect-MgGraph -Scopes "BitlockerKey.Read.All", "Device.Read.All"
$bitlockerKeys = Get-MgInformationProtectionBitlockerRecoveryKey -All | `
Select-Object Id, DeviceId, CreatedDateTime, VolumeType
# Dla każdego klucza pobierz pełną wartość
$fullKeys = foreach ($key in $bitlockerKeys) {
$fullKey = Get-MgInformationProtectionBitlockerRecoveryKey -BitlockerRecoveryKeyId $key.Id `
-Property "key"
[PSCustomObject]@{
KeyId = $key.Id
DeviceId = $key.DeviceId
RecoveryKey = $fullKey.Key
Created = $key.CreatedDateTime
VolumeType = $key.VolumeType
}
}
$fullKeys | Export-Csv "$env:USERPROFILE\Desktop\bitlocker-keys-backup.csv" -NoTypeInformation
Write-Host "Zbackupowano $($fullKeys.Count) kluczy BitLocker"
Ten plik traktuj jak tajny dokument — zawiera klucze odblokowania dysków. Przechowaj go w bezpiecznym miejscu (zaszyfrowane archiwum, sejf, dedykowane repozytorium haseł).
Krok 4: Disable przed delete — zawsze
Nigdy nie usuwaj urządzenia bezpośrednio. Procedura: najpierw disable, czekasz 14-30 dni, sprawdzasz czy ktoś nie zgłosił problemu, dopiero wtedy delete.
# Ustaw próg: urządzenia nieaktywne od 90 dni
$threshold = (Get-Date).AddDays(-90)
# Filtruj — WAŻNE: pomijaj urządzenia z pustym timestampem (aktywne!)
$staleDevices = Get-MgDevice -All | Where-Object {
$_.ApproximateLastSignInDateTime -ne $null -and
$_.ApproximateLastSignInDateTime -le $threshold -and
$_.AccountEnabled -eq $true
}
Write-Host "Urządzeń do wyłączenia: $($staleDevices.Count)"
# Disable — nie delete
foreach ($device in $staleDevices) {
Update-MgDevice -DeviceId $device.Id -AccountEnabled:$false
Write-Host "Disabled: $($device.DisplayName) | Last seen: $($device.ApproximateLastSignInDateTime)"
}
Zwróć uwagę na $_.ApproximateLastSignInDateTime -ne $null — to jest ochrona przed przypadkowym wyłączeniem urządzeń z pustym timestampem.
Krok 5: Delete — po minimum 14 dniach od disable
# Szukaj urządzeń wyłączonych I nieaktywnych od 120+ dni
$deleteThreshold = (Get-Date).AddDays(-120)
$devicesToDelete = Get-MgDevice -All | Where-Object {
$_.ApproximateLastSignInDateTime -ne $null -and
$_.ApproximateLastSignInDateTime -le $deleteThreshold -and
$_.AccountEnabled -eq $false
}
Write-Host "Urządzeń do usunięcia: $($devicesToDelete.Count)"
Write-Host "Kontynuować? (y/n)"
$confirm = Read-Host
if ($confirm -eq "y") {
foreach ($device in $devicesToDelete) {
Remove-MgDevice -DeviceId $device.Id
Write-Host "Deleted: $($device.DisplayName)"
}
}
Krok 6: Konfiguracja Intune Device Cleanup Rules
W portalu Intune: Devices > Device cleanup rules. Dostępne opcje:
Delete devices that haven’t checked in for this many days: zakres 30-270 dni
Reguła działa tylko na Intune — nie dotyka Entra ID
Urządzenia usunięte przez tę regułę mogą wrócić w ciągu 180 dni jeśli zrobią check-in (auto-recovery)
Zalecane ustawienie: 90 dni jako kompromis między czystością inventory a obsługą pracowników na dłuższym urlopie. Ważne: po usunięciu z Intune nadal musisz ręcznie (lub skryptem) wyczyścić Entra ID.
Typowe pułapki i edge cases
Pułapka 1: Urządzenia Hybrid Joined i synchronizacja z on-premises AD
Dla urządzeń Hybrid Entra ID Joined sekwencja czyszczenia jest odwrotna niż myślisz:
Nie usuwaj z Entra ID jako pierwszego kroku. Jeśli usuniesz obiekt z Entra ID, a urządzenie nadal istnieje w on-premises Active Directory, Microsoft Entra Connect przy następnej synchronizacji (domyślnie co 30 minut) odtworzy obiekt w Entra ID ze statusem “Pending”. Będziesz miał go z powrotem, ale bez normalnej rejestracji — urządzenie będzie musiało się ponownie zarejestrować.
Prawidłowa kolejność dla Hybrid Joined (Windows 10/11):
Disable lub delete komputer w on-premises Active Directory
Poczekaj na synchronizację Entra Connect (lub wymuś:
Start-ADSyncSyncCycle -PolicyType Delta)Entra ID automatycznie zaktualizuje / usunie obiekt
Opcjonalnie: usuń ręcznie z Intune jeśli cleanup rules jeszcze nie zadziałały
Dla starszych urządzeń Windows 7/8 (tak, nadal się zdarzają w legacy środowiskach): musisz wyłączyć ZARÓWNO w on-premises AD jak i ręcznie w Entra ID — Entra Connect nie synchronizuje zmian dla tych wersji.
Pułapka 2: Pusty ApproximateLastSignInDateTime — fałszywe stale devices
Microsoft explicite ostrzega: “Some active devices may have a blank time stamp.” Dotyczy to urządzeń, które:
Zostały zarejestrowane przed wdrożeniem tej funkcji w Entra ID
Działają w trybie, który nie triggeruje aktualizacji timestampu (np. tylko on-premises, bez Conditional Access)
Mają problemy z uwierzytelnieniem w Entra ID
Skrypt który robi $_.ApproximateLastSignInDateTime -le $dt bez sprawdzenia null traktuje null jako 1 stycznia 0001 — czyli wyraźnie “starsze niż 90 dni”. Może to być aktywny komputer dyrektora, który po prostu nie korzysta z usług cloud.
Zanim usuniesz urządzenie z pustym timestampem, sprawdź historię logowań w Entra ID > Audit logs > Sign-ins i wyszukaj po Device ID.
Pułapka 3: Auto-recovery w Intune — urządzenie “wraca z martwych”
Intune device cleanup rule usuwa urządzenie z Intune portal, ale nie jest to operacja nieodwracalna (przez 180 dni od usunięcia). Jeśli urządzenie zrobi check-in do Intune w tym oknie, automatycznie pojawi się z powrotem — o ile certyfikat MDM na urządzeniu nie wygasł (ważność certyfikatu = 1 rok).
Skutek: w październiku widzisz 300 urządzeń w Intune, w grudniu po cleanup masz 150. W lutym znowu 200 — bo część “usuniętych” urządzeń wróciła.
Jeśli chcesz trwałego usunięcia: wydaj najpierw akcję Retire na urządzeniu (usuwa dane firmowe i wyrejestrowuje MDM), a dopiero potem czekaj na cleanup lub usuń ręcznie. Retire jest nieodwracalny — nie ma auto-recovery.
Pułapka 4: Jamf — cleanup rules go nie dotyczy
Jeśli część urządzeń macOS jest zarządzana przez Jamf Pro (z integracją Intune), device cleanup rules Intune nie obejmują tych urządzeń. Musisz zarządzać ich cyklem życia bezpośrednio w Jamf.
Pułapka 5: Conditional Access i Registered devices (BYOD)
Urządzenia w trybie “Entra registered” (prywatne telefony, BYOD) mają inną mechanikę. Po usunięciu z Entra ID — rejestracja pozostaje aktywna po stronie klienta. Użytkownik nadal widzi konto firmowe w ustawieniach telefonu. Jeśli ma dostęp przez Conditional Access na warunek “Registered device” — teoretycznie może nadal mieć dostęp do zasobów (zależy od timingu odświeżenia token).
Dla tych urządzeń: wyrejestrowanie po stronie klienta (Ustawienia > Konta > Usuń konto firmowe) powinno poprzedzać usunięcie z Entra ID.
Jak my to rozwiązujemy w Evolit
W Evolit używamy Nexmy do zarządzania cyklem życia sprzętu — każde urządzenie przypisane pracownikowi jest ewidencjonowane z datą wydania, modelem i numerem seryjnym. Kiedy pracownik odchodzi, Nexma generuje zadanie offboardingowe które w ramach checklisty zawiera: zwrot sprzętu, wyrejestrowanie z Intune i Entra ID, oraz weryfikację kluczy BitLocker przed usunięciem. Eliminuje to sytuację, gdy dział IT dowiaduje się o oddanym laptopie dwa miesiące po fakcie.
Jeśli nie korzystasz z Nexmy, alternatywą jest Power Automate z triggerem na wyrejestrowanie z Intune lub Azure Automation Runbook odpalany na harmonogramie — przykłady takich rozwiązań pokazujemy w innych artykułach. Opis ewidencji sprzętu i automatyzacji offboardingu znajdziesz na nexma.app.
Podsumowanie
Intune cleanup rules i Entra ID to oddzielne systemy — czyszczenie jednego nie czyści drugiego automatycznie
ApproximateLastSignInDateTime jest przybliżone i bywa null — zawsze filtruj
not nullprzed operacjami deleteBackup kluczy BitLocker przed każdym usunięciem — po usunięciu obiektu Entra ID klucz znika bezpowrotnie
Urządzenia Autopilot wymagają oddzielnej procedury — usuń najpierw z portalu Autopilot, dopiero potem z Entra ID
Hybrid Joined czyść z on-premises AD — Entra Connect zsynchronizuje zmiany, nie rób odwrotnie
Disable → poczekaj → delete — nigdy nie usuwaj bezpośrednio, daj sobie 14-30 dni grace period
Bonus: Skrypt automatyzacji cleanup z logowaniem
Kompletny skrypt który możesz odpalić jako scheduled task lub Azure Automation Runbook. Tworzy log CSV z każdą operacją i wysyła podsumowanie na e-mail (opcjonalnie).
param(
[int]$DisableAfterDays = 90,
[int]$DeleteAfterDays = 120,
[string]$LogPath = "$env:USERPROFILE\Desktop\device-cleanup-$(Get-Date -f 'yyyyMMdd').csv"
)
Connect-MgGraph -Scopes "Device.ReadWrite.All" -NoWelcome
$now = Get-Date
$report = [System.Collections.Generic.List[object]]::new()
$allDevices = Get-MgDevice -All | Where-Object {
$_.ApproximateLastSignInDateTime -ne $null
}
foreach ($device in $allDevices) {
$age = ($now - $device.ApproximateLastSignInDateTime).Days
$action = "None"
if ($age -ge $DeleteAfterDays -and -not $device.AccountEnabled) {
# Faza 2: usuń urządzenie wyłączone od 120+ dni
Remove-MgDevice -DeviceId $device.Id
$action = "Deleted"
}
elseif ($age -ge $DisableAfterDays -and $device.AccountEnabled) {
# Faza 1: wyłącz urządzenie nieaktywne od 90+ dni
Update-MgDevice -DeviceId $device.Id -AccountEnabled:$false
$action = "Disabled"
}
$report.Add([PSCustomObject]@{
DisplayName = $device.DisplayName
OS = $device.OperatingSystem
TrustType = $device.TrustType
AgeInDays = $age
WasEnabled = $device.AccountEnabled
Action = $action
LastSignIn = $device.ApproximateLastSignInDateTime
})
}
$report | Export-Csv $LogPath -NoTypeInformation -Encoding UTF8
Write-Host "Cleanup complete. Log: $LogPath"
Write-Host "Disabled: $(($report | Where Action -eq 'Disabled').Count)"
Write-Host "Deleted: $(($report | Where Action -eq 'Deleted').Count)"
Kilka rzeczy które warto dostosować przed produkcyjnym odpaleniem:
Dodaj wykluczenie urządzeń Autopilot przez porównanie z listą z KROK 2
Dodaj wykluczenie po TrustType == “ServerAD” jeśli obsługujesz Hybrid Joined z on-premises (czyść je z AD, nie PowerShellem)
W Azure Automation zamień
Connect-MgGraphna uwierzytelnienie przez Managed Identity z uprawnieniamiDevice.ReadWrite.All
FAQ — pytania, które zawsze się pojawiają
Q: Ile urządzeń można usunąć jednorazowo przez portal Entra ID? A: Bulk delete w portalu Entra ID (Devices > Bulk actions > Delete) obsługuje do 20 urządzeń w jednym pliku CSV. Powyżej tej liczby musisz użyć PowerShell lub Graph API. Przy tysiącach urządzeń użyj paginacji w skrypcie (-All w Get-MgDevice pobiera wszystko automatycznie, ale pamiętaj o throttling — Graph API ma limit 20 zapytań na sekundę).
Q: Co się stanie z użytkownikiem gdy wyłączę jego urządzenie w Entra ID? A: Dla urządzenia Entra Joined: użytkownik nie może zalogować się na urządzeniu do Entra ID / M365. Dla Hybrid Joined: nadal może zalogować się do domeny on-premises, ale nie ma dostępu do zasobów M365 i Azure. Dla Registered (BYOD): traci dostęp do zasobów objętych Conditional Access.
Q: Czy Intune cleanup rules wpływają na licencje M365? A: Nie bezpośrednio. Usunięcie urządzenia z Intune nie zwalnia licencji przypisanej do użytkownika. Licencje zarządzasz oddzielnie w centrum administracyjnym M365.
Q: Jak sprawdzić czy urządzenie jest Autopilot zanim je usunę? A: Najszybciej przez pole managementCertificateExpirationDate i presence w Get-MgDeviceManagementWindowsAutopilotDeviceIdentity. Alternatywnie w portalu Intune: filtruj po “Enrollment type: Windows Autopilot”.