@pnp/cli-microsoft365 10.5.0 → 10.6.0-beta.195c8d5

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 (72) hide show
  1. package/.eslintrc.cjs +3 -1
  2. package/allCommands.json +1 -1
  3. package/allCommandsFull.json +1 -1
  4. package/dist/Auth.js +2 -1
  5. package/dist/Command.js +14 -26
  6. package/dist/auth/MsalNetworkClient.js +32 -0
  7. package/dist/config.js +2 -0
  8. package/dist/m365/adaptivecard/commands/adaptivecard-send.js +2 -1
  9. package/dist/m365/app/commands/app-get.js +3 -13
  10. package/dist/m365/app/commands/permission/permission-list.js +4 -14
  11. package/dist/m365/base/SpoCommand.js +2 -1
  12. package/dist/m365/commands/request.js +3 -12
  13. package/dist/m365/commands/setup.js +2 -0
  14. package/dist/m365/entra/commands/administrativeunit/administrativeunit-add.js +10 -5
  15. package/dist/m365/entra/commands/app/app-add.js +5 -0
  16. package/dist/m365/entra/commands/app/app-get.js +27 -21
  17. package/dist/m365/entra/commands/app/app-permission-list.js +28 -22
  18. package/dist/m365/entra/commands/app/app-remove.js +22 -19
  19. package/dist/m365/entra/commands/app/app-role-add.js +22 -19
  20. package/dist/m365/entra/commands/app/app-role-list.js +22 -19
  21. package/dist/m365/entra/commands/app/app-role-remove.js +39 -36
  22. package/dist/m365/entra/commands/app/app-set.js +45 -19
  23. package/dist/m365/entra/commands/group/group-add.js +1 -0
  24. package/dist/m365/entra/commands/group/group-set.js +12 -6
  25. package/dist/m365/entra/commands/policy/policy-list.js +46 -3
  26. package/dist/m365/entra/commands/user/user-add.js +1 -0
  27. package/dist/m365/entra/commands/user/user-list.js +2 -1
  28. package/dist/m365/external/commands/item/item-add.js +2 -1
  29. package/dist/m365/flow/commands/flow-list.js +1 -1
  30. package/dist/m365/graph/commands/openextension/openextension-add.js +73 -0
  31. package/dist/m365/graph/commands/openextension/openextension-get.js +57 -0
  32. package/dist/m365/graph/commands/openextension/openextension-list.js +62 -0
  33. package/dist/m365/graph/commands/openextension/openextension-remove.js +68 -0
  34. package/dist/m365/graph/commands.js +4 -0
  35. package/dist/m365/pp/commands/card/card-clone.js +12 -16
  36. package/dist/m365/pp/commands/card/card-get.js +13 -19
  37. package/dist/m365/pp/commands/card/card-remove.js +13 -16
  38. package/dist/m365/pp/commands/solution/solution-get.js +5 -11
  39. package/dist/m365/pp/commands/solution/solution-publish.js +6 -16
  40. package/dist/m365/pp/commands/solution/solution-remove.js +4 -13
  41. package/dist/m365/spfx/commands/project/project-doctor/doctor-1.21.0.js +25 -0
  42. package/dist/m365/spfx/commands/project/project-doctor.js +2 -1
  43. package/dist/m365/spfx/commands/project/project-upgrade/rules/FN002029_DEVDEP_microsoft_rush_stack_compiler_5_3.js +13 -0
  44. package/dist/m365/spfx/commands/project/project-upgrade/upgrade-1.21.0.js +63 -0
  45. package/dist/m365/spfx/commands/project/project-upgrade.js +2 -1
  46. package/dist/m365/spfx/commands/spfx-doctor.js +15 -0
  47. package/dist/m365/spo/commands/folder/folder-roleassignment-add.js +12 -47
  48. package/dist/m365/spo/commands/folder/folder-roleassignment-remove.js +13 -31
  49. package/dist/m365/spo/commands/listitem/listitem-roleassignment-add.js +12 -43
  50. package/dist/m365/spo/commands/listitem/listitem-roleassignment-remove.js +8 -27
  51. package/dist/m365/spo/commands/web/web-roleassignment-add.js +22 -47
  52. package/dist/m365/spo/commands/web/web-roleassignment-remove.js +17 -32
  53. package/dist/m365/tenant/commands/people/people-profilecardproperty-add.js +4 -3
  54. package/dist/m365/tenant/commands/people/people-profilecardproperty-set.js +4 -3
  55. package/dist/m365/todo/commands/list/list-remove.js +1 -1
  56. package/dist/m365/util/commands/accesstoken/accesstoken-get.js +13 -3
  57. package/dist/utils/accessToken.js +8 -0
  58. package/dist/utils/entraApp.js +3 -1
  59. package/dist/utils/optionsUtils.js +28 -0
  60. package/dist/utils/powerPlatform.js +51 -1
  61. package/dist/utils/prompt.js +9 -2
  62. package/dist/utils/spo.js +32 -3
  63. package/docs/docs/cmd/entra/policy/policy-list.mdx +1 -1
  64. package/docs/docs/cmd/graph/directoryextension/directoryextension-get.mdx +2 -3
  65. package/docs/docs/cmd/graph/openextension/openextension-add.mdx +120 -0
  66. package/docs/docs/cmd/graph/openextension/openextension-get.mdx +111 -0
  67. package/docs/docs/cmd/graph/openextension/openextension-list.mdx +129 -0
  68. package/docs/docs/cmd/graph/openextension/openextension-remove.mdx +59 -0
  69. package/docs/docs/cmd/spfx/project/project-upgrade.mdx +1 -4
  70. package/docs/docs/cmd/util/accesstoken/accesstoken-get.mdx +72 -0
  71. package/npm-shrinkwrap.json +517 -481
  72. package/package.json +15 -15
@@ -7,6 +7,7 @@ var _UtilAccessTokenGetCommand_instances, _UtilAccessTokenGetCommand_initTelemet
7
7
  import auth, { Auth } from '../../../../Auth.js';
8
8
  import Command from '../../../../Command.js';
9
9
  import commands from '../../commands.js';
10
+ import { accessToken } from '../../../../utils/accessToken.js';
10
11
  class UtilAccessTokenGetCommand extends Command {
11
12
  get name() {
12
13
  return commands.ACCESSTOKEN_GET;
@@ -34,8 +35,14 @@ class UtilAccessTokenGetCommand extends Command {
34
35
  resource = Auth.getEndpointForResource('https://graph.microsoft.com', auth.connection.cloudType);
35
36
  }
36
37
  try {
37
- const accessToken = await auth.ensureAccessToken(resource, logger, this.debug, args.options.new);
38
- await logger.log(accessToken);
38
+ const token = await auth.ensureAccessToken(resource, logger, this.debug, args.options.new);
39
+ if (args.options.decoded) {
40
+ const { header, payload } = accessToken.getDecodedAccessToken(token);
41
+ await logger.logRaw(`${JSON.stringify(header, null, 2)}.${JSON.stringify(payload, null, 2)}.[signature]`);
42
+ }
43
+ else {
44
+ await logger.log(token);
45
+ }
39
46
  }
40
47
  catch (err) {
41
48
  this.handleRejectedODataJsonPromise(err);
@@ -45,7 +52,8 @@ class UtilAccessTokenGetCommand extends Command {
45
52
  _UtilAccessTokenGetCommand_instances = new WeakSet(), _UtilAccessTokenGetCommand_initTelemetry = function _UtilAccessTokenGetCommand_initTelemetry() {
46
53
  this.telemetry.push((args) => {
47
54
  Object.assign(this.telemetryProperties, {
48
- new: args.options.new
55
+ new: args.options.new,
56
+ decoded: args.options.decoded
49
57
  });
50
58
  });
51
59
  }, _UtilAccessTokenGetCommand_initOptions = function _UtilAccessTokenGetCommand_initOptions() {
@@ -53,6 +61,8 @@ _UtilAccessTokenGetCommand_instances = new WeakSet(), _UtilAccessTokenGetCommand
53
61
  option: '-r, --resource <resource>'
54
62
  }, {
55
63
  option: '--new'
64
+ }, {
65
+ option: '--decoded'
56
66
  });
57
67
  };
58
68
  export default new UtilAccessTokenGetCommand();
@@ -75,6 +75,14 @@ export const accessToken = {
75
75
  }
76
76
  return userId;
77
77
  },
78
+ getDecodedAccessToken(accessToken) {
79
+ const chunks = accessToken.split('.');
80
+ const headerString = Buffer.from(chunks[0], 'base64').toString();
81
+ const payloadString = Buffer.from(chunks[1], 'base64').toString();
82
+ const header = JSON.parse(headerString);
83
+ const payload = JSON.parse(payloadString);
84
+ return { header, payload };
85
+ },
78
86
  /**
79
87
  * Asserts the presence of a delegated access token.
80
88
  * @throws {CommandError} Will throw an error if the access token is not available.
@@ -3,6 +3,7 @@ import request from '../request.js';
3
3
  import { odata } from './odata.js';
4
4
  import { formatting } from './formatting.js';
5
5
  import { cli } from '../cli/cli.js';
6
+ import { optionsUtils } from './optionsUtils.js';
6
7
  async function getCertificateBase64Encoded({ options, logger, debug }) {
7
8
  if (options.certificateBase64Encoded) {
8
9
  return options.certificateBase64Encoded;
@@ -129,7 +130,7 @@ function updateAppPermissions({ spId, resourceAccessPermission, oAuth2Permission
129
130
  }
130
131
  export const entraApp = {
131
132
  appPermissions: [],
132
- createAppRegistration: async ({ options, apis, logger, verbose, debug }) => {
133
+ createAppRegistration: async ({ options, apis, logger, verbose, debug, unknownOptions }) => {
133
134
  const applicationInfo = {
134
135
  displayName: options.name,
135
136
  signInAudience: options.multitenant ? 'AzureADMultipleOrgs' : 'AzureADMyOrg'
@@ -164,6 +165,7 @@ export const entraApp = {
164
165
  if (options.allowPublicClientFlows) {
165
166
  applicationInfo.isFallbackPublicClient = true;
166
167
  }
168
+ optionsUtils.addUnknownOptionsToPayload(applicationInfo, unknownOptions);
167
169
  if (verbose) {
168
170
  await logger.logToStderr(`Creating Microsoft Entra app registration...`);
169
171
  }
@@ -0,0 +1,28 @@
1
+ const longOptionRegex = /--([^\s]+)/;
2
+ const shortOptionRegex = /-([a-z])\b/;
3
+ export const optionsUtils = {
4
+ getUnknownOptions(options, knownOptions) {
5
+ const unknownOptions = JSON.parse(JSON.stringify(options));
6
+ // remove minimist catch-all option
7
+ delete unknownOptions._;
8
+ knownOptions.forEach(o => {
9
+ const longOptionName = longOptionRegex.exec(o.option)[1];
10
+ delete unknownOptions[longOptionName];
11
+ // short names are optional so we need to check if the current command has
12
+ // one before continuing
13
+ const shortOptionMatch = shortOptionRegex.exec(o.option);
14
+ if (shortOptionMatch) {
15
+ const shortOptionName = shortOptionMatch[1];
16
+ delete unknownOptions[shortOptionName];
17
+ }
18
+ });
19
+ return unknownOptions;
20
+ },
21
+ addUnknownOptionsToPayload(payload, unknownOptions) {
22
+ const unknownOptionsNames = Object.getOwnPropertyNames(unknownOptions);
23
+ unknownOptionsNames.forEach(o => {
24
+ payload[o] = unknownOptions[o];
25
+ });
26
+ }
27
+ };
28
+ //# sourceMappingURL=optionsUtils.js.map
@@ -51,7 +51,7 @@ export const powerPlatform = {
51
51
  }
52
52
  if (items.length > 1) {
53
53
  const resultAsKeyValuePair = formatting.convertArrayToHashTable('websiteUrl', items);
54
- return cli.handleMultipleResultsFound(`Multiple Power Page websites with name '${websiteName}' found`, resultAsKeyValuePair);
54
+ return cli.handleMultipleResultsFound(`Multiple Power Page websites with name '${websiteName}' found.`, resultAsKeyValuePair);
55
55
  }
56
56
  return items[0];
57
57
  },
@@ -62,6 +62,56 @@ export const powerPlatform = {
62
62
  throw Error(`The specified Power Page website with url '${url}' does not exist.`);
63
63
  }
64
64
  return items[0];
65
+ },
66
+ /**
67
+ * Get a card by name
68
+ * Returns a card object
69
+ * @param dynamicsApiUrl The dynamics api url of the environment
70
+ * @param name The name of the card
71
+ * @param logger The logger object
72
+ * @param verbose Set for verbose logging
73
+ */
74
+ async getCardByName(dynamicsApiUrl, name) {
75
+ const requestOptions = {
76
+ url: `${dynamicsApiUrl}/api/data/v9.1/cards?$filter=name eq '${name}'`,
77
+ headers: {
78
+ accept: 'application/json;odata.metadata=none'
79
+ },
80
+ responseType: 'json'
81
+ };
82
+ const result = await request.get(requestOptions);
83
+ if (result.value.length === 0) {
84
+ throw Error(`The specified card '${name}' does not exist.`);
85
+ }
86
+ if (result.value.length > 1) {
87
+ const resultAsKeyValuePair = formatting.convertArrayToHashTable('cardid', result.value);
88
+ return cli.handleMultipleResultsFound(`Multiple cards with name '${name}' found.`, resultAsKeyValuePair);
89
+ }
90
+ return result.value[0];
91
+ },
92
+ /**
93
+ * Get a solution by name
94
+ * Returns the solution object
95
+ * @param dynamicsApiUrl The dynamics api url of the environment
96
+ * @param name The name of the solution
97
+ */
98
+ async getSolutionByName(dynamicsApiUrl, name) {
99
+ const requestOptions = {
100
+ url: `${dynamicsApiUrl}/api/data/v9.0/solutions?$filter=isvisible eq true and uniquename eq \'${name}\'&$expand=publisherid($select=friendlyname)&$select=solutionid,uniquename,version,publisherid,installedon,solutionpackageversion,friendlyname,versionnumber&api-version=9.1`,
101
+ headers: {
102
+ accept: 'application/json;odata.metadata=none'
103
+ },
104
+ responseType: 'json'
105
+ };
106
+ const result = await request.get(requestOptions);
107
+ if (result.value.length === 0) {
108
+ throw Error(`The specified solution '${name}' does not exist.`);
109
+ }
110
+ if (result.value.length > 1) {
111
+ const resultAsKeyValuePair = formatting.convertArrayToHashTable('solutionid', result.value);
112
+ return cli.handleMultipleResultsFound(`Multiple solutions with name '${name}' found.`, resultAsKeyValuePair);
113
+ }
114
+ return result.value[0];
65
115
  }
66
116
  };
67
117
  //# sourceMappingURL=powerPlatform.js.map
@@ -6,13 +6,20 @@ let inquirerSelect;
6
6
  ;
7
7
  ;
8
8
  export const prompt = {
9
- /* c8 ignore next 9 */
9
+ /* c8 ignore next 16 */
10
10
  async forInput(config) {
11
11
  if (!inquirerInput) {
12
12
  inquirerInput = await import('@inquirer/input');
13
13
  }
14
14
  const errorOutput = cli.getSettingWithDefaultValue(settingsNames.errorOutput, 'stderr');
15
- return inquirerInput.default(config, { output: errorOutput === 'stderr' ? process.stderr : process.stdout });
15
+ return inquirerInput
16
+ .default(config, { output: errorOutput === 'stderr' ? process.stderr : process.stdout })
17
+ .catch(error => {
18
+ if (error instanceof Error && error.name === 'ExitPromptError') {
19
+ return ''; // noop; handle Ctrl + C
20
+ }
21
+ throw error;
22
+ });
16
23
  },
17
24
  /* c8 ignore next 9 */
18
25
  async forConfirmation(config) {
package/dist/utils/spo.js CHANGED
@@ -519,10 +519,11 @@ export const spo = {
519
519
  },
520
520
  /**
521
521
  * Retrieves the spo user by email.
522
+ * Returns a user object
522
523
  * @param webUrl Web url
523
524
  * @param email The email of the user
524
525
  * @param logger the Logger object
525
- * @param verbose set for verbose logging
526
+ * @param verbose Set for verbose logging
526
527
  */
527
528
  async getUserByEmail(webUrl, email, logger, verbose) {
528
529
  if (verbose && logger) {
@@ -593,10 +594,11 @@ export const spo = {
593
594
  },
594
595
  /**
595
596
  * Retrieves the spo group by name.
597
+ * Returns a group object
596
598
  * @param webUrl Web url
597
599
  * @param name The name of the group
598
600
  * @param logger the Logger object
599
- * @param verbose set for verbose logging
601
+ * @param verbose Set for verbose logging
600
602
  */
601
603
  async getGroupByName(webUrl, name, logger, verbose) {
602
604
  if (verbose && logger) {
@@ -615,10 +617,13 @@ export const spo = {
615
617
  },
616
618
  /**
617
619
  * Retrieves the role definition by name.
620
+ * Returns a RoleDefinition object
621
+ * Returns a RoleDefinition object
618
622
  * @param webUrl Web url
619
623
  * @param name the name of the role definition
620
624
  * @param logger the Logger object
621
- * @param verbose set for verbose logging
625
+ * @param verbose Set for verbose logging
626
+ * @param verbose Set for verbose logging
622
627
  */
623
628
  async getRoleDefinitionByName(webUrl, name, logger, verbose) {
624
629
  if (verbose && logger) {
@@ -1753,6 +1758,30 @@ export const spo = {
1753
1758
  responseType: 'json'
1754
1759
  };
1755
1760
  return request.post(requestOptions);
1761
+ },
1762
+ /**
1763
+ * Get a role definition by name
1764
+ * Returns a RoleDefinition object
1765
+ * @param webUrl The web url
1766
+ * @param name the name of the role definition
1767
+ * @param logger The logger object
1768
+ * @param verbose Set for verbose logging
1769
+ */
1770
+ async getRoleDefintionByName(webUrl, name, logger, verbose) {
1771
+ if (verbose && logger) {
1772
+ await logger.logToStderr(`Retrieving the role definition by name ${name}`);
1773
+ }
1774
+ const response = await odata.getAllItems(`${webUrl}/_api/web/roledefinitions`);
1775
+ const roleDefinition = response.find((role) => role.Name === name);
1776
+ if (!roleDefinition) {
1777
+ throw new Error(`The specified role definition name '${name}' does not exist.`);
1778
+ }
1779
+ const permissions = new BasePermissions();
1780
+ permissions.high = roleDefinition.BasePermissions.High;
1781
+ permissions.low = roleDefinition.BasePermissions.Low;
1782
+ roleDefinition.BasePermissionsValue = permissions.parse();
1783
+ roleDefinition.RoleTypeKindValue = RoleType[roleDefinition.RoleTypeKind];
1784
+ return roleDefinition;
1756
1785
  }
1757
1786
  };
1758
1787
  //# sourceMappingURL=spo.js.map
@@ -16,7 +16,7 @@ m365 entra policy list [options]
16
16
 
17
17
  ```md definition-list
18
18
  `-t, --type [type]`
19
- : The type of policies to return. Allowed values `activityBasedTimeout`, `authorization`, `claimsMapping`, `homeRealmDiscovery`, `identitySecurityDefaultsEnforcement`, `tokenIssuance`, `tokenLifetime`. If omitted, all policies are returned.
19
+ : The type of policies to return. Allowed values `activityBasedTimeout`, `adminConsentRequest`, `appManagement`, `authenticationFlows`, `authenticationMethods`, `authenticationStrength`, `authorization`, `claimsMapping`, `conditionalAccess`, `crossTenantAccess`, `defaultAppManagement`, `deviceRegistration`, `featureRolloutPolicy`, `homeRealmDiscovery`, `identitySecurityDefaultsEnforcement`, `permissionGrant`, `roleManagement`, `tokenIssuance`, `tokenLifetime`. If omitted, all policies are returned.
20
20
  ```
21
21
 
22
22
  <Global />
@@ -38,16 +38,15 @@ m365 graph directoryextension get [options]
38
38
  Get directory extension by id registered for an application specified by app id.
39
39
 
40
40
  ```sh
41
- m365 directoryextension get --id 1f0f15e3-925d-40f0-8fc8-9d3ad135bce0 --appId fd918e4b-c821-4efb-b50a-5eddd23afc6f
41
+ m365 graph directoryextension get --id 1f0f15e3-925d-40f0-8fc8-9d3ad135bce0 --appId fd918e4b-c821-4efb-b50a-5eddd23afc6f
42
42
  ```
43
43
 
44
44
  Get directory extension by name registered for an application specified by name.
45
45
 
46
46
  ```sh
47
- m365 directoryextension get --name extension_105be60b603845fea385e58772d9d630_GitHubWorkAccount --appName ContosoApp
47
+ m365 graph directoryextension get --name extension_105be60b603845fea385e58772d9d630_GitHubWorkAccount --appName ContosoApp
48
48
  ```
49
49
 
50
-
51
50
  ## Response
52
51
 
53
52
  <Tabs>
@@ -0,0 +1,120 @@
1
+ import Global from '/docs/cmd/_global.mdx';
2
+ import Tabs from '@theme/Tabs';
3
+ import TabItem from '@theme/TabItem';
4
+
5
+ # graph openextension add
6
+
7
+ Adds an open extension to a resource
8
+
9
+ ## Usage
10
+
11
+ ```sh
12
+ m365 graph openextension add [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 the extension is created.
23
+
24
+ `-t, --resourceType <resourceType>`
25
+ : The resource type for which the extension is created. Allowed values are `user`, `group`, `device`, `organization`.
26
+ ```
27
+
28
+ <Global />
29
+
30
+ ## Remarks
31
+
32
+ This command allows using unknown options to add custom data to the open extension.
33
+
34
+ When adding an open extension to a user, it's possible to use the UPN as the resourceId.
35
+
36
+ :::warning[Escaping JSON in PowerShell]
37
+
38
+ When creating 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.
39
+
40
+ :::
41
+
42
+ ## Examples
43
+
44
+ Create a new open extension for a user specified by id. Extension properties are specified by unknown options.
45
+
46
+ ```sh
47
+ m365 graph openextension add --resourceId eb77fbcf-6fe8-458b-985d-1747284793bc --resourceType user --name 'com.contoso.roamingSettings' --theme dark --color red --language English
48
+ ```
49
+
50
+ Create a new open extension for a user specified by userName. Extension properties are specified by unknown options.
51
+
52
+ ```sh
53
+ m365 graph openextension add --resourceId adelev@contoso.com --resourceType user --name 'com.contoso.roamingSettings' --theme dark --color red --language English
54
+ ```
55
+
56
+ Create a new open extension for a group, one of the property represents a JSON object
57
+
58
+ ```sh
59
+ m365 graph openextension add --resourceId eb77fbcf-6fe8-458b-985d-1747284793bc --resourceType group --name 'com.contoso.roamingSettings' --settings '{"theme": "dark", "color": "red", "language": "English"}' --supportedSystem 'Linux'
60
+ ```
61
+
62
+ ## Response
63
+
64
+ <Tabs>
65
+ <TabItem value="JSON">
66
+
67
+ ```json
68
+ {
69
+ "extensionName": "com.contoso.roamingSettings",
70
+ "settings": {
71
+ "theme": "dark",
72
+ "color": "red",
73
+ "language": "English"
74
+ },
75
+ "supportedSystem": "Linux",
76
+ "id": "com.contoso.roamingSettings"
77
+ }
78
+ ```
79
+
80
+ </TabItem>
81
+ <TabItem value="Text">
82
+
83
+ ```text
84
+ extensionName : com.contoso.roamingSettings
85
+ id : com.contoso.roamingSettings
86
+ settings : {"theme":"dark","color":"red","language":"English"}
87
+ supportedSystem: Linux
88
+ ```
89
+
90
+ </TabItem>
91
+ <TabItem value="CSV">
92
+
93
+ ```csv
94
+ extensionName,supportedSystem,id
95
+ com.contoso.roamingSettings,Linux,com.contoso.roamingSettings
96
+ ```
97
+
98
+ </TabItem>
99
+ <TabItem value="Markdown">
100
+
101
+ ```md
102
+ # graph openextension add --name "com.contoso.roamingSettings" --resourceId "01b62bc5-9701-4f93-9587-9d1ea58a086d" --resourceType "user" --settings "{"theme": "dark", "color": "red", "language": "English"}" --supportedSystem "Linux"
103
+
104
+ Date: 3/13/2025
105
+
106
+ ## com.contoso.roamingSettings
107
+
108
+ Property | Value
109
+ ---------|-------
110
+ extensionName | com.contoso.roamingSettings
111
+ supportedSystem | Linux
112
+ id | com.contoso.roamingSettings
113
+ ```
114
+
115
+ </TabItem>
116
+ </Tabs>
117
+
118
+ ## More information
119
+
120
+ - Open extensions: https://learn.microsoft.com/graph/api/opentypeextension-post-opentypeextension
@@ -0,0 +1,111 @@
1
+ import Global from '/docs/cmd/_global.mdx';
2
+ import Tabs from '@theme/Tabs';
3
+ import TabItem from '@theme/TabItem';
4
+
5
+ # graph openextension get
6
+
7
+ Retrieves a specific open extension for a resource
8
+
9
+ ## Usage
10
+
11
+ ```sh
12
+ m365 graph openextension get [options]
13
+ ```
14
+
15
+ ## Options
16
+
17
+ ```md definition-list
18
+ `-n, --name <name>`
19
+ : The name of the open extension to retrieve.
20
+
21
+ `-i, --resourceId <resourceId>`
22
+ : The Id of the resource for which to retrieve the open extension.
23
+
24
+ `-t, --resourceType <resourceType>`
25
+ : The type of resource. Allowed values are `user`, `group`, `device`, `organization`.
26
+ ```
27
+
28
+ <Global />
29
+
30
+ ## Examples
31
+
32
+ Retrieve a specified open extension for a user specified by id.
33
+
34
+ ```sh
35
+ m365 graph openextension get --resourceId eb77fbcf-6fe8-458b-985d-1747284793bc --name 'com.contoso.roamingSettings' --resourceType user
36
+ ```
37
+
38
+ Retrieve a specified open extension for a user specified by UPN.
39
+
40
+ ```sh
41
+ m365 graph openextension get --resourceId john.doe@contoso.com --name 'com.contoso.roamingSettings' --resourceType user
42
+ ```
43
+
44
+ ## Response
45
+
46
+ <Tabs>
47
+ <TabItem value="JSON">
48
+
49
+ ```json
50
+ {
51
+ "extensionName": "com.contoso.roamingSettings",
52
+ "name": "com.contoso.roamingSettings",
53
+ "resourceId": "john.doe@contoso.com",
54
+ "resourceType": "user",
55
+ "theme": "dark",
56
+ "color": "red",
57
+ "language": "English",
58
+ "id": "com.contoso.roamingSettings"
59
+ }
60
+ ```
61
+
62
+ </TabItem>
63
+ <TabItem value="Text">
64
+
65
+ ```text
66
+ color : red
67
+ extensionName: com.contoso.roamingSettings
68
+ id : com.contoso.roamingSettings
69
+ language : English
70
+ name : com.contoso.roamingSettings
71
+ resourceId : john.doe@contoso.com
72
+ resourceType : user
73
+ theme : dark
74
+ ```
75
+
76
+ </TabItem>
77
+ <TabItem value="CSV">
78
+
79
+ ```csv
80
+ extensionName,name,resourceId,resourceType,theme,color,language,id
81
+ com.contoso.roamingSettings,com.contoso.roamingSettings,john.doe@contoso.com,user,dark,red,English,com.contoso.roamingSettings
82
+ ```
83
+
84
+ </TabItem>
85
+ <TabItem value="Markdown">
86
+
87
+ ```md
88
+ # graph openextension get --debug "false" --verbose "false" --resourceId "john.doe@contoso.com" --resourceType "user" --name "com.contoso.roamingSettings"
89
+
90
+ Date: 2025-04-07
91
+
92
+ ## com.contoso.roamingSettings (com.contoso.roamingSettings)
93
+
94
+ Property | Value
95
+ ---------|-------
96
+ extensionName | com.contoso.roamingSettings
97
+ name | com.contoso.roamingSettings
98
+ resourceId | john.doe@contoso.com
99
+ resourceType | user
100
+ theme | dark
101
+ color | red
102
+ language | English
103
+ id | com.contoso.roamingSettings
104
+ ```
105
+
106
+ </TabItem>
107
+ </Tabs>
108
+
109
+ ## More information
110
+
111
+ - Open extensions: https://learn.microsoft.com/graph/extensibility-overview?tabs=http#open-extensions
@@ -0,0 +1,129 @@
1
+ import Global from '/docs/cmd/_global.mdx';
2
+ import Tabs from '@theme/Tabs';
3
+ import TabItem from '@theme/TabItem';
4
+
5
+ # graph openextension list
6
+
7
+ Retrieves all open extensions for a resource
8
+
9
+ ## Usage
10
+
11
+ ```sh
12
+ m365 graph openextension list [options]
13
+ ```
14
+
15
+ ## Options
16
+
17
+ ```md definition-list
18
+ `-i, --resourceId <resourceId>`
19
+ : The Id of the resource for which to retrieve open extensions.
20
+
21
+ `-t, --resourceType <resourceType>`
22
+ : The type of resource. Allowed values are `user`, `group`, `device`, `organization`.
23
+ ```
24
+
25
+ <Global />
26
+
27
+ ## Examples
28
+
29
+ Retrieve open extensions for a user specified by id
30
+
31
+ ```sh
32
+ m365 graph openextension list --resourceId eb77fbcf-6fe8-458b-985d-1747284793bc --resourceType user
33
+ ```
34
+
35
+ Retrieve open extensions for a user specified by UPN
36
+
37
+ ```sh
38
+ m365 graph openextension list --resourceId john.doe@contoso.com --resourceType user
39
+ ```
40
+
41
+ Retrieve open extensions for a group specified by id
42
+
43
+ ```sh
44
+ m365 graph openextension list --resourceId 19588303-70bf-44a4-beb1-e2f0f1ed06b3 --resourceType group
45
+ ```
46
+
47
+ Retrieve open extensions for an organization specified by id
48
+
49
+ ```sh
50
+ m365 graph openextension list --resourceId c956e711-f074-40c3-8431-fbd69bb67d9c --resourceType organization
51
+ ```
52
+
53
+ ## Response
54
+
55
+ <Tabs>
56
+ <TabItem value="JSON">
57
+
58
+ ```json
59
+ [
60
+ {
61
+ "extensionName": "com.contoso.roamingSettings",
62
+ "theme": "dark",
63
+ "color": "purple",
64
+ "lang": "Japanese",
65
+ "id": "com.contoso.roamingSettings"
66
+ },
67
+ {
68
+ "extensionName": "com.test.m365",
69
+ "settings": {
70
+ "theme": "dark"
71
+ },
72
+ "supportedSystem": "Linux",
73
+ "id": "com.test.m365"
74
+ }
75
+ ]
76
+ ```
77
+
78
+ </TabItem>
79
+ <TabItem value="Text">
80
+
81
+ ```text
82
+ extensionName id
83
+ --------------------------- ---------------------------
84
+ com.contoso.roamingSettings com.contoso.roamingSettings
85
+ com.test.m365 com.test.m365
86
+ ```
87
+
88
+ </TabItem>
89
+ <TabItem value="CSV">
90
+
91
+ ```csv
92
+ extensionName,theme,color,lang,id
93
+ com.contoso.roamingSettings,dark,purple,Japanese,com.contoso.roamingSettings
94
+ com.test.m365,,,,com.test.m365
95
+ ```
96
+
97
+ </TabItem>
98
+ <TabItem value="Markdown">
99
+
100
+ ```md
101
+ # graph openextension list --resourceId "eb77fbcf-6fe8-458b-985d-1747284793bc" --resourceType "user"
102
+
103
+ Date: 3/29/2025
104
+
105
+ ## com.contoso.roamingSettings
106
+
107
+ Property | Value
108
+ ---------|-------
109
+ extensionName | com.contoso.roamingSettings
110
+ theme | dark
111
+ color | purple
112
+ lang | Japanese
113
+ id | com.contoso.roamingSettings
114
+
115
+ ## com.test.m365
116
+
117
+ Property | Value
118
+ ---------|-------
119
+ extensionName | com.test.m365
120
+ supportedSystem | Linux
121
+ id | com.test.m365
122
+ ```
123
+
124
+ </TabItem>
125
+ </Tabs>
126
+
127
+ ## More information
128
+
129
+ - Open extensions: https://learn.microsoft.com/graph/extensibility-overview?tabs=http#open-extensions