Remove all users except admins or a few select users whichever is easier

Is there a quick script which will allow me to bulk remove all users except either admins or a select few users identified by their IDs/emails? Whichever option is easier is fine.

Will want to do this from the rails console.

Thanks

 User.where(admin: false).destroy_all

I think should do it. You can do the above without the destroy_all to see what users are selected.

2 Likes

Thanks, is destroy_all the same as UserDestroyer or is one recommended over the other. Saw UserDestroyer mentioned a few times in other posts. Thanks

Its now failing with this after deleting around 200, but its now stuck:

ActiveRecord::RecordInvalid: Validation failed: Primary email can't be blank
from /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.3/lib/active_record/validations.rb:80:in `raise_validation_error'

I’ve had a search and found one post about checking for blocked emails in Admin > Logs > Screened Emails and nothing is showing but not sure what to do next. Thanks

UserDestroyer is what you should use. It will delete other data associated with the user.

Don’t know why you’d get that error.

You might restore your backup to before you started the delete and try the destroyer instead.

1 Like

I’ve restored and tried again with the UserDestroyer, but still getting that error. Anyway to track down whats causing it?

You can use a rails script or Data Explorer to check for the email addresses and see if one is blank… Though it would be weird. No email field is blank by default even for automatically generated accounts like discobot ou system (which are admins by default).

Were your users imported? But even so, I’m pretty sure that account creation methods don’t allow blank email fields.

We’ve used oauth with a custom app. I did this yesterday but returned no users:

User.joins(:user_emails).where(user_emails.email = "") and that returned nil so I don’t think any are empty.

Must just be one or two users though because the majority work but its getting stcuk instantly on the same one now.

My delete script is:

User.where(admin: false).find_each do |user| UserDestroyer.new(Discourse.system_user).destroy(user, delete_posts: true) end

Is there anyway to echo which user its doing as it loops round?

You can output the usernames and their corresponding emails:

User.where(admin: false).find_each do |user|
  puts "#{user.username}: #{user.email}"
  UserDestroyer.new(Discourse.system_user).destroy(user, delete_posts: true)
end
3 Likes

Thanks, this is great, will run this now and hopefully should tell me who it is struggling on.

1 Like

Yeah, this worked, showed me which it was struggling with and it was an illegal character in the email somehow so updated that and it worked. Thanks

3 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.