@pnp/cli-microsoft365 10.11.0-beta.b1eeb91 → 10.11.0

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.
package/dist/config.js CHANGED
@@ -16,6 +16,7 @@ export default {
16
16
  'https://graph.microsoft.com/Community.ReadWrite.All',
17
17
  'https://graph.microsoft.com/Directory.AccessAsUser.All',
18
18
  'https://graph.microsoft.com/Directory.ReadWrite.All',
19
+ 'https://graph.microsoft.com/EngagementRole.ReadWrite.All',
19
20
  'https://graph.microsoft.com/ExternalConnection.ReadWrite.All',
20
21
  'https://graph.microsoft.com/ExternalItem.ReadWrite.All',
21
22
  'https://graph.microsoft.com/FileStorageContainer.Selected',
@@ -32,13 +32,16 @@ class EntraGroupMemberAddCommand extends GraphCommand {
32
32
  if (args.options.groupDisplayName) {
33
33
  await this.warn(logger, `Option 'groupDisplayName' is deprecated and will be removed in the next major release.`);
34
34
  }
35
+ if (args.options.ids) {
36
+ await this.warn(logger, `Option 'ids' is deprecated and will be removed in the next major release. Please use 'userIds' instead.`);
37
+ }
35
38
  if (this.verbose) {
36
- await logger.logToStderr(`Adding member(s) ${args.options.ids || args.options.userNames} to group ${args.options.groupId || args.options.groupDisplayName || args.options.groupName}...`);
39
+ await logger.logToStderr(`Adding member(s) ${args.options.ids || args.options.userIds || args.options.userNames || args.options.subgroupIds || args.options.subgroupNames} to group ${args.options.groupId || args.options.groupDisplayName || args.options.groupName}...`);
37
40
  }
38
41
  const groupId = await this.getGroupId(logger, args.options);
39
- const userIds = await this.getUserIds(logger, args.options);
40
- for (let i = 0; i < userIds.length; i += 400) {
41
- const userIdsBatch = userIds.slice(i, i + 400);
42
+ const objectIds = await this.getObjectIds(logger, args.options);
43
+ for (let i = 0; i < objectIds.length; i += 400) {
44
+ const objectIdsBatch = objectIds.slice(i, i + 400);
42
45
  const requestOptions = {
43
46
  url: `${this.resource}/v1.0/$batch`,
44
47
  headers: {
@@ -49,8 +52,8 @@ class EntraGroupMemberAddCommand extends GraphCommand {
49
52
  requests: []
50
53
  }
51
54
  };
52
- for (let j = 0; j < userIdsBatch.length; j += 20) {
53
- const userIdsChunk = userIdsBatch.slice(j, j + 20);
55
+ for (let j = 0; j < objectIdsBatch.length; j += 20) {
56
+ const objectIdsChunk = objectIdsBatch.slice(j, j + 20);
54
57
  requestOptions.data.requests.push({
55
58
  id: j + 1,
56
59
  method: 'PATCH',
@@ -59,7 +62,7 @@ class EntraGroupMemberAddCommand extends GraphCommand {
59
62
  'content-type': 'application/json;odata.metadata=none'
60
63
  },
61
64
  body: {
62
- [`${args.options.role === 'Member' ? 'members' : 'owners'}@odata.bind`]: userIdsChunk.map(u => `${this.resource}/v1.0/directoryObjects/${u}`)
65
+ [`${args.options.role === 'Member' ? 'members' : 'owners'}@odata.bind`]: objectIdsChunk.map(u => `${this.resource}/v1.0/directoryObjects/${u}`)
63
66
  }
64
67
  });
65
68
  }
@@ -84,15 +87,33 @@ class EntraGroupMemberAddCommand extends GraphCommand {
84
87
  }
85
88
  return entraGroup.getGroupIdByDisplayName(options.groupDisplayName || options.groupName);
86
89
  }
90
+ async getObjectIds(logger, options) {
91
+ if (options.ids || options.userIds || options.userNames) {
92
+ return this.getUserIds(logger, options);
93
+ }
94
+ return this.getGroupIds(logger, options);
95
+ }
87
96
  async getUserIds(logger, options) {
88
97
  if (options.ids) {
89
98
  return options.ids.split(',').map(i => i.trim());
90
99
  }
100
+ if (options.userIds) {
101
+ return options.userIds.split(',').map(i => i.trim());
102
+ }
91
103
  if (this.verbose) {
92
104
  await logger.logToStderr('Retrieving ID(s) of user(s)...');
93
105
  }
94
106
  return entraUser.getUserIdsByUpns(options.userNames.split(',').map(u => u.trim()));
95
107
  }
108
+ async getGroupIds(logger, options) {
109
+ if (options.subgroupIds) {
110
+ return options.subgroupIds.split(',').map(i => i.trim());
111
+ }
112
+ if (this.verbose) {
113
+ await logger.logToStderr('Retrieving ID(s) of group(s)...');
114
+ }
115
+ return entraGroup.getGroupIdsByDisplayNames(options.subgroupNames.split(',').map(u => u.trim()));
116
+ }
96
117
  }
97
118
  _EntraGroupMemberAddCommand_instances = new WeakSet(), _EntraGroupMemberAddCommand_initTelemetry = function _EntraGroupMemberAddCommand_initTelemetry() {
98
119
  this.telemetry.push((args) => {
@@ -101,7 +122,10 @@ _EntraGroupMemberAddCommand_instances = new WeakSet(), _EntraGroupMemberAddComma
101
122
  groupDisplayName: typeof args.options.groupDisplayName !== 'undefined',
102
123
  groupName: typeof args.options.groupName !== 'undefined',
103
124
  ids: typeof args.options.ids !== 'undefined',
104
- userNames: typeof args.options.userNames !== 'undefined'
125
+ userIds: typeof args.options.userIds !== 'undefined',
126
+ userNames: typeof args.options.userNames !== 'undefined',
127
+ subgroupIds: typeof args.options.subgroupIds !== 'undefined',
128
+ subgroupNames: typeof args.options.subgroupNames !== 'undefined'
105
129
  });
106
130
  });
107
131
  }, _EntraGroupMemberAddCommand_initOptions = function _EntraGroupMemberAddCommand_initOptions() {
@@ -113,8 +137,14 @@ _EntraGroupMemberAddCommand_instances = new WeakSet(), _EntraGroupMemberAddComma
113
137
  option: '-n, --groupName [groupName]'
114
138
  }, {
115
139
  option: '--ids [ids]'
140
+ }, {
141
+ option: '--userIds [userIds]'
116
142
  }, {
117
143
  option: '--userNames [userNames]'
144
+ }, {
145
+ option: '--subgroupIds [subgroupIds]'
146
+ }, {
147
+ option: '--subgroupNames [subgroupNames]'
118
148
  }, {
119
149
  option: '-r, --role <role>',
120
150
  autocomplete: this.roleValues
@@ -130,21 +160,36 @@ _EntraGroupMemberAddCommand_instances = new WeakSet(), _EntraGroupMemberAddComma
130
160
  return `The following GUIDs are invalid for the option 'ids': ${isValidGUIDArrayResult}.`;
131
161
  }
132
162
  }
163
+ if (args.options.userIds) {
164
+ const isValidGUIDArrayResult = validation.isValidGuidArray(args.options.userIds);
165
+ if (isValidGUIDArrayResult !== true) {
166
+ return `The following GUIDs are invalid for the option 'userIds': ${isValidGUIDArrayResult}.`;
167
+ }
168
+ }
133
169
  if (args.options.userNames) {
134
170
  const isValidUPNArrayResult = validation.isValidUserPrincipalNameArray(args.options.userNames);
135
171
  if (isValidUPNArrayResult !== true) {
136
172
  return `The following user principal names are invalid for the option 'userNames': ${isValidUPNArrayResult}.`;
137
173
  }
138
174
  }
175
+ if (args.options.subgroupIds) {
176
+ const isValidGUIDArrayResult = validation.isValidGuidArray(args.options.subgroupIds);
177
+ if (isValidGUIDArrayResult !== true) {
178
+ return `The following GUIDs are invalid for the option 'subgroupIds': ${isValidGUIDArrayResult}.`;
179
+ }
180
+ }
181
+ if ((args.options.subgroupIds || args.options.subgroupNames) && args.options.role === 'Owner') {
182
+ return `Subgroups cannot be set as owners.`;
183
+ }
139
184
  if (this.roleValues.indexOf(args.options.role) === -1) {
140
185
  return `Option 'role' must be one of the following values: ${this.roleValues.join(', ')}.`;
141
186
  }
142
187
  return true;
143
188
  });
