Select to view content in your preferred language

Query for Users that have not logged in for 40 days

2091
8
Jump to solution
11-16-2022 10:54 AM
kapalczynski
Frequent Contributor

I am trying to see how to query our ARCGIS Online account to get a list of users and their Last Login Date.  From there I want to grab the users that have not logged in say for 40 days.  And then create a new list and do something with it like email them etc.

I can do something like this to get a full count of the users but don't know how to query for the Users and their Login Date....

Any thoughts?

 

from arcgis.gis import GIS
import arcgis 

gis = GIS("https://xxx.maps.arcgis.com", "usernamne", "passaword") # set first arguement to your Portal or AGOL
users = arcgis.gis.UserManager(gis)

# get the total number of users in your AGOL account provided you have administrative priveledges
totalUsers = users.counts('user_type', as_df=False)[0]['count']
print(totalUsers)

 

0 Kudos
1 Solution

Accepted Solutions
RhettZufelt
MVP Notable Contributor

not where I can test at the moment, but your actualDate will be a string and datetime.now will be a datetime object.

will need to convert the string time to a datetime object, then the math should work.

R_

View solution in original post

8 Replies
DavidAnderson_1701
Frequent Contributor

I've seen the ESRI staff present just this use case several times when demoing the API.
2022 User Conference - Proceedings (esri.com)

This notebook looks like it has some guidance:

https://github.com/Esri/arcgis-python-api/tree/conference_talks/talks/uc2021/Administering%20Your%20...

 

RhettZufelt
MVP Notable Contributor

 

 

time.localtime(user.lastLogin/1000)

#though, I like this better as it looks like a "normal" date format

time.strftime('%m/%d/%Y', time.localtime(user.lastLogin/1000))

 

 

 

Found that here.  Might help.

R_

0 Kudos
RhettZufelt
MVP Notable Contributor

Since this reminded me that I was going to do a logon inventory myself, I modified the snippet from @JosephRhodes2 in this post to just write the username and last login date to a csv file.

from arcgis import GIS
import csv
import time

agol_username = 'AdminUser'                       # change
agol_password = 'userPassword'                    # change
output_csv = r'C:\path\to\out\file\users.csv'     # change
search_user = '*'                                 # change to query individual user

gis = GIS('https://arcgis.com', agol_username, agol_password)

user_list = gis.users.search(query=search_user, max_users=10000)

with open(output_csv, 'w', encoding='utf-8') as file:
    csvfile = csv.writer(file, delimiter=',', lineterminator='\n')
    csvfile.writerow(["Name",                         # these are the headers; modify according to whatever properties you want in your report
					"Title",
                      "LastLogOn"
                    ])  
    
    for item in user_list:
        if item.lastLogin != -1:
           csvfile.writerow([item.username,          # modify according to whatever properties you want in your report
                            time.strftime('%m/%d/%Y', time.localtime(item.lastLogin/1000))
                            ])  

R_

kapalczynski
Frequent Contributor

@RhettZufelt  

time.localtime(item.lastLogin/1000))

What is the /1000 how do I equate that to days or hours 

Where can I get a list of properties that I can use to return values?

 

Or does this look back to who logged in within the last Day?

if item.lastLogin != -1:

 

Just looking how to modify the code to look for users that have not logged in in the last 20 days, 40 days etc...

0 Kudos
kapalczynski
Frequent Contributor

Trying this but getting str vs Date error

ERROR:

if actualDate < lastFewDays:
TypeError: '<' not supported between instances of 'str' and 'datetime.datetime'

 

gis = GIS('https://vdot.maps.arcgis.com', agol_username, agol_password)
user_list = gis.users.search(query=search_user, max_users=5)

for item in user_list:
    lastFewDays = datetime.now() + timedelta(days=-30)
    print(lastFewDays)
    actualDate = time.strftime('%m/%d/%Y', time.localtime(item.lastLogin/1000))
    print(actualDate)
    
    if actualDate > lastFewDays:

 

0 Kudos
RhettZufelt
MVP Notable Contributor

not where I can test at the moment, but your actualDate will be a string and datetime.now will be a datetime object.

will need to convert the string time to a datetime object, then the math should work.

R_

kapalczynski
Frequent Contributor

Awesome I got it with this... Maybe a smoother way to do this?

Thanks for steering he correct direction!!!!

 

 

def findUsers():
    counter = 0
    with open(output_csv, 'w', encoding='utf-8') as file:
        csvfile = csv.writer(file, delimiter=',', lineterminator='\n')
        csvfile.writerow(["Name", 
                          "LastLogOn",
                          "Email",
                          "Days"
                        ])

        for item in user_list:
            lastThirtyDays = datetime.now() + timedelta(days=-numberOfDays)
            lastLogintime = item.lastLogin/1000
            lastLoginTimeConvert = (datetime.utcfromtimestamp(lastLogintime).strftime('%Y-%m-%d %H:%M:%S'))

            format = '%Y-%m-%d %H:%M:%S'
            lastLoginDate = datetime.strptime(lastLoginTimeConvert, format)

            diffdays = lastThirtyDays - lastLoginDate
            diffDays2 = diffdays.days
            
            if lastLoginDate < lastThirtyDays:
                if diffDays2 > 35:
                    print(item.username + " logged in " + str(diffDays2) + " days ago - " + item.email)
                    counter += 1
                    csvfile.writerow([item.username,    
                                lastLoginTimeConvert,
                                item.email,
                                diffDays2
                                ])
    return counter

 

 

 

0 Kudos
RhettZufelt
MVP Notable Contributor

Apperantly lastLogin returns UNIX style date format in miliseconds.  the val/1000 converts it to seconds so the time functions work properly.

That is why I used this one in the updated script that I posted, as it give MM/DD/YY.

time.strftime('%m/%d/%Y', time.localtime(user.lastLogin/1000)

If a user has never logged on, it will return -1 and will throw an error.  so, that line just tells it to skip that user if they have never logged on and continue running the script rather than error out.

I am not good at finding documentation for these types of things (or, the docs barely exist) so I just tested it to see what properties were availalbe for users.

Basically, I used the piece of code you have above (in IDLE) to get a list of the users:

users = arcgis.gis.UserManager(gis)

then I just grabbed a single user from the list (this grabs the first user):

user = users[0]

Then, I use the IDLE code suggestions (hold windows key and press spacebar after the . ) to find the available properties, and scrolled down until I saw lastLogin.

RhettZufelt_0-1668645893260.png

Once I knew the property I was after was called lastLogin, I did Google search for "ESRI lastLogin" to find info/examples of how to use it.

Hope this helps,

R_

 

0 Kudos