diff --git a/docs/docs/cmd/spo/tenant/tenant-homesite-add.mdx b/docs/docs/cmd/spo/tenant/tenant-homesite-add.mdx
new file mode 100644
index 00000000000..dac2dc98860
--- /dev/null
+++ b/docs/docs/cmd/spo/tenant/tenant-homesite-add.mdx
@@ -0,0 +1,97 @@
+import Global from '/docs/cmd/_global.mdx';
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+# spo tenant homesite add
+
+Add a Home Site.
+
+## Usage
+
+```sh
+m365 spo tenant homesite add [options]
+```
+
+## Options
+
+
+
+## Examples
+
+Add a Home Site
+
+```sh
+m365 spo tenant homesite add --url "https://contoso.sharepoint.com/sites/testcomms"
+
+```
+
+## Response
+
+
+
+
+ ```json
+ {
+ "Audiences": [],
+ "IsInDraftMode": true,
+ "IsVivaBackendSite": false,
+ "SiteId": "ca49054c-85f3-41eb-a290-46ffda8f219c",
+ "TargetedLicenseType": 0,
+ "Title": "testcommsite",
+ "Url": "https://contoso.sharepoint.com/sites/testcomms",
+ "VivaConnectionsDefaultStart": false,
+ "WebId": "256c4f0f-e372-47b4-a891-b4888e829e20"
+ }
+ ```
+
+
+
+
+ ```text
+ Audiences : []
+ IsInDraftMode : true
+ IsVivaBackendSite : false
+ SiteId : ca49054c-85f3-41eb-a290-46ffda8f219c
+ TargetedLicenseType : 0
+ Title : testcommsite
+ Url : https://contoso.sharepoint.com/sites/testcomms
+ VivaConnectionsDefaultStart: false
+ WebId : 256c4f0f-e372-47b4-a891-b4888e829e20
+ ```
+
+
+
+
+ ```csv
+ IsInDraftMode,IsVivaBackendSite,SiteId,TargetedLicenseType,Title,Url,VivaConnectionsDefaultStart,WebId
+ 1,0,ca49054c-85f3-41eb-a290-46ffda8f219c,0,testcommsite,https://contoso.sharepoint.com/sites/testcomms,0,256c4f0f-e372-47b4-a891-b4888e829e20
+ ```
+
+
+
+
+ ```md
+ # spo tenant homesite add --url "https://contoso.sharepoint.com/sites/testcomms"
+
+ Date: 12/23/2024
+
+ ## testcommsite (https://contoso.sharepoint.com/sites/testcomms)
+
+ Property | Value
+ ---------|-------
+ IsInDraftMode | true
+ IsVivaBackendSite | false
+ SiteId | ca49054c-85f3-41eb-a290-46ffda8f219c
+ TargetedLicenseType | 0
+ Title | testcommsite
+ Url | https://contoso.sharepoint.com/sites/testcomms
+ VivaConnectionsDefaultStart | false
+ WebId | 256c4f0f-e372-47b4-a891-b4888e829e20
+ ```
+
+
+
+## More information
+
+- SharePoint home sites [Viva Connections set up](https://learn.microsoft.com/en-us/viva/connections/set-up-admin-center)
+
diff --git a/docs/src/config/sidebars.ts b/docs/src/config/sidebars.ts
index 68fa5ec4249..f6162777e22 100644
--- a/docs/src/config/sidebars.ts
+++ b/docs/src/config/sidebars.ts
@@ -3766,6 +3766,11 @@ const sidebars: SidebarsConfig = {
label: 'tenant commandset set',
id: 'cmd/spo/tenant/tenant-commandset-set'
},
+ {
+ type: 'doc',
+ label: 'tenant homesite add',
+ id: 'cmd/spo/tenant/tenant-homesite-add'
+ },
{
type: 'doc',
label: 'tenant homesite list',
diff --git a/src/m365/spo/commands.ts b/src/m365/spo/commands.ts
index f17b2edca20..b8bbb1165cc 100644
--- a/src/m365/spo/commands.ts
+++ b/src/m365/spo/commands.ts
@@ -318,6 +318,7 @@ export default {
TENANT_COMMANDSET_LIST: `${prefix} tenant commandset list`,
TENANT_COMMANDSET_REMOVE: `${prefix} tenant commandset remove`,
TENANT_COMMANDSET_SET: `${prefix} tenant commandset set`,
+ TENANT_HOMESITE_ADD: `${prefix} tenant homesite add`,
TENANT_HOMESITE_LIST: `${prefix} tenant homesite list`,
TENANT_RECYCLEBINITEM_LIST: `${prefix} tenant recyclebinitem list`,
TENANT_RECYCLEBINITEM_REMOVE: `${prefix} tenant recyclebinitem remove`,
diff --git a/src/m365/spo/commands/tenant/tenant-homesite-add.spec.ts b/src/m365/spo/commands/tenant/tenant-homesite-add.spec.ts
new file mode 100644
index 00000000000..c86c4040323
--- /dev/null
+++ b/src/m365/spo/commands/tenant/tenant-homesite-add.spec.ts
@@ -0,0 +1,116 @@
+import assert from 'assert';
+import sinon from 'sinon';
+import auth from '../../../../Auth.js';
+import { cli } from '../../../../cli/cli.js';
+import { Logger } from '../../../../cli/Logger.js';
+import { CommandError } from '../../../../Command.js';
+import { CommandInfo } from '../../../../cli/CommandInfo.js';
+import request from '../../../../request.js';
+import { telemetry } from '../../../../telemetry.js';
+import { pid } from '../../../../utils/pid.js';
+import { session } from '../../../../utils/session.js';
+import { sinonUtil } from '../../../../utils/sinonUtil.js';
+import commands from '../../commands.js';
+import command from './tenant-homesite-add.js';
+
+describe(commands.TENANT_HOMESITE_ADD, () => {
+ let log: string[];
+ let logger: Logger;
+ let loggerLogSpy: sinon.SinonSpy;
+ let commandInfo: CommandInfo;
+ const homeSite = "https://contoso.sharepoint.com/sites/testcomms";
+ const homeSites = {
+ "Audiences": [],
+ "IsInDraftMode": true,
+ "IsVivaBackendSite": false,
+ "SiteId": "ca49054c-85f3-41eb-a290-46ffda8f219c",
+ "TargetedLicenseType": 0,
+ "Title": "testcommsite",
+ "Url": homeSite,
+ "VivaConnectionsDefaultStart": false,
+ "WebId": "256c4f0f-e372-47b4-a891-b4888e829e20"
+ };
+
+ before(() => {
+ sinon.stub(auth, 'restoreAuth').resolves();
+ sinon.stub(telemetry, 'trackEvent').returns();
+ sinon.stub(pid, 'getProcessName').returns('');
+ sinon.stub(session, 'getId').returns('');
+ auth.connection.active = true;
+ auth.connection.spoUrl = 'https://contoso.sharepoint.com';
+ });
+
+ beforeEach(() => {
+ log = [];
+ logger = {
+ log: async (msg: string) => {
+ log.push(msg);
+ },
+ logRaw: async (msg: string) => {
+ log.push(msg);
+ },
+ logToStderr: async (msg: string) => {
+ log.push(msg);
+ }
+ };
+ loggerLogSpy = sinon.spy(logger, 'log');
+ commandInfo = cli.getCommandInfo(command);
+ });
+
+ afterEach(() => {
+ sinonUtil.restore([
+ request.post
+ ]);
+ });
+
+ after(() => {
+ sinon.restore();
+ auth.connection.active = false;
+ auth.connection.spoUrl = undefined;
+ });
+
+ it('has correct name', () => {
+ assert.strictEqual(command.name, commands.TENANT_HOMESITE_ADD);
+ });
+
+ it('has a description', () => {
+ assert.notStrictEqual(command.description, null);
+ });
+
+ it('adds available home sites', async () => {
+ sinon.stub(request, 'post').callsFake(async (opts) => {
+ if (opts.url === `https://contoso-admin.sharepoint.com/_api/SPO.Tenant/AddHomeSite`) {
+ return homeSites;
+ }
+
+ throw opts.url;
+ });
+
+ await command.action(logger, { options: { url: homeSite, verbose: true } });
+ assert(loggerLogSpy.calledWith(homeSites));
+ });
+
+ it('fails validation if the url is not a valid SharePoint url', async () => {
+ const actual = await command.validate({
+ options: {
+ url: "test"
+ }
+ }, commandInfo);
+ assert.notStrictEqual(actual, true);
+ });
+
+ it('passes validation', async () => {
+ const actual = await command.validate({
+ options: {
+ url: homeSite
+ }
+ }, commandInfo);
+ assert.strictEqual(actual, true);
+ });
+
+ it('correctly handles OData error when adding a home site', async () => {
+ sinon.stub(request, 'post').rejects({ error: { 'odata.error': { message: { value: 'An error has occurred' } } } });
+
+ await assert.rejects(command.action(logger, { options: {} } as any), new CommandError('An error has occurred'));
+ });
+});
diff --git a/src/m365/spo/commands/tenant/tenant-homesite-add.ts b/src/m365/spo/commands/tenant/tenant-homesite-add.ts
new file mode 100644
index 00000000000..f3acf17581e
--- /dev/null
+++ b/src/m365/spo/commands/tenant/tenant-homesite-add.ts
@@ -0,0 +1,87 @@
+import { Logger } from '../../../../cli/Logger.js';
+import GlobalOptions from '../../../../GlobalOptions.js';
+import { spo } from '../../../../utils/spo.js';
+import { validation } from '../../../../utils/validation.js';
+import SpoCommand from '../../../base/SpoCommand.js';
+import commands from '../../commands.js';
+import request, { CliRequestOptions } from '../../../../request.js';
+
+interface CommandArgs {
+ options: Options;
+}
+
+interface Options extends GlobalOptions {
+ url: string;
+}
+
+class SpoTenantHomeSiteAddCommand extends SpoCommand {
+ public get name(): string {
+ return commands.TENANT_HOMESITE_ADD;
+ }
+
+ public get description(): string {
+ return 'Add a Home Site';
+ }
+
+ constructor() {
+ super();
+
+ this.#initTelemetry();
+ this.#initOptions();
+ this.#initValidators();
+ }
+
+ #initTelemetry(): void {
+ this.telemetry.push((args: CommandArgs) => {
+ Object.assign(this.telemetryProperties, {
+ url: args.options.url
+ });
+ });
+ }
+
+ #initOptions(): void {
+ this.options.unshift(
+ {
+ option: '-u, --url '
+ }
+ );
+ }
+
+ #initValidators(): void {
+ this.validators.push(
+ async (args: CommandArgs) => {
+ const isValidSharePointUrl: boolean | string = validation.isValidSharePointUrl(args.options.url);
+ if (isValidSharePointUrl !== true) {
+ return isValidSharePointUrl;
+ }
+ return true;
+ }
+ );
+ }
+
+ public async commandAction(logger: Logger, args: CommandArgs): Promise {
+ try {
+ const spoAdminUrl: string = await spo.getSpoAdminUrl(logger, this.verbose);
+ const requestOptions: CliRequestOptions = {
+ url: `${spoAdminUrl}/_api/SPO.Tenant/AddHomeSite`,
+ headers: {
+ accept: 'application/json;odata=nometadata'
+ },
+ responseType: 'json',
+ data: {
+ homeSiteUrl: args.options.url
+ }
+ };
+ if (this.verbose) {
+ await logger.logToStderr(`Adding the home site...`);
+ }
+ const res = await request.post(requestOptions);
+ await logger.log(res);
+ }
+ catch (err: any) {
+ this.handleRejectedODataJsonPromise(err);
+ }
+ }
+}
+
+export default new SpoTenantHomeSiteAddCommand();
\ No newline at end of file