@pnp/cli-microsoft365 10.8.0-beta.708bf27 → 10.8.0-beta.cdb5c81

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 (48) hide show
  1. package/.eslintrc.cjs +2 -1
  2. package/allCommands.json +1 -1
  3. package/allCommandsFull.json +1 -1
  4. package/dist/Auth.js +82 -22
  5. package/dist/cli/cli.js +1 -1
  6. package/dist/config.js +1 -0
  7. package/dist/m365/adaptivecard/commands/adaptivecard-send.js +54 -67
  8. package/dist/m365/cli/commands/app/app-reconsent.js +103 -0
  9. package/dist/m365/cli/commands.js +1 -0
  10. package/dist/m365/commands/login.js +1 -1
  11. package/dist/m365/commands/setup.js +1 -2
  12. package/dist/m365/entra/commands/organization/organization-list.js +51 -0
  13. package/dist/m365/entra/commands.js +1 -0
  14. package/dist/m365/graph/commands/openextension/openextension-set.js +107 -0
  15. package/dist/m365/graph/commands.js +1 -0
  16. package/dist/m365/spe/commands/container/container-add.js +85 -0
  17. package/dist/m365/spe/commands/container/container-list.js +2 -9
  18. package/dist/m365/spe/commands/container/container-permission-list.js +52 -0
  19. package/dist/m365/spe/commands/container/container-recyclebinitem-list.js +62 -0
  20. package/dist/m365/spe/commands/container/container-remove.js +99 -0
  21. package/dist/m365/spe/commands/containertype/containertype-add.js +11 -11
  22. package/dist/m365/spe/commands/containertype/containertype-get.js +28 -32
  23. package/dist/m365/spe/commands/containertype/containertype-list.js +14 -4
  24. package/dist/m365/spe/commands/containertype/containertype-remove.js +81 -0
  25. package/dist/m365/spe/commands.js +6 -1
  26. package/dist/m365/spo/commands/page/page-section-add.js +20 -23
  27. package/dist/utils/entraServicePrincipal.js +11 -0
  28. package/dist/utils/formatting.js +12 -0
  29. package/dist/utils/spe.js +77 -0
  30. package/dist/utils/spo.js +0 -18
  31. package/dist/utils/zod.js +26 -1
  32. package/docs/docs/cmd/adaptivecard/adaptivecard-send.mdx +1 -1
  33. package/docs/docs/cmd/cli/app/app-reconsent.mdx +63 -0
  34. package/docs/docs/cmd/entra/organization/organization-list.mdx +154 -0
  35. package/docs/docs/cmd/graph/openextension/openextension-set.mdx +97 -0
  36. package/docs/docs/cmd/spe/container/container-activate.mdx +0 -2
  37. package/docs/docs/cmd/spe/container/container-add.mdx +128 -0
  38. package/docs/docs/cmd/spe/container/container-permission-list.mdx +90 -0
  39. package/docs/docs/cmd/spe/container/container-recyclebinitem-list.mdx +96 -0
  40. package/docs/docs/cmd/spe/container/container-remove.mdx +65 -0
  41. package/docs/docs/cmd/spe/containertype/containertype-add.mdx +9 -1
  42. package/docs/docs/cmd/spe/containertype/containertype-get.mdx +8 -0
  43. package/docs/docs/cmd/spe/containertype/containertype-list.mdx +8 -0
  44. package/docs/docs/cmd/spe/containertype/containertype-remove.mdx +52 -0
  45. package/docs/docs/cmd/spo/field/field-get.mdx +0 -1
  46. package/npm-shrinkwrap.json +894 -477
  47. package/package.json +10 -10
  48. package/dist/m365/spe/ContainerProperties.js +0 -2
@@ -1,10 +1,15 @@
1
1
  const prefix = 'spe';
