diff --git a/commands/core/archive.drush.inc b/commands/core/archive.drush.inc
index 9f9d21d..85dd5b6 100644
--- a/commands/core/archive.drush.inc
+++ b/commands/core/archive.drush.inc
@@ -35,6 +35,7 @@ function archive_drush_command() {
       'file' => 'The site archive file that should be expanded.',
       'site name' => 'Optional. Which site within the archive you want to restore. Defaults to all.',
     ),
+    'required-arguments' => 1,
     'options' => array(
       'destination' => 'Specify where the Drupal site should be expanded, including the docroot. Defaults to the current working directory.',
       'db-prefix' => 'An optional table prefix to use during restore.',
diff --git a/commands/core/cache.drush.inc b/commands/core/cache.drush.inc
index bd21f71..78732ec 100644
--- a/commands/core/cache.drush.inc
+++ b/commands/core/cache.drush.inc
@@ -18,6 +18,7 @@ function cache_drush_command() {
       'cid' => 'The id of the object to fetch.',
       'bin' => 'Optional. The cache bin to fetch from.',
     ),
+    'required-arguments' => 1,
     'options' => array(
       'format' => 'Format to output the object. Use "print_r" for print_r (default), "export" for var_export, and "json" for JSON.',
     ),
@@ -41,6 +42,7 @@ function cache_drush_command() {
       'bin' => 'Optional. The cache bin to store the object in.',
       'expire' => 'Optional. CACHE_PERMANENT, CACHE_TEMPORARY, or a Unix timestamp.',
     ),
+    'required-arguments' => 2,
     'options' => array(
       'format' => 'Format to parse the object. Use "string" for string (default), and "json" for JSON.',
       'cache-get' => 'If the object is the result a previous fetch from the cache, only store the value in the "data" property of the object in the cache.',
diff --git a/commands/core/core.drush.inc b/commands/core/core.drush.inc
index 29d5747..ab80348 100644
--- a/commands/core/core.drush.inc
+++ b/commands/core/core.drush.inc
@@ -106,6 +106,7 @@ function core_drush_command() {
     'arguments' => array(
       'code' => 'PHP code',
     ),
+    'required-arguments' => TRUE,
     'allow-additional-options' => TRUE,
     'bootstrap' => DRUSH_BOOTSTRAP_MAX,
     'aliases' => array('eval', 'ev'),
@@ -155,6 +156,7 @@ function core_drush_command() {
     'arguments' => array(
       'command' => 'The shell command to be executed.',
     ),
+    'required-arguments' => TRUE,
     'examples' => array(
       'drush exec \'git pull\'' => 'Retrieve latest code from git',
     ),
@@ -271,9 +273,10 @@ function core_drush_command() {
   $items['batch-process'] = array(
     'description' => 'Process operations in the specified batch set',
     'hidden' => TRUE,
-      'arguments' => array(
-        'batch-id' => 'The batch id that will be processed',
-      ),
+    'arguments' => array(
+      'batch-id' => 'The batch id that will be processed',
+    ),
+    'required-arguments' => TRUE,
     'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_LOGIN,
   );
 
@@ -283,6 +286,7 @@ function core_drush_command() {
     'arguments' => array(
       'batch-id' => 'The batch id that will be processed',
     ),
+    'required-arguments' => TRUE,
     'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_SITE,
   );
   $items['core-global-options'] = array(
diff --git a/commands/core/field.drush.inc b/commands/core/field.drush.inc
index ff216da..01113fd 100644
--- a/commands/core/field.drush.inc
+++ b/commands/core/field.drush.inc
@@ -29,6 +29,7 @@ function field_drush_command() {
       'bundle' => 'Content type (for nodes). Name of bundle to attach fields to. Required.',
       'field_spec' => 'Comma delimited triple in the form: field_name,field_type,widget_name. If widget_name is omitted, the default widget will be used. Separate multiple fields by space. If omitted, a wizard will prompt you.'
     ),
+    'required-arguments' => 1,
     'options' => array(
       'entity_type' => 'Type of entity (e.g. node, user, comment). Defaults to node.',
     ),
diff --git a/commands/core/ssh.drush.inc b/commands/core/ssh.drush.inc
index 07bbc92..263ef5f 100644
--- a/commands/core/ssh.drush.inc
+++ b/commands/core/ssh.drush.inc
@@ -13,6 +13,7 @@ function ssh_drush_command() {
       'site-alias' => 'A remote site alias. Can be an alias list.',
       'bash' => 'Bash to execute on target. Optional, except when site-alias is a list.',
     ),
+    'required-arguments' => 1,
     'options' => array(
       'ssh-options' => 'A string of extra options that will be passed to the ssh command (e.g. "-p 100")',
     ),
diff --git a/commands/core/variable.drush.inc b/commands/core/variable.drush.inc
index 3976bc9..e4968c4 100644
--- a/commands/core/variable.drush.inc
+++ b/commands/core/variable.drush.inc
@@ -35,6 +35,7 @@ function variable_drush_command() {
       'name' => 'The name of a variable or the first few letters of its name.',
       'value' => 'The value to assign to the variable. Use \'-\' to read the object from STDIN.',
     ),
+    'required-arguments' => TRUE,
     'options' => array(
       'yes' => 'Skip confirmation if only one variable name matches.',
       'always-set' => 'Always skip confirmation.',
@@ -52,6 +53,7 @@ function variable_drush_command() {
     'arguments' => array(
       'name' => 'The name of a variable or the first few letters of its name.',
     ),
+    'required-arguments' => TRUE,
     'options' => array(
       'yes' => 'Skip confirmation if only one variable name matches.',
     ),
diff --git a/commands/user/user.drush.inc b/commands/user/user.drush.inc
index 76eb796..23e5724 100644
--- a/commands/user/user.drush.inc
+++ b/commands/user/user.drush.inc
@@ -29,6 +29,7 @@ function user_drush_command() {
     'arguments' => array(
       'users' => 'A comma delimited list of uids, user names, or email addresses.',
     ),
+    'required-arguments' => TRUE,
     'options' => array(
       'full' => 'show extended information about the user',
       'short' => 'show basic information about the user (this is the default)',
@@ -41,6 +42,7 @@ function user_drush_command() {
     'arguments' => array(
       'users' => 'A comma delimited list of uids, user names, or email addresses.',
     ),
+    'required-arguments' => TRUE,
     'examples' => array(
       'drush user-block 5,user3 --uid=2,3 --name=someguy,somegal --mail=billgates@microsoft.com' =>
         'Block the users with name, id, or email 5 or user3, uids 2 and 3, names someguy and somegal, and email address of billgates@microsoft.com',
@@ -58,6 +60,7 @@ function user_drush_command() {
     'arguments' => array(
       'users' => 'A comma delimited list of uids, user names, or email addresses.',
     ),
+    'required-arguments' => TRUE,
     'examples' => array(
       'drush user-unblock 5,user3 --uid=2,3 --name=someguy,somegal --mail=billgates@microsoft.com' =>
         'Unblock the users with name, id, or email 5 or user3, uids 2 and 3, names someguy and somegal, and email address of billgates@microsoft.com',
@@ -76,6 +79,7 @@ function user_drush_command() {
       'role' => 'The name of the role to add',
       'users' => '(optional) A comma delimited list of uids, user names, or email addresses.',
     ),
+    'required-arguments' => 1,
     'examples' => array(
       'drush user-add-role "power user" 5,user3 --uid=2,3 --name=someguy,somegal --mail=billgates@microsoft.com' =>
         'Add the "power user" role to the accounts with name, id, or email 5 or user3, uids 2 and 3, names someguy and somegal, and email address of billgates@microsoft.com',
@@ -94,6 +98,7 @@ function user_drush_command() {
       'role' => 'The name of the role to remove',
       'users' => '(optional) A comma delimited list of uids, user names, or email addresses.',
     ),
+    'required-arguments' => 1,
     'examples' => array(
       'drush user-remove-role "power user" 5,user3 --uid=2,3 --name=someguy,somegal --mail=billgates@microsoft.com' =>
         'Remove the "power user" role from the accounts with name, id, or email 5 or user3, uids 2 and 3, names someguy and somegal, and email address of billgates@microsoft.com',
@@ -111,6 +116,7 @@ function user_drush_command() {
     'arguments' => array(
       'name' => 'The name of the account to add'
     ),
+    'required-arguments' => TRUE,
     'examples' => array(
       'drush user-create newuser --mail="person@example.com" --password="letmein"' =>
         'Create a new user account with the name newuser, the email address person@example.com, and the password letmein',
@@ -127,6 +133,7 @@ function user_drush_command() {
     'arguments' => array(
       'name' => 'The name of the account to cancel',
     ),
+    'required-arguments' => TRUE,
     'examples' => array(
       'drush user-cancel username' =>
         'Cancel the user account with the name username and anonymize all content created by that user.',
@@ -139,6 +146,7 @@ function user_drush_command() {
     'arguments' => array(
       'name' => 'The name of the account to modify.'
     ),
+    'required-arguments' => TRUE,
     'options' => array(
       'password' => array('required' => TRUE, 'description' => 'The new password for the account.'),
     ),
diff --git a/includes/command.inc b/includes/command.inc
index ff30e4b..add48bd 100644
--- a/includes/command.inc
+++ b/includes/command.inc
@@ -200,7 +200,7 @@ function drush_dispatch($command, $arguments = array()) {
 
     // Test to see if any of the options in the 'cli' context
     // are not represented in the command structure.
-    if (_drush_verify_cli_options($command) === FALSE) {
+    if ((_drush_verify_cli_options($command) === FALSE) || (_drush_verify_cli_arguments($command) === FALSE)) {
       return FALSE;
     }
 
@@ -294,6 +294,22 @@ function _drush_verify_cli_options($command) {
   return TRUE;
 }
 
+function _drush_verify_cli_arguments($command) {
+  // Check to see if all of the required arguments
+  // are specified.
+  if ($command['required-arguments']) {
+    $required_arg_count = $command['required-arguments'];
+    if ($required_arg_count === TRUE) {
+      $required_arg_count = count($command['argument-description']);
+    }
+    if ((count($command['arguments'])) < $required_arg_count) {
+      $missing = count($required_arg_count) > 1 ? dt('Missing required arguments') : dt('Missing required argument');
+      return drush_set_error(dt("@missing.  See `drush help @command` for information on usage.", array('@missing' => $missing, '@command' => $command['command'])));
+    }
+  }
+  return TRUE;
+}
+
 /**
  * Return the list of all of the options for the given
  * command record by merging the 'options' and 'sub-options'
@@ -711,6 +727,7 @@ function drush_command_defaults($key, $commandfile, $path) {
       'options' => 'Options',
     ),
     'arguments' => array(),
+    'required-arguments' => FALSE,
     'options' => array(),
     'sub-options' => array(),
     'allow-additional-options' => FALSE,
@@ -814,6 +831,10 @@ function drush_parse_command() {
  * this function.
  */
 function _drush_prepare_command(&$command, $arguments = array()) {
+  // Drush overloads $command['arguments']; save the argument description
+  if (!isset($command['argument-description'])) {
+    $command['argument-description'] = $command['arguments'];
+  }
   // Merge specified callback arguments, which precede the arguments passed on the command line.
   if (isset($command['callback arguments']) && is_array($command['callback arguments'])) {
     $arguments = array_merge($command['callback arguments'], $arguments);
