diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/Upgrade6Test.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/Upgrade6Test.php
index 4ee6cda5a7f..f5a681faa5f 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/Upgrade6Test.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/Upgrade6Test.php
@@ -93,7 +93,7 @@ protected function getEntityCounts() {
       'search_page' => 2,
       'shortcut' => 2,
       'shortcut_set' => 1,
-      'action' => 33,
+      'action' => 34,
       'menu' => 8,
       'path_alias' => 8,
       'taxonomy_term' => 15,
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7Test.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7Test.php
index 864c5dd8e47..0017ff7cda5 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7Test.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7Test.php
@@ -96,7 +96,7 @@ protected function getEntityCounts() {
       'search_page' => 2,
       'shortcut' => 6,
       'shortcut_set' => 2,
-      'action' => 27,
+      'action' => 28,
       'menu' => 7,
       'taxonomy_term' => 25,
       'taxonomy_vocabulary' => 8,
diff --git a/core/modules/user/config/install/system.action.user_welcome_message_action.yml b/core/modules/user/config/install/system.action.user_welcome_message_action.yml
new file mode 100644
index 00000000000..2f9ee18c349
--- /dev/null
+++ b/core/modules/user/config/install/system.action.user_welcome_message_action.yml
@@ -0,0 +1,10 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - user
+id: user_welcome_message_action
+label: 'Send the welcome message to the selected user(s)'
+type: user
+plugin: user_welcome_message_action
+configuration: {  }
diff --git a/core/modules/user/config/schema/user.schema.yml b/core/modules/user/config/schema/user.schema.yml
index 2f9bda44f28..6f9be423a61 100644
--- a/core/modules/user/config/schema/user.schema.yml
+++ b/core/modules/user/config/schema/user.schema.yml
@@ -150,6 +150,10 @@ action.configuration.user_remove_role_action:
       type: string
       label: 'The ID of the role to remove'
 
+action.configuration.user_welcome_message_action:
+  type: action_configuration_default
+  label: 'Send the welcome message to selected users configuration'
+
 action.configuration.user_unblock_user_action:
   type: action_configuration_default
   label: 'Unblock the selected users configuration'
diff --git a/core/modules/user/src/Plugin/Action/SendWelcomeMessage.php b/core/modules/user/src/Plugin/Action/SendWelcomeMessage.php
new file mode 100644
index 00000000000..0707e228c0e
--- /dev/null
+++ b/core/modules/user/src/Plugin/Action/SendWelcomeMessage.php
@@ -0,0 +1,95 @@
+<?php
+
+namespace Drupal\user\Plugin\Action;
+
+use Drupal\Core\Action\ActionBase;
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\user\UserInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Send welcome message to a user.
+ *
+ * @Action(
+ *   id = "user_welcome_message_action",
+ *   label = @Translation("Send welcome message to selected users"),
+ *   type = "user"
+ * )
+ */
+class SendWelcomeMessage extends ActionBase implements ContainerFactoryPluginInterface {
+
+  /**
+   * The config factory.
+   *
+   * @var \Drupal\Core\Config\ConfigFactoryInterface
+   */
+  protected $configFactory;
+
+  /**
+   * Constructs a new SendWelcomeMessage object.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin ID for the plugin instance.
+   * @param array $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   The configuration factory.
+   */
+  public function __construct(array $configuration, $plugin_id, array $plugin_definition, ConfigFactoryInterface $config_factory) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+    $this->configFactory = $config_factory;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('config.factory')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function execute($account = NULL) {
+    if (empty($account) || empty($account->getEmail())) {
+      return;
+    }
+
+    $op = 'register_pending_approval';
+    if ($account->isActive()) {
+      // Determine the user approval method.
+      switch ($this->configFactory->get('user.settings')->get('register')) {
+        case UserInterface::REGISTER_ADMINISTRATORS_ONLY:
+          $op = 'register_admin_created';
+          break;
+
+        case UserInterface::REGISTER_VISITORS:
+        default:
+          $op = 'register_no_approval_required';
+      }
+    }
+
+    _user_mail_notify($op, $account);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
+    /** @var \Drupal\user\UserInterface $object */
+    $access = $object->status->access('edit', $account, TRUE)
+      ->andIf($object->access('update', $account, TRUE));
+
+    return $return_as_object ? $access : $access->isAllowed();
+  }
+
+}
diff --git a/core/modules/user/src/ProfileForm.php b/core/modules/user/src/ProfileForm.php
index a1e15503604..769ec66d72b 100644
--- a/core/modules/user/src/ProfileForm.php
+++ b/core/modules/user/src/ProfileForm.php
@@ -25,6 +25,11 @@ protected function actions(array $form, FormStateInterface $form_state) {
     $element['delete']['#submit'] = ['::editCancelSubmit'];
     $element['delete']['#access'] = $account->id() > 1 && $account->access('delete');
 
+    $element['send']['#type'] = 'submit';
+    $element['send']['#value'] = $account->isActive() ? $this->t('Send welcome message') : $this->t('Send awaiting approval message');
+    $element['send']['#submit'] = ['::editSendSubmit'];
+    $element['send']['#access'] = $account->getEmail() && $this->currentUser()->hasPermission('administer users');
+
     return $element;
   }
 
@@ -57,4 +62,56 @@ public function editCancelSubmit($form, FormStateInterface $form_state) {
     );
   }
 
+  /**
+   * Provides a submit handler for the 'Send welcome message' button.
+   */
+  public function editSendSubmit(array $form, FormStateInterface $form_state) {
+    $account = $this->entity;
+
+    if (!$account->isActive()) {
+      $op = 'register_pending_approval';
+    }
+    else {
+      // Determine the user approval method.
+      switch (\Drupal::config('user.settings')->get('register')) {
+        case UserInterface::REGISTER_ADMINISTRATORS_ONLY:
+          $op = 'register_admin_created';
+          break;
+
+        case UserInterface::REGISTER_VISITORS:
+        default:
+          $op = 'register_no_approval_required';
+      }
+    }
+
+    // Notify the user via email.
+    $mail = _user_mail_notify($op, $account);
+
+    // Log the mail.
+    if (!empty($mail)) {
+      $this->getLogger('user')
+        ->notice('Welcome message has been sent to %name at %email.', [
+          '%name' => $account->getAccountName(),
+          '%email' => $account->getEmail(),
+        ]);
+      $this->messenger()
+        ->addMessage($this->t('Welcome message has been sent to %name at %email', [
+          '%name' => $account->getAccountName(),
+          '%email' => $account->getEmail(),
+        ]));
+    }
+    else {
+      $this->getLogger('user')
+        ->notice('There was an error sending the welcome message to %name at %email', [
+          '%name' => $account->getAccountName(),
+          '%email' => $account->getEmail(),
+        ]);
+      $this->messenger()
+        ->addMessage($this->t('There was an error sending the welcome message to %name at %email', [
+          '%name' => $account->getAccountName(),
+          '%email' => $account->getEmail(),
+        ]), 'error');
+    }
+  }
+
 }
