Search code examples
azurepowershellazure-active-directorymicrosoft-graph-apimicrosoft-entra-id

Powershell - find last logon activity for a specific device


I am new to Powershell. I have a powershell script that uses the Microsoft Graph API. It loops through list of users reading from a CSV file and finds the devices for that user. For each of these devices I need to be able to find the logon date-time. I am trying the find the right cmdlet and syntax to use to achieve the desired result.

The info I am looking for is the one you see under the "Activity" column on the Microsoft Azure portal Users > Devices screen:

enter image description here I have tried to call Get-AzureADAuditSignInLogs using the below syntax, but it is not returning a value. Here is what I have tried:

$deviceID = ‘123456-abcd-5555-9999-588888f66a11’
$deviceResults = Get-AzureADAuditSignInLogs -Filter "DeviceDetail/DeviceId eq '$deviceID'" -Top 1

I also tried this one:

Get-AzureADAuditSignInLogs | where-object -property DeviceDetail/DeviceId -eq '$deviceID' 

Both these calls return nothing. I have also added Connect-AzureAD to the beginning of the code.

Any suggestions, ideas to solve my question would be tremendously helpful. Thanks!

Here is the complete code as I have it now:

# Connect to Graph API
Connect-MgGraph -NoWelcome
#Connect-AzureAD 

#Import data from CSV file
$CSVData = Import-CSV -Path "C:\PSTest\Employees.csv"

function Test-AccountExists {
  param(
  $UserN
)
  [bool] (Get-MgUser -Filter "Displayname eq '$UserN'" -ErrorAction 
 Ignore)
}

$resultsArr = @()

ForEach ($row in $CSVData){


$fullname = $($row.”First Name”) + “ “ + $($row.”Last Name”)
Write-Host $fullname

$empId = $($row.”Employee Id”)

# Function invocation
$result = Test-AccountExists -UserN $fullname

Write-Host $result
Write-Host $empId

If (($result) -eq $true) {

$userName = $fullname
$user = Get-MgUser -Filter "Displayname eq '$userName'"
$userId = $user.Id
Write-Host "User Principal Name: $($user.UserPrincipalName)"
Write-Host "User Id: $($userId)"

                                                                            
$devices = Get-MgUserOwnedDevice -UserId $userId

If ($devices) {

    foreach ($device in $devices) {
        $test = get-MgDevice -DeviceId $device.Id
        
        #based on deviceId
        #$LoginTime = Get-AzureADAuditSignInLogs -Filter "DeviceId eq '$device.Id'" -Top 1 | Select -ExpandProperty CreatedDateTime
        
        Write-Host $test.DisplayName
        
        Write-Host $device.Id

        $deviceId = $device.Id
        $testCompliance = Get-MgDevice -Filter "id eq '$deviceId' and isCompliant eq true"
        if ($testCompliance) {
            $complianceState = "Y"
        }
        else{
            $complianceState = "N"
        }

        $resultrec = [PSCustomObject]@{
        ‘Employee Id’= $empId
        ‘Full Name’= $userName
        ‘User Principal Name’ = $user.UserPrincipalName
        ‘Device Name’ = $test.DisplayName
        ‘Compliance State’ = $complianceState
        ‘Azure Account’ = “Yes”
        }
        $resultsArr += $resultrec
    } #for each device
 }#If devices
 else{
        Write-Host “No devices exist for user”
        $resultrec = [PSCustomObject]@{
        ‘Employee Id’= $empId
        ‘Full Name’= $userName
        ‘User Principal Name’ = $user.UserPrincipalName
        ‘Device Name’ = “No device in Azure”
        ‘Compliance State’ = “NA”
        ‘Azure Account’ = “Yes”  
        }
        $resultsArr += $resultrec
  }#No devices
}#If account exists

ElseIf (($result) -eq $false) {

Write-Host “Function returned false”

    Write-Host "User Name in ElseIf:” + ($fullname)

    $resultrec2 = [PSCustomObject]@{
    ‘Employee Id’= $empId
    ‘Full Name’= $fullname
    ‘User Principal Name’ = “NA”
    ‘Device Name’ = “NA”
    ‘Compliance State’ = “NA”
    ‘Azure Account’ = “No”
    }
    
$resultsArr += $resultrec2

}


}#ForEach

# Export the resultsArrArr to a new CSV file
$resultsArr | Export-Csv -Path “C:\pstest\Results.csv” - 
NoTypeInformation

#clear array after export
$resultsArr = @()

Solution

  • This answer requires the Microsoft.Graph.Authentication Module (Connect-MgGraph and Invoke-MgGraphRequest are cmdlets from this Module) and the required permissions are:

    permissions


    You can get the user's owned devices by calling the List ownedDevices Method from the user Endpoint. For a single user and assuming you have their UserPrincipalName or Id, the code would look like this:

    Connect-MgGraph
    
    $endpoint = 'v1.0' # or `beta`
    $user = '[email protected]' # Can use user's Id or UPN here
    $response = Invoke-MgGraphRequest GET ('{0}/users/{1}?$expand=ownedDevices' -f $endpoint, $user)
    $response['ownedDevices'] | ForEach-Object {
        [pscustomobject]@{
            DeviceOwner                         = $response['userPrincipalName']
            DeviceId                            = $_['deviceId']
            DeviceDisplayName                   = $_['displayName']
            DeviceEnabled                       = $_['accountEnabled']
            DeviceApproximateLastSignInDateTime = $_['approximateLastSignInDateTime']
        }
    }
    

    Note that you will find much more properties in $response['ownedDevices'], for the complete list see device Properties. If you want additional properties added to your output, those need to be included in the [pscustomobject] expression, i.e.: for isCompliant you would need to add a IsCompliant = $_['isCompliant'] and so on.