diff --git a/core/Command/User/AddAppPassword.php b/core/Command/User/AddAppPassword.php
new file mode 100644
index 0000000000000000000000000000000000000000..d7011342030e482ccfab156f787d173e143c6461
--- /dev/null
+++ b/core/Command/User/AddAppPassword.php
@@ -0,0 +1,137 @@
+<?php
+/**
+ * @copyright Copyright (c) 2020, NextCloud, Inc.
+ *
+ * @author Andreas Fischer <bantu@owncloud.com>
+ * @author Christopher Schäpers <kondou@ts.unde.re>
+ * @author Clark Tomlinson <fallen013@gmail.com>
+ * @author Joas Schilling <coding@schilljs.com>
+ * @author Laurens Post <lkpost@scept.re>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ * @author Sujith H <sharidasan@owncloud.com>
+ * @author Sean Molenaar <sean@seanmolenaar.eu>
+ *
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\Core\Command\User;
+
+use OC\Authentication\Token\IProvider;
+use OC\Authentication\Token\IToken;
+use OCP\IUserManager;
+use OCP\Security\ICrypto;
+use OCP\Security\ISecureRandom;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Helper\QuestionHelper;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Question\Question;
+
+class AddAppPassword extends Command {
+
+	/** @var IUserManager */
+	protected $userManager;
+	/** @var IProvider */
+	protected $tokenProvider;
+	/** @var ISecureRandom */
+	private $random;
+	/** @var ICrypto */
+	private $crypto;
+
+	public function __construct(IUserManager $userManager,
+								IProvider $tokenProvider,
+								ISecureRandom $random,
+								ICrypto $crypto) {
+		$this->tokenProvider = $tokenProvider;
+		$this->userManager = $userManager;
+		$this->random = $random;
+		$this->crypto = $crypto;
+		parent::__construct();
+	}
+
+	protected function configure() {
+		$this
+			->setName('user:add-app-password')
+			->setDescription('Add app password for the named user')
+			->addArgument(
+				'user',
+				InputArgument::REQUIRED,
+				'Username to add app password for'
+			)
+			->addOption(
+				'password-from-env',
+				null,
+				InputOption::VALUE_NONE,
+				'read password from environment variable NC_PASS/OC_PASS'
+			)
+		;
+	}
+
+	protected function execute(InputInterface $input, OutputInterface $output): int {
+		$username = $input->getArgument('user');
+
+		$user = $this->userManager->get($username);
+		if (is_null($user)) {
+			$output->writeln('<error>User does not exist</error>');
+			return 1;
+		}
+
+		if ($input->getOption('password-from-env')) {
+			$password = getenv('NC_PASS') ?? getenv('OC_PASS');
+			if (!$password) {
+				$output->writeln('<error>--password-from-env given, but NC_PASS is empty!</error>');
+				return 1;
+			}
+		} elseif ($input->isInteractive()) {
+			/** @var QuestionHelper $helper */
+			$helper = $this->getHelper('question');
+
+			$question = new Question('Enter the user password: ');
+			$question->setHidden(true);
+			$password = $helper->ask($input, $output, $question);
+
+			if ($password === null) {
+				$output->writeln("<error>Password cannot be empty!</error>");
+				return 1;
+			}
+		} else {
+			$output->writeln("<error>Interactive input or --password-from-env is needed for entering a new password!</error>");
+			return 1;
+		}
+
+		$output->writeln('<info>The password is not validated so what you provide is what gets recorded in the token</info>');
+
+
+		$token = $this->random->generate(72, ISecureRandom::CHAR_UPPER.ISecureRandom::CHAR_LOWER.ISecureRandom::CHAR_DIGITS);
+		$this->tokenProvider->generateToken(
+			$token,
+			$user->getUID(),
+			$user->getDisplayName(),
+			$password,
+			'cli',
+			IToken::PERMANENT_TOKEN,
+			IToken::DO_NOT_REMEMBER
+		);
+
+		$output->writeln('app password:');
+		$output->writeln($token);
+
+		return 0;
+	}
+}
diff --git a/core/register_command.php b/core/register_command.php
index dc53c7290670381433e2a2ac2586b5c7ef332a6e..fe998020d20728454e5de83722ae6651e6763a9c 100644
--- a/core/register_command.php
+++ b/core/register_command.php
@@ -45,6 +45,7 @@
  */
 
 /** @var Symfony\Component\Console\Application $application */
+
 $application->add(new \Stecman\Component\Symfony\Console\BashCompletion\CompletionCommand());
 $application->add(new OC\Core\Command\Status);
 $application->add(new OC\Core\Command\Check(\OC::$server->getSystemConfig()));
@@ -178,6 +179,7 @@ if (\OC::$server->getConfig()->getSystemValue('installed', false)) {
 	$application->add(new OC\Core\Command\User\Setting(\OC::$server->getUserManager(), \OC::$server->getConfig(), \OC::$server->getDatabaseConnection()));
 	$application->add(new OC\Core\Command\User\ListCommand(\OC::$server->getUserManager(), \OC::$server->getGroupManager()));
 	$application->add(new OC\Core\Command\User\Info(\OC::$server->getUserManager(), \OC::$server->getGroupManager()));
+	$application->add(new OC\Core\Command\User\AddAppPassword(\OC::$server->get(\OCP\IUserManager::class), \OC::$server->get(\OC\Authentication\Token\IProvider::class), \OC::$server->get(\OCP\Security\ISecureRandom::class), \OC::$server->get(\OCP\Security\ICrypto::class)));
 
 	$application->add(new OC\Core\Command\Group\Add(\OC::$server->getGroupManager()));
 	$application->add(new OC\Core\Command\Group\Delete(\OC::$server->getGroupManager()));
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index 4193aef1fda640b06989ba61b4f7946a7e345aef..3a65a05c5a9c4fc2071dac9986024680157d409c 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -863,6 +863,7 @@ return array(
     'OC\\Core\\Command\\TwoFactorAuth\\State' => $baseDir . '/core/Command/TwoFactorAuth/State.php',
     'OC\\Core\\Command\\Upgrade' => $baseDir . '/core/Command/Upgrade.php',
     'OC\\Core\\Command\\User\\Add' => $baseDir . '/core/Command/User/Add.php',
+    'OC\\Core\\Command\\User\\AddAppPassword' => $baseDir . '/core/Command/User/AddAppPassword.php',
     'OC\\Core\\Command\\User\\Delete' => $baseDir . '/core/Command/User/Delete.php',
     'OC\\Core\\Command\\User\\Disable' => $baseDir . '/core/Command/User/Disable.php',
     'OC\\Core\\Command\\User\\Enable' => $baseDir . '/core/Command/User/Enable.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index da56fe2d8b64d39da5796ce9ce8a999921488a3f..521991cff733f8ec75fda3bd2dd9abaed9cbd4ce 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -892,6 +892,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
         'OC\\Core\\Command\\TwoFactorAuth\\State' => __DIR__ . '/../../..' . '/core/Command/TwoFactorAuth/State.php',
         'OC\\Core\\Command\\Upgrade' => __DIR__ . '/../../..' . '/core/Command/Upgrade.php',
         'OC\\Core\\Command\\User\\Add' => __DIR__ . '/../../..' . '/core/Command/User/Add.php',
+        'OC\\Core\\Command\\User\\AddAppPassword' => __DIR__ . '/../../..' . '/core/Command/User/AddAppPassword.php',
         'OC\\Core\\Command\\User\\Delete' => __DIR__ . '/../../..' . '/core/Command/User/Delete.php',
         'OC\\Core\\Command\\User\\Disable' => __DIR__ . '/../../..' . '/core/Command/User/Disable.php',
         'OC\\Core\\Command\\User\\Enable' => __DIR__ . '/../../..' . '/core/Command/User/Enable.php',