It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

How to deactivate a user programmatically (java, rest, sql)?

I have lots of users that I need to deactivate. Is there an API of some kind to do this? Using the UI will take to long.

I've tried setting the Active field to 0 directly in the cwd_user table, but JIRA ignores this (though when done via the JIRA UI this column is changed to 0).

Using JIRA version is 5.2.4.1 with a local user directory

8 answers

1 accepted

8 votes
Answer accepted

If you don't want to shut down JIRA you can get the Script Runner plugin and use this script to deactivate users.

import com.atlassian.crowd.embedded.api.User
import com.atlassian.crowd.embedded.impl.ImmutableUser
import com.atlassian.jira.bc.user.UserService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.user.util.UserManager

UserManager userManager = ComponentAccessor.getUserManager()
UserService userService = ComponentAccessor.getComponent(UserService.class)
User updateUser
UserService.UpdateUserValidationResult updateUserValidationResult

errors = ''
userManager.getUsers().findAll{user -> user.name == 'username'}.each { user ->
    updateUser = ImmutableUser.newUser(user).active(false).toUser()
    updateUserValidationResult = userService.validateUpdateUser(updateUser)
    if (updateUserValidationResult.isValid()) {
        userService.updateUser(updateUserValidationResult)
    } else {
        errors += "Update of ${user.name} failed: ${updateUserValidationResult.getErrorCollection().getErrors().entrySet().join(',')}\n"
    }
}
return errors

You have to adapt the findAll{} part to find the users you want to deactivate.

Henning

Nice. We are deactivating the users as part of an upgrade, so shutting down is not a problem. But I'll keep this in mind in the future.

Thanks

Is there any way to do this by the crowd client alone? I've got a crowd client written and can search for all the required users that way. I just can't find out how to deactivate a user with the crowd.service.client.CrowdClient class. I've tried to user client.updateUser but it takes a crowd.model.user.User and not an ImmutableUser.toUser().

Hi Henning, This is a great script and I have used it to delete a few users and it works! Is there anyway I can import a CSV file with usernames and have the script read that file and perform this on the findAll to make the users inactive? We have a list of terminated users from HR and we can't categorize them based on Jira attributes. If you have any ideas let me know. Thanks so much! Rich

Sure, just add a list of usernames to the beginning of the script like this def usernamelist = [ 'auser', 'buser' 'cuser' ] And than change the findAll{} part of the script to .findAll{user -> usernamelist.contains(user.name)} Now test on a test system :-) Henning

Like Amir Katz likes this

Updated version for JIRA 7 below.

this is not working with jira 7

Updated for version 7:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.bc.JiraServiceContextImpl
import com.atlassian.crowd.embedded.impl.ImmutableUser
import com.atlassian.jira.user.DelegatingApplicationUser
import com.atlassian.jira.bc.user.search.UserSearchService
import com.atlassian.jira.bc.user.UserService
def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def jiraServiceContext = new JiraServiceContextImpl(currentUser)
def userSearchService = ComponentAccessor.getComponent(UserSearchService.class)
def userService = ComponentAccessor.getComponent(UserService.class)
def appUser = userSearchService.getUserByName(jiraServiceContext, 'test')
def errors = ''
if (appUser != null) {
    
    ImmutableUser.Builder builder = ImmutableUser.newUser(appUser.getDirectoryUser());
    builder.active(false)
    //builder.displayName('New display name')
    //builder.emailAddress('newemail@somewhere.com')
    def updateUser = new DelegatingApplicationUser(appUser.getId(), appUser.getKey(), builder.toUser());
    
    def updateUserValidationResult = userService.validateUpdateUser(updateUser)
    if (updateUserValidationResult.isValid()) {
        userService.updateUser(updateUserValidationResult)
    } else {
        errors += "Update of ${appUser.name} failed: ${updateUserValidationResult.getErrorCollection().getErrors().entrySet().join(',')}\n"
    }
}

we need to do any modification in the above script. to delete users

How can I use this to get users from csv file

Finally got the SQL approach to work. Lucas' answer triggered an idea. I had to shutdown JIRA to get it to pick up the change. It's caching user information each time a user is examined in the admin UI.

The SQL is simple:

update cwd_user set active = 0 where <your filter here>;

Thanks for both answers

JIRA Command Line Interface has a new enhancement for updateUser that provides this - you will need to look at JCLI-352 for details until 3.2.0 is released. Example:
jira --action updateUser --userId xxxx --deactivate

This doesn't seem to work in our cloud instance {code} [root@uk-ctoolbox-1 ~]# /usr/bin/java -jar /usr/local/jira_cli/lib/jira-cli-4.5.0-SNAPSHOT.jar --server https://mimecast.jira.com --user tsweeney --password 'XXXXXXXX' --project CoreGrid -a updateUser --userId aali --deactivate Client error: Activate and deactivate cannot be set for Cloud. [root@uk-ctoolbox-1 ~]# {code}

Hi Chiz,

Many user modifications via database doesn't work on the fly. You can disable them via database as well but I sugest you to shutdown JIRA (and perform a database backup) before modifying the data under cwd_user table.

Best regards,
Lucas Timm

1 vote
Tim Evans Atlassian Team Jul 13, 2015

Hi All,

Please note that direct database modification is not supported by Atlassian per our Support Offerings.

  • From the Support Offerings: "Atlassian does not support customers performing direct data manipulation of application databases via queries such as INSERT, UPDATE or DELETE, as they can easily lead to data integrity problems. If Atlassian encounters manipulation or customisations at this level, we may ask customers to restore data from their last known working state, or to engage an Expert to help recover their instance to a supportable state. If you are confident your UPDATE or INSERT is safe and your change management system is reliable, refer to the specific product's database documentation."

The ability to bulk deactivate users has been requested as a new feature, see JRA-30708

  • You are encouraged to add a vote and/or comment as the votes and comments are used by our team to determine the impact of issues and feature requests.

Cheers!

Tim | Atlassian

Sorry Tim....customers don't have time to wait for 5 years for such small changes. JRA-30708 was opened in Nov 2012. 

Like Amir Katz likes this

Tim's response seems like a boilerplate one that Jira product managers are required to post whenever the AI detects the the phrase 'UPDATE/INSERT/DELETE <whatever>' in a forum posting :-(

Good for Jira... 

Any similar suggestions for Confluence? 6.5.4

Have to free up about 400 inactive user licenses...

Appreciate any suggestions.

thx,

V

With ScriptRunner for Confluence this is similar possible.

Henning

Hi @Henning Tietgens , this is not working with Jira 7.13

 

How can I disable users from csv file?

Hi Alvin,

create a list of usernames from the csv file and paste the list into this script.

import com.atlassian.jira.bc.user.ApplicationUserBuilderImpl
import com.atlassian.jira.bc.user.UserService
import com.atlassian.jira.component.ComponentAccessor

def usernames = [
'username1',
'username2',
'username3'
]

def test = true

def userManager = ComponentAccessor.userManager
def userService = ComponentAccessor.getComponent(UserService.class)
def result = ""
usernames.each{username ->
def appUser = userManager.getUserByName(username)
def updateUser = (new ApplicationUserBuilderImpl(appUser)).active(false).build()
def updateUserValidationResult = userService.validateUpdateUser(updateUser)
if (updateUserValidationResult.isValid()) {
if (!test) {
userService.updateUser(updateUserValidationResult)
}
result += "Deactivated ${updateUser.name}<br>"
} else {
result += "<b>Update of ${updateUser.displayName} (${updateUser.name}) failed: ${updateUserValidationResult.getErrorCollection().getErrors().entrySet().join(',')}</b><br>"
}
}
result

Check I a first run if everything would run fine and than change test = true to test = false.

Henning

Hi @Henning Tietgens ,

Thank you for your very quick response, I have achieved this using iteration and placing the whole process inside while loop. 

I will give your suggestion a try. Thank you so much. If you can suggest on how can I do this without pasting the whole usernames inside the script , that would be great!

Best Regards,
Alvin

Try this for the first part. Adapt filename, delimiter and column (starting at 0) according to your csv file.

def test = true
def csvFilename = '/var/opt/jira/data/users.csv'
def delimiter = ','
def username_column = 2

def result = ""
def usernames = []
try {
def f = new File(csvFilename)
def lines = f.readLines()
lines.each { line ->
def parts = line.split(delimiter)
if (parts.size() > username_column) {
usernames.add(parts[username_column])
} else {
result += "Line '$line' of file $csvFilename could not be interpreted (size ${parts.size()}).<br>"
}
}
}
catch (e) {
result += "File error. $e<br>"
return
}

Henning

Like # people like this

Hi @Henning Tietgens ,

Thank you so much for keeping an extra eye and effort regarding with my questions, will definitely give this a try. Thank you so much!

I will let you know with the results.

Best Regards,
Alvin

Hi @Henning Tietgens ,

For the first solution you've given, test = false made the users to inactive. Thank you!

Best Regards,
Alvin

Like Amir Katz likes this

Hi @Henning Tietgens,

Could you help me?

I want to pass the enumerate using query parameter. 

def usernames = [
'username1',
'username2',
'username3'
]

 

how can I get the enumerate via groovy script?

 

Thank you in advance! 

What did you mean with "query parameter"? For which query?

For example I want to send next request

http://jiratest.ex.ru/rest/my-groovy/latest/custom/MyScript?username=testUser

 

"username=testUser" is the query parameter the request

And then I want to get "testUser" in my script 

I don't know how to do this with mygroovy plugin, too. Sorry.

Suggest an answer

Log in or Sign up to answer
Community showcase
Published in Off-topic

Run into these Solution Partners at Atlassian Open

Hey there Community! Atlassian Open is kicking off in less than a month and we can't wait to touch down in Vienna, Sydney and Boston. This is an opportunity to create the future of teamwork with ...

82 views 0 4
Read article

Community Events

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

Find an event

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

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you