cancel
Showing results for 
Search instead for 
Did you mean: 
Disclaimer
JUMPCLOUD EXPRESSLY DISCLAIMS ALL REPRESENTATIONS, WARRANTIES, CONDITIONS, AND LIABILITIES OF ANY KIND ARISING FROM OR RELATED TO THIRD-PARTY SOFTWARE, SCRIPTS, REPOSITORIES, AND APIS. JUMPCLOUD IS NOT REQUIRED TO SUPPORT ANY SUCH THIRD-PARTY MATERIALS AND ALL RISKS RELATED TO THIRD-PARTY MATERIALS ARE YOUR RESPONSIBILITY. PLEASE ALSO REVIEW THE JUMPCLOUD TOS.

Report on User Last Logon Events

jworkman
JumpCloud Employee
JumpCloud Employee

JumpCloud Directory Insights data contains a wide range of information about organization users, their systems and how they are accessing managed resources. Understanding how to access and use the Directory Insights data can help administrators secure their organization and identify trends. In this blog post, I will describe how to use the JumpCloud PowerShell Module to access Directory Insights data and return the latest event information. 

The JumpCloud PowerShell Module is a tool designed to help interact with the JumpCloud API. It’s something that can be run and installed on any computer regardless of its operating system. The module provides several nice-to-have features like auto-pagination when returning data longer than our standard page size. It’s a tool commonly used to perform bulk actions and get data about a JumpCloud Organization. In this post, the JumpCloud PowerShell Module will be required to run commands and get data about an organization. 

Note: Please update to the latest version of the JumpCloud PowerShell Module to run the code examples below. At the time of this writing, the latest JumpCloud PowerShell Module is 2.12.0. The SDKs should also be updated when the Module is updated. The latest version of the V2, V1 and DirectoryInsights SDK modules are 0.0.48, 0.0.44 0.0.32 respectively. 

Get-JCEvent

The JumpCloud PowerShell Module has a number of functions that interact with various endpoints in the JumpCloud API. Get-JCEvent is the function designed to get and filter data from Directory Insights. Help documentation for Get-JCEvent can be found on the corresponding GitHub help page or through PowerShell directly by typing “help Get-JCEvent” once the PowerShell Module is installed.

The Get-JCEvent function requires a parameter for “StartTime” and “Service”. “StartTime” is the furthest date in the past in which to return Directory Insights data. “Service” refers to the various services described in the Directory Insights Scheme documentation.

The function also supports various filtering and sorting parameters which limits the time it takes to return data and can be used to return specific information about events. 

In the examples below I’ll show how to get various types of data from Directory Insights.

Get all data from the last day

 

 

Get-JCEvent -Service:('all') -StartTime:((Get-date).AddDays(-1))

 

 

This command would return Directory Insights data between the current time and exactly 24 hours ago, data from all services would be included in this response.

Get System data from the last day

 

 

Get-JCEvent -Service:('systems') -StartTime:((Get-date).AddDays(-1))

 

 

This command would return Directory Insights data filtered by the “systems” service between the current time and exactly 24 hours ago.

Get System data from the last twenty days, filter by username

 

 

Get-JCEvent -Service:('systems') -StartTime:((Get-date).AddDays(-20)) -SearchTermAnd @{'username' = "reid.sullivan"}

 

 

This command would return Directory Insights data filtered by the “systems” service between the current time and exactly 20 days ago. Only events where the username is “reid.sullivan” would be returned. 

Get the last System login_attempt event filtered by username

 

 

Get-JCEvent -Service:('systems') -StartTime:((Get-date).AddDays(-20)) -SearchTermAnd @{'username' = "reid.sullivan"; 'event_type' = 'login_attempt'} -Limit 1 -Sort "DESC"

 

 

This command would return Directory Insights data filtered by the “systems” service between the current time and exactly 20 days ago. Only one single event where the username is “reid.sullivan” and the event_type is “login_attempt” would be returned.

The number of events returned is limited to just 1 single event. Calling this endpoint with a limit of just 1 event will return results much faster than not specifying a limit. The PowerShell Modules will auto-paginate and return all possible events otherwise. 

A note on sorting:

The data returned is sorted in descending order because the sort parameter was set to: "DESC". The latest event which occurred is returned. By default, events are returned in ascending order. Removing the “Sort” parameter from the previous command would return the first event found which is ascending order ("ASC")

Loops example

With the brief set of usage examples out of the way, the concept of variables and loops can be addressed. Loops are a rather simple programming concept and can be employed to perform work that would otherwise be impossible to hand code. In order to get all the latest events for users a loop will be required. The following example is just an introduction to the concept of iteration.

Imagine wanting to write a script to print the numbers 1 through 5. The following script would suffice:

 

 

Write-Host "1"
Write-Host "2"
Write-Host "3"
Write-Host "4"
Write-Host "5"

 

 

This would would produce this result:

jworkman_0-1718907456696.png

The same result can be achieved with a loop:

 

 

for ($i = 1; $i -lt 5; $i++) {
    Write-Host "$i"
}

 

 

The code above contains a definition for an initial state, a conditional test and a step of work to execute.

Essentially, the variable $i is given an initial value of “1”, the code body “Write-Host $i” will execute once and print “1” to the console. 

The conditional test “$i -le 5” states that while $i is less than or equal to 5 that the code body should execute.

The step of work to execute, “$i++” states that after each code body iteration the value of $i should be incremented by 1. 

