diff --git a/docs/docs/cmd/spo/site/site-list.mdx b/docs/docs/cmd/spo/site/site-list.mdx
index eebe060ee7d..9c19e21bb24 100644
--- a/docs/docs/cmd/spo/site/site-list.mdx
+++ b/docs/docs/cmd/spo/site/site-list.mdx
@@ -16,7 +16,7 @@ m365 spo site list [options]
```md definition-list
`-t, --type [type]`
-: convenience option for type of sites to list. Allowed values are `TeamSite,CommunicationSite`.
+: convenience option for type of sites to list. Allowed values are `TeamSite,CommunicationSite,fullyArchived,recentlyArchived,archived`.
`--webTemplate [webTemplate]`
: type of sites to list. To be used with values like `GROUP#0` and `SITEPAGEPUBLISHING#0`. Specify either `type` or `webTemplate`, but not both.
@@ -31,6 +31,11 @@ m365 spo site list [options]
## Remarks
+When providing a value for option `type`, consider the following:
+
+- `fullyArchived`: return sites that are fully archived (longer than 7 days)
+- `recentlyArchived`: return sites that are recently archived (within 7 days)
+- `archived`: return both recently archived and fully archived sites
Using the `--filter` option you can specify which sites you want to retrieve. For example, to get sites with _project_ in their URL, use `Url -like 'project'` as the filter.
diff --git a/src/m365/spo/commands/site/site-list.spec.ts b/src/m365/spo/commands/site/site-list.spec.ts
index 221fa46478f..f06f1c7fd89 100644
--- a/src/m365/spo/commands/site/site-list.spec.ts
+++ b/src/m365/spo/commands/site/site-list.spec.ts
@@ -1,4 +1,5 @@
import assert from 'assert';
+import { z } from 'zod';
import sinon from 'sinon';
import auth from '../../../../Auth.js';
import { cli } from '../../../../cli/cli.js';
@@ -20,6 +21,7 @@ describe(commands.SITE_LIST, () => {
let logger: Logger;
let loggerLogSpy: sinon.SinonSpy;
let commandInfo: CommandInfo;
+ let commandOptionsSchema: z.ZodTypeAny;
before(() => {
sinon.stub(auth, 'restoreAuth').resolves();
@@ -30,6 +32,7 @@ describe(commands.SITE_LIST, () => {
auth.connection.active = true;
auth.connection.spoUrl = 'https://contoso.sharepoint.com';
commandInfo = cli.getCommandInfo(command);
+ commandOptionsSchema = commandInfo.command.getSchemaToParse()!;
});
beforeEach(() => {
@@ -72,39 +75,34 @@ describe(commands.SITE_LIST, () => {
assert.deepStrictEqual(command.defaultProperties(), ['Title', 'Url']);
});
- it('passes validation if type TeamSite specified', async () => {
- const actual = await command.validate({ options: { type: 'TeamSite' } }, commandInfo);
- assert.strictEqual(actual, true);
- });
-
- it('passes validation if type CommunicationSite specified', async () => {
- const actual = await command.validate({ options: { type: 'CommunicationSite' } }, commandInfo);
- assert.strictEqual(actual, true);
+ it('fails when type is invalid', () => {
+ const parsed = commandOptionsSchema.safeParse({ type: 'invalid' });
+ assert.strictEqual(parsed.success, false);
});
- it('fails validation if non existing type specified', async () => {
- const actual = await command.validate({ options: { type: 'invalid' } }, commandInfo);
- assert.notStrictEqual(actual, true);
+ it('fails when both type and webTemplate are specified', () => {
+ const parsed = commandOptionsSchema.safeParse({ type: 'TeamSite', webTemplate: 'STS#3' });
+ assert.strictEqual(parsed.success, false);
});
- it('fails validation if type and webTemplate are both specified', async () => {
- const actual = await command.validate({ options: { type: 'TeamSite', webTemplate: 'STS#3' } }, commandInfo);
- assert.notStrictEqual(actual, true);
+ it('fails when withOneDriveSites is used with type', () => {
+ const parsed = commandOptionsSchema.safeParse({ type: 'TeamSite', withOneDriveSites: true });
+ assert.strictEqual(parsed.success, false);
});
- it('fails validation if withOneDriveSites is specified together with the type option', async () => {
- const actual = await command.validate({ options: { type: 'TeamSite', withOneDriveSites: '1' } }, commandInfo);
- assert.notStrictEqual(actual, true);
+ it('fails when withOneDriveSites is used with webTemplate', () => {
+ const parsed = commandOptionsSchema.safeParse({ webTemplate: 'STS#3', withOneDriveSites: true });
+ assert.strictEqual(parsed.success, false);
});
- it('fails validation if withOneDriveSites is specified together with the webTemplate option', async () => {
- const actual = await command.validate({ options: { webTemplate: 'STS#3', withOneDriveSites: '1' } }, commandInfo);
- assert.notStrictEqual(actual, true);
+ it('passes when only withOneDriveSites is set', () => {
+ const parsed = commandOptionsSchema.safeParse({ withOneDriveSites: true });
+ assert.strictEqual(parsed.success, true);
});
it('retrieves list of sites when no type and no filter specified', async () => {
sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_vti_bin/client.svc/ProcessQuery`) > -1) {
+ if (opts.url === `https://contoso-admin.sharepoint.com/_vti_bin/client.svc/ProcessQuery`) {
if (opts.headers &&
opts.headers['X-RequestDigest'] &&
opts.headers['X-RequestDigest'] === 'abc' &&
@@ -144,7 +142,7 @@ describe(commands.SITE_LIST, () => {
it('retrieves list of sites when no type and no filter specified (debug)', async () => {
sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_vti_bin/client.svc/ProcessQuery`) > -1) {
+ if (opts.url === `https://contoso-admin.sharepoint.com/_vti_bin/client.svc/ProcessQuery`) {
if (opts.headers &&
opts.headers['X-RequestDigest'] &&
opts.headers['X-RequestDigest'] === 'abc' &&
@@ -184,7 +182,7 @@ describe(commands.SITE_LIST, () => {
it('retrieves list of sites when type TeamSite is specified', async () => {
sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_vti_bin/client.svc/ProcessQuery`) > -1) {
+ if (opts.url === `https://contoso-admin.sharepoint.com/_vti_bin/client.svc/ProcessQuery`) {
if (opts.headers &&
opts.headers['X-RequestDigest'] &&
opts.headers['X-RequestDigest'] === 'abc' &&
@@ -224,7 +222,7 @@ describe(commands.SITE_LIST, () => {
it('retrieves list of sites when type CommunicationSite is specified', async () => {
sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_vti_bin/client.svc/ProcessQuery`) > -1) {
+ if (opts.url === `https://contoso-admin.sharepoint.com/_vti_bin/client.svc/ProcessQuery`) {
if (opts.headers &&
opts.headers['X-RequestDigest'] &&
opts.headers['X-RequestDigest'] === 'abc' &&
@@ -264,7 +262,7 @@ describe(commands.SITE_LIST, () => {
it('retrieves list of all sites when results returned in multiple pages', async () => {
sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_vti_bin/client.svc/ProcessQuery`) > -1) {
+ if (opts.url === `https://contoso-admin.sharepoint.com/_vti_bin/client.svc/ProcessQuery`) {
if (opts.headers &&
opts.headers['X-RequestDigest'] &&
opts.headers['X-RequestDigest'] === 'abc' &&
@@ -332,7 +330,7 @@ describe(commands.SITE_LIST, () => {
it('includes all properties for json output', async () => {
sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_vti_bin/client.svc/ProcessQuery`) > -1) {
+ if (opts.url === `https://contoso-admin.sharepoint.com/_vti_bin/client.svc/ProcessQuery`) {
if (opts.headers &&
opts.headers['X-RequestDigest'] &&
opts.headers['X-RequestDigest'] === 'abc' &&
@@ -372,7 +370,7 @@ describe(commands.SITE_LIST, () => {
it('retrieves list of sites when STS#0 type and no filter specified', async () => {
sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_vti_bin/client.svc/ProcessQuery`) > -1) {
+ if (opts.url === `https://contoso-admin.sharepoint.com/_vti_bin/client.svc/ProcessQuery`) {
if (opts.headers &&
opts.headers['X-RequestDigest'] &&
opts.headers['X-RequestDigest'] === 'abc' &&
@@ -412,7 +410,7 @@ describe(commands.SITE_LIST, () => {
it('retrieves list of sites when no type and filter specified', async () => {
sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_vti_bin/client.svc/ProcessQuery`) > -1) {
+ if (opts.url === `https://contoso-admin.sharepoint.com/_vti_bin/client.svc/ProcessQuery`) {
if (opts.headers &&
opts.headers['X-RequestDigest'] &&
opts.headers['X-RequestDigest'] === 'abc' &&
@@ -452,7 +450,7 @@ describe(commands.SITE_LIST, () => {
it('retrieves list of sites when no filter and withOneDriveSites is specified', async () => {
sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_vti_bin/client.svc/ProcessQuery`) > -1) {
+ if (opts.url === `https://contoso-admin.sharepoint.com/_vti_bin/client.svc/ProcessQuery`) {
if (opts.headers &&
opts.headers['X-RequestDigest'] &&
opts.headers['X-RequestDigest'] === 'abc' &&
@@ -492,7 +490,7 @@ describe(commands.SITE_LIST, () => {
it('retrieves list of sites when STS#0 webTemplate and filter specified', async () => {
sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_vti_bin/client.svc/ProcessQuery`) > -1) {
+ if (opts.url === `https://contoso-admin.sharepoint.com/_vti_bin/client.svc/ProcessQuery`) {
if (opts.headers &&
opts.headers['X-RequestDigest'] &&
opts.headers['X-RequestDigest'] === 'abc' &&
@@ -532,7 +530,7 @@ describe(commands.SITE_LIST, () => {
it('escapes XML in the filter', async () => {
sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_vti_bin/client.svc/ProcessQuery`) > -1) {
+ if (opts.url === `https://contoso-admin.sharepoint.com/_vti_bin/client.svc/ProcessQuery`) {
if (opts.headers &&
opts.headers['X-RequestDigest'] &&
opts.headers['X-RequestDigest'] === 'abc' &&
@@ -570,6 +568,145 @@ describe(commands.SITE_LIST, () => {
]));
});
+ it('passes validation if type fullyArchived specified', async () => {
+ const actual = await command.validate({ options: { type: 'fullyArchived' } }, commandInfo);
+ assert.strictEqual(actual, true);
+ });
+
+ it('passes validation if type recentlyArchived specified', async () => {
+ const actual = await command.validate({ options: { type: 'recentlyArchived' } }, commandInfo);
+ assert.strictEqual(actual, true);
+ });
+
+ it('passes validation if type archived specified', async () => {
+ const actual = await command.validate({ options: { type: 'archived' } }, commandInfo);
+ assert.strictEqual(actual, true);
+ });
+
+ it('retrieves list of sites when type fullyArchived is specified', async () => {
+ sinon.stub(request, 'post').callsFake(async (opts) => {
+ if (opts.url === `https://contoso-admin.sharepoint.com/_vti_bin/client.svc/ProcessQuery`) {
+ if (opts.headers &&
+ opts.headers['X-RequestDigest'] &&
+ opts.headers['X-RequestDigest'] === 'abc' &&
+ opts.data === `ArchiveStatus -eq 'FullyArchived'false00`) {
+ return JSON.stringify([
+ {
+ "SchemaVersion": "15.0.0.0", "LibraryVersion": "16.0.7206.1204", "ErrorInfo": null, "TraceCorrelationId": "487c379e-80f8-4000-80be-1d37a4995717"
+ }, 2, {
+ "IsNull": false
+ }, 4, {
+ "IsNull": false
+ }, 5, {
+ "_ObjectType_": "Microsoft.Online.SharePoint.TenantAdministration.SPOSitePropertiesEnumerable", "NextStartIndex": -1, "NextStartIndexFromSharePoint": null, "_Child_Items_": [
+ {
+ "_ObjectType_": "Microsoft.Online.SharePoint.TenantAdministration.SiteProperties", "_ObjectIdentity_": "487c379e-80f8-4000-80be-1d37a4995717|908bed80-a04a-4433-b4a0-883d9847d110:67753f63-bc14-4012-869e-f808a43fe023\nSiteProperties\nhttps%3a%2f%2fcontoso.sharepoint.com%2fsites%2farchived_1", "AllowDownloadingNonWebViewableFiles": false, "AllowEditing": false, "AllowSelfServiceUpgrade": true, "AverageResourceUsage": 0, "CommentsOnSitePagesDisabled": false, "CompatibilityLevel": 15, "ConditionalAccessPolicy": 0, "CurrentResourceUsage": 0, "DenyAddAndCustomizePages": 2, "DisableAppViews": 0, "DisableCompanyWideSharingLinks": 0, "DisableFlows": 0, "HasHolds": false, "Lcid": 1033, "Status": "Active", "Title": "Archived site 1", "Url": "https:\u002f\u002fcontoso.sharepoint.com\u002fsites\u002farchived_1"
+ }
+ ]
+ }
+ ]);
+ }
+ }
+
+ throw 'Invalid request';
+ });
+
+ await command.action(logger, { options: { type: 'fullyArchived' } });
+ assert(loggerLogSpy.calledOnce);
+ });
+
+ it('retrieves list of sites when type recentlyArchived is specified', async () => {
+ sinon.stub(request, 'post').callsFake(async (opts) => {
+ if (opts.url === `https://contoso-admin.sharepoint.com/_vti_bin/client.svc/ProcessQuery`) {
+ if (opts.headers &&
+ opts.headers['X-RequestDigest'] &&
+ opts.headers['X-RequestDigest'] === 'abc' &&
+ opts.data === `ArchiveStatus -eq 'RecentlyArchived'false00`) {
+ return JSON.stringify([
+ {
+ "SchemaVersion": "15.0.0.0", "LibraryVersion": "16.0.7206.1204", "ErrorInfo": null, "TraceCorrelationId": "487c379e-80f8-4000-80be-1d37a4995717"
+ }, 2, {
+ "IsNull": false
+ }, 4, {
+ "IsNull": false
+ }, 5, {
+ "_ObjectType_": "Microsoft.Online.SharePoint.TenantAdministration.SPOSitePropertiesEnumerable", "NextStartIndex": -1, "NextStartIndexFromSharePoint": null, "_Child_Items_": [
+ {
+ "_ObjectType_": "Microsoft.Online.SharePoint.TenantAdministration.SiteProperties", "_ObjectIdentity_": "487c379e-80f8-4000-80be-1d37a4995717|908bed80-a04a-4433-b4a0-883d9847d110:67753f63-bc14-4012-869e-f808a43fe023\nSiteProperties\nhttps%3a%2f%2fcontoso.sharepoint.com%2fsites%2frecent_1", "AllowDownloadingNonWebViewableFiles": false, "AllowEditing": false, "AllowSelfServiceUpgrade": true, "AverageResourceUsage": 0, "CommentsOnSitePagesDisabled": false, "CompatibilityLevel": 15, "ConditionalAccessPolicy": 0, "CurrentResourceUsage": 0, "DenyAddAndCustomizePages": 2, "DisableAppViews": 0, "DisableCompanyWideSharingLinks": 0, "DisableFlows": 0, "HasHolds": false, "Lcid": 1033, "Status": "Active", "Title": "Recently archived 1", "Url": "https:\u002f\u002fcontoso.sharepoint.com\u002fsites\u002frecent_1"
+ }
+ ]
+ }
+ ]);
+ }
+ }
+
+ throw 'Invalid request';
+ });
+
+ await command.action(logger, { options: { type: 'recentlyArchived' } });
+ assert(loggerLogSpy.calledOnce);
+ });
+
+ it('retrieves list of sites when type archived is specified', async () => {
+ sinon.stub(request, 'post').callsFake(async (opts) => {
+ if (opts.url === `https://contoso-admin.sharepoint.com/_vti_bin/client.svc/ProcessQuery`) {
+ if (opts.headers &&
+ opts.headers['X-RequestDigest'] &&
+ opts.headers['X-RequestDigest'] === 'abc' &&
+ opts.data === `ArchiveStatus -ne 'NotArchived'false00`) {
+ return JSON.stringify([
+ {
+ "SchemaVersion": "15.0.0.0", "LibraryVersion": "16.0.7206.1204", "ErrorInfo": null, "TraceCorrelationId": "487c379e-80f8-4000-80be-1d37a4995717"
+ }, 2, {
+ "IsNull": false
+ }, 4, {
+ "IsNull": false
+ }, 5, {
+ "_ObjectType_": "Microsoft.Online.SharePoint.TenantAdministration.SPOSitePropertiesEnumerable", "NextStartIndex": -1, "NextStartIndexFromSharePoint": null, "_Child_Items_": [
+ {
+ "_ObjectType_": "Microsoft.Online.SharePoint.TenantAdministration.SiteProperties", "_ObjectIdentity_": "487c379e-80f8-4000-80be-1d37a4995717|908bed80-a04a-4433-b4a0-883d9847d110:67753f63-bc14-4012-869e-f808a43fe023\nSiteProperties\nhttps%3a%2f%2fcontoso.sharepoint.com%2fsites%2farchived_any_1", "AllowDownloadingNonWebViewableFiles": false, "AllowEditing": false, "AllowSelfServiceUpgrade": true, "AverageResourceUsage": 0, "CommentsOnSitePagesDisabled": false, "CompatibilityLevel": 15, "ConditionalAccessPolicy": 0, "CurrentResourceUsage": 0, "DenyAddAndCustomizePages": 2, "DisableAppViews": 0, "DisableCompanyWideSharingLinks": 0, "DisableFlows": 0, "HasHolds": false, "Lcid": 1033, "Status": "Active", "Title": "Archived any 1", "Url": "https:\u002f\u002fcontoso.sharepoint.com\u002fsites\u002farchived_any_1"
+ }
+ ]
+ }
+ ]);
+ }
+ }
+
+ throw 'Invalid request';
+ });
+
+ await command.action(logger, { options: { type: 'archived' } });
+ assert(loggerLogSpy.calledOnce);
+ });
+
+ it('combines provided filter with archived filter when type archived is specified', async () => {
+ sinon.stub(request, 'post').callsFake(async (opts) => {
+ if (opts.url === `https://contoso-admin.sharepoint.com/_vti_bin/client.svc/ProcessQuery`) {
+ if (opts.headers &&
+ opts.headers['X-RequestDigest'] &&
+ opts.headers['X-RequestDigest'] === 'abc' &&
+ opts.data === `Url -like 'ctest' and ArchiveStatus -ne 'NotArchived'false00`) {
+ return JSON.stringify([
+ {
+ "SchemaVersion": "15.0.0.0", "LibraryVersion": "16.0.7206.1204", "ErrorInfo": null, "TraceCorrelationId": "487c379e-80f8-4000-80be-1d37a4995717"
+ }, 2, {
+ "IsNull": false
+ }, 4, {
+ "IsNull": false
+ }, 5, {
+ "_ObjectType_": "Microsoft.Online.SharePoint.TenantAdministration.SPOSitePropertiesEnumerable", "NextStartIndex": -1, "NextStartIndexFromSharePoint": null, "_Child_Items_": []
+ }
+ ]);
+ }
+ }
+
+ throw 'Invalid request';
+ });
+
+ await command.action(logger, { options: { type: 'archived', filter: "Url -like 'ctest'" } });
+ assert(loggerLogSpy.calledOnce);
+ });
+
it('correctly handles error when retrieving sites', async () => {
sinon.stub(request, 'post').callsFake(async (opts) => {
if ((opts.url as string).indexOf(`/_vti_bin/client.svc/ProcessQuery`) > -1) {
diff --git a/src/m365/spo/commands/site/site-list.ts b/src/m365/spo/commands/site/site-list.ts
index c743d142456..8ad78266c1b 100644
--- a/src/m365/spo/commands/site/site-list.ts
+++ b/src/m365/spo/commands/site/site-list.ts
@@ -1,23 +1,36 @@
import { Logger } from '../../../../cli/Logger.js';
+import { z } from 'zod';
+import { globalOptionsZod } from '../../../../Command.js';
import config from '../../../../config.js';
-import GlobalOptions from '../../../../GlobalOptions.js';
import request, { CliRequestOptions } from '../../../../request.js';
import { formatting } from '../../../../utils/formatting.js';
import { ClientSvcResponse, ClientSvcResponseContents, FormDigestInfo, spo } from '../../../../utils/spo.js';
+import { zod } from '../../../../utils/zod.js';
import SpoCommand from '../../../base/SpoCommand.js';
import commands from '../../commands.js';
import { SiteProperties } from './SiteProperties.js';
import { SPOSitePropertiesEnumerable } from './SPOSitePropertiesEnumerable.js';
-interface CommandArgs {
- options: Options;
+enum SiteListType {
+ TeamSite = 'TeamSite',
+ CommunicationSite = 'CommunicationSite',
+ fullyArchived = 'fullyArchived',
+ recentlyArchived = 'recentlyArchived',
+ archived = 'archived'
}
-interface Options extends GlobalOptions {
- type?: string;
- webTemplate?: string;
- filter?: string;
- withOneDriveSites?: boolean;
+const options = globalOptionsZod
+ .extend({
+ type: zod.alias('t', zod.coercedEnum(SiteListType)).optional(),
+ webTemplate: z.string().optional(),
+ filter: z.string().optional(),
+ withOneDriveSites: z.boolean().optional()
+ })
+ .strict();
+declare type Options = z.infer;
+
+interface CommandArgs {
+ options: Options;
}
class SpoSiteListCommand extends SpoCommand {
@@ -35,64 +48,18 @@ class SpoSiteListCommand extends SpoCommand {
return ['Title', 'Url'];
}
- constructor() {
- super();
-
- this.#initTelemetry();
- this.#initOptions();
- this.#initValidators();
+ public get schema(): z.ZodTypeAny | undefined {
+ return options;
}
- #initTelemetry(): void {
- this.telemetry.push((args: CommandArgs) => {
- Object.assign(this.telemetryProperties, {
- webTemplate: args.options.webTemplate,
- type: args.options.type,
- filter: (!(!args.options.filter)).toString(),
- withOneDriveSites: typeof args.options.withOneDriveSites !== 'undefined'
+ public getRefinedSchema(schema: typeof options): z.ZodEffects | undefined {
+ return schema
+ .refine(o => !(o.type && o.webTemplate), {
+ message: 'Specify either type or webTemplate, but not both'
+ })
+ .refine(o => !(o.withOneDriveSites && (o.type !== undefined || o.webTemplate !== undefined)), {
+ message: 'When using withOneDriveSites, don\'t specify the type or webTemplate options'
});
- });
- }
-
- #initOptions(): void {
- this.options.unshift(
- {
- option: '-t, --type [type]',
- autocomplete: ['TeamSite', 'CommunicationSite']
- },
- {
- option: '--webTemplate [webTemplate]'
- },
- {
- option: '--filter [filter]'
- },
- {
- option: '--withOneDriveSites'
- }
- );
- }
-
- #initValidators(): void {
- this.validators.push(
- async (args: CommandArgs) => {
- if (args.options.type && args.options.webTemplate) {
- return 'Specify either type or webTemplate, but not both';
- }
-
- const typeValues = ['TeamSite', 'CommunicationSite'];
- if (args.options.type &&
- typeValues.indexOf(args.options.type) < 0) {
- return `${args.options.type} is not a valid value for the type option. Allowed values are ${typeValues.join('|')}`;
- }
-
- if (args.options.withOneDriveSites
- && (args.options.type || args.options.webTemplate)) {
- return 'When using withOneDriveSites, don\'t specify the type or webTemplate options';
- }
-
- return true;
- }
- );
}
public alias(): string[] | undefined {
@@ -103,6 +70,7 @@ class SpoSiteListCommand extends SpoCommand {
const webTemplate: string = this.getWebTemplateId(args.options);
const includeOneDriveSites: boolean = args.options.withOneDriveSites || false;
const personalSite: string = includeOneDriveSites === false ? '0' : '1';
+ const effectiveFilter: string = this.buildFilter(args.options);
try {
const spoAdminUrl: string = await spo.getSpoAdminUrl(logger, this.debug);
@@ -113,7 +81,7 @@ class SpoSiteListCommand extends SpoCommand {
this.allSites = [];
- await this.getAllSites(spoAdminUrl, formatting.escapeXml(args.options.filter || ''), '0', personalSite, webTemplate, undefined, logger);
+ await this.getAllSites(spoAdminUrl, formatting.escapeXml(effectiveFilter), '0', personalSite, webTemplate, undefined, logger);
await logger.log(this.allSites);
}
catch (err: any) {
@@ -170,6 +138,29 @@ class SpoSiteListCommand extends SpoCommand {
return '';
}
}
+
+ private buildFilter(options: Options): string {
+ const providedFilter: string = options.filter || '';
+
+ let archivedFilter: string = '';
+ switch (options.type) {
+ case 'fullyArchived':
+ archivedFilter = "ArchiveStatus -eq 'FullyArchived'";
+ break;
+ case 'recentlyArchived':
+ archivedFilter = "ArchiveStatus -eq 'RecentlyArchived'";
+ break;
+ case 'archived':
+ archivedFilter = "ArchiveStatus -ne 'NotArchived'";
+ break;
+ }
+
+ if (archivedFilter && providedFilter) {
+ return `${providedFilter} and ${archivedFilter}`;
+ }
+
+ return archivedFilter || providedFilter;
+ }
}
export default new SpoSiteListCommand();
\ No newline at end of file