Headless PHP Drupal script deletes spam zombie user accounts

For for the last few months automatic bots have been creating hundreds of zombie accounts per day on the TurnKey web site. I'm not sure why they bother. I assume it has something to do with spamming, but they never log in. Besides, spam almost never gets past our content filter (Mollom) and when it does we always nuke it. Zero tolerance.


Meanwhile these zombie accounts are polluting my precious database, and that bothers me. Besides, call me prejudiced, but I just hate zombies. You're either alive or you're dead. Pick a side!

We could enable CAPTCHA but we'd rather make user registration more complicated only as a last resort.

So I wrote a quick and dirty script to delete all 38489 zombie accounts on the TurnKey Linux web site. As you can see below my definition of a zombie user is one that has never logged in or accessed the site, and is over a week old.


   require_once './includes/bootstrap.inc';

   print "<pre>";

   $results = db_query("select uid, name, mail, access, created, login
                        FROM users WHERE created != 0 AND login=0 AND access=0");

   $i = 0;
   while ($result = db_fetch_object($results)) {
       $daysago = ((time() - $result->created) / (24 * 60 * 60));
       printf("created = %s, days ago = %d\n",
              date("Y-m-d", $result->created), $daysago);

       print "n";
       if($daysago < 7)

       user_delete(NULL, $result->uid);
       $i += 1;

   print "COUNT: $in";
   print "</pre>";

Hope somebody else finds this useful!


Guest's picture

I noticed two things in the script which probably were intended slightly different. Even though it wouldn't affect the workings, it affects the clarity of the output - which goes to how we manually confirm that it actually does work:

  • Just below the while loop, there's a print_r call. My best guess is that that should not be there - as it confuses output. It's very useful for debugging though ;)
  • Just above the if ($daysago < 7) it says: print "n";, I guess this should have been
  • 		print "\n";
  • to create a new line in the output rather than print an n.
Liraz Siri's picture

Thanks for pointing that out. I'll fix it in the post above. The line is correct in the original script so this must be a weird quoting issue.
David Killingsworth's picture

Would you place this is the Drupal root directory?

I too have had this problem and periodically deleted them by hand!

Julio Mondragón's picture

It worked perfectly, I just changed a little the search query "select users.uid, name, mail, access, created, login, rid FROM users, users_roles WHERE users.uid = users_roles.uid and created != 0 and rid = 5" in order to remove all accounts that were created for a specific role and were older than 7 days no matter if there is any content associated or if was accesed or not. Thank you very much!


Add new comment