144
189
  }, _EntraGroupMemberAddCommand_initOptionSets = function _EntraGroupMemberAddCommand_initOptionSets() {
145
- this.optionSets.push({ options: ['groupId', 'groupDisplayName', 'groupName'] }, { options: ['ids', 'userNames'] });
190
+ this.optionSets.push({ options: ['groupId', 'groupDisplayName', 'groupName'] }, { options: ['ids', 'userIds', 'userNames', 'subgroupIds', 'subgroupNames'] });
146
191
  }, _EntraGroupMemberAddCommand_initTypes = function _EntraGroupMemberAddCommand_initTypes() {
147
- this.types.string.push('groupId', 'groupDisplayName', 'groupName', 'ids', 'userNames', 'role');
192
+ this.types.string.push('groupId', 'groupDisplayName', 'groupName', 'ids', 'userIds', 'userNames', 'subgroupIds', 'subgroupNames', 'role');
148
193
  };
149
194
  export default new EntraGroupMemberAddCommand();
150
195
  //# sourceMappingURL=group-member-add.js.map
@@ -32,8 +32,11 @@ class EntraGroupMemberSetCommand extends GraphCommand {
32
32
  if (args.options.groupDisplayName) {
33
33
  await this.warn(logger, `Option 'groupDisplayName' is deprecated and will be removed in the next major release.`);
34
34
  }
35
+ if (args.options.ids) {
36
+ await this.warn(logger, `Option 'ids' is deprecated and will be removed in the next major release. Please use 'userIds' instead.`);
37
+ }
35
38
  if (this.verbose) {
36
- await logger.logToStderr(`Adding member(s) ${args.options.ids || args.options.userNames} to role ${args.options.role} of group ${args.options.groupId || args.options.groupDisplayName || args.options.groupName}...`);
39
+ await logger.logToStderr(`Adding member(s) ${args.options.ids || args.options.userIds || args.options.userNames} to role ${args.options.role} of group ${args.options.groupId || args.options.groupDisplayName || args.options.groupName}...`);
37
40
  }
38
41
  const groupId = await this.getGroupId(logger, args.options);
39
42
  const userIds = await this.getUserIds(logger, args.options);
@@ -60,6 +63,9 @@ class EntraGroupMemberSetCommand extends GraphCommand {
60
63
  if (options.ids) {
61
64
  return options.ids.split(',').map(i => i.trim());
62
65
  }
66
+ if (options.userIds) {
67
+ return options.userIds.split(',').map(i => i.trim());
68
+ }
63
69
  if (this.verbose) {
64
70
  await logger.logToStderr('Retrieving ID(s) of user(s)...');
65
71
  }
@@ -163,6 +169,7 @@ _EntraGroupMemberSetCommand_instances = new WeakSet(), _EntraGroupMemberSetComma
163
169
  groupDisplayName: typeof args.options.groupDisplayName !== 'undefined',
164
170
  groupName: typeof args.options.groupName !== 'undefined',
165
171
  ids: typeof args.options.ids !== 'undefined',
172
+ userIds: typeof args.options.userIds !== 'undefined',
166
173
  userNames: typeof args.options.userNames !== 'undefined'
167
174
  });
168
175
  });
@@ -175,6 +182,8 @@ _EntraGroupMemberSetCommand_instances = new WeakSet(), _EntraGroupMemberSetComma
175
182
  option: '-n, --groupName [groupName]'
176
183
  }, {
177
184
  option: '--ids [ids]'
185
+ }, {
186
+ option: '--userIds [userIds]'
178
187
  }, {
179
188
  option: '--userNames [userNames]'
180
189
  }, {
@@ -192,6 +201,12 @@ _EntraGroupMemberSetCommand_instances = new WeakSet(), _EntraGroupMemberSetComma
192
201
  return `'${isValidGUIDArrayResult}' is not a valid GUID for option 'ids'.`;
193
202
  }
194
203
  }
204
+ if (args.options.userIds) {
205
+ const isValidGUIDArrayResult = validation.isValidGuidArray(args.options.userIds);
206
+ if (isValidGUIDArrayResult !== true) {
207
+ return `The following GUIDs are invalid for the option 'userIds': ${isValidGUIDArrayResult}.`;
208
+ }
209
+ }
195
210
  if (args.options.userNames) {
196
211
  const isValidUserPrincipalNameArray = validation.isValidUserPrincipalNameArray(args.options.userNames);
197
212
  if (isValidUserPrincipalNameArray !== true) {
@@ -204,9 +219,9 @@ _EntraGroupMemberSetCommand_instances = new WeakSet(), _EntraGroupMemberSetComma
204
219
  return true;
205
220
  });
206
221
  }, _EntraGroupMemberSetCommand_initOptionSets = function _EntraGroupMemberSetCommand_initOptionSets() {
207
- this.optionSets.push({ options: ['groupId', 'groupDisplayName', 'groupName'] }, { options: ['ids', 'userNames'] });
222
+ this.optionSets.push({ options: ['groupId', 'groupDisplayName', 'groupName'] }, { options: ['ids', 'userIds', 'userNames'] });
208
223
  }, _EntraGroupMemberSetCommand_initTypes = function _EntraGroupMemberSetCommand_initTypes() {
209
- this.types.string.push('groupId', 'groupDisplayName', 'groupName', 'ids', 'userNames', 'role');
224
+ this.types.string.push('groupId', 'groupDisplayName', 'groupName', 'ids', 'userIds', 'userNames', 'role');
210
225
  };
211
226
  export default new EntraGroupMemberSetCommand();
212
227
  //# sourceMappingURL=group-member-set.js.map
@@ -8,6 +8,7 @@ import { FN002013_DEVDEP_types_webpack_env } from './rules/FN002013_DEVDEP_types
8
8
  import { FN002015_DEVDEP_types_react } from './rules/FN002015_DEVDEP_types_react.js';
9
9
  import { FN002016_DEVDEP_types_react_dom } from './rules/FN002016_DEVDEP_types_react_dom.js';
10
10
  import { FN002019_DEVDEP_microsoft_rush_stack_compiler } from './rules/FN002019_DEVDEP_microsoft_rush_stack_compiler.js';
11
+ import { FN002022_DEVDEP_typescript } from './rules/FN002022_DEVDEP_typescript.js';
11
12
  import { FN021001_PKG_spfx_deps_versions_match_project_version } from './rules/FN021001_PKG_spfx_deps_versions_match_project_version.js';
12
13
  export default [
13
14
  new FN001008_DEP_react('17'),
@@ -20,6 +21,7 @@ export default [
20
21
  new FN002016_DEVDEP_types_react_dom('17'),
21
22
  new FN002019_DEVDEP_microsoft_rush_stack_compiler(['5.3']),
22
23
  new FN002021_DEVDEP_rushstack_eslint_config('4.0.1'),
24
+ new FN002022_DEVDEP_typescript('~5.3.3'),
23
25
  new FN021001_PKG_spfx_deps_versions_match_project_version(true)
24
26
  ];
25
27
  //# sourceMappingURL=doctor-1.21.0.js.map
@@ -8,6 +8,7 @@ import { FN002013_DEVDEP_types_webpack_env } from './rules/FN002013_DEVDEP_types
8
8
  import { FN002015_DEVDEP_types_react } from './rules/FN002015_DEVDEP_types_react.js';
9
9
  import { FN002016_DEVDEP_types_react_dom } from './rules/FN002016_DEVDEP_types_react_dom.js';
10
10
  import { FN002019_DEVDEP_microsoft_rush_stack_compiler } from './rules/FN002019_DEVDEP_microsoft_rush_stack_compiler.js';
11
+ import { FN002022_DEVDEP_typescript } from './rules/FN002022_DEVDEP_typescript.js';
11
12
  import { FN021001_PKG_spfx_deps_versions_match_project_version } from './rules/FN021001_PKG_spfx_deps_versions_match_project_version.js';
12
13
  export default [
13
14
  new FN001008_DEP_react('17'),
@@ -20,6 +21,7 @@ export default [
20
21
  new FN002016_DEVDEP_types_react_dom('17'),
21
22
  new FN002019_DEVDEP_microsoft_rush_stack_compiler(['5.3']),
22
23
  new FN002021_DEVDEP_rushstack_eslint_config('4.0.1'),
24
+ new FN002022_DEVDEP_typescript('~5.3.3'),
23
25
  new FN021001_PKG_spfx_deps_versions_match_project_version(true)
24
26
  ];
25
27
  //# sourceMappingURL=doctor-1.21.1.js.map
@@ -5,6 +5,7 @@ import { FN001035_DEP_fluentui_react } from './rules/FN001035_DEP_fluentui_react
5
5
  import { FN002013_DEVDEP_types_webpack_env } from './rules/FN002013_DEVDEP_types_webpack_env.js';
6
6
  import { FN002015_DEVDEP_types_react } from './rules/FN002015_DEVDEP_types_react.js';
7
7
  import { FN002016_DEVDEP_types_react_dom } from './rules/FN002016_DEVDEP_types_react_dom.js';
8
+ import { FN002022_DEVDEP_typescript } from './rules/FN002022_DEVDEP_typescript.js';
8
9
  import { FN021001_PKG_spfx_deps_versions_match_project_version } from './rules/FN021001_PKG_spfx_deps_versions_match_project_version.js';
9
10
  export default [
10
11
  new FN001008_DEP_react('17'),
@@ -14,6 +15,7 @@ export default [
14
15
  new FN002015_DEVDEP_types_react('17'),
15
16
  new FN002016_DEVDEP_types_react_dom('17'),
16
17
  new FN002021_DEVDEP_rushstack_eslint_config('4.3.0'),
18
+ new FN002022_DEVDEP_typescript('5.3.3'),
17
19
  new FN021001_PKG_spfx_deps_versions_match_project_version(true)
18
20
  ];
19
21
  //# sourceMappingURL=doctor-1.22.0-beta.1.js.map
@@ -0,0 +1,10 @@
1
+ import { DependencyRule } from './DependencyRule.js';
2
+ export class FN002022_DEVDEP_typescript extends DependencyRule {
3
+ constructor(version) {
4
+ super('typescript', version, true);
5
+ }
6
+ get id() {
7
+ return 'FN002022';
8
+ }
9
+ }
10
+ //# sourceMappingURL=FN002022_DEVDEP_typescript.js.map
@@ -47,6 +47,7 @@ class SpoFileVersionGetCommand extends SpoCommand {
47
47
  else {
48
48
  requestUrl += `GetFileById('${args.options.fileId}')/versions/?$filter=VersionLabel eq '${args.options.label}'`;
49
49
  }
50
+ requestUrl += `&$select=*,ExpirationDate`;
50
51
  const requestOptions = {
51
52
  url: requestUrl,
52
53
  headers: {
@@ -18,7 +18,7 @@ class SpoFileVersionListCommand extends SpoCommand {
18
18
  return 'Retrieves all versions of a file';
19
19
  }
20
20
  defaultProperties() {
21
- return ['Created', 'ID', 'IsCurrentVersion', 'VersionLabel'];
21
+ return ['Created', 'ID', 'IsCurrentVersion', 'VersionLabel', 'ExpirationDate'];
22
22
  }
23
23
  constructor() {
24
24
  super();
@@ -42,7 +42,7 @@ class SpoFileVersionListCommand extends SpoCommand {
42
42
  else {
43
43
  requestUrl += `/GetFileById('${args.options.fileId}')`;
44
44
  }
45
- requestUrl += `/versions`;
45
+ requestUrl += `/versions?$select=*,ExpirationDate`;
46
46
  const response = await odata.getAllItems(requestUrl);
47
47
  await logger.log(response);
48
48
  }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=EngageRole.js.map
@@ -0,0 +1,28 @@
1
+ import { odata } from '../../../../utils/odata.js';
2
+ import GraphCommand from '../../../base/GraphCommand.js';
3
+ import commands from '../../commands.js';
4
+ class VivaEngageRoleListCommand extends GraphCommand {
5
+ get name() {
6
+ return commands.ENGAGE_ROLE_LIST;
7
+ }
8
+ get description() {
9
+ return 'Lists all Viva Engage roles';
10
+ }
11
+ defaultProperties() {
12
+ return ['id', 'displayName'];
13
+ }
14
+ async commandAction(logger) {
15
+ if (this.verbose) {
16
+ await logger.logToStderr('Getting all Viva Engage roles...');
17
+ }
18
+ try {
19
+ const results = await odata.getAllItems(`${this.resource}/beta/employeeExperience/roles`);
20
+ await logger.log(results);
21
+ }
22
+ catch (err) {
23
+ this.handleRejectedODataJsonPromise(err);
24
+ }
25
+ }
26
+ }
27
+ export default new VivaEngageRoleListCommand();
28
+ //# sourceMappingURL=engage-role-list.js.map
@@ -0,0 +1,57 @@
1
+ import { z } from 'zod';
2
+ import { globalOptionsZod } from '../../../../Command.js';
3
+ import { zod } from '../../../../utils/zod.js';
4
+ import { odata } from '../../../../utils/odata.js';
5
+ import GraphCommand from '../../../base/GraphCommand.js';
6
+ import commands from '../../commands.js';
7
+ import { validation } from '../../../../utils/validation.js';
8
+ import { vivaEngage } from '../../../../utils/vivaEngage.js';
9
+ const options = globalOptionsZod
10
+ .extend({
11
+ roleId: zod.alias('i', z.string().refine(name => validation.isValidGuid(name), name => ({
12
+ message: `'${name}' is not a valid GUID.`
13
+ })).optional()),
14
+ roleName: zod.alias('n', z.string().optional())
15
+ })
16
+ .strict();
17
+ class VivaEngageRoleMemberListCommand extends GraphCommand {
18
+ get name() {
19
+ return commands.ENGAGE_ROLE_MEMBER_LIST;
20
+ }
21
+ get description() {
22
+ return 'Lists all users assigned to a Viva Engage role';
23
+ }
24
+ get schema() {
25
+ return options;
26
+ }
27
+ getRefinedSchema(schema) {
28
+ return schema
29
+ .refine(options => [options.roleId, options.roleName].filter(x => x !== undefined).length === 1, {
30
+ message: 'Specify either roleId, or roleName, but not both.'
31
+ });
32
+ }
33
+ defaultProperties() {
34
+ return ['id', 'userId'];
35
+ }
36
+ async commandAction(logger, args) {
37
+ let roleId = args.options.roleId;
38
+ try {
39
+ if (args.options.roleName) {
40
+ if (this.verbose) {
41
+ await logger.logToStderr(`Retrieving Viva Engage role ID for role name '${args.options.roleName}'...`);
42
+ }
43
+ roleId = await vivaEngage.getRoleIdByName(args.options.roleName);
44
+ }
45
+ if (this.verbose) {
46
+ await logger.logToStderr(`Getting all users assigned to a Viva Engage role ${roleId}...`);
47
+ }
48
+ const results = await odata.getAllItems(`${this.resource}/beta/employeeExperience/roles/${roleId}/members`);
49
+ await logger.log(results);
50
+ }
51
+ catch (err) {
52
+ this.handleRejectedODataJsonPromise(err);
53
+ }
54
+ }
55
+ }
56
+ export default new VivaEngageRoleMemberListCommand();
57
+ //# sourceMappingURL=engage-role-member-list.js.map
@@ -27,6 +27,8 @@ export default {
27
27
  ENGAGE_REPORT_GROUPSACTIVITYCOUNTS: `${prefix} engage report groupsactivitycounts`,
28
28
  ENGAGE_REPORT_GROUPSACTIVITYDETAIL: `${prefix} engage report groupsactivitydetail`,
29
29
  ENGAGE_REPORT_GROUPSACTIVITYGROUPCOUNTS: `${prefix} engage report groupsactivitygroupcounts`,
30
+ ENGAGE_ROLE_LIST: `${prefix} engage role list`,
31
+ ENGAGE_ROLE_MEMBER_LIST: `${prefix} engage role member list`,
30
32
  ENGAGE_SEARCH: `${prefix} engage search`,
31
33
  ENGAGE_USER_GET: `${prefix} engage user get`,
32
34
  ENGAGE_USER_LIST: `${prefix} engage user list`
@@ -142,6 +142,49 @@ export const entraGroup = {
142
142
  };
143
143
  const group = await request.get(requestOptions);
144
144
  return group.groupTypes.some(type => type === 'Unified');
145
+ },
146
+ /**
147
+ * Retrieve the IDs of groups by their display names. There is no guarantee that the order of the returned IDs will match the order of the specified names.
148
+ * @param names Array of group names.
149
+ * @returns Array of group IDs.
150
+ */
151
+ async getGroupIdsByDisplayNames(names) {
152
+ const groupIds = [];
153
+ for (let i = 0; i < names.length; i += 20) {
154
+ const namesChunk = names.slice(i, i + 20);
155
+ const requestOptions = {
156
+ url: `${graphResource}/v1.0/$batch`,
157
+ headers: {
158
+ accept: 'application/json;odata.metadata=none'
159
+ },
160
+ responseType: 'json',
161
+ data: {
162
+ requests: namesChunk.map((name, index) => ({
163
+ id: index + 1,
164
+ method: 'GET',
165
+ url: `/groups?$filter=displayName eq '${formatting.encodeQueryParameter(name)}'&$select=id`,
166
+ headers: {
167
+ accept: 'application/json;odata.metadata=none'
168
+ }
169
+ }))
170
+ }
171
+ };
172
+ const res = await request.post(requestOptions);
173
+ for (const response of res.responses) {
174
+ if (response.body.value.length === 1) {
175
+ groupIds.push(response.body.value[0].id);
176
+ }
177
+ else if (response.body.value.length > 1) {
178
+ const resultAsKeyValuePair = formatting.convertArrayToHashTable('id', response.body.value);
179
+ const result = await cli.handleMultipleResultsFound(`Multiple groups with the name '${namesChunk[response.id - 1]}' found.`, resultAsKeyValuePair);
180
+ groupIds.push(result.id);
181
+ }
182
+ else {
183
+ throw Error(`The specified group with name '${namesChunk[response.id - 1]}' does not exist.`);
184
+ }
185
+ }
186
+ }
187
+ return groupIds;
145
188
  }
146
189
  };
147
190
  //# sourceMappingURL=entraGroup.js.map
@@ -56,6 +56,25 @@ export const vivaEngage = {
56
56
  throw `The Microsoft Entra group with id '${entraGroupId}' is not associated with any Viva Engage community.`;
57
57
  }
58
58
  return filteredCommunity;
59
+ },
60
+ /**
61
+ * Get the ID of a Viva Engage role by its display name.
62
+ * @param roleName The display name of the role.
63
+ * @returns The ID of the role.
64
+ */
65
+ async getRoleIdByName(roleName) {
66
+ // This endpoint doesn't support filtering by displayName
67
+ const response = await odata.getAllItems('https://graph.microsoft.com/beta/employeeExperience/roles');
68
+ const roles = response.filter(role => role.displayName.toLowerCase() === roleName.toLowerCase());
69
+ if (roles.length === 0) {
70
+ throw new Error(`The specified Viva Engage role '${roleName}' does not exist.`);
71
+ }
72
+ if (roles.length > 1) {
73
+ const resultAsKeyValuePair = formatting.convertArrayToHashTable('id', roles);
74
+ const selectedRole = await cli.handleMultipleResultsFound(`Multiple Viva Engage roles with name '${roleName}' found.`, resultAsKeyValuePair);
75
+ return selectedRole.id;
76
+ }
77
+ return roles[0].id;
59
78
  }
60
79
  };
61
80
  //# sourceMappingURL=vivaEngage.js.map
@@ -23,10 +23,19 @@ m365 entra group member add [options]
23
23
  : The display name of the Microsoft Entra group. Specify `groupId`, `groupDisplayName` or `groupName` but not multiple.
24
24
 
25
25
  `--ids [ids]`
26
- : Microsoft Entra IDs of users. You can also pass a comma-separated list of IDs. Specify either `ids` or `userNames` but not both.
26
+ : (deprecated. Use option `userIds` instead) Microsoft Entra IDs of users. You can also pass a comma-separated list of IDs. Specify either `ids`, `userIds`,`userNames`, `subgroupIds`, or `subgroupNames` but not multiple.
27
+
28
+ `--userIds [userIds]`
29
+ : Microsoft Entra IDs of users. You can also pass a comma-separated list of IDs. Specify either `ids`, `userIds`,`userNames`, `subgroupIds`, or `subgroupNames` but not multiple.
27
30
 
28
31
  `--userNames [userNames]`
29
- : The user principal names of users. You can also pass a comma-separated list of UPNs. Specify either `ids` or `userNames` but not both.
32
+ : The user principal names of users. You can also pass a comma-separated list of UPNs. Specify either `ids`, `userIds`,`userNames`, `subgroupIds`, or `subgroupNames` but not multiple.
33
+
34
+ `--subgroupIds [subgroupIds]`
35
+ : Comma-separated list of Microsoft Entra group IDs to add. Specify either `ids`, `userIds`,`userNames`, `subgroupIds`, or `subgroupNames` but not multiple.
36
+
37
+ `--subgroupNames [subgroupNames]`
38
+ : Comma-separated list of Microsoft Entra group titles to add. Specify either `ids`, `userIds`,`userNames`, `subgroupIds`, or `subgroupNames` but not multiple.
30
39
 
31
40
  `-r, --role <role>`
32
41
  : The role to be assigned to the new users. Valid values: `Owner`, `Member`.
@@ -39,19 +48,19 @@ m365 entra group member add [options]
39
48
  Add a single member specified by ID as a member to a group specified by display name.
40
49
 
41
50
  ```sh
42
- m365 entra group member add --groupDisplayName Developers --ids 098b9f52-f48c-4401-819f-29c33794c3f5 --role Member
51
+ m365 entra group member add --groupDisplayName Developers --userIds 098b9f52-f48c-4401-819f-29c33794c3f5 --role Member
43
52
  ```
44
53
 
45
54
  Add a single member specified by ID as a member to a group specified by group name.
46
55
 
47
56
  ```sh
48
- m365 entra group member add --groupName Developers --ids 098b9f52-f48c-4401-819f-29c33794c3f5 --role Member
57
+ m365 entra group member add --groupName Developers --userIds 098b9f52-f48c-4401-819f-29c33794c3f5 --role Member
49
58
  ```
50
59
 
51
60
  Add multiple members specified by ID as members to a group specified by ID.
52
61
 
53
62
  ```sh
54
- m365 entra group member add --groupId a03c0c35-ef9a-419b-8cab-f89e0a8d2d2a --ids "098b9f52-f48c-4401-819f-29c33794c3f5,f1e06e31-3abf-4746-83c2-1513d71f38b8" --role Member
63
+ m365 entra group member add --groupId a03c0c35-ef9a-419b-8cab-f89e0a8d2d2a --userIds "098b9f52-f48c-4401-819f-29c33794c3f5,f1e06e31-3abf-4746-83c2-1513d71f38b8" --role Member
55
64
  ```
56
65
 
57
66
  Add a single member specified by UPN as an owner to a group specified by display name.
@@ -72,6 +81,18 @@ Adds multiple members specified by UPN as owners to a group specified by ID.
72
81
  m365 entra group member add --groupId a03c0c35-ef9a-419b-8cab-f89e0a8d2d2a --userNames "john.doe@contoso.com,adele.vance@contoso.com" --role Owner
73
82
  ```
74
83
 
84
+ Add multiple members (subgroups) specified by ID as members to a group specified by ID.
85
+
86
+ ```sh
87
+ m365 entra group member add --groupId a03c0c35-ef9a-419b-8cab-f89e0a8d2d2a --subgroupIds "098b9f52-f48c-4401-819f-29c33794c3f5,f1e06e31-3abf-4746-83c2-1513d71f38b8" --role Member
88
+ ```
89
+
90
+ Adds multiple members (subgroups) specified by name as members to a group specified by ID.
91
+
92
+ ```sh
93
+ m365 entra group member add --groupId a03c0c35-ef9a-419b-8cab-f89e0a8d2d2a --subgroupNames "Developers,Human Resources" --role Member
94
+ ```
95
+
75
96
  ## Response
76
97
 
77
98
  The command won't return a response on success.
@@ -23,7 +23,10 @@ m365 entra group member set [options]
23
23
  : The display name of the Microsoft Entra group. Specify `groupId`, `groupDisplayName` or `groupName` but not multiple.
24
24
 
25
25
  `--ids [ids]`
26
- : Comma-separated list of user IDs. Specify either `ids` or `userNames` but not both.
26
+ : (deprecated. Use option `userIds` instead) Comma-separated list of user IDs. Specify either `ids`, `userIds` or `userNames` but not multiple.
27
+
28
+ `--userIds [userIds]`
29
+ : Comma-separated list of user IDs. Specify either `ids`, `userIds` or `userNames` but not multiple.
27
30
 
28
31
  `--userNames [userNames]`
29
32
  : The user principal names of users. You can also pass a comma-separated list of UPNs. Specify either `ids` or `userNames` but not both.
@@ -39,19 +42,19 @@ m365 entra group member set [options]
39
42
  Update a single member specified by ID to a member of a group specified by display name
40
43
 
41
44
  ```sh
42
- m365 entra group member set --groupDisplayName Developers --ids 098b9f52-f48c-4401-819f-29c33794c3f5 --role Member
45
+ m365 entra group member set --groupDisplayName Developers --userIds 098b9f52-f48c-4401-819f-29c33794c3f5 --role Member
43
46
  ```
44
47
 
45
48
  Update a single member specified by ID to a member of a group specified by group name
46
49
 
47
50
  ```sh
48
- m365 entra group member set --groupName Developers --ids 098b9f52-f48c-4401-819f-29c33794c3f5 --role Member
51
+ m365 entra group member set --groupName Developers --userIds 098b9f52-f48c-4401-819f-29c33794c3f5 --role Member
49
52
  ```
50
53
 
51
54
  Update multiple members specified by ID to members of a group specified by ID
52
55
 
53
56
  ```sh
54
- m365 entra group member set --groupId a03c0c35-ef9a-419b-8cab-f89e0a8d2d2a --ids "098b9f52-f48c-4401-819f-29c33794c3f5,f1e06e31-3abf-4746-83c2-1513d71f38b8" --role Member
57
+ m365 entra group member set --groupId a03c0c35-ef9a-419b-8cab-f89e0a8d2d2a --userIds "098b9f52-f48c-4401-819f-29c33794c3f5,f1e06e31-3abf-4746-83c2-1513d71f38b8" --role Member
55
58
  ```
56
59
 
57
60
  Update a single member specified by UPN to an owner of a group specified by display name
@@ -53,6 +53,7 @@ m365 spo file version get --webUrl https://contoso.sharepoint.com --label "1.0"
53
53
  {
54
54
  "CheckInComment": "",
55
55
  "Created": "2022-10-30T12:03:06Z",
56
+ "ExpirationDate": "2026-01-31T08:23:43.0000000Z",
56
57
  "ID": 512,
57
58
  "IsCurrentVersion": false,
58
59
  "Length": "18898",
@@ -68,6 +69,7 @@ m365 spo file version get --webUrl https://contoso.sharepoint.com --label "1.0"
68
69
  ```text
69
70
  CheckInComment :
70
71
  Created : 2022-10-30T12:03:06Z
72
+ ExpirationDate : 2026-01-31T08:23:43.0000000Z
71
73
  ID : 512
72
74
  IsCurrentVersion: false
73
75
  Length : 18898
@@ -80,8 +82,8 @@ m365 spo file version get --webUrl https://contoso.sharepoint.com --label "1.0"
80
82
  <TabItem value="CSV">
81
83
 
82
84
  ```csv
83
- CheckInComment,Created,ID,IsCurrentVersion,Length,Size,Url,VersionLabel
84
- ,2022-10-30T12:03:06Z,512,,18898,18898,_vti_history/512/Shared Documents/Document.docx,1.0
85
+ CheckInComment,Created,ExpirationDate,ID,IsCurrentVersion,Length,Size,Url,VersionLabel
86
+ ,2022-10-30T12:03:06Z,2026-01-31T08:23:43.0000000Z,512,0,18898,18898,_vti_history/512/Shared Documents/Document.docx,1.0
85
87
  ```
86
88
 
87
89
  </TabItem>
@@ -98,6 +100,7 @@ m365 spo file version get --webUrl https://contoso.sharepoint.com --label "1.0"
98
100
  ---------|-------
99
101
  CheckInComment |
100
102
  Created | 2022-10-30T12:03:06Z
103
+ ExpirationDate | 2026-01-31T08:23:43.0000000Z
101
104
  ID | 512
102
105
  IsCurrentVersion | false
103
106
  Length | 18898