AzureADLastLoginReport.ps1

<#PSScriptInfo
 
.VERSION 1.0
 
.GUID 1ba45abc-d909-42d5-8cae-3ae7b7b81c2e
 
.AUTHOR Vikas Sukhija
 
.COMPANYNAME Techwizard.cloud
 
.COPYRIGHT Techwizard.cloud
 
.TAGS
 
.LICENSEURI
 
.PROJECTURI
 
.ICONURI
 
.EXTERNALMODULEDEPENDENCIES
 
.REQUIREDSCRIPTS
 
.EXTERNALSCRIPTDEPENDENCIES
 
.RELEASENOTES
 
 
.PRIVATEDATA
 
#>


<#
    .NOTES
    ===========================================================================
    Created with: ISE
    Created on: 5/1/2023 1:46 PM
    Created by: Vikas Sukhija
    Organization:
    Filename: AzureADLastLoginReport.ps1
    refrence: Microsoft script
    ===========================================================================
    .DESCRIPTION
    This script will report on AzureAd last login and can send the report on designated emaail address
    also you can filter the reports based on days, like whoever has not loggedin since 90days so
    that in case you want to deactivate guest accounts or other accounts based on that.
 
    User.Read.All and AuditLog.Read.All permissions are required for the APP
#>

[CmdletBinding()]
  param
  (
    [Parameter(Mandatory = $true)]
    $DaysSinceLastLogin,
    [Parameter(Mandatory = $true)]
    [ValidateSet('guest','member','All')]
    $UserType,
    $smtpserver="smtpserver",
    $from="DoNotRespond@labtest.com",
    $erroremail="Reports@labtest.com",
    $logrecyclelimit = '60'
  ) 
 
#################logs and variables##########################
$log = Write-Log -Name "AzureADLastLoginReport" -folder "logs" -Ext "log"
$ReportFull = Write-Log -Name "ReportFull-AzureADLastLoginReport" -folder "Report" -Ext "csv"
$ReportActual = Write-Log -Name "ReportActual-AzureADLastLoginReport" -folder "Report" -Ext "csv"
$URI = "https://graph.microsoft.com/beta/users?`$select=displayName,userPrincipalName, mail, id, CreatedDateTime, signInActivity, UserType, assignedLicenses&`$top=999"

#####################get access token ##############################
$AppId = ''
$TenantId = ''
$AppSecret = ''

$uri = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"
 $body = @{
     client_id     = $AppId
     scope         = "https://graph.microsoft.com/.default"
     client_secret = $AppSecret
     grant_type    = "client_credentials" }

$tokenRequest = Invoke-WebRequest -Method Post -Uri $uri -ContentType "application/x-www-form-urlencoded" -Body $body -UseBasicParsing
$Accesstoken = ($tokenRequest.Content | ConvertFrom-Json).access_token
#######################get report based on days#########################
Write-Log -Message "Start....................Script" -path $log
$headers = @{Authorization = "Bearer $Accesstoken"}
$SignInData = (Invoke-RestMethod -Uri $URI -Headers $Headers -Method Get -ContentType "application/json") 
switch($UserType){
"guest"{$SignInDatareport = $SignInData.value | where{$_.userType -eq 'Guest'}}
"member"{$SignInDatareport = $SignInData.value | where{$_.userType -eq 'member'}}
"All"{$SignInDatareport = $SignInData.value }
}
Write-Log -message "Fetched user sign-in data" -path $log
$pagecount = 1
##########generate report############
$Report = [System.Collections.Generic.List[Object]]::new() 
Foreach ($User in $SignInDatareport) {
    If ($Null -ne $User.SignInActivity.lastSignInDateTime){$LastSignInDateTime = [DateTime]$User.SignInActivity.LastSignInDateTime}
    else{$LastSignInDateTime = "" }
    if($Null -ne $User.SignInActivity.LastNonInteractiveSignInDateTime){$LastNonInteractiveSignInDateTime = [DateTime]$User.SignInActivity.LastNonInteractiveSignInDateTime}
    else{$LastNonInteractiveSignInDateTime = ""}    
    
    $ReportLine  = [PSCustomObject] @{          
      UPN                = $User.UserPrincipalName
      DisplayName        = $User.DisplayName
      Email              = $User.Mail
      Id                 = $User.Id
      Created            = [DateTime]$User.CreatedDateTime  
      LastSignInDateTime = $LastSignInDateTime
      LastNonInteractiveSignInDateTime = $LastNonInteractiveSignInDateTime
      UserType           = $User.UserType 
      IsLicensed  = if ($User.assignedLicenses.Count -ne 0) { $true } else { $false } }
      $Report.Add($ReportLine) 
 } # End ForEach

 # Go to next page to fetch more data
 $NextLink = $SignInData.'@Odata.NextLink'
    
 While ($NextLink -ne $Null) { # We do... so process them.
    $pagecount = $pagecount + 1
    Write-log -message "Processing Page - $pagecount" -path $log
    $SignInData =  Invoke-RestMethod -Uri $NextLink -Headers $Headers -Method Get -ContentType "application/json"

    switch($UserType){
      "guest"{$SignInDatareport = $SignInData.value | where{$_.userType -eq 'Guest'}}
      "member"{$SignInDatareport = $SignInData.value | where{$_.userType -eq 'member'}}
      "All"{$SignInDatareport = $SignInData.value}
      }
Foreach ($User in $SignInDatareport) {  
    If ($Null -ne $User.SignInActivity.lastSignInDateTime){$LastSignInDateTime = [DateTime]$User.SignInActivity.LastSignInDateTime}
    else{$LastSignInDateTime = "" }
    if($Null -ne $User.SignInActivity.LastNonInteractiveSignInDateTime){$LastNonInteractiveSignInDateTime = [DateTime]$User.SignInActivity.LastNonInteractiveSignInDateTime}
    else{$LastNonInteractiveSignInDateTime = ""}   
         
    $ReportLine  = [PSCustomObject] @{          
      UPN                = $User.UserPrincipalName
      DisplayName        = $User.DisplayName
      Email              = $User.Mail
      Id                 = $User.Id
      Created            = [DateTime]$User.CreatedDateTime  
      LastSignInDateTime = $LastSignInDateTime
      LastNonInteractiveSignInDateTime = $LastNonInteractiveSignInDateTime
      UserType           = $User.UserType
      IsLicensed  = if ($User.assignedLicenses.Count -ne 0) { $true } else { $false } } 
      $Report.Add($ReportLine) }
    
    # Check for more data
    $NextLink = $SignInData.'@Odata.NextLink'
 } # End While


Write-log -message "All pages processed - export report - $($Report.count)" -path $log
###############################process last login data##########################################
$ReportCreatedpast90days = $Report | where{$(get-date $_.Created)  -lt (get-date).AddDays(-$DaysSinceLastLogin)}

[System.Collections.ArrayList]$collection = @() 
foreach($i in $ReportCreatedpast90days){
  $mcoll = "" | Select-Object UPN,DisplayName,Email ,Id ,Created ,LastSignInDateTime,LastNonInteractiveSignInDateTime, UserType ,IsLicensed, Status
  $mcoll.UPN = $i.UPN
  $mcoll.DisplayName = $i.DisplayName
  $mcoll.Email = $i.Email
  $mcoll.Id = $i.Id
  $mcoll.Created = $i.Created
  $mcoll.UserType = $i.UserType
  $mcoll.IsLicensed = $i.IsLicensed
  if($i.LastSignInDateTime -eq "" -and $i.LastNonInteractiveSignInDateTime -eq ""){
  $mcoll.LastSignInDateTime = $i.LastSignInDateTime
  $mcoll.LastNonInteractiveSignInDateTime = $i.LastNonInteractiveSignInDateTime
  $mcoll.status = "NullData"

  }
  elseif($i.LastSignInDateTime -eq "" -and $i.LastNonInteractiveSignInDateTime -ne ""){
  if($(get-date $i.LastNonInteractiveSignInDateTime) -lt (get-date).AddDays(-$DaysSinceLastLogin)){
  $mcoll.LastSignInDateTime = $i.LastSignInDateTime
  $mcoll.LastNonInteractiveSignInDateTime = $i.LastNonInteractiveSignInDateTime
  $mcoll.status = "Deactivate"
  }else{
    $mcoll.LastSignInDateTime = $i.LastSignInDateTime
    $mcoll.LastNonInteractiveSignInDateTime = $i.LastNonInteractiveSignInDateTime
    $mcoll.status = "NoAction"
  }
  }
  elseif($i.LastSignInDateTime -ne "" -and $i.LastNonInteractiveSignInDateTime -eq ""){
    if($(get-date $i.LastSignInDateTime) -lt (get-date).AddDays(-$DaysSinceLastLogin)){
  $mcoll.LastSignInDateTime = $i.LastSignInDateTime
  $mcoll.LastNonInteractiveSignInDateTime = $i.LastNonInteractiveSignInDateTime
  $mcoll.status = "Deactivate"
  }else{
    $mcoll.LastSignInDateTime = $i.LastSignInDateTime
    $mcoll.LastNonInteractiveSignInDateTime = $i.LastNonInteractiveSignInDateTime
    $mcoll.status = "NoAction"
  }

  }
  else{
  if($(get-date $i.LastSignInDateTime) -gt $(get-date $i.LastNonInteractiveSignInDateTime)){
  if($(get-date $i.LastSignInDateTime) -lt (get-date).AddDays(-$DaysSinceLastLogin)){
  $mcoll.LastSignInDateTime = $i.LastSignInDateTime
  $mcoll.LastNonInteractiveSignInDateTime = $i.LastNonInteractiveSignInDateTime
  $mcoll.status = "Deactivate"
  }else{
    $mcoll.LastSignInDateTime = $i.LastSignInDateTime
    $mcoll.LastNonInteractiveSignInDateTime = $i.LastNonInteractiveSignInDateTime
    $mcoll.status = "NoAction"
  }

  }
  else{
    if($(get-date $i.LastNonInteractiveSignInDateTime) -lt (get-date).AddDays(-$DaysSinceLastLogin)){
  $mcoll.LastSignInDateTime = $i.LastSignInDateTime
  $mcoll.LastNonInteractiveSignInDateTime = $i.LastNonInteractiveSignInDateTime
  $mcoll.status = "Deactivate"
  }else{
    $mcoll.LastSignInDateTime = $i.LastSignInDateTime
    $mcoll.LastNonInteractiveSignInDateTime = $i.LastNonInteractiveSignInDateTime
    $mcoll.status = "NoAction"
  }

  }

  }

  $collection.Add($mcoll)
}
###########################Exatract reports#################################
$collection | export-csv $ReportFull -NoTypeInformation
$deletecollection = $collection | Where{$_.Status -eq 'Deactivate' -or $_.Status -eq 'NullData'} 
$deletecollection | export-csv $ReportActual -NoTypeInformation
if($error){
  Write-Log -message "Error - $error" -path $log
  Send-MailMessage -SmtpServer $smtpserver -From $from -To $erroremail -Subject "Error Guest Deletion will not occur AzureADLastLoginReport" -Body $error[0].ToString()
  exit
}
Set-Recyclelogs -foldername "logs" -limit $logrecyclelimit -confirm:$false
Set-Recyclelogs -foldername "Report" -limit $logrecyclelimit -confirm:$false
Write-Log -Message "Script Finished" -path $log
#############################completed####################################