@pnp/cli-microsoft365 10.3.1 → 10.4.0-beta.1d1e5a7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/.eslintrc.cjs +3 -1
  2. package/allCommands.json +1 -1
  3. package/allCommandsFull.json +1 -1
  4. package/dist/cli/cli.js +10 -2
  5. package/dist/config.js +1 -0
  6. package/dist/m365/entra/commands/group/group-member-add.js +12 -6
  7. package/dist/m365/entra/commands/group/group-member-set.js +12 -6
  8. package/dist/m365/entra/commands/resourcenamespace/resourcenamespace-list.js +28 -0
  9. package/dist/m365/entra/commands/user/user-session-revoke.js +70 -0
  10. package/dist/m365/entra/commands.js +2 -0
  11. package/dist/m365/outlook/commands/mailbox/mailbox-settings-get.js +71 -0
  12. package/dist/m365/outlook/commands/mailbox/mailbox-settings-set.js +5 -2
  13. package/dist/m365/outlook/commands.js +1 -0
  14. package/dist/m365/spo/commands/field/field-get.js +6 -3
  15. package/dist/m365/spo/commands/field/field-remove.js +10 -8
  16. package/dist/m365/spo/commands/field/field-set.js +6 -2
  17. package/dist/m365/spo/commands/mail/mail-send.js +2 -0
  18. package/dist/m365/spo/commands/page/clientsidepages.js +101 -9
  19. package/dist/m365/spo/commands/page/page-clientsidewebpart-add.js +2 -1
  20. package/dist/m365/spo/commands/page/page-get.js +40 -27
  21. package/dist/m365/spo/commands/page/page-text-add.js +7 -1
  22. package/dist/m365/tenant/commands/report/report-settings-get.js +32 -0
  23. package/dist/m365/tenant/commands.js +1 -0
  24. package/docs/docs/cmd/entra/group/group-member-add.mdx +17 -2
  25. package/docs/docs/cmd/entra/group/group-member-set.mdx +17 -2
  26. package/docs/docs/cmd/entra/resourcenamespace/resourcenamespace-list.mdx +96 -0
  27. package/docs/docs/cmd/entra/rolepermission/rolepermission-list.mdx +2 -0
  28. package/docs/docs/cmd/entra/user/user-session-revoke.mdx +65 -0
  29. package/docs/docs/cmd/outlook/mailbox/mailbox-settings-get.mdx +131 -0
  30. package/docs/docs/cmd/spo/field/field-get.mdx +12 -2
  31. package/docs/docs/cmd/spo/field/field-remove.mdx +12 -3
  32. package/docs/docs/cmd/spo/field/field-set.mdx +17 -3
  33. package/docs/docs/cmd/spo/page/page-get.mdx +11 -2
  34. package/docs/docs/cmd/tenant/report/report-settings-get.mdx +67 -0
  35. package/npm-shrinkwrap.json +570 -1141
  36. package/package.json +14 -14
@@ -271,6 +271,12 @@ export class ClientSidePage {
271
271
  for (let i = 0; i < this.sections.length; i++) {
272
272
  html.push(this.sections[i].toHtml());
273
273
  }
274
+ if (this.pageSettings) {
275
+ html.push(this.pageSettings.toHtml());
276
+ }
277
+ if (this.backgroundSettings) {
278
+ html.push(this.backgroundSettings.toHtml());
279
+ }
274
280
  html.push("</div>");
275
281
  return html.join("");
276
282
  }
@@ -286,17 +292,23 @@ export class ClientSidePage {
286
292
  // gather our controls from the supplied html
287
293
  getBoundedDivMarkup(html, /<div\b[^>]*data-sp-canvascontrol[^>]*?>/i, markup => {
288
294
  // get the control type
289
- const ct = /controlType&quot;&#58;(\d*?),/i.exec(markup);
295
+ const ct = /controlType&quot;&#58;(\d*?)(,|&)/i.exec(markup);
290
296
  // if no control type is present this is a column which we give type 0 to let us process it
291
- const controlType = ct == null || ct.length < 2 ? 0 : parseInt(ct[1], 10);
297
+ const controlType = ct == null || ct.length < 0 ? -1 : parseInt(ct[1], 10);
292
298
  let control = null;
293
299
  switch (controlType) {
294
- case 0:
300
+ case -1:
295
301
  // empty canvas column
296
302
  control = new CanvasColumn(null, 0);
297
303
  control.fromHtml(markup);
298
304
  page.mergeColumnToTree(control);
299
305
  break;
306
+ case 0:
307
+ // page settings
308
+ control = new PageSettings();
309
+ control.fromHtml(markup);
310
+ page.pageSettings = control;
311
+ break;
300
312
  case 3:
301
313
  // client side webpart
302
314
  control = new ClientSideWebpart("");
@@ -309,6 +321,12 @@ export class ClientSidePage {
309
321
  control.fromHtml(markup);
310
322
  page.mergePartToTree(control);
311
323
  break;
324
+ case 14:
325
+ // backgroundSection
326
+ control = new BackgroundSettings();
327
+ control.fromHtml(markup);
328
+ page.backgroundSettings = control;
329
+ break;
312
330
  }
313
331
  });
314
332
  // refresh all the orders within the tree
@@ -364,7 +382,7 @@ export class ClientSidePage {
364
382
  }
365
383
  const sections = this.sections.filter(s => s.order === zoneIndex);
366
384
  if (sections.length < 1) {
367
- section = new CanvasSection(this, zoneIndex);
385
+ section = new CanvasSection(this, zoneIndex, [], control?.controlData?.position.zoneId, control.controlData?.zoneGroupMetadata);
368
386
  this.sections.push(section);
369
387
  }
370
388
  else {
@@ -392,7 +410,7 @@ export class ClientSidePage {
392
410
  let section = null;
393
411
  const sections = this.sections.filter(s => s.order === order);
394
412
  if (sections.length < 1) {
395
- section = new CanvasSection(this, order);
413
+ section = new CanvasSection(this, order, [], column.controlData?.position?.zoneId, column.controlData?.zoneGroupMetadata);
396
414
  this.sections.push(section);
397
415
  }
398
416
  else {
@@ -403,10 +421,12 @@ export class ClientSidePage {
403
421
  }
404
422
  }
405
423
  export class CanvasSection {
406
- constructor(page, order, columns = []) {
424
+ constructor(page, order, columns = [], zoneId, zoneGroupMetadata) {
407
425
  this.page = page;
408
426
  this.order = order;
409
427
  this.columns = columns;
428
+ this.zoneId = zoneId;
429
+ this.zoneGroupMetadata = zoneGroupMetadata;
410
430
  }
411
431
  /**
412
432
  * Default column (this.columns[0]) for this section
@@ -457,6 +477,20 @@ class CanvasControl {
457
477
  this.id = this.controlData.id;
458
478
  }
459
479
  }
480
+ export class PageSettings extends CanvasControl {
481
+ constructor() {
482
+ super(0, "1.0");
483
+ }
484
+ getControlData() {
485
+ return this.controlData;
486
+ }
487
+ toHtml() {
488
+ return `<div data-sp-canvascontrol="" data-sp-canvasdataversion="${this.dataVersion}" data-sp-controldata="${this.jsonData}"></div>`;
489
+ }
490
+ fromHtml(html) {
491
+ super.fromHtml(html);
492
+ }
493
+ }
460
494
  export class CanvasColumn extends CanvasControl {
461
495
  constructor(section, order, factor = 12, controls = [], dataVersion = "1.0") {
462
496
  super(0, dataVersion);
@@ -513,8 +547,10 @@ export class CanvasColumn extends CanvasControl {
513
547
  position: {
514
548
  sectionFactor: this.factor,
515
549
  sectionIndex: this.order,
516
- zoneIndex: this.section ? this.section.order : 0
550
+ zoneIndex: this.section ? this.section.order : 0,
551
+ zoneId: this.section?.zoneId
517
552
  },
553
+ zoneGroupMetadata: this.section?.zoneGroupMetadata,
518
554
  };
519
555
  }
520
556
  /**
@@ -543,6 +579,58 @@ export class ClientSidePart extends CanvasControl {
543
579
  }
544
580
  }
545
581
  }
582
+ export class BackgroundSettings extends ClientSidePart {
583
+ constructor() {
584
+ super(0, "1.0");
585
+ this.propertieJson = {};
586
+ this.serverProcessedContent = null;
587
+ }
588
+ getControlData() {
589
+ return {
590
+ controlType: this.controlType
591
+ };
592
+ }
593
+ toHtml() {
594
+ // will form the value of the data-sp-webpartdata attribute
595
+ const data = {
596
+ dataVersion: this.dataVersion,
597
+ instanceId: this.id,
598
+ properties: this.propertieJson,
599
+ serverProcessedContent: this.serverProcessedContent,
600
+ };
601
+ const html = [];
602
+ html.push(`<div data-sp-canvascontrol="" data-sp-canvasdataversion="${this.dataVersion}" data-sp-controldata="${this.jsonData}">`);
603
+ html.push(`<div data-sp-webpart="" data-sp-webpartdataversion="${this.dataVersion}" data-sp-webpartdata="${ClientSidePage.jsonToEscapedString(data)}">`);
604
+ html.push(`<div data-sp-componentid="">`);
605
+ html.push("</div>");
606
+ html.push(`<div data-sp-htmlproperties="">`);
607
+ for (let imageSource in this.serverProcessedContent?.imageSources) {
608
+ html.push(`<img data-sp-prop-name="${imageSource}" src="${this.serverProcessedContent?.imageSources[imageSource]}" />`);
609
+ }
610
+ html.push("</div>");
611
+ html.push("</div>");
612
+ html.push("</div>");
613
+ return html.join("");
614
+ }
615
+ setProperties(properties) {
616
+ this.propertieJson = extend(this.propertieJson, properties);
617
+ return this;
618
+ }
619
+ fromHtml(html) {
620
+ super.fromHtml(html);
621
+ const webPartData = ClientSidePage.escapedStringToJson(getAttrValueFromString(html, "data-sp-webpartdata"));
622
+ this.setProperties(webPartData.properties);
623
+ if (typeof webPartData.serverProcessedContent !== "undefined") {
624
+ this.serverProcessedContent = webPartData.serverProcessedContent;
625
+ }
626
+ if (typeof webPartData.dynamicDataPaths !== "undefined") {
627
+ this.dynamicDataPaths = webPartData.dynamicDataPaths;
628
+ }
629
+ if (typeof webPartData.dynamicDataValues !== "undefined") {
630
+ this.dynamicDataValues = webPartData.dynamicDataValues;
631
+ }
632
+ }
633
+ }
546
634
  export class ClientSideText extends ClientSidePart {
547
635
  constructor(text = "") {
548
636
  super(4, "1.0");
@@ -570,8 +658,10 @@ export class ClientSideText extends ClientSidePart {
570
658
  controlIndex: this.order,
571
659
  sectionFactor: this.column ? this.column.factor : 0,
572
660
  sectionIndex: this.column ? this.column.order : 0,
573
- zoneIndex: this.column && this.column.section ? this.column.section.order : 0
661
+ zoneIndex: this.column && this.column.section ? this.column.section.order : 0,
662
+ zoneId: this.column?.section?.zoneId
574
663
  },
664
+ zoneGroupMetadata: this.column?.section?.zoneGroupMetadata,
575
665
  };
576
666
  }
577
667
  toHtml(index) {
@@ -684,9 +774,11 @@ export class ClientSideWebpart extends ClientSidePart {
684
774
  controlIndex: this.order,
685
775
  sectionFactor: this.column ? this.column.factor : 0,
686
776
  sectionIndex: this.column ? this.column.order : 0,
687
- zoneIndex: this.column && this.column.section ? this.column.section.order : 0
777
+ zoneIndex: this.column && this.column.section ? this.column.section.order : 0,
778
+ zoneId: this.column?.section?.zoneId
688
779
  },
689
780
  webPartId: this.webPartId,
781
+ zoneGroupMetadata: this.column?.section?.zoneGroupMetadata,
690
782
  };
691
783
  }
692
784
  renderHtmlProperties() {
@@ -132,7 +132,8 @@ class SpoPageClientSideWebPartAddCommand extends SpoCommand {
132
132
  id: webPart.id,
133
133
  position: Object.assign({}, control.position),
134
134
  webPartId: webPart.webPartId,
135
- emphasis: {}
135
+ emphasis: {},
136
+ zoneGroupMetadata: control.zoneGroupMetadata
136
137
  }, webPart);
137
138
  if (!control.controlType) {
138
139
  // it's an empty column so we need to replace it with the web part
@@ -1,15 +1,23 @@
1
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
- };
6
- var _SpoPageGetCommand_instances, _SpoPageGetCommand_initOptions, _SpoPageGetCommand_initValidators;
1
+ import { z } from 'zod';
2
+ import { zod } from '../../../../utils/zod.js';
3
+ import { globalOptionsZod } from '../../../../Command.js';
7
4
  import request from '../../../../request.js';
8
5
  import { formatting } from '../../../../utils/formatting.js';
9
6
  import { urlUtil } from '../../../../utils/urlUtil.js';
10
7
  import { validation } from '../../../../utils/validation.js';
11
8
  import SpoCommand from '../../../base/SpoCommand.js';
12
9
  import commands from '../../commands.js';
10
+ const options = globalOptionsZod
11
+ .extend({
12
+ webUrl: zod.alias('u', z.string()
13
+ .refine(url => validation.isValidSharePointUrl(url) === true, url => ({
14
+ message: `'${url}' is not a valid SharePoint Online site URL.`
15
+ }))),
16
+ name: zod.alias('n', z.string()).optional(),
17
+ default: z.boolean().optional(),
18
+ metadataOnly: z.boolean().optional()
19
+ })
20
+ .strict();
13
21
  class SpoPageGetCommand extends SpoCommand {
14
22
  get name() {
15
23
  return commands.PAGE_GET;
@@ -20,21 +28,37 @@ class SpoPageGetCommand extends SpoCommand {
20
28
  defaultProperties() {
21
29
  return ['commentsDisabled', 'numSections', 'numControls', 'title', 'layoutType'];
22
30
  }
23
- constructor() {
24
- super();
25
- _SpoPageGetCommand_instances.add(this);
26
- __classPrivateFieldGet(this, _SpoPageGetCommand_instances, "m", _SpoPageGetCommand_initOptions).call(this);
27
- __classPrivateFieldGet(this, _SpoPageGetCommand_instances, "m", _SpoPageGetCommand_initValidators).call(this);
31
+ get schema() {
32
+ return options;
33
+ }
34
+ getRefinedSchema(schema) {
35
+ return schema
36
+ .refine(options => [options.name, options.default].filter(x => x !== undefined).length === 1, {
37
+ message: `Specify either name or default, but not both.`
38
+ });
28
39
  }
29
40
  async commandAction(logger, args) {
30
41
  if (this.verbose) {
31
42
  await logger.logToStderr(`Retrieving information about the page...`);
32
43
  }
33
- let pageName = args.options.name;
34
- if (args.options.name.indexOf('.aspx') < 0) {
35
- pageName += '.aspx';
36
- }
44
+ let pageName = '';
37
45
  try {
46
+ if (args.options.name) {
47
+ pageName = args.options.name.endsWith('.aspx')
48
+ ? args.options.name
49
+ : `${args.options.name}.aspx`;
50
+ }
51
+ else if (args.options.default) {
52
+ const requestOptions = {
53
+ url: `${args.options.webUrl}/_api/Web/RootFolder?$select=WelcomePage`,
54
+ headers: {
55
+ accept: 'application/json;odata=nometadata'
56
+ },
57
+ responseType: 'json'
58
+ };
59
+ const { WelcomePage } = await request.get(requestOptions);
60
+ pageName = WelcomePage.split('/').pop();
61
+ }
38
62
  let requestOptions = {
39
63
  url: `${args.options.webUrl}/_api/web/GetFileByServerRelativePath(DecodedUrl='${urlUtil.getServerRelativeSiteUrl(args.options.webUrl)}/SitePages/${formatting.encodeQueryParameter(pageName)}')?$expand=ListItemAllFields/ClientSideApplicationId,ListItemAllFields/PageLayoutType,ListItemAllFields/CommentsDisabled`,
40
64
  headers: {
@@ -45,7 +69,7 @@ class SpoPageGetCommand extends SpoCommand {
45
69
  };
46
70
  const page = await request.get(requestOptions);
47
71
  if (page.ListItemAllFields.ClientSideApplicationId !== 'b6917cb1-93a0-4b97-a84d-7cf49975d4ec') {
48
- throw `Page ${args.options.name} is not a modern page.`;
72
+ throw `Page ${pageName} is not a modern page.`;
49
73
  }
50
74
  let pageItemData = {};
51
75
  pageItemData = Object.assign({}, page);
@@ -80,16 +104,5 @@ class SpoPageGetCommand extends SpoCommand {
80
104
  }
81
105
  }
82
106
  }
83
- _SpoPageGetCommand_instances = new WeakSet(), _SpoPageGetCommand_initOptions = function _SpoPageGetCommand_initOptions() {
84
- this.options.unshift({
85
- option: '-n, --name <name>'
86
- }, {
87
- option: '-u, --webUrl <webUrl>'
88
- }, {
89
- option: '--metadataOnly'
90
- });
91
- }, _SpoPageGetCommand_initValidators = function _SpoPageGetCommand_initValidators() {
92
- this.validators.push(async (args) => validation.isValidSharePointUrl(args.options.webUrl));
93
- };
94
107
  export default new SpoPageGetCommand();
95
108
  //# sourceMappingURL=page-get.js.map
@@ -10,7 +10,7 @@ import { urlUtil } from '../../../../utils/urlUtil.js';
10
10
  import { validation } from '../../../../utils/validation.js';
11
11
  import SpoCommand from '../../../base/SpoCommand.js';
12
12
  import commands from '../../commands.js';
13
- import { ClientSideText } from './clientsidepages.js';
13
+ import { CanvasSection, ClientSideText } from './clientsidepages.js';
14
14
  import { Page } from './Page.js';
15
15
  class SpoPageTextAddCommand extends SpoCommand {
16
16
  get name() {
@@ -46,6 +46,12 @@ class SpoPageTextAddCommand extends SpoCommand {
46
46
  const page = await Page.getPage(pageName, args.options.webUrl, logger, this.debug, this.verbose);
47
47
  const section = (args.options.section || 1) - 1;
48
48
  const column = (args.options.column || 1) - 1;
49
+ // Add a new section when page does not contain any sections
50
+ if (page.sections.length < 1) {
51
+ const newSection = new CanvasSection(page, 1);
52
+ newSection.defaultColumn;
53
+ page.sections.push(newSection);
54
+ }
49
55
  // Make sure the section is in range
50
56
  if (section >= page.sections.length) {
51
57
  throw new Error(`Invalid section '${section + 1}'`);
@@ -0,0 +1,32 @@
1
+ import GraphCommand from '../../../base/GraphCommand.js';
2
+ import commands from '../../commands.js';
3
+ import request from '../../../../request.js';
4
+ class TenantReportSettingsGetCommand extends GraphCommand {
5
+ get name() {
6
+ return commands.REPORT_SETTINGS_GET;
7
+ }
8
+ get description() {
9
+ return 'Get the tenant-level settings for Microsoft 365 reports';
10
+ }
11
+ async commandAction(logger) {
12
+ if (this.verbose) {
13
+ await logger.logToStderr('Getting tenant-level settings for Microsoft 365 reports...');
14
+ }
15
+ const requestOptions = {
16
+ url: `${this.resource}/v1.0/admin/reportSettings`,
17
+ headers: {
18
+ accept: 'application/json;odata.metadata=none'
19
+ },
20
+ responseType: 'json'
21
+ };
22
+ try {
23
+ const res = await request.get(requestOptions);
24
+ await logger.log(res);
25
+ }
26
+ catch (err) {
27
+ this.handleRejectedODataJsonPromise(err);
28
+ }
29
+ }
30
+ }
31
+ export default new TenantReportSettingsGetCommand();
32
+ //# sourceMappingURL=report-settings-get.js.map
@@ -15,6 +15,7 @@ export default {
15
15
  REPORT_OFFICE365ACTIVATIONSUSERDETAIL: `${prefix} report office365activationsuserdetail`,
16
16
  REPORT_OFFICE365ACTIVATIONSUSERCOUNTS: `${prefix} report office365activationsusercounts`,
17
17
  REPORT_SERVICESUSERCOUNTS: `${prefix} report servicesusercounts`,
18
+ REPORT_SETTINGS_GET: `${prefix} report settings get`,
18
19
  REPORT_SETTINGS_SET: `${prefix} report settings set`,
19
20
  SECURITY_ALERTS_LIST: `${prefix} security alerts list`,
20
21
  SERVICEANNOUNCEMENT_HEALTHISSUE_GET: `${prefix} serviceannouncement healthissue get`,
@@ -14,10 +14,13 @@ m365 entra group member add [options]
14
14
 
15
15
  ```md definition-list
16
16
  `-i, --groupId [groupId]`
17
- : The ID of the Microsoft Entra group. Specify `groupId` or `groupDisplayName` but not both.
17
+ : The ID of the Microsoft Entra group. Specify `groupId`, `groupDisplayName` or `groupName` but not multiple.
18
18
 
19
19
  `-n, --groupDisplayName [groupDisplayName]`
20
- : The display name of the Microsoft Entra group. Specify `groupId` or `groupDisplayName` but not both.
20
+ : (deprecated. Use option `groupName` instead) The display name of the Microsoft Entra group. Specify `groupId`, `groupDisplayName` or `groupName` but not multiple.
21
+
22
+ `--groupName [groupName]`
23
+ : The display name of the Microsoft Entra group. Specify `groupId`, `groupDisplayName` or `groupName` but not multiple.
21
24
 
22
25
  `--ids [ids]`
23
26
  : Microsoft Entra IDs of users. You can also pass a comma-separated list of IDs. Specify either `ids` or `userNames` but not both.
@@ -39,6 +42,12 @@ Add a single member specified by ID as a member to a group specified by display
39
42
  m365 entra group member add --groupDisplayName Developers --ids 098b9f52-f48c-4401-819f-29c33794c3f5 --role Member
40
43
  ```
41
44
 
45
+ Add a single member specified by ID as a member to a group specified by group name.
46
+
47
+ ```sh
48
+ m365 entra group member add --groupName Developers --ids 098b9f52-f48c-4401-819f-29c33794c3f5 --role Member
49
+ ```
50
+
42
51
  Add multiple members specified by ID as members to a group specified by ID.
43
52
 
44
53
  ```sh
@@ -51,6 +60,12 @@ Add a single member specified by UPN as an owner to a group specified by display
51
60
  m365 entra group member add --groupDisplayName Developers --userNames john.doe@contoso.com --role Owner
52
61
  ```
53
62
 
63
+ Add a single member specified by UPN as an owner to a group specified by group name.
64
+
65
+ ```sh
66
+ m365 entra group member add --groupName Developers --userNames john.doe@contoso.com --role Owner
67
+ ```
68
+
54
69
  Adds multiple members specified by UPN as owners to a group specified by ID.
55
70
 
56
71
  ```sh
@@ -14,10 +14,13 @@ m365 entra group member set [options]
14
14
 
15
15
  ```md definition-list
16
16
  `-i, --groupId [groupId]`
17
- : The ID of the Entra ID group. Specify `groupId` or `groupDisplayName` but not both.
17
+ : The ID of the Entra ID group. Specify `groupId`, `groupDisplayName` or `groupName` but not multiple.
18
18
 
19
19
  `-n, --groupDisplayName [groupDisplayName]`
20
- : The display name of the Entra ID group. Specify `groupId` or `groupDisplayName` but not both.
20
+ : (deprecated. Use option `groupName` instead) The display name of the Entra ID group. Specify `groupId`, `groupDisplayName` or `groupName` but not multiple.
21
+
22
+ `--groupName [groupName]`
23
+ : The display name of the Microsoft Entra group. Specify `groupId`, `groupDisplayName` or `groupName` but not multiple.
21
24
 
22
25
  `--ids [ids]`
23
26
  : Comma-separated list of user IDs. Specify either `ids` or `userNames` but not both.
@@ -39,6 +42,12 @@ Update a single member specified by ID to a member of a group specified by displ
39
42
  m365 entra group member set --groupDisplayName Developers --ids 098b9f52-f48c-4401-819f-29c33794c3f5 --role Member
40
43
  ```
41
44
 
45
+ Update a single member specified by ID to a member of a group specified by group name
46
+
47
+ ```sh
48
+ m365 entra group member set --groupName Developers --ids 098b9f52-f48c-4401-819f-29c33794c3f5 --role Member
49
+ ```
50
+
42
51
  Update multiple members specified by ID to members of a group specified by ID
43
52
 
44
53
  ```sh
@@ -51,6 +60,12 @@ Update a single member specified by UPN to an owner of a group specified by disp
51
60
  m365 entra group member set --groupDisplayName Developers --userNames john.doe@contoso.com --role Owner
52
61
  ```
53
62
 
63
+ Update a single member specified by UPN to an owner of a group specified by group name
64
+
65
+ ```sh
66
+ m365 entra group member set --groupName Developers --userNames john.doe@contoso.com --role Owner
67
+ ```
68
+
54
69
  Update multiple members specified by UPN to owners of a group specified by ID
55
70
 
56
71
  ```sh
@@ -0,0 +1,96 @@
1
+ import Global from '/docs/cmd/_global.mdx';
2
+ import Tabs from '@theme/Tabs';
3
+ import TabItem from '@theme/TabItem';
4
+
5
+ # entra resourcenamespace list
6
+
7
+ Get a list of the RBAC resource namespaces and their properties
8
+
9
+ ## Usage
10
+
11
+ ```sh
12
+ m365 entra resourcenamespace list [options]
13
+ ```
14
+
15
+ ## Options
16
+
17
+ <Global />
18
+
19
+ ## Remarks
20
+
21
+ :::warning
22
+
23
+ The command is based on an API that is currently in preview and is subject to change once the API reached general availability.
24
+
25
+ :::
26
+
27
+ ## Examples
28
+
29
+ Retrieve all resource namespaces.
30
+
31
+ ```sh
32
+ m365 entra resourcenamespace list
33
+ ```
34
+
35
+ ## Response
36
+
37
+ <Tabs>
38
+ <TabItem value="JSON">
39
+
40
+ ```json
41
+ [
42
+ {
43
+ "id": "microsoft.directory",
44
+ "name": "microsoft.directory"
45
+ },
46
+ {
47
+ "id": "microsoft.aad.b2c",
48
+ "name": "microsoft.aad.b2c"
49
+ }
50
+ ]
51
+ ```
52
+
53
+ </TabItem>
54
+ <TabItem value="Text">
55
+
56
+ ```text
57
+ id name
58
+ -------------------- --------------------
59
+ microsoft.directory microsoft.directory
60
+ microsoft.aad.b2c microsoft.aad.b2c
61
+ ```
62
+
63
+ </TabItem>
64
+ <TabItem value="CSV">
65
+
66
+ ```csv
67
+ id,name
68
+ microsoft.directory,microsoft.directory
69
+ microsoft.aad.b2c,microsoft.aad.b2c
70
+ ```
71
+
72
+ </TabItem>
73
+ <TabItem value="Markdown">
74
+
75
+ ```md
76
+ # entra resourcenamespace list
77
+
78
+ Date: 1/31/2025
79
+
80
+ ## microsoft.directory (microsoft.directory)
81
+
82
+ Property | Value
83
+ ---------|-------
84
+ id | microsoft.directory
85
+ name | microsoft.directory
86
+
87
+ ## microsoft.aad.b2c (microsoft.aad.b2c)
88
+
89
+ Property | Value
90
+ ---------|-------
91
+ id | microsoft.aad.b2c
92
+ name | microsoft.aad.b2c
93
+ ```
94
+
95
+ </TabItem>
96
+ </Tabs>
@@ -32,6 +32,8 @@ The command is based on an API that is currently in preview and is subject to ch
32
32
 
33
33
  :::
34
34
 
35
+ Use the `m365 entra resourcenamespace list` command to get a list of available resource namespaces.
36
+
35
37
  ## Examples
36
38
 
37
39
  Get a list of role permissions
@@ -0,0 +1,65 @@
1
+ import Global from '/docs/cmd/_global.mdx';
2
+
3
+ # entra user session revoke
4
+
5
+ Revokes all sign-in sessions for a given user
6
+
7
+ ## Usage
8
+
9
+ ```sh
10
+ m365 entra user session revoke [options]
11
+ ```
12
+
13
+ ## Options
14
+ ```md definition-list
15
+ `-i, --userId [userId]`
16
+ : The id of the user. Specify either `userId` or `userName`, but not both.
17
+
18
+ `-n, --userName [userName]`
19
+ : The user principal name of the user. Specify either `userId` or `userName`, but not both.
20
+
21
+ `-f, --force`
22
+ : Don't prompt for confirmation.
23
+ ```
24
+
25
+ <Global />
26
+
27
+ ## Remarks
28
+
29
+ :::info
30
+
31
+ To use this command you must be either **User Administrator** or **Global Administrator**.
32
+
33
+ :::
34
+
35
+ :::note
36
+
37
+ There might be a small delay of a few minutes before tokens are revoked.
38
+
39
+ This API doesn't revoke sign-in sessions for external users, because external users sign in through their home tenant.
40
+
41
+ :::
42
+
43
+ ## Examples
44
+
45
+ Revoke sign-in sessions of a user specified by id
46
+
47
+ ```sh
48
+ m365 entra user session revoke --userId 4fb72b9b-d0b0-4a35-8bc1-83f9a6488c48
49
+ ```
50
+
51
+ Revoke sign-in sessions of a user specified by its UPN
52
+
53
+ ```sh
54
+ m365 entra user session revoke --userName john.doe@contoso.onmicrosoft.com
55
+ ```
56
+
57
+ Revoke sign-in sessions of a user specified by its UPN without prompting for confirmation
58
+
59
+ ```sh
60
+ m365 entra user session revoke --userName john.doe@contoso.onmicrosoft.com --force
61
+ ```
62
+
63
+ ## Response
64
+
65
+ The command won't return a response on success.