How to get inactive users of JIRA with jelly or groovy script?

Hi All,

is it possible to get the list of inactive users of JIRA by jelly or groovy?

Note, I do not have access to DB so SQL is not possible.

Thanks in advance,

Rumi

1 answer

3 votes
Henning Tietgens Community Champion Feb 11, 2014

Yes.

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.user.util.UserManager

UserManager userManager = ComponentAccessor.getUserManager()
userManager.getUsers().findAll{user -> !user.isActive()}.each { user ->
   //...
}

Hello Henning,

 

Can we get list of inactive users for specific time, like I need list of users who are inactive from last 30 days?

 

Regards,

 

 

 

Henning Tietgens Community Champion Nov 15, 2016

Hi,

if you define inactive as "not logged in" you can use something like this.

import com.atlassian.jira.component.ComponentAccessor
def crowdService = ComponentAccessor.crowdService
def ofBizUserDao = ComponentAccessor.getComponent(OfBizUserDao)
def userUtil = ComponentAccessor.userUtil
def dateLimit = (new Date()) - 30
userUtil.getUsers().findAll { it.isActive() }.each {
	def user = crowdService.getUserWithAttributes(it.getName())
	def lastLoginMillis = user.getValue('login.lastLoginMillis')
	if (!lastLoginMillis?.isNumber()) {
		def tu = ofBizUserDao.findByName(user.directoryId, user.name)
		lastLoginMillis = tu.getCreatedDate()?.time
	}
	if (lastLoginMillis) {
		def d = new Date(Long.parseLong(lastLoginMillis))
		if (d.before(dateLimit)) {
			// not logged in for 30 days...
		}
	}
}

If the user never was logged in, this uses the created date for calculating the time of "inactivity".

Henning

Henning Tietgens Community Champion Nov 16, 2016

Ah, I missed an import while copying..

import com.atlassian.jira.crowd.embedded.ofbiz.OfBizUserDao
Henning Tietgens Community Champion Nov 16, 2016

And you have to do something at the position of the comment (// blue), like 

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.crowd.embedded.ofbiz.OfBizUserDao


def crowdService = ComponentAccessor.crowdService
def ofBizUserDao = ComponentAccessor.getComponent(OfBizUserDao)
def userUtil = ComponentAccessor.userUtil
def dateLimit = (new Date()) - 30
def result = ""


userUtil.getUsers().findAll { it.isActive() }.each {
    def user = crowdService.getUserWithAttributes(it.getName())
    String lastLoginMillis = user.getValue('login.lastLoginMillis')
    if (!lastLoginMillis?.isNumber()) {
        def tu = ofBizUserDao.findByName(user.directoryId, user.name)
        lastLoginMillis = tu.getCreatedDate()?.time
    }
    if (lastLoginMillis) {
        def d = new Date(Long.parseLong(lastLoginMillis))
        if (d.before(dateLimit)) {
            // not logged in for 30 days...
			result += "${user.displayName} (${user.name})<br>"
        }
    }
}
result

to print a list of "inactive" users.

Please note the change to String lastLoginMillis, otherwise you'll get a runtime error.

Henning

Thanks, it works perfectly well..

 

Thanks,

Tushar

I can't seem to comment on this, it says I'm a spammer :(

 

There it goes, now for my actual comment:

Does this need to be revised?  I'm getting 

Cannot invoke method findByName() on null object.

 Thanks!

 
Henning Tietgens Community Champion Aug 09, 2017

There were some changes in JIRA 7. Here's my current script to deactivate inactive users:

import com.atlassian.crowd.embedded.api.UserWithAttributes
import com.atlassian.crowd.embedded.spi.UserDao
import com.atlassian.jira.application.ApplicationAuthorizationService
import com.atlassian.jira.application.ApplicationKeys
import com.atlassian.jira.bc.user.ApplicationUserBuilderImpl
import com.atlassian.jira.bc.user.UserService
import com.atlassian.jira.bc.user.search.UserSearchParams
import com.atlassian.jira.bc.user.search.UserSearchService
import com.atlassian.jira.component.ComponentAccessor

def test = true // to really deactivate users, change to false
int numOfDays = 182 // Number of days the user was not logged in
def blockedUsers = // User who should not be deactivated
[
'administrator'
]
def maximumNumberOfUsers = 10000 // search is restricted to find at max this number of users

def userSearchService = ComponentAccessor.getComponent(UserSearchService)
def crowdService = ComponentAccessor.crowdService
def userService = ComponentAccessor.getComponent(UserService.class)
def userDao = ComponentAccessor.getComponent(UserDao)
def applicationAuthorizationService = ComponentAccessor.getComponent(ApplicationAuthorizationService)
def updateUser
def updateUserValidationResult

Date dateLimit = (new Date()) - numOfDays
String result = ""

def userSearchParamsBuilder = new UserSearchParams.Builder()
userSearchParamsBuilder
.allowEmptyQuery(true)
.ignorePermissionCheck(true)
.maxResults(maximumNumberOfUsers)

def allActiveUsers = userSearchService.findUsers("", userSearchParamsBuilder.build())
result += "All active Users: ${allActiveUsers.size()}<br>"
allActiveUsers.findAll {
!blockedUsers.contains(it.name) &&
(
applicationAuthorizationService.canUseApplication(it, ApplicationKeys.SOFTWARE) ||
applicationAuthorizationService.canUseApplication(it, ApplicationKeys.SERVICE_DESK)
)
}.each { appUser ->
UserWithAttributes user = crowdService.getUserWithAttributes(appUser.getName())
String lastLoginMillis = user.getValue('login.lastLoginMillis')
def start_text = "Last Login was"
if (!lastLoginMillis?.isNumber()) {
if (user.directoryId && user.name) {
def tu = userDao.findByName(user.directoryId, user.name)
lastLoginMillis = tu?.getCreatedDate()?.time
start_text = "Not logged in, created on"
} else {
start_text = "SOMETHING WRONG: $user.directoryId && $user.name"
}
}
if (lastLoginMillis) {
Date d = new Date(Long.parseLong(lastLoginMillis))
if (d.before(dateLimit)) {
updateUser = (new ApplicationUserBuilderImpl(appUser)).active(false).build()
updateUserValidationResult = userService.validateUpdateUser(updateUser)
if (updateUserValidationResult.isValid()) {
if (!test) {
userService.updateUser(updateUserValidationResult)
}
result += "Deactivated ${updateUser.name} - $start_text ${d.format("dd.MM.yyyy hh:mm")}"
} else {
result += "Update of ${updateUser.displayName} (${updateUser.name}) failed: ${updateUserValidationResult.getErrorCollection().getErrors().entrySet().join(',')}"
}
}
}
}
result

Henning

Hi Henning

 

Regarding your script for JIRA 7. What would be the script if I nly need to display user who did not login in the last 60 days without deactivationg them.

 

Thanks for your help,

Elvir

Hi Elvir,

just exchange the inner part of if (d.before(dateLimit)):

if (d.before(dateLimit)) {
result += "Inactive user: ${appUser.name} - $start_text ${d.format("dd.MM.yyyy hh:mm")}<br>"
}

Henning

Suggest an answer

Log in or Join to answer
Community showcase
Sarah Schuster
Posted Jan 29, 2018 in Jira

What are common themes you've seen across successful & failed Jira Software implementations?

Hey everyone! My name is Sarah Schuster, and I'm a Customer Success Manager in Atlassian specializing in Jira Software Cloud. Over the next few weeks I will be posting discussion topics (8 total) to ...

3,301 views 14 20
Join discussion

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you
Atlassian Team Tour

Join us on the Team Tour

We're bringing product updates and pro tips on teamwork to ten cities around the world.

Save your spot