Upgrading a real-world Drupal 6 install to Drupal 7 is a chore. One of the more annoying aspects of the core upgrade process is step 5, 'disabling non-core modules'.

The UI for disabling modules is not nice, particularly once module dependencies are thrown into the mix. It's not a case of simply boring through the list of modules unchecking everything. First you need to uncheck everything you can. Save changes. Then go through the list again disabling the previously greyed out modules (because they still had active dependants) and disabling those. It can take about 4-5 passes before you're done.

Thankfully there is a much easier way using Drush. Drush is a command-line utility for managing aspects of a Drupal installation. Pertinently for Drupal upgraders it provides the ability to:

  • List installed modules
  • Disable modules

Running Drush without any arguments provides a list of commands and options. The two commands we are interested in are 'pm-list' (list installed modules) and 'pm-disable' (disable a module).

For these commands to work, you must issue your calls to drush from within your Drupal site's install directory e.g. /home/user/public_html/drupal

Keep in mind you can get information on any of Drush's commands by issuing a call to the help command.

$ drush help pm-list
> Show a list of available extensions (modules and themes).
> Options:
>  --type                                    Filter by extension type. Choices:   
>                                            module, theme.                       
>  --status                                  Filter by extension status. Choices: 
>                                            enabled, disable and/or 'not         
>                                            installed'. You can use multiple     
>                                            comma separated values. (i.e.        
>                                            --status="disabled,not installed").  
>  --package                                 Filter by project packages. You can  
>                                            use multiple comma separated values. 
>                                            (i.e. --package="Core -              
>                                            required,Other").                    
>  --core                                    Filter out extensions that are not   
>                                            in drupal core.                      
>  --no-core                                 Filter out extensions that are       
>                                            provided by drupal core.             
>  --pipe                                    Returns a space delimited list of    
>                                            the names of the resulting           
>                                            extensions.                          
> Aliases: pml

We want a list of non-core modules and we would prefer non-formatted output so our command call looks like this:

$ drush pm-list --type=module --no-core --pipe
> ad
> ad_channel
> click_filter
> ad_embed
> ad_cache_file
> ad_notify
> ad_owners
> ad_report
> ...

Now can produce a list of non-core modules to pass to the disable module Drush command.

$ drush help pm-disable
> Disable one or more extensions (modules or themes). Disable dependant extensions as well.
> Arguments:
>  extensions                                A list of modules or themes. You can 
>                                           use the * wildcard at the end of     
>                                           extension names to disable multiple  
>                                           matches.                             
> Aliases: dis

Simple then. Putting it all together we can chain together the module list command output using shell command substitution and pass that output as arguments to the disable command, all in one neat line.

$ drush pm-disable `drush pm-list --no-core --type=module --pipe`

Press 'y' in response to the resulting confirmation prompt and the tedious work in the Drupal admin UI is replaced with a neat one-line shell command!