nieaktywni użytkownicy EntraID

w AD sprawa była prosta… no może nie tak bardzo prosta, bo historia atrybutów lastLogon i lastLogonTimeStamp też ma swoje drugie dno, ale od wielu lat wiadomo jak aktywność użytkownika zbadać… i pojawiła się Chmura i hybryda, która całość skomplikowała…

przez wiele lat nie było prostego sposobu na zapytanie 'wyszukaj nieużywane konta’, ponieważ nie było w EntraID odpowiednika lastLogonTimeStamp i trzeba było każdy system badać na dziwne sposoby. wedle Microsoft, należało odpytać logu audytu, który miał standardowo 3o dni.. wielce przydatne. nie drążąc dalej historii, od kwietnia 2o2o GraphAPI produkcyjnie obsługuje ’signInActivity’ – w końcu atrybut/zasób, który jest automatycznie aktualizowany ostatnią datą uwierzytelnienia.

uwaga. atrybut może mieć do 6h opóźnienia w aktualizacji

jak odpytać

kilka przykładów jak przygotować sobie raport, korzystając z commandletów Microsoft.Graph

wyświetlenie wszystkich użytkowników, wraz z ich mailem oraz datą ostatniej aktywności:

Get-MgUser -Property displayname,mail,signInActivity -all|
    select displayname,mail,@{L='signin';E={$_.SignInActivity.LastSignInDateTime}}

korzystanie z commandletów graphowych nie jest przyjemne i wymaga cierpliwości. większość operacji, ze względu na optymalizację, nie wyświetla prawie żadnych atrybutów – dla tego trzeba wyraźnie zaznaczyć w 'property’ czego będzie się potrzebowało.

trochę bardziej złożony raport, wyrzucany na csv, zawierający dodatkowo informacje o licencjach:

Get-MgUser -Property id,displayname,givenname,surname,accountenabled,userprincipalname,mail,signInActivity,userType -all|
    select id,displayname,givenname,surname,accountenabled,userprincipalname,userType,mail,`
    @{L='signin';E={$_.SignInActivity.LastSignInDateTime}},`
    @{L='licenses';E={(Get-MgUserLicenseDetail -UserId $_.id).SkuPartNumber -join ','}}|
        export-csv -nti c:\temp\EntraUsers.csv -Encoding utf8

co mnie denerwuje w tych commandletach, to że nie są przyjmują w prosty sposób obiektów, np to nie zadziała:

get-mgUser -all|get-mgUserLicenseDetail

to było abecadło PS, ale wzięli się za to developerzy webowi i taki efekt… trzeba też zawsze pamiętać o dodaniu 'all’ bo standardowo jest paging na 1oo obiektów.

i jeszcze drobny przykład na użycie filtra. nie jest co prawda widoczne w helpie od get-mgUser ale to jest filtr OData – z którego ogólnie korzysta cały Graph. tutaj prosty filtr, żeby wyświetlić tylko konta typu guest. nie podjąłem się filtrowania po dacie w OData bo to by kosztowało mnie za dużo czasu na rozkminkę – operacje na datach nie są oczywiste, a PowerShell sobie świetnie z tym radzi:

Get-MgUser -Filter "userType eq 'guest'" -Property displayname,usertype,signinactivity|
    ?{$_.SignInActivity.LastSignInDateTime -lt (get-date).AddMonths(-2)}|
    select displayname,usertype,@{L='activity';E={($_|select -ExpandProperty SignInActivity).LastSignInDateTime}}

connect

oczywiście żeby korzystać z commandletów graph trzeba się połaczyć z odpowiednim zakresem (scope). jeśli to jest dla ciebie nadal problemem to koniecznie wrzuć do bookmarków ten link, który opisuje jak użyć Find-MgGraphCommand żeby sprawdzić niezbędne zakresy.

jak Microsoft potrafi strzelić klientom w kolano

ciekawostką jest, że żeby być w stanie odczytać ten atrybut, trzeba mieć minimum EntraID P1 – inaczej wyskoczy błąd:

Get-MgUser_List: Neither tenant is B2C or tenant doesn't have premium license

Status: 403 (Forbidden)
ErrorCode: Authentication_RequestFromNonPremiumTenantOrB2CTenant

…dlaczego? nie chodzi mi o techniczne wyjaśnienie, ale to krzyk w stronę MS – dla czego tak podstawowa funkcjonalność, jak wyszukiwanie nieaktywnych kont, wymaga dodatkowej licencji?

eN.