@pnp/cli-microsoft365 10.6.0-beta.a7465c9 → 10.6.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/allCommands.json +1 -1
- package/allCommandsFull.json +1 -1
- package/dist/Auth.js +2 -1
- package/dist/Command.js +10 -0
- package/dist/auth/MsalNetworkClient.js +48 -0
- package/dist/config.js +1 -0
- package/dist/m365/app/commands/app-get.js +3 -13
- package/dist/m365/app/commands/permission/permission-list.js +4 -14
- package/dist/m365/entra/commands/app/app-get.js +27 -21
- package/dist/m365/entra/commands/app/app-permission-list.js +28 -22
- package/dist/m365/entra/commands/app/app-remove.js +22 -19
- package/dist/m365/entra/commands/app/app-role-add.js +22 -19
- package/dist/m365/entra/commands/app/app-role-list.js +22 -19
- package/dist/m365/entra/commands/app/app-role-remove.js +39 -36
- package/dist/m365/entra/commands/app/app-set.js +22 -19
- package/dist/m365/entra/commands/group/group-member-add.js +1 -1
- package/dist/m365/entra/commands/group/group-member-remove.js +197 -0
- package/dist/m365/entra/commands/policy/policy-list.js +46 -3
- package/dist/m365/entra/commands.js +1 -0
- package/dist/m365/flow/commands/flow-list.js +1 -1
- package/dist/m365/graph/commands/openextension/openextension-get.js +57 -0
- package/dist/m365/graph/commands/openextension/openextension-list.js +62 -0
- package/dist/m365/graph/commands/openextension/openextension-remove.js +68 -0
- package/dist/m365/graph/commands.js +3 -0
- package/dist/m365/pp/commands/card/card-clone.js +12 -16
- package/dist/m365/pp/commands/card/card-get.js +13 -19
- package/dist/m365/pp/commands/card/card-remove.js +13 -16
- package/dist/m365/pp/commands/solution/solution-get.js +5 -11
- package/dist/m365/pp/commands/solution/solution-publish.js +6 -16
- package/dist/m365/pp/commands/solution/solution-remove.js +4 -13
- package/dist/m365/spfx/commands/project/DeployWorkflow.js +9 -2
- package/dist/m365/spfx/commands/project/project-azuredevops-pipeline-add.js +0 -19
- package/dist/m365/spfx/commands/project/project-doctor/doctor-1.21.0.js +25 -0
- package/dist/m365/spfx/commands/project/project-doctor.js +2 -1
- package/dist/m365/spfx/commands/project/project-github-workflow-add.js +0 -16
- package/dist/m365/spfx/commands/project/project-upgrade/rules/FN002029_DEVDEP_microsoft_rush_stack_compiler_5_3.js +13 -0
- package/dist/m365/spfx/commands/project/project-upgrade/upgrade-1.21.0.js +63 -0
- package/dist/m365/spfx/commands/project/project-upgrade.js +2 -1
- package/dist/m365/spfx/commands/spfx-doctor.js +15 -0
- package/dist/m365/spo/commands/folder/folder-roleassignment-add.js +12 -47
- package/dist/m365/spo/commands/folder/folder-roleassignment-remove.js +13 -31
- package/dist/m365/spo/commands/listitem/listitem-roleassignment-add.js +12 -43
- package/dist/m365/spo/commands/listitem/listitem-roleassignment-remove.js +8 -27
- package/dist/m365/util/commands/accesstoken/accesstoken-get.js +13 -3
- package/dist/utils/accessToken.js +8 -0
- package/dist/utils/powerPlatform.js +51 -1
- package/dist/utils/prompt.js +9 -2
- package/dist/utils/spo.js +26 -0
- package/dist/utils/types.js +1 -0
- package/docs/docs/cmd/entra/group/group-member-add.mdx +1 -1
- package/docs/docs/cmd/entra/group/group-member-remove.mdx +96 -0
- package/docs/docs/cmd/entra/policy/policy-list.mdx +1 -1
- package/docs/docs/cmd/graph/openextension/openextension-get.mdx +111 -0
- package/docs/docs/cmd/graph/openextension/openextension-list.mdx +129 -0
- package/docs/docs/cmd/graph/openextension/openextension-remove.mdx +59 -0
- package/docs/docs/cmd/spfx/project/project-upgrade.mdx +1 -4
- package/docs/docs/cmd/util/accesstoken/accesstoken-get.mdx +72 -0
- package/npm-shrinkwrap.json +515 -479
- package/package.json +15 -15
|
@@ -11,8 +11,6 @@ import { urlUtil } from '../../../../utils/urlUtil.js';
|
|
|
11
11
|
import { validation } from '../../../../utils/validation.js';
|
|
12
12
|
import SpoCommand from '../../../base/SpoCommand.js';
|
|
13
13
|
import commands from '../../commands.js';
|
|
14
|
-
import spoGroupGetCommand from '../group/group-get.js';
|
|
15
|
-
import spoUserGetCommand from '../user/user-get.js';
|
|
16
14
|
import { entraGroup } from '../../../../utils/entraGroup.js';
|
|
17
15
|
import { spo } from '../../../../utils/spo.js';
|
|
18
16
|
class SpoFolderRoleAssignmentRemoveCommand extends SpoCommand {
|
|
@@ -38,11 +36,12 @@ class SpoFolderRoleAssignmentRemoveCommand extends SpoCommand {
|
|
|
38
36
|
const serverRelativeUrl = urlUtil.getServerRelativePath(args.options.webUrl, args.options.folderUrl);
|
|
39
37
|
const requestUrl = `${args.options.webUrl}/_api/web/GetFolderByServerRelativePath(DecodedUrl='${formatting.encodeQueryParameter(serverRelativeUrl)}')/ListItemAllFields`;
|
|
40
38
|
try {
|
|
39
|
+
let principalId = args.options.principalId;
|
|
41
40
|
if (args.options.upn) {
|
|
42
|
-
|
|
41
|
+
principalId = await this.getUserPrincipalId(args.options, logger);
|
|
43
42
|
}
|
|
44
43
|
else if (args.options.groupName) {
|
|
45
|
-
|
|
44
|
+
principalId = await this.getGroupPrincipalId(args.options, logger);
|
|
46
45
|
}
|
|
47
46
|
else if (args.options.entraGroupId || args.options.entraGroupName) {
|
|
48
47
|
if (this.verbose) {
|
|
@@ -52,9 +51,9 @@ class SpoFolderRoleAssignmentRemoveCommand extends SpoCommand {
|
|
|
52
51
|
? await entraGroup.getGroupById(args.options.entraGroupId)
|
|
53
52
|
: await entraGroup.getGroupByDisplayName(args.options.entraGroupName);
|
|
54
53
|
const siteUser = await spo.ensureEntraGroup(args.options.webUrl, group);
|
|
55
|
-
|
|
54
|
+
principalId = siteUser.Id;
|
|
56
55
|
}
|
|
57
|
-
await this.removeRoleAssignment(requestUrl,
|
|
56
|
+
await this.removeRoleAssignment(requestUrl, principalId);
|
|
58
57
|
}
|
|
59
58
|
catch (err) {
|
|
60
59
|
this.handleRejectedODataJsonPromise(err);
|
|
@@ -70,9 +69,9 @@ class SpoFolderRoleAssignmentRemoveCommand extends SpoCommand {
|
|
|
70
69
|
}
|
|
71
70
|
}
|
|
72
71
|
}
|
|
73
|
-
async removeRoleAssignment(requestUrl,
|
|
72
|
+
async removeRoleAssignment(requestUrl, principalId) {
|
|
74
73
|
const requestOptions = {
|
|
75
|
-
url: `${requestUrl}/roleassignments/removeroleassignment(principalid='${
|
|
74
|
+
url: `${requestUrl}/roleassignments/removeroleassignment(principalid='${principalId}')`,
|
|
76
75
|
method: 'POST',
|
|
77
76
|
headers: {
|
|
78
77
|
'accept': 'application/json;odata=nometadata',
|
|
@@ -82,30 +81,13 @@ class SpoFolderRoleAssignmentRemoveCommand extends SpoCommand {
|
|
|
82
81
|
};
|
|
83
82
|
return request.post(requestOptions);
|
|
84
83
|
}
|
|
85
|
-
async getGroupPrincipalId(options) {
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
name: options.groupName,
|
|
89
|
-
output: 'json',
|
|
90
|
-
debug: this.debug,
|
|
91
|
-
verbose: this.verbose
|
|
92
|
-
};
|
|
93
|
-
const output = await cli.executeCommandWithOutput(spoGroupGetCommand, { options: { ...groupGetCommandOptions, _: [] } });
|
|
94
|
-
const getGroupOutput = JSON.parse(output.stdout);
|
|
95
|
-
return getGroupOutput.Id;
|
|
84
|
+
async getGroupPrincipalId(options, logger) {
|
|
85
|
+
const group = await spo.getGroupByName(options.webUrl, options.groupName, logger, this.verbose);
|
|
86
|
+
return group.Id;
|
|
96
87
|
}
|
|
97
|
-
async getUserPrincipalId(options) {
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
email: options.upn,
|
|
101
|
-
id: undefined,
|
|
102
|
-
output: 'json',
|
|
103
|
-
debug: this.debug,
|
|
104
|
-
verbose: this.verbose
|
|
105
|
-
};
|
|
106
|
-
const output = await cli.executeCommandWithOutput(spoUserGetCommand, { options: { ...userGetCommandOptions, _: [] } });
|
|
107
|
-
const getUserOutput = JSON.parse(output.stdout);
|
|
108
|
-
return getUserOutput.Id;
|
|
88
|
+
async getUserPrincipalId(options, logger) {
|
|
89
|
+
const user = await spo.getUserByEmail(options.webUrl, options.upn, logger, this.verbose);
|
|
90
|
+
return user.Id;
|
|
109
91
|
}
|
|
110
92
|
}
|
|
111
93
|
_SpoFolderRoleAssignmentRemoveCommand_instances = new WeakSet(), _SpoFolderRoleAssignmentRemoveCommand_initTelemetry = function _SpoFolderRoleAssignmentRemoveCommand_initTelemetry() {
|
|
@@ -4,7 +4,6 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
4
4
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
5
|
};
|
|
6
6
|
var _SpoListItemRoleAssignmentAddCommand_instances, _SpoListItemRoleAssignmentAddCommand_initTelemetry, _SpoListItemRoleAssignmentAddCommand_initOptions, _SpoListItemRoleAssignmentAddCommand_initValidators;
|
|
7
|
-
import { cli } from '../../../../cli/cli.js';
|
|
8
7
|
import request from '../../../../request.js';
|
|
9
8
|
import { entraGroup } from '../../../../utils/entraGroup.js';
|
|
10
9
|
import { formatting } from '../../../../utils/formatting.js';
|
|
@@ -12,9 +11,6 @@ import { urlUtil } from '../../../../utils/urlUtil.js';
|
|
|
12
11
|
import { validation } from '../../../../utils/validation.js';
|
|
13
12
|
import SpoCommand from '../../../base/SpoCommand.js';
|
|
14
13
|
import commands from '../../commands.js';
|
|
15
|
-
import spoGroupGetCommand from '../group/group-get.js';
|
|
16
|
-
import spoRoleDefinitionListCommand from '../roledefinition/roledefinition-list.js';
|
|
17
|
-
import spoUserGetCommand from '../user/user-get.js';
|
|
18
14
|
import { spo } from '../../../../utils/spo.js';
|
|
19
15
|
class SpoListItemRoleAssignmentAddCommand extends SpoCommand {
|
|
20
16
|
get name() {
|
|
@@ -47,15 +43,13 @@ class SpoListItemRoleAssignmentAddCommand extends SpoCommand {
|
|
|
47
43
|
requestUrl += `GetList('${formatting.encodeQueryParameter(listServerRelativeUrl)}')/`;
|
|
48
44
|
}
|
|
49
45
|
requestUrl += `items(${args.options.listItemId})/`;
|
|
50
|
-
const roleDefinitionId = await this.getRoleDefinitionId(args.options);
|
|
46
|
+
const roleDefinitionId = await this.getRoleDefinitionId(args.options, logger);
|
|
51
47
|
let principalId = args.options.principalId;
|
|
52
48
|
if (args.options.upn) {
|
|
53
|
-
principalId = await this.getUserPrincipalId(args.options);
|
|
54
|
-
await this.addRoleAssignment(requestUrl, roleDefinitionId, principalId);
|
|
49
|
+
principalId = await this.getUserPrincipalId(args.options, logger);
|
|
55
50
|
}
|
|
56
51
|
else if (args.options.groupName) {
|
|
57
|
-
principalId = await this.getGroupPrincipalId(args.options);
|
|
58
|
-
await this.addRoleAssignment(requestUrl, roleDefinitionId, principalId);
|
|
52
|
+
principalId = await this.getGroupPrincipalId(args.options, logger);
|
|
59
53
|
}
|
|
60
54
|
else if (args.options.entraGroupId || args.options.entraGroupName) {
|
|
61
55
|
if (this.verbose) {
|
|
@@ -85,45 +79,20 @@ class SpoListItemRoleAssignmentAddCommand extends SpoCommand {
|
|
|
85
79
|
};
|
|
86
80
|
await request.post(requestOptions);
|
|
87
81
|
}
|
|
88
|
-
async getRoleDefinitionId(options) {
|
|
82
|
+
async getRoleDefinitionId(options, logger) {
|
|
89
83
|
if (!options.roleDefinitionName) {
|
|
90
84
|
return options.roleDefinitionId;
|
|
91
85
|
}
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
output: 'json',
|
|
95
|
-
debug: this.debug,
|
|
96
|
-
verbose: this.verbose
|
|
97
|
-
};
|
|
98
|
-
const output = await cli.executeCommandWithOutput(spoRoleDefinitionListCommand, { options: { ...roleDefinitionListCommandOptions, _: [] } });
|
|
99
|
-
const getRoleDefinitionListOutput = JSON.parse(output.stdout);
|
|
100
|
-
const roleDefinitionId = getRoleDefinitionListOutput.find((role) => role.Name === options.roleDefinitionName).Id;
|
|
101
|
-
return roleDefinitionId;
|
|
86
|
+
const roleDefintion = await spo.getRoleDefinitionByName(options.webUrl, options.roleDefinitionName, logger, this.verbose);
|
|
87
|
+
return roleDefintion.Id;
|
|
102
88
|
}
|
|
103
|
-
async getGroupPrincipalId(options) {
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
name: options.groupName,
|
|
107
|
-
output: 'json',
|
|
108
|
-
debug: this.debug,
|
|
109
|
-
verbose: this.verbose
|
|
110
|
-
};
|
|
111
|
-
const output = await cli.executeCommandWithOutput(spoGroupGetCommand, { options: { ...groupGetCommandOptions, _: [] } });
|
|
112
|
-
const getGroupOutput = JSON.parse(output.stdout);
|
|
113
|
-
return getGroupOutput.Id;
|
|
89
|
+
async getGroupPrincipalId(options, logger) {
|
|
90
|
+
const group = await spo.getGroupByName(options.webUrl, options.groupName, logger, this.verbose);
|
|
91
|
+
return group.Id;
|
|
114
92
|
}
|
|
115
|
-
async getUserPrincipalId(options) {
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
email: options.upn,
|
|
119
|
-
id: undefined,
|
|
120
|
-
output: 'json',
|
|
121
|
-
debug: this.debug,
|
|
122
|
-
verbose: this.verbose
|
|
123
|
-
};
|
|
124
|
-
const output = await cli.executeCommandWithOutput(spoUserGetCommand, { options: { ...userGetCommandOptions, _: [] } });
|
|
125
|
-
const getUserOutput = JSON.parse(output.stdout);
|
|
126
|
-
return getUserOutput.Id;
|
|
93
|
+
async getUserPrincipalId(options, logger) {
|
|
94
|
+
const user = await spo.getUserByEmail(options.webUrl, options.upn, logger, this.verbose);
|
|
95
|
+
return user.Id;
|
|
127
96
|
}
|
|
128
97
|
}
|
|
129
98
|
_SpoListItemRoleAssignmentAddCommand_instances = new WeakSet(), _SpoListItemRoleAssignmentAddCommand_initTelemetry = function _SpoListItemRoleAssignmentAddCommand_initTelemetry() {
|
|
@@ -11,8 +11,6 @@ import { urlUtil } from '../../../../utils/urlUtil.js';
|
|
|
11
11
|
import { validation } from '../../../../utils/validation.js';
|
|
12
12
|
import SpoCommand from '../../../base/SpoCommand.js';
|
|
13
13
|
import commands from '../../commands.js';
|
|
14
|
-
import spoGroupGetCommand from '../group/group-get.js';
|
|
15
|
-
import spoUserGetCommand from '../user/user-get.js';
|
|
16
14
|
import { entraGroup } from '../../../../utils/entraGroup.js';
|
|
17
15
|
import { spo } from '../../../../utils/spo.js';
|
|
18
16
|
class SpoListItemRoleAssignmentRemoveCommand extends SpoCommand {
|
|
@@ -59,10 +57,10 @@ class SpoListItemRoleAssignmentRemoveCommand extends SpoCommand {
|
|
|
59
57
|
}
|
|
60
58
|
requestUrl += `items(${options.listItemId})/`;
|
|
61
59
|
if (options.upn) {
|
|
62
|
-
options.principalId = await this.getUserPrincipalId(options);
|
|
60
|
+
options.principalId = await this.getUserPrincipalId(options, logger);
|
|
63
61
|
}
|
|
64
62
|
else if (options.groupName) {
|
|
65
|
-
options.principalId = await this.getGroupPrincipalId(options);
|
|
63
|
+
options.principalId = await this.getGroupPrincipalId(options, logger);
|
|
66
64
|
}
|
|
67
65
|
else if (options.entraGroupId || options.entraGroupName) {
|
|
68
66
|
if (this.verbose) {
|
|
@@ -92,30 +90,13 @@ class SpoListItemRoleAssignmentRemoveCommand extends SpoCommand {
|
|
|
92
90
|
};
|
|
93
91
|
await request.post(requestOptions);
|
|
94
92
|
}
|
|
95
|
-
async getGroupPrincipalId(options) {
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
name: options.groupName,
|
|
99
|
-
output: 'json',
|
|
100
|
-
debug: this.debug,
|
|
101
|
-
verbose: this.verbose
|
|
102
|
-
};
|
|
103
|
-
const output = await cli.executeCommandWithOutput(spoGroupGetCommand, { options: { ...groupGetCommandOptions, _: [] } });
|
|
104
|
-
const getGroupOutput = JSON.parse(output.stdout);
|
|
105
|
-
return getGroupOutput.Id;
|
|
93
|
+
async getGroupPrincipalId(options, logger) {
|
|
94
|
+
const group = await spo.getGroupByName(options.webUrl, options.groupName, logger, this.verbose);
|
|
95
|
+
return group.Id;
|
|
106
96
|
}
|
|
107
|
-
async getUserPrincipalId(options) {
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
email: options.upn,
|
|
111
|
-
id: undefined,
|
|
112
|
-
output: 'json',
|
|
113
|
-
debug: this.debug,
|
|
114
|
-
verbose: this.verbose
|
|
115
|
-
};
|
|
116
|
-
const output = await cli.executeCommandWithOutput(spoUserGetCommand, { options: { ...userGetCommandOptions, _: [] } });
|
|
117
|
-
const getUserOutput = JSON.parse(output.stdout);
|
|
118
|
-
return getUserOutput.Id;
|
|
97
|
+
async getUserPrincipalId(options, logger) {
|
|
98
|
+
const user = await spo.getUserByEmail(options.webUrl, options.upn, logger, this.verbose);
|
|
99
|
+
return user.Id;
|
|
119
100
|
}
|
|
120
101
|
}
|
|
121
102
|
_SpoListItemRoleAssignmentRemoveCommand_instances = new WeakSet(), _SpoListItemRoleAssignmentRemoveCommand_initTelemetry = function _SpoListItemRoleAssignmentRemoveCommand_initTelemetry() {
|
|
@@ -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
|
|
38
|
-
|
|
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.
|
|
@@ -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
|
|
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
|
package/dist/utils/prompt.js
CHANGED
|
@@ -6,13 +6,20 @@ let inquirerSelect;
|
|
|
6
6
|
;
|
|
7
7
|
;
|
|
8
8
|
export const prompt = {
|
|
9
|
-
/* c8 ignore next
|
|
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
|
|
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
|
@@ -618,10 +618,12 @@ export const spo = {
|
|
|
618
618
|
/**
|
|
619
619
|
* Retrieves the role definition by name.
|
|
620
620
|
* Returns a RoleDefinition object
|
|
621
|
+
* Returns a RoleDefinition object
|
|
621
622
|
* @param webUrl Web url
|
|
622
623
|
* @param name the name of the role definition
|
|
623
624
|
* @param logger the Logger object
|
|
624
625
|
* @param verbose Set for verbose logging
|
|
626
|
+
* @param verbose Set for verbose logging
|
|
625
627
|
*/
|
|
626
628
|
async getRoleDefinitionByName(webUrl, name, logger, verbose) {
|
|
627
629
|
if (verbose && logger) {
|
|
@@ -1756,6 +1758,30 @@ export const spo = {
|
|
|
1756
1758
|
responseType: 'json'
|
|
1757
1759
|
};
|
|
1758
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;
|
|
1759
1785
|
}
|
|
1760
1786
|
};
|
|
1761
1787
|
//# sourceMappingURL=spo.js.map
|
package/dist/utils/types.js
CHANGED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import Global from '/docs/cmd/_global.mdx';
|
|
2
|
+
|
|
3
|
+
# entra group member remove
|
|
4
|
+
|
|
5
|
+
Removes members from a Microsoft Entra group
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
m365 entra group member remove [options]
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Options
|
|
14
|
+
|
|
15
|
+
```md definition-list
|
|
16
|
+
`-i, --groupId [groupId]`
|
|
17
|
+
: The ID of the Entra ID group. Specify `groupId` or `groupName` but not both.
|
|
18
|
+
|
|
19
|
+
`-n, --groupName [groupName]`
|
|
20
|
+
: The display name of the Entra ID group. Specify `groupId` or `groupName` but not both.
|
|
21
|
+
|
|
22
|
+
`--userIds [userIds]`
|
|
23
|
+
: Microsoft Entra user IDs. You can also pass a comma-separated list of IDs. Specify either `userIds`, `userNames`, `subgroupIds` or `subgroupNames` but not multiple.
|
|
24
|
+
|
|
25
|
+
`--userNames [userNames]`
|
|
26
|
+
: The user principal names of users. You can also pass a comma-separated list of UPNs. Specify either `userIds`, `userNames`, `subgroupIds` or `subgroupNames` but not multiple.
|
|
27
|
+
|
|
28
|
+
`--subgroupIds [subgroupIds]`
|
|
29
|
+
: Microsoft Entra group IDs. You can also pass a comma-separated list of IDs. Specify either `userIds`, `userNames`, `subgroupIds` or `subgroupNames` but not multiple.
|
|
30
|
+
|
|
31
|
+
`--subgroupNames [subgroupNames]`
|
|
32
|
+
: The display names of Microsoft Entra groups. You can also pass a comma-separated list of group display names. Specify either `userIds`, `userNames`, `subgroupIds` or `subgroupNames` but not multiple.
|
|
33
|
+
|
|
34
|
+
`-r, --role [role]`
|
|
35
|
+
: The role to be removed from the users. Valid values: `Owner`, `Member`. Defaults to both.
|
|
36
|
+
|
|
37
|
+
`--suppressNotFound`
|
|
38
|
+
: Suppress errors when a user was not found in a group.
|
|
39
|
+
|
|
40
|
+
`-f, --force`
|
|
41
|
+
: Don't prompt for confirmation.
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
<Global />
|
|
45
|
+
|
|
46
|
+
## Remarks
|
|
47
|
+
|
|
48
|
+
:::tip
|
|
49
|
+
|
|
50
|
+
When you use the `suppressNotFound` option, the command will not return an error if a user is not found as either an owner or a member of the group.
|
|
51
|
+
This feature proves useful when you need to remove a user from a group, but you are uncertain whether the user holds the role of a member or an owner within that group.
|
|
52
|
+
Without using this option, you would need to manually verify the user's role in the group before proceeding with removal.
|
|
53
|
+
|
|
54
|
+
:::
|
|
55
|
+
|
|
56
|
+
## Examples
|
|
57
|
+
|
|
58
|
+
Remove a single user specified by ID as member from a group specified by display name
|
|
59
|
+
|
|
60
|
+
```sh
|
|
61
|
+
m365 entra group member remove --groupName Developers --userIds 098b9f52-f48c-4401-819f-29c33794c3f5 --role Member
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Remove multiple users specified by ID from a group specified by ID
|
|
65
|
+
|
|
66
|
+
```sh
|
|
67
|
+
m365 entra group member remove --groupId a03c0c35-ef9a-419b-8cab-f89e0a8d2d2a --userIds "098b9f52-f48c-4401-819f-29c33794c3f5,f1e06e31-3abf-4746-83c2-1513d71f38b8"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Remove a single user specified by UPN as an owner from a group specified by display name
|
|
71
|
+
|
|
72
|
+
```sh
|
|
73
|
+
m365 entra group member remove --groupName Developers --userNames john.doe@contoso.com --role Owner
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Remove multiple users specified by UPN from a group specified by ID
|
|
77
|
+
|
|
78
|
+
```sh
|
|
79
|
+
m365 entra group member remove --groupId a03c0c35-ef9a-419b-8cab-f89e0a8d2d2a --userNames "john.doe@contoso.com,adele.vance@contoso.com"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Remove a single user specified by ID as owner and member of the group and suppress errors when the user was not found as owner or member
|
|
83
|
+
|
|
84
|
+
```sh
|
|
85
|
+
m365 entra group member remove --groupName Developers --userIds 098b9f52-f48c-4401-819f-29c33794c3f5 --suppressNotFound
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Remove 2 nested groups referenced by id from a security group
|
|
89
|
+
|
|
90
|
+
```sh
|
|
91
|
+
m365 entra group member remove --groupName Developers --subgroupIds "b51b6157-839f-4d92-8dab-ac61b53c6c40,1e793f86-8dc6-4df6-8037-649ef9a22330" --role Member
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Response
|
|
95
|
+
|
|
96
|
+
The command doesn't return a response on success.
|
|
@@ -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 />
|
|
@@ -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
|