Each step explained:

  • On the first iteration, the value of $i is set to 1 and the code body: “Write-Host $i” executes and prints “1” to the console, after this iteration the value of $i is incremented by 1 resulting in $i being equal to 2” in the next iteration
  • On the second iteration the value of $i is now 2. The value of $i is compared against the test condition” “$i -lt 5”. Since 2 is less than or equal to 5, the body of the loop executes and prints 2 to the console. Again after this, the value of $i is incremented by 1 resulting in $i being equal to 3” in the next iteration.
  • On the second iteration the value of $i is now 3. The value of $i is compared against the test condition” “$i -lt 5”. Since 3 is less than or equal to 5, the body of the loop executes and prints 2 to the console. Again after this, the value of $i is incremented by 1 resulting in $i being equal to 3” in the next iteration.
  • This continues as the value of $i is increased to 5. During this iteration, the value of $i is compared against the test condition” “$i -lt 5”. Since 5 is less than or equal to 5, the body of the loop executes and prints 5 to the console. The value of $i is increased by 1 once again meaning it’s value is now 6. 
  • When the next iteration of the loop is run the value of $i is 6 which is greater than 5 and the loop body will not execute. 

The concept of loops in general will go far beyond the scope of this post. I’d encourage anyone interested to read more.

Get Last Login Event for each user

In order to get login event data for every user, we’ll use a loop to iterate through each user and perform an action very similar to that loop example discussed previously. In these examples I’ll show how to build each part of the script before showing the final script. 

At a high level the script we’ll create will need to do the following:

  • Get a list of every JumpCloud user
  • Get each user’s last login event
  • Save the data from each user to a CSV

Get All JumpCloud users

 

 

$users = Get-JCUser

 

 

This command will get all of the JumpCloud users in an organization and save the data into the $users variable.

Get each user’s last login event data

 

 

Foreach ($user in $users){
    Get-JCEvent -Service:('systems') -StartTime:((Get-date).AddDays(-20)) -SearchTermAnd @{'username' = "$($user.username)"; 'event_type' = 'login_attempt'} -Limit 1 -Sort "DESC"
}

 

 

This command will iterate through each user from the $users variable and return the user’s last login but it’s not really helpful unless we can save each event to our own table. 

Get and save each user’s last login event data to a list

In order to return some set of data we need to create a variable to store that data within. Array lists are perfect for the application. To create an array list:

 

 

$list = New-Object System.Collections.ArrayList

 

 

This command will declare $list as an array list — some list we can store data in. To store each user’s last login event, the result from Get-JCEvent can be added to the $list variable with the “.Add()” method:

 

 

# Get all the users
$users = Get-JCUser
# Declare a new list
$list = New-Object System.Collections.ArrayList
# Get the login data for each user and add it to the list
Foreach ($user in $users){
    $list.Add(Get-JCsdkEvent -Service:('systems') -StartTime:((Get-date).AddDays(-90)) -SearchTermAnd @{'username' = "$($user.username)"; 'event_type' = 'login_attempt'} -Limit 1 -Sort "DESC") | Out-Null
}
# Get the list data where data exists and save to a CSV File
$list | Where-Object {$_ -ne $null} | ConvertTo-CSV | Out-File ~/lastLogin.csv

 

 

The code will get all the users in the organization and write the contents of that report to a CSV.

Get multiple events and create a custom report

Building on the previous examples, let’s create a custom report containing only certain fields and multiple event types. In the last example we simply added every property from the Get-JCEvent function into a list. In this example we’ll combine two different event types and pair down the report to only contain the information we need by building a PsCustomObject.

 

 

# Get all the users
$users = Get-JCUser
# Declare a new list
$list = New-Object System.Collections.ArrayList
# Get the login data for each user and add it to the list
Foreach ($user in $users){
    $systemLogin = Get-JCsdkEvent -Service:('systems') -StartTime:((Get-date).AddDays(-90)) -SearchTermAnd @{'username' = "$($user.username)"; 'event_type' = 'login_attempt'} -Limit 1 -Sort "DESC"
    $userPortalLogin = Get-JCsdkEvent -Service:('directory') -StartTime:((Get-date).AddDays(-90)) -SearchTermAnd @{'initiated_by.username' = "$($user.username)"; 'event_type' = 'user_login_attempt'} -Limit 1 -Sort "DESC"
    $list.Add(
        [PSCustomObject]@{
            username = $user.username
            firstName = $user.firstName
            lastName = $user.lastName
            email = $user.email
            lastSystemLoginHostname = $systemLogin.system.hostname
            lastSystemLoginId = $systemLogin.system.id
            lastSystemLoginGeoip = $systemLogin.Geoip
            lastSystemLoginSystemTimestamp = $systemLogin.system_timestamp
            lastUserPortalLoginGeoip = $userPortalLogin.geoip
            lastUserPortalLoginTimestamp = $userPortalLogin.timestamp
        }

    ) | Out-Null
}
# Get the list data where data exists and save to a CSV File
$list | Where-Object {$_ -ne $null} | ConvertTo-CSV | Out-File ~/lastLogin.csv

 

Screenshot 2024-06-20 at 12.55.33 PM.png

The following report should only contain the fields specified in the PSCustomObject. For each user there should be a login event for the user portal login and system login. 

Feel free to build upon this template and make it your own. Hopefully this is a helpful introduction to custom reports, our events API and some basic programming concepts. 

0 REPLIES 0
You Might Like

New to the site? Take a look at these additional resources:

Community created scripts:

Our new Radical Admin blog:

Keep up with Product News:

Read our community guidelines

Ready to join us? You can register here.