diff --git a/core/modules/user/tests/src/Functional/UserAdminTest.php b/core/modules/user/tests/src/Functional/UserAdminTest.php
index 8fedf64f7c0..efa59fef66d 100644
--- a/core/modules/user/tests/src/Functional/UserAdminTest.php
+++ b/core/modules/user/tests/src/Functional/UserAdminTest.php
@@ -47,7 +47,6 @@ private static function getLinkSelectorForUser(UserInterface $user): string {
    * Registers a user and deletes it.
    */
   public function testUserAdmin() {
-    $config = $this->config('user.settings');
     $user_a = $this->drupalCreateUser();
     $user_a->name = 'User A';
     $user_a->mail = $this->randomMachineName() . '@example.com';
@@ -121,7 +120,7 @@ public function testUserAdmin() {
     $edit = [];
     $edit['action'] = 'user_block_user_action';
     $edit['user_bulk_form[4]'] = TRUE;
-    $config
+    $this->config('user.settings')
       ->set('notify.status_blocked', TRUE)
       ->save();
     $this->drupalGet('admin/people', [
@@ -188,10 +187,8 @@ public function testNotificationEmailAddress() {
     $this->assertSession()->responseContains('id="edit-mail-notification-address"');
     $this->drupalLogout();
 
-    // Test custom user registration approval email address(es).
-    $config = $this->config('user.settings');
     // Allow users to register with admin approval.
-    $config
+    $this->config('user.settings')
       ->set('verify_mail', TRUE)
       ->set('register', UserInterface::REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL)
       ->save();
@@ -229,4 +226,191 @@ public function testNotificationEmailAddress() {
     $this->assertCount(1, $user_mail, 'New user mail to user is sent from configured Notification Email address');
   }
 
+  /**
+   * Tests the sending of a welcome email notification.
+   *
+   * @dataProvider welcomeNotifications
+   */
+  public function testSendWelcomeEmailNotification($register_mode, $mail_id) {
+    $admin_user = $this->drupalCreateUser(['administer users']);
+    $this->drupalLogin($admin_user);
+
+    $this->config('user.settings')
+      ->set('register', $register_mode)
+      ->save();
+
+    // Create an active user.
+    $test_user = $this->drupalCreateUser();
+    $test_user->save();
+
+    // Send the welcome message.
+    $this->drupalGet('user/' . $test_user->id() . '/edit');
+    $this->submitForm(['status' => 0], 'Send welcome message');
+    $mails = $this->getMails();
+
+    // Assert that only one mail was sent to test_user.
+    $this->assertCount(1, $mails);
+
+    $this->assertEquals($mails[0]['to'], $test_user->getEmail(), 'Activation mail send to user');
+    $this->assertEquals($mails[0]['id'], $mail_id);
+  }
+
+  /**
+   * Collection of alternatives registrations configurations.
+   *
+   * @return array
+   *   List of registration config & expected user mail.
+   */
+  public function welcomeNotifications() {
+    return [
+      [
+        UserInterface::REGISTER_VISITORS,
+        'user_register_no_approval_required',
+      ],
+      [
+        UserInterface::REGISTER_ADMINISTRATORS_ONLY,
+        'user_register_admin_created',
+      ],
+      [
+        UserInterface::REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL,
+        'user_register_no_approval_required',
+      ],
+    ];
+  }
+
+  /**
+   * Tests the sending of a waiting approval email notification.
+   *
+   * @dataProvider awaitingApprovalNotifications
+   */
+  public function testSendAwaitingApprovalEmailNotification($register_mode, $mail_id) {
+    $admin_user = $this->drupalCreateUser(['administer users']);
+    $this->drupalLogin($admin_user);
+
+    $this->config('user.settings')
+      ->set('register', $register_mode)
+      ->save();
+
+    // Create a blocked user.
+    $blocked_user = $this->drupalCreateUser()->block();
+    $blocked_user->save();
+
+    $this->drupalGet('user/' . $blocked_user->id() . '/edit');
+    $this->submitForm(['status' => 0], 'Send awaiting approval message');
+    $mails = $this->getMails();
+
+    // Assert that an email was sent to a blocked user and admin.
+    $this->assertCount(2, $mails);
+    $this->assertEquals($mails[0]['to'], $blocked_user->getEmail(), 'Awaiting approval mail send to user');
+    $this->assertEquals($mails[0]['id'], $mail_id);
+    $this->assertEquals($mails[1]['to'], 'simpletest@example.com', 'Pending admin approval mail send to admin');
+    $this->assertEquals($mails[1]['id'], 'user_register_pending_approval_admin');
+  }
+
+  /**
+   * Returns a collection of alternative registration configurations.
+   *
+   * @return array
+   *   List of registration config & expected user mail.
+   */
+  public function awaitingApprovalNotifications() {
+    return [
+      [
+        UserInterface::REGISTER_VISITORS,
+        'user_register_pending_approval',
+      ],
+      [
+        UserInterface::REGISTER_ADMINISTRATORS_ONLY,
+        'user_register_pending_approval',
+      ],
+      [
+        UserInterface::REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL,
+        'user_register_pending_approval',
+      ],
+    ];
+  }
+
+  /**
+   * Tests the bulk action sending of welcome emails notifications.
+   */
+  public function testBulkSendWelcomeEmailsNotifications() {
+    $admin_user = $this->drupalCreateUser(['administer users']);
+    $this->drupalLogin($admin_user);
+
+    // Create users at a certain timestamp to fix order of "Member for".
+    $user_a = $this->drupalCreateUser();
+    $user_a->created = 1363219200;
+    $user_a->save();
+    $user_b = $this->drupalCreateUser();
+    $user_b->created = 1394755200;
+    $user_b->save();
+    $user_c = $this->drupalCreateUser();
+    $user_c->created = 1426291200;
+    $user_c->save();
+
+    // Send welcome message to user_b and user_c.
+    $edit = [
+      'action'            => 'user_welcome_message_action',
+      'user_bulk_form[3]' => TRUE,
+      'user_bulk_form[2]' => TRUE,
+    ];
+    $this->drupalGet('admin/people');
+    $this->submitForm($edit, 'Apply to selected items');
+    $mails = $this->getMails();
+
+    // Assert that welcome emails were sent to user_b and user_c.
+    $this->assertCount(2, $mails);
+    $this->assertEquals($mails[0]['to'], $user_c->getEmail(), 'Activation mail send to user C');
+    $this->assertEquals($mails[0]['id'], 'user_register_no_approval_required');
+    $this->assertEquals($mails[1]['to'], $user_b->getEmail(), 'Activation mail send to user B');
+    $this->assertEquals($mails[1]['id'], 'user_register_no_approval_required');
+  }
+
+  /**
+   * Tests the bulk action sending of waiting approval email notification.
+   */
+  public function testBulkSendAwaitingApprovalEmailNotification() {
+    $admin_user = $this->drupalCreateUser(['administer users']);
+    $this->drupalLogin($admin_user);
+
+    // Create users at a certain timestamp to fix order of "Member for".
+    $user_a = $this->drupalCreateUser()->block();
+    $user_a->created = 1363219200;
+    $user_a->save();
+    $user_b = $this->drupalCreateUser()->block();
+    $user_b->created = 1394755200;
+    $user_b->save();
+    $user_c = $this->drupalCreateUser()->block();
+    $user_c->created = 1426291200;
+    $user_c->save();
+
+    // Send waiting approval mail to user_b & user_c.
+    $edit = [
+      'action'            => 'user_welcome_message_action',
+      'user_bulk_form[3]' => TRUE,
+      'user_bulk_form[2]' => TRUE,
+    ];
+    $this->drupalGet('admin/people');
+    $this->submitForm($edit, ('Apply to selected items'));
+    $mails = $this->getMails();
+
+    // Assert that welcome emails were sent to user_b and user_c.
+    // The admin should be notified twice.
+    $this->assertCount(4, $mails);
+
+    // Assert that awaiting approval and notification emails have been sent to
+    // user_b and user_c.
+    $this->assertEquals($mails[0]['id'], 'user_register_pending_approval');
+    $this->assertEquals($mails[0]['to'], $user_c->getEmail(), 'Awaiting approval mail send to user C');
+    // Admin notification about user C notification send.
+    $this->assertEquals($mails[1]['id'], 'user_register_pending_approval_admin');
+    $this->assertEquals($mails[1]['to'], 'simpletest@example.com', 'Pending admin approval mail send to admin');
+    // Awaiting approval mail send to user B.
+    $this->assertEquals($mails[2]['id'], 'user_register_pending_approval');
+    $this->assertEquals($mails[2]['to'], $user_b->getEmail(), 'Awaiting approval mail send to user B');
+    // Admin notification about user B notification send.
+    $this->assertEquals($mails[3]['id'], 'user_register_pending_approval_admin');
+    $this->assertEquals($mails[3]['to'], 'simpletest@example.com', 'Pending admin approval mail send to admin');
+  }
+
 }
diff --git a/core/modules/user/tests/src/Functional/UserSendTest.php b/core/modules/user/tests/src/Functional/UserSendTest.php
new file mode 100644
index 00000000000..4832677e8d2
--- /dev/null
+++ b/core/modules/user/tests/src/Functional/UserSendTest.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace Drupal\Tests\user\Functional;
+
+use Drupal\Tests\BrowserTestBase;
+
+/**
+ * Tests the user send element access on administration page.
+ *
+ * @group user
+ */
+class UserSendTest extends BrowserTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'stark';
+
+  /**
+   * Tests the access to email notifications form element.
+   */
+  public function testSendWelcomeEmailAccess() {
+    $admin_user = $this->drupalCreateUser(['administer users']);
+    $this->drupalLogin($admin_user);
+
+    // Create an active user without email.
+    $name = $this->randomMachineName();
+    $edit = [
+      'name' => $name,
+      'pass[pass1]' => $pass = $this->randomString(),
+      'pass[pass2]' => $pass,
+      'notify' => FALSE,
+    ];
+    $this->drupalGet('admin/people/create');
+    $this->submitForm($edit, 'Create new account');
+    $account = user_load_by_name($edit['name']);
+    $this->drupalGet('user/' . $account->id() . '/edit');
+    // Send button is not displayed.
+    $this->assertSession()->responseNotContains('Send welcome message');
+
+    // Create an active user with email.
+    $test_user = $this->drupalCreateUser();
+    $test_user->save();
+    $this->drupalGet('user/' . $test_user->id() . '/edit');
+    // Send button is displayed.
+    $this->assertSession()->responseContains('Send welcome message');
+  }
+
+}
diff --git a/core/modules/user/user.post_update.php b/core/modules/user/user.post_update.php
index 14662df8ef0..f47070ecb04 100644
--- a/core/modules/user/user.post_update.php
+++ b/core/modules/user/user.post_update.php
@@ -9,6 +9,8 @@
 use Drupal\Core\StringTranslation\PluralTranslatableMarkup;
 use Drupal\user\Entity\Role;
 
+use Drupal\system\Entity\Action;
+
 /**
  * Implements hook_removed_post_updates().
  */
@@ -47,3 +49,17 @@ function user_post_update_update_roles(&$sandbox = NULL) {
     );
   }
 }
+
+/**
+ * Add an action to send activation emails to multiple users.
+ */
+function user_post_update_add_send_action() {
+  $action = Action::create([
+    'id' => 'user_welcome_message_action',
+    'type' => 'user',
+    'label' => 'Send the welcome message to the selected user(s)',
+    'configuration' => [],
+    'plugin' => 'user_welcome_message_action',
+  ]);
+  $action->trustData()->save();
+}