2
2
  export default {
3
3
  CONTAINER_ACTIVATE: `${prefix} container activate`,
4
+ CONTAINER_ADD: `${prefix} container add`,
4
5
  CONTAINER_GET: `${prefix} container get`,
5
6
  CONTAINER_LIST: `${prefix} container list`,
7
+ CONTAINER_REMOVE: `${prefix} container remove`,
8
+ CONTAINER_PERMISSION_LIST: `${prefix} container permission list`,
9
+ CONTAINER_RECYCLEBINITEM_LIST: `${prefix} container recyclebinitem list`,
6
10
  CONTAINERTYPE_ADD: `${prefix} containertype add`,
7
11
  CONTAINERTYPE_GET: `${prefix} containertype get`,
8
- CONTAINERTYPE_LIST: `${prefix} containertype list`
12
+ CONTAINERTYPE_LIST: `${prefix} containertype list`,
13
+ CONTAINERTYPE_REMOVE: `${prefix} containertype remove`
9
14
  };
10
15
  //# sourceMappingURL=commands.js.map
@@ -59,19 +59,25 @@ class SpoPageSectionAddCommand extends SpoCommand {
59
59
  };
60
60
  await request.post(requestOptions);
61
61
  }
62
- // get columns
63
- const columns = canvasContent
64
- .filter(c => typeof c.controlType === 'undefined');
65
62
  // get unique zoneIndex values given each section can have 1 or more
66
63
  // columns each assigned to the zoneIndex of the corresponding section
67
- const zoneIndices = columns
64
+ const zoneIndices = canvasContent
65
+ // Exclude the vertical section
66
+ .filter(c => c.position)
68
67
  .map(c => c.position.zoneIndex)
69
68
  .filter((value, index, array) => {
70
69
  return array.indexOf(value) === index;
71
70
  })
72
- .sort();
73
- // zoneIndex for the new section to add
74
- const zoneIndex = this.getSectionIndex(zoneIndices, args.options.order);
71
+ .sort((a, b) => a - b);
72
+ // Add a new zoneIndex at the end of the array
73
+ zoneIndices.push(zoneIndices.length > 0 ? zoneIndices[zoneIndices.length - 1] + 1 : 1);
74
+ // get section number. if not specified, get the last section
75
+ let section = args.options.order || zoneIndices.length;
76
+ if (section > zoneIndices.length) {
77
+ section = zoneIndices.length;
78
+ }
79
+ // zoneIndex that represents the section where the web part should be added
80
+ const zoneIndex = zoneIndices[section - 1];
75
81
  let zoneId;
76
82
  let backgroundControlToAdd = undefined;
77
83
  if (args.options.zoneEmphasis && ['image', 'gradient'].includes(args.options.zoneEmphasis.toLowerCase())) {
@@ -83,11 +89,17 @@ class SpoPageSectionAddCommand extends SpoCommand {
83
89
  canvasContent.push(backgroundControlToAdd);
84
90
  }
85
91
  }
92
+ // Increment the zoneIndex of all columns that are greater than or equal to the new zoneIndex
93
+ canvasContent.forEach((c) => {
94
+ if (c.position && c.position.zoneIndex >= zoneIndex) {
95
+ c.position.zoneIndex += 1;
96
+ }
97
+ });
86
98
  // get the list of columns to insert based on the selected template
87
99
  const columnsToAdd = this.getColumns(zoneIndex, args, zoneId);
88
100
  // insert the column in the right place in the array so that
89
101
  // it stays sorted ascending by zoneIndex
90
- let pos = canvasContent.findIndex(c => typeof c.controlType === 'undefined' && c.position && c.position.zoneIndex > zoneIndex);
102
+ let pos = canvasContent.findIndex(c => c.position && c.position.zoneIndex >= zoneIndex);
91
103
  if (pos === -1) {
92
104
  pos = canvasContent.length - 1;
93
105
  }
@@ -109,21 +121,6 @@ class SpoPageSectionAddCommand extends SpoCommand {
109
121
  this.handleRejectedODataJsonPromise(err);
110
122
  }
111
123
  }
112
- getSectionIndex(zoneIndices, order) {
113
- // zoneIndex of the first column on the page
114
- const minIndex = zoneIndices.length === 0 ? 0 : zoneIndices[0];
115
- // zoneIndex of the last column on the page
116
- const maxIndex = zoneIndices.length === 0 ? 0 : zoneIndices[zoneIndices.length - 1];
117
- if (!order || order > zoneIndices.length) {
118
- // no order specified, add section to the end
119
- return maxIndex === 0 ? 1 : maxIndex * 2;
120
- }
121
- // add to the beginning
122
- if (order === 1) {
123
- return minIndex / 2;
124
- }
125
- return zoneIndices[order - 2] + ((zoneIndices[order - 1] - zoneIndices[order - 2]) / 2);
126
- }
127
124
  getColumns(zoneIndex, args, zoneId) {
128
125
  const columns = [];
129
126
  let sectionIndex = 1;
@@ -41,6 +41,17 @@ export const entraServicePrincipal = {
41
41
  return await cli.handleMultipleResultsFound(`Multiple service principals with name '${appName}' found in Microsoft Entra ID.`, resultAsKeyValuePair);
42
42
  }
43
43
  return apps[0];
44
+ },
45
+ /**
46
+ * Get all available service principals.
47
+ * @param properties Comma-separated list of properties to include in the response.
48
+ */
49
+ async getServicePrincipals(properties) {
50
+ let url = `https://graph.microsoft.com/v1.0/servicePrincipals`;
51
+ if (properties) {
52
+ url += `?$select=${properties}`;
53
+ }
54
+ return odata.getAllItems(url);
44
55
  }
45
56
  };
46
57
  //# sourceMappingURL=entraServicePrincipal.js.map
@@ -177,6 +177,18 @@ export const formatting = {
177
177
  resultAsKeyValuePair[obj[key]] = obj;
178
178
  });
179
179
  return resultAsKeyValuePair;
180
+ },
181
+ /**
182
+ * Extracts the GUID from a string in CSOM format.
183
+ * @param str The string to extract the GUID from
184
+ * @description The string should be in the format /Guid(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)/
185
+ * @returns The extracted GUID or the original string if no match is found
186
+ * @example /Guid(eae15efb-ac09-49b9-8906-e579efd622e4)/ => eae15efb-ac09-49b9-8906-e579efd622e4
187
+ */
188
+ extractCsomGuid(str) {
189
+ const guidPattern = /\/Guid\(([0-9a-f-]+)\)\//i;
190
+ const match = str.match(guidPattern);
191
+ return match ? match[1] : str;
180
192
  }
181
193
  };
182
194
  //# sourceMappingURL=formatting.js.map
@@ -0,0 +1,77 @@
1
+ import request from '../request.js';
2
+ import { formatting } from './formatting.js';
3
+ import { cli } from '../cli/cli.js';
4
+ import config from '../config.js';
5
+ import { odata } from './odata.js';
6
+ const graphResource = 'https://graph.microsoft.com';
7
+ export const spe = {
8
+ /**
9
+ * Get all container types.
10
+ * @param spoAdminUrl The URL of the SharePoint Online admin center site (e.g. https://contoso-admin.sharepoint.com)
11
+ * @returns Array of container types
12
+ */
13
+ async getAllContainerTypes(spoAdminUrl) {
14
+ const requestOptions = {
15
+ url: `${spoAdminUrl}/_vti_bin/client.svc/ProcessQuery`,
16
+ headers: {
17
+ accept: 'application/json;odata=nometadata'
18
+ },
19
+ responseType: 'json',
20
+ data: `<Request AddExpandoFieldTypeSuffix="true" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName="${config.applicationName}" xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009"><Actions><ObjectPath Id="46" ObjectPathId="45" /><Method Name="GetSPOContainerTypes" Id="47" ObjectPathId="45"><Parameters><Parameter Type="Enum">1</Parameter></Parameters></Method></Actions><ObjectPaths><Constructor Id="45" TypeId="{268004ae-ef6b-4e9b-8425-127220d84719}" /></ObjectPaths></Request>`
21
+ };
22
+ const json = await request.post(requestOptions);
23
+ const response = json[0];
24
+ if (response.ErrorInfo) {
25
+ throw new Error(response.ErrorInfo.ErrorMessage);
26
+ }
27
+ const containerTypes = json[json.length - 1];
28
+ // Format the response to remove CSOM GUIDs and convert them to real GUIDs
29
+ containerTypes.forEach(ct => {
30
+ delete ct._ObjectType_;
31
+ ct.AzureSubscriptionId = formatting.extractCsomGuid(ct.AzureSubscriptionId);
32
+ ct.ContainerTypeId = formatting.extractCsomGuid(ct.ContainerTypeId);
33
+ ct.OwningAppId = formatting.extractCsomGuid(ct.OwningAppId);
34
+ ct.OwningTenantId = formatting.extractCsomGuid(ct.OwningTenantId);
35
+ });
36
+ return containerTypes;
37
+ },
38
+ /**
39
+ * Get the ID of a container type by its name.
40
+ * @param spoAdminUrl SharePoint Online admin center URL (e.g. https://contoso-admin.sharepoint.com)
41
+ * @param name Name of the container type to search for
42
+ * @returns ID of the container type
43
+ */
44
+ async getContainerTypeIdByName(spoAdminUrl, name) {
45
+ const allContainerTypes = await this.getAllContainerTypes(spoAdminUrl);
46
+ const containerTypes = allContainerTypes.filter(ct => ct.DisplayName.toLowerCase() === name.toLowerCase());
47
+ if (containerTypes.length === 0) {
48
+ throw new Error(`The specified container type '${name}' does not exist.`);
49
+ }
50
+ if (containerTypes.length > 1) {
51
+ const containerTypeKeyValuePair = formatting.convertArrayToHashTable('ContainerTypeId', containerTypes);
52
+ const containerType = await cli.handleMultipleResultsFound(`Multiple container types with name '${name}' found.`, containerTypeKeyValuePair);
53
+ return containerType.ContainerTypeId;
54
+ }
55
+ return containerTypes[0].ContainerTypeId;
56
+ },
57
+ /**
58
+ * Get the ID of a container by its name.
59
+ * @param containerTypeId ID of the container type.
60
+ * @param name Name of the container to search for.
61
+ * @returns ID of the container.
62
+ */
63
+ async getContainerIdByName(containerTypeId, name) {
64
+ const containers = await odata.getAllItems(`${graphResource}/v1.0/storage/fileStorage/containers?$filter=containerTypeId eq ${containerTypeId}&$select=id,displayName`);
65
+ const matchingContainers = containers.filter(c => c.displayName.toLowerCase() === name.toLowerCase());
66
+ if (matchingContainers.length === 0) {
67
+ throw new Error(`The specified container '${name}' does not exist.`);
68
+ }
69
+ if (matchingContainers.length > 1) {
70
+ const containerKeyValuePair = formatting.convertArrayToHashTable('id', matchingContainers);
71
+ const container = await cli.handleMultipleResultsFound(`Multiple containers with name '${name}' found.`, containerKeyValuePair);
72
+ return container.id;
73
+ }
74
+ return matchingContainers[0].id;
75
+ }
76
+ };
77
+ //# sourceMappingURL=spe.js.map
package/dist/utils/spo.js CHANGED
@@ -53,24 +53,6 @@ export const spo = {
53
53
  };
54
54
  return context;
55
55
  },
56
- async getAllContainerTypes(spoAdminUrl, logger, verbose) {
57
- const formDigestInfo = await spo.ensureFormDigest(spoAdminUrl, logger, undefined, verbose);
58
- const requestOptions = {
59
- url: `${spoAdminUrl}/_vti_bin/client.svc/ProcessQuery`,
60
- headers: {
61
- 'X-RequestDigest': formDigestInfo.FormDigestValue
62
- },
63
- data: `<Request AddExpandoFieldTypeSuffix="true" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName="${config.applicationName}" xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009"><Actions><ObjectPath Id="46" ObjectPathId="45" /><Method Name="GetSPOContainerTypes" Id="47" ObjectPathId="45"><Parameters><Parameter Type="Enum">1</Parameter></Parameters></Method></Actions><ObjectPaths><Constructor Id="45" TypeId="{268004ae-ef6b-4e9b-8425-127220d84719}" /></ObjectPaths></Request>`
64
- };
65
- const res = await request.post(requestOptions);
66
- const json = JSON.parse(res);
67
- const response = json[0];
68
- if (response.ErrorInfo) {
69
- throw new Error(response.ErrorInfo.ErrorMessage);
70
- }
71
- const containerTypes = json[json.length - 1];
72
- return containerTypes;
73
- },
74
56
  async waitUntilFinished({ operationId, siteUrl, logger, currentContext, debug, verbose }) {
75
57
  const resFormDigest = await spo.ensureFormDigest(siteUrl, logger, currentContext, debug);
76
58
  currentContext = resFormDigest;
package/dist/utils/zod.js CHANGED
@@ -110,16 +110,41 @@ function parseDef(def, options, currentOption) {
110
110
  }
111
111
  } while (parsedDef);
112
112
  }
113
+ function optionToString(optionInfo) {
114
+ let s = '';
115
+ if (optionInfo.short) {
116
+ s += `-${optionInfo.short}, `;
117
+ }
118
+ s += `--${optionInfo.long}`;
119
+ if (optionInfo.type !== 'boolean') {
120
+ s += ' ';
121
+ s += optionInfo.required ? '<' : '[';
122
+ s += optionInfo.long;
123
+ s += optionInfo.required ? '>' : ']';
124
+ }
125
+ return s;
126
+ }
127
+ ;
113
128
  export const zod = {
114
129
  alias(alias, type) {
115
130
  type._def.alias = alias;
116
131
  return type;
117
132
  },
118
- schemaToOptions(schema) {
133
+ schemaToOptionInfo(schema) {
119
134
  const options = [];
120
135
  parseDef(schema._def, options);
121
136
  return options;
122
137
  },
138
+ schemaToOptions(schema) {
139
+ const optionsInfo = this.schemaToOptionInfo(schema);
140
+ const options = optionsInfo.map(option => {
141
+ return {
142
+ option: optionToString(option),
143
+ autocomplete: option.autocomplete
144
+ };
145
+ });
146
+ return options;
147
+ },
123
148
  coercedEnum: (e) => z.preprocess(val => {
124
149
  const target = String(val)?.toLowerCase();
125
150
  for (const k of Object.values(e)) {
@@ -17,7 +17,7 @@ m365 adaptivecard send [options]
17
17
  : URL where to send the card to.
18
18
 
19
19
  `-t, --title [title]`
20
- : Title of the card. Specify either `title` or `card` but not both.
20
+ : Title of the card. If you specify `title` and `card`, the `title` will be merged into the card.
21
21
 
22
22
  `-d, --description [description]`
23
23
  : Contents of the card.
@@ -0,0 +1,63 @@
1
+ import Global from '/docs/cmd/_global.mdx';
2
+ import Tabs from '@theme/Tabs';
3
+ import TabItem from '@theme/TabItem';
4
+
5
+ # cli app reconsent
6
+
7
+ Reconsent all permission scopes used in CLI for Microsoft 365
8
+
9
+ ## Usage
10
+
11
+ ```sh
12
+ m365 cli app reconsent [options]
13
+ ```
14
+
15
+ ## Options
16
+
17
+ <Global />
18
+
19
+ ## Remarks
20
+
21
+ This command will add all missing scopes used in CLI for Microsoft 365 to your current app registration. It will only add missing scopes and won't remove any scopes that are already present in the app registration.
22
+
23
+ ## Examples
24
+
25
+ Consent all permission scopes used in CLI for Microsoft 365 to the current app registration
26
+
27
+ ```sh
28
+ m365 cli app reconsent
29
+ ```
30
+
31
+ ## Response
32
+
33
+ <Tabs>
34
+ <TabItem value="JSON">
35
+
36
+ ```json
37
+ "To consent to the new scopes for your Microsoft Entra application registration, please navigate to the following URL: https://login.microsoftonline.com/f72203fd-b0a0-472d-85eb-079a117a80de/adminconsent?client_id=62b981af-59d3-4d25-8baf-6cc067a03102"
38
+ ```
39
+
40
+ </TabItem>
41
+ <TabItem value="Text">
42
+
43
+ ```text
44
+ To consent to the new scopes for your Microsoft Entra application registration, please navigate to the following URL: https://login.microsoftonline.com/f72203fd-b0a0-472d-85eb-079a117a80de/adminconsent?client_id=62b981af-59d3-4d25-8baf-6cc067a03102
45
+ ```
46
+
47
+ </TabItem>
48
+ <TabItem value="CSV">
49
+
50
+ ```csv
51
+ To consent to the new scopes for your Microsoft Entra application registration, please navigate to the following URL: https://login.microsoftonline.com/f72203fd-b0a0-472d-85eb-079a117a80de/adminconsent?client_id=62b981af-59d3-4d25-8baf-6cc067a03102
52
+ ```
53
+
54
+ </TabItem>
55
+ <TabItem value="Markdown">
56
+
57
+ ```md
58
+ To consent to the new scopes for your Microsoft Entra application registration, please navigate to the following URL: https://login.microsoftonline.com/f72203fd-b0a0-472d-85eb-079a117a80de/adminconsent?client_id=62b981af-59d3-4d25-8baf-6cc067a03102
59
+ ```
60
+
61
+ </TabItem>
62
+ </Tabs>
63
+
@@ -0,0 +1,154 @@
1
+ import Global from '/docs/cmd/_global.mdx';
2
+ import Tabs from '@theme/Tabs';
3
+ import TabItem from '@theme/TabItem';
4
+
5
+ # entra organization list
6
+
7
+ Retrieves a list of organizations
8
+
9
+ ## Usage
10
+
11
+ ```sh
12
+ m365 entra organization list [options]
13
+ ```
14
+
15
+ ## Options
16
+
17
+ ```md definition-list
18
+ `-p, --properties [properties]`
19
+ : The comma separated list of properties to be returned.
20
+ ```
21
+
22
+ <Global />
23
+
24
+ ## Remarks
25
+
26
+ :::info
27
+
28
+ Applications granted the `User.Read` permission are able to read only the id, displayName, and verifiedDomains properties of the organization.
29
+ All other properties return with null values. To read all properties, use at least `Organization.Read.All`.
30
+
31
+ :::
32
+
33
+ ## Examples
34
+
35
+ Retrieve organizations
36
+
37
+ ```sh
38
+ m365 entra organization list
39
+ ```
40
+
41
+ Retrieve specific info
42
+
43
+ ```sh
44
+ m365 entra organization list --properties 'id,displayName,tenantType'
45
+ ```
46
+
47
+ ## Response
48
+
49
+ <Tabs>
50
+ <TabItem value="JSON">
51
+
52
+ ```json
53
+ [
54
+ {
55
+ "id": "e65b162c-6f87-4eb1-a24e-1b37d3504663",
56
+ "deletedDateTime": null,
57
+ "businessPhones": [
58
+ "4258828080"
59
+ ],
60
+ "city": null,
61
+ "country": null,
62
+ "countryLetterCode": "IE",
63
+ "createdDateTime": "2023-02-21T19:56:38Z",
64
+ "defaultUsageLocation": null,
65
+ "displayName": "Contoso",
66
+ "isMultipleDataLocationsForServicesEnabled": null,
67
+ "marketingNotificationEmails": [],
68
+ "onPremisesLastSyncDateTime": null,
69
+ "onPremisesSyncEnabled": null,
70
+ "partnerTenantType": null,
71
+ "postalCode": null,
72
+ "preferredLanguage": "en",
73
+ "securityComplianceNotificationMails": [],
74
+ "securityComplianceNotificationPhones": [],
75
+ "state": null,
76
+ "street": null,
77
+ "technicalNotificationMails": [
78
+ "john.doe@contoso.com"
79
+ ],
80
+ "tenantType": "AAD",
81
+ "directorySizeQuota": {
82
+ "used": 1400,
83
+ "total": 300000
84
+ },
85
+ "assignedPlans": [],
86
+ "onPremisesSyncStatus": [],
87
+ "privacyProfile": {
88
+ "contactEmail": "john.doe@contoso.com",
89
+ "statementUrl": ""
90
+ },
91
+ "provisionedPlans": [],
92
+ "verifiedDomains": [
93
+ {
94
+ "capabilities": "Email, OfficeCommunicationsOnline",
95
+ "isDefault": true,
96
+ "isInitial": true,
97
+ "name": "contoso.onmicrosoft.com",
98
+ "type": "Managed"
99
+ },
100
+ {
101
+ "capabilities": "Email, OfficeCommunicationsOnline, MoeraDomain",
102
+ "isDefault": false,
103
+ "isInitial": false,
104
+ "name": "contoso2.onmicrosoft.com",
105
+ "type": "Managed"
106
+ }
107
+ ]
108
+ }
109
+ ]
110
+ ```
111
+
112
+ </TabItem>
113
+ <TabItem value="Text">
114
+
115
+ ```text
116
+ displayName: Contoso
117
+ id : e65b162c-6f87-4eb1-a24e-1b37d3504663
118
+ tenantType : AAD
119
+ ```
120
+
121
+ </TabItem>
122
+ <TabItem value="CSV">
123
+
124
+ ```csv
125
+ id,deletedDateTime,city,country,countryLetterCode,createdDateTime,defaultUsageLocation,displayName,isMultipleDataLocationsForServicesEnabled,onPremisesLastSyncDateTime,onPremisesSyncEnabled,partnerTenantType,postalCode,preferredLanguage,state,street,tenantType
126
+ e65b162c-6f87-4eb1-a24e-1b37d3504663,,,,IE,2023-02-21T19:56:38Z,,Contoso,,,,,,en,,,AAD
127
+ ```
128
+
129
+ </TabItem>
130
+ <TabItem value="Markdown">
131
+
132
+ ```md
133
+ # entra organization list --debug "false" --verbose "false"
134
+
135
+ Date: 4/18/2025
136
+
137
+ ## Contoso (e65b162c-6f87-4eb1-a24e-1b37d3504663)
138
+
139
+ Property | Value
140
+ ---------|-------
141
+ id | e65b162c-6f87-4eb1-a24e-1b37d3504663
142
+ countryLetterCode | IE
143
+ createdDateTime | 2023-02-21T19:56:38Z
144
+ displayName | Contoso
145
+ preferredLanguage | en
146
+ tenantType | AAD
147
+ ```
148
+
149
+ </TabItem>
150
+ </Tabs>
151
+
152
+ ## More information
153
+
154
+ - Organization: https://learn.microsoft.com/graph/api/organization-list
@@ -0,0 +1,97 @@
1
+ import Global from '/docs/cmd/_global.mdx';
2
+ import Tabs from '@theme/Tabs';
3
+ import TabItem from '@theme/TabItem';
4
+
5
+ # graph openextension set
6
+
7
+ Updates an open extension for a resource
8
+
9
+ ## Usage
10
+
11
+ ```sh
12
+ m365 graph openextension set [options]
13
+ ```
14
+
15
+ ## Options
16
+
17
+ ```md definition-list
18
+ `-n, --name <name>`
19
+ : The name of the open extension.
20
+
21
+ `-i, --resourceId <resourceId>`
22
+ : The Id of the resource for which to update the open extension.
23
+
24
+ `-t, --resourceType <resourceType>`
25
+ : The type of resource. Allowed values are `user`, `group`, `device`, `organization`.
26
+
27
+ `-k, --keepUnchangedProperties`
28
+ : Keeps unspecified properties. Without this flag, any property that is not updated will be removed from the extension.
29
+ ```
30
+
31
+ <Global />
32
+
33
+ ## Remarks
34
+
35
+ This command allows using unknown options to update custom data of the open extension.
36
+
37
+ When updating an open extension to a user, it's possible to use the UPN as the resourceId.
38
+
39
+ :::warning[Escaping JSON in PowerShell]
40
+
41
+ When updating open extensions it's possible to enter a JSON string. In PowerShell 5 to 7.2 [specific escaping rules](./../../../user-guide/using-cli.mdx#escaping-double-quotes-in-powershell) apply due to an issue. Remember that you can also use [file tokens](./../../../user-guide/using-cli.mdx#passing-complex-content-into-cli-options) instead.
42
+
43
+ :::
44
+
45
+ :::info
46
+
47
+ If a property of the open extension is not specified, the property is removed from the open extension.
48
+
49
+ If a property of the open extension is not specified and `keepUnchangedProperties` is specified, the property will be kept in the open extension.
50
+
51
+ :::
52
+
53
+ ## Examples
54
+
55
+ Updates an open extension for a user specified by id
56
+
57
+ ```sh
58
+ m365 graph openextension set --userId eb77fbcf-6fe8-458b-985d-1747284793bc --name 'com.contoso.roamingSettings' --resourceType user --theme dark --color red --language English
59
+ ```
60
+
61
+ Updates an open extension for a user specified by UPN
62
+
63
+ ```sh
64
+ m365 graph openextension set --userName john.doe@contoso.com --name 'com.contoso.roamingSettings' --resourceType user --theme dark --color red --language English
65
+ ```
66
+
67
+ Updates an open extension for a group specified by id, one of the property represents a JSON object
68
+
69
+ ```sh
70
+ m365 graph openextension set --resourceId c956e711-f074-40c3-8431-fbd69bb67d9c --name 'com.contoso.roamingSettings' --resourceType group --settings '{"theme": "dark", "color": "red" }'
71
+ ```
72
+
73
+ Updates an open extension, but keeps the properties that are not specified
74
+
75
+ ```sh
76
+ m365 graph openextension set --userId eb77fbcf-6fe8-458b-985d-1747284793bc --name 'com.contoso.roamingSettings' --resourceType user --color red --keepUnchangedProperties
77
+ ```
78
+
79
+ Updates an open extension, but removes the properties that are not specified
80
+
81
+ ```sh
82
+ m365 graph openextension set --userId eb77fbcf-6fe8-458b-985d-1747284793bc --name 'com.contoso.roamingSettings' --resourceType user --color red
83
+ ```
84
+
85
+ Clears the value of the property
86
+
87
+ ```sh
88
+ m365 graph openextension set --userId eb77fbcf-6fe8-458b-985d-1747284793bc --name 'com.contoso.roamingSettings' --resourceType user --theme ""
89
+ ```
90
+
91
+ ## Response
92
+
93
+ The command won't return a response on success.
94
+
95
+ ## More information
96
+
97
+ - Open extensions: https://learn.microsoft.com/graph/extensibility-overview?tabs=http#open-extensions
@@ -1,6 +1,4 @@
1
1
  import Global from '/docs/cmd/_global.mdx';
2
- import Tabs from '@theme/Tabs';
3
- import TabItem from '@theme/TabItem';
4
2
 
5
3
  # spe container activate
6
4