From a4d91458178e557397202fba6fe4cc7162d688e9 Mon Sep 17 00:00:00 2001
From: Martin Machacek <machacek@edhouse.cz>
Date: Sun, 15 Dec 2024 15:56:51 +0100
Subject: [PATCH 1/4] New command: entra roledefinition add

---
 .../roledefinition/roledefinition-add.mdx     | 127 +++++++++++++
 docs/src/config/sidebars.ts                   |   5 +
 src/m365/entra/commands.ts                    |   1 +
 .../roledefinition/roledefinition-add.spec.ts | 178 ++++++++++++++++++
 .../roledefinition/roledefinition-add.ts      |  73 +++++++
 5 files changed, 384 insertions(+)
 create mode 100644 docs/docs/cmd/entra/roledefinition/roledefinition-add.mdx
 create mode 100644 src/m365/entra/commands/roledefinition/roledefinition-add.spec.ts
 create mode 100644 src/m365/entra/commands/roledefinition/roledefinition-add.ts

diff --git a/docs/docs/cmd/entra/roledefinition/roledefinition-add.mdx b/docs/docs/cmd/entra/roledefinition/roledefinition-add.mdx
new file mode 100644
index 0000000000..5a61d82087
--- /dev/null
+++ b/docs/docs/cmd/entra/roledefinition/roledefinition-add.mdx
@@ -0,0 +1,127 @@
+import Global from '/docs/cmd/_global.mdx';
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+# entra roledefinition add
+
+Creates a custom Microsoft Entra ID role definition
+
+## Usage
+
+```sh
+m365 entra roledefinition add [options]
+```
+
+## Options
+
+```md definition-list
+`-n, --displayName <displayName>`
+: The display name for the role definition.
+
+`--allowedResourceActions <allowedResourceActions>`	
+: Comma-separated list of resource actions allowed for the role.
+
+`--description [description]`
+: The description for the role definition.
+
+`--enabled [enabled]`
+: Indicates if the role is enabled for the assignment. If not specified, the role is enabled by default.
+
+`--version [version]`
+: The version of the role definition.
+```
+
+<Global />
+
+## Examples
+
+Create a custom Microsoft Entra ID role
+
+```sh
+m365 entra roledefinition add --displayName 'Application Remover' --description 'Allows to remove any Entra ID application' --allowedResourceActions 'microsoft.directory/applications/delete'
+```
+
+Create a custom Microsoft Entra ID role, but disable it for the assignment
+
+```sh
+m365 entra roledefinition add --displayName 'Application Remover' --version '1.0' --enabled false --allowedResourceActions 'microsoft.directory/applications/delete,microsoft.directory/applications/owners/update'
+```
+
+## Response
+
+<Tabs>
+  <TabItem value="JSON">
+
+  ```json
+  {
+    "id": "3844129d-f748-4c03-8165-4412ee9b4ceb",
+    "description": null,
+    "displayName": "Custom Role",
+    "isBuiltIn": false,
+    "isEnabled": true,
+    "resourceScopes": [
+      "/"
+    ],
+    "templateId": "3844129d-f748-4c03-8165-4412ee9b4ceb",
+    "version": "1",
+    "rolePermissions": [
+      {
+        "allowedResourceActions": [
+          "microsoft.directory/groups.unified/create",
+          "microsoft.directory/groups.unified/delete"
+        ],
+        "condition": null
+      }
+    ]
+  }
+  ```
+
+  </TabItem>
+  <TabItem value="Text">
+
+  ```text
+  description    : null
+  displayName    : Custom Role
+  id             : 3844129d-f748-4c03-8165-4412ee9b4ceb
+  isBuiltIn      : false
+  isEnabled      : true
+  resourceScopes : ["/"]
+  rolePermissions: [{"allowedResourceActions":["microsoft.directory/groups.unified/create","microsoft.directory/groups.unified/delete"],"condition":null}]
+  templateId     : 3844129d-f748-4c03-8165-4412ee9b4ceb
+  version        : 1
+  ```
+
+  </TabItem>
+  <TabItem value="CSV">
+
+  ```csv
+  id,description,displayName,isBuiltIn,isEnabled,templateId,version
+  3844129d-f748-4c03-8165-4412ee9b4ceb,,Custom Role,0,1,3844129d-f748-4c03-8165-4412ee9b4ceb,1
+  ```
+
+  </TabItem>
+  <TabItem value="Markdown">
+
+  ```md
+  # entra roledefinition add --displayName "Custom Role" --allowedResourceActions "microsoft.directory/groups.unified/create,microsoft.directory/groups.unified/delete" --version 1
+
+  Date: 12/15/2024
+
+  ## Custom Role (3844129d-f748-4c03-8165-4412ee9b4ceb)
+
+  Property | Value
+  ---------|-------
+  id | 3844129d-f748-4c03-8165-4412ee9b4ceb
+  displayName | Custom Role
+  isBuiltIn | false
+  isEnabled | true
+  templateId | 3844129d-f748-4c03-8165-4412ee9b4ceb
+  version | 1
+  ```
+
+  </TabItem>
+</Tabs>
+
+## More information
+
+- https://learn.microsoft.com/graph/api/rbacapplication-post-roledefinitions
\ No newline at end of file
diff --git a/docs/src/config/sidebars.ts b/docs/src/config/sidebars.ts
index 78006f1998..7faf08cbee 100644
--- a/docs/src/config/sidebars.ts
+++ b/docs/src/config/sidebars.ts
@@ -629,6 +629,11 @@ const sidebars: SidebarsConfig = {
         },
         {
           roledefinition: [
+            {
+              type: 'doc',
+              label: 'roledefinition add',
+              id: 'cmd/entra/roledefinition/roledefinition-add'
+            },
             {
               type: 'doc',
               label: 'roledefinition get',
diff --git a/src/m365/entra/commands.ts b/src/m365/entra/commands.ts
index dc270f50c7..2f7ca15cdf 100644
--- a/src/m365/entra/commands.ts
+++ b/src/m365/entra/commands.ts
@@ -88,6 +88,7 @@ export default {
   PIM_ROLE_ASSIGNMENT_ELIGIBILITY_LIST: `${prefix} pim role assignment eligibility list`,
   PIM_ROLE_REQUEST_LIST: `${prefix} pim role request list`,
   POLICY_LIST: `${prefix} policy list`,
+  ROLEDEFINITION_ADD: `${prefix} roledefinition add`,
   ROLEDEFINITION_LIST: `${prefix} roledefinition list`,
   ROLEDEFINITION_GET: `${prefix} roledefinition get`,
   ROLEDEFINITION_REMOVE: `${prefix} roledefinition remove`,
diff --git a/src/m365/entra/commands/roledefinition/roledefinition-add.spec.ts b/src/m365/entra/commands/roledefinition/roledefinition-add.spec.ts
new file mode 100644
index 0000000000..af4d326a53
--- /dev/null
+++ b/src/m365/entra/commands/roledefinition/roledefinition-add.spec.ts
@@ -0,0 +1,178 @@
+import assert from 'assert';
+import sinon from 'sinon';
+import auth from '../../../../Auth.js';
+import commands from '../../commands.js';
+import request from '../../../../request.js';
+import { Logger } from '../../../../cli/Logger.js';
+import { telemetry } from '../../../../telemetry.js';
+import { pid } from '../../../../utils/pid.js';
+import { session } from '../../../../utils/session.js';
+import command from './roledefinition-add.js';
+import { sinonUtil } from '../../../../utils/sinonUtil.js';
+import { CommandError } from '../../../../Command.js';
+import { z } from 'zod';
+import { CommandInfo } from '../../../../cli/CommandInfo.js';
+import { cli } from '../../../../cli/cli.js';
+
+describe(commands.ROLEDEFINITION_ADD, () => {
+  const roleDefinitionResponse = {
+    "id": "e1ede50a-487c-49b3-a43e-cda270d3341f",
+    "description": null,
+    "displayName": "Custom Role",
+    "isBuiltIn": false,
+    "isEnabled": true,
+    "resourceScopes": [
+      "/"
+    ],
+    "templateId": "e1ede50a-487c-49b3-a43e-cda270d3341f",
+    "version": null,
+    "rolePermissions": [
+      {
+        "allowedResourceActions": [
+          "microsoft.directory/groups.unified/create",
+          "microsoft.directory/groups.unified/delete"
+        ],
+        "condition": null
+      }
+    ]
+  };
+
+  const roleDefinitionWithDeatilsResponse = {
+    "id": "abcde50a-487c-49b3-a43e-cda270d3341f",
+    "description": "Allows creating and deleting unified groups",
+    "displayName": "Custom Role",
+    "isBuiltIn": false,
+    "isEnabled": false,
+    "resourceScopes": [
+      "/"
+    ],
+    "templateId": "abcnpm instade50a-487c-49b3-a43e-cda270d3341f",
+    "version": "1",
+    "rolePermissions": [
+      {
+        "allowedResourceActions": [
+          "microsoft.directory/groups.unified/create",
+          "microsoft.directory/groups.unified/delete"
+        ],
+        "condition": null
+      }
+    ]
+  };
+
+  let log: string[];
+  let logger: Logger;
+  let loggerLogSpy: sinon.SinonSpy;
+  let commandInfo: CommandInfo;
+  let commandOptionsSchema: z.ZodTypeAny;
+
+  before(() => {
+    sinon.stub(auth, 'restoreAuth').resolves();
+    sinon.stub(telemetry, 'trackEvent').returns();
+    sinon.stub(pid, 'getProcessName').returns('');
+    sinon.stub(session, 'getId').returns('');
+    auth.connection.active = true;
+    commandInfo = cli.getCommandInfo(command);
+    commandOptionsSchema = commandInfo.command.getSchemaToParse()!;
+  });
+
+  beforeEach(() => {
+    log = [];
+    logger = {
+      log: async (msg: string) => {
+        log.push(msg);
+      },
+      logRaw: async (msg: string) => {
+        log.push(msg);
+      },
+      logToStderr: async (msg: string) => {
+        log.push(msg);
+      }
+    };
+    loggerLogSpy = sinon.spy(logger, 'log');
+  });
+
+  afterEach(() => {
+    sinonUtil.restore([
+      request.post,
+      cli.promptForConfirmation
+    ]);
+  });
+
+  after(() => {
+    sinon.restore();
+    auth.connection.active = false;
+  });
+
+  it('has correct name', () => {
+    assert.strictEqual(command.name, commands.ROLEDEFINITION_ADD);
+  });
+
+  it('has a description', () => {
+    assert.notStrictEqual(command.description, null);
+  });
+
+  it('fails validation if displayName is not provided', () => {
+    const actual = commandOptionsSchema.safeParse({ allowedResourceActions: "microsoft.directory/groups.unified/create"});
+    assert.notStrictEqual(actual.success, true);
+  });
+
+  it('fails validation if allowedResourceActions is not provided', () => {
+    const actual = commandOptionsSchema.safeParse({ displayName: "Custom Role" });
+    assert.notStrictEqual(actual.success, true);
+  });
+
+  it('creates a custom role definition with a specific display name and resource actions', async () => {
+    sinon.stub(request, 'post').callsFake(async (opts) => {
+      if (opts.url === 'https://graph.microsoft.com/v1.0/roleManagement/directory/roleDefinitions') {
+        return roleDefinitionResponse;
+      }
+
+      throw 'Invalid request';
+    });
+
+    await command.action(logger, { options: { displayName: 'Custom Role', allowedResourceActions: "microsoft.directory/groups.unified/create,microsoft.directory/groups.unified/delete" } });
+    assert(loggerLogSpy.calledOnceWithExactly(roleDefinitionResponse));
+  });
+
+  it('creates a custom role definition with a specific display name, description, version and resource actions', async () => {
+    sinon.stub(request, 'post').callsFake(async (opts) => {
+      if (opts.url === 'https://graph.microsoft.com/v1.0/roleManagement/directory/roleDefinitions') {
+        return roleDefinitionWithDeatilsResponse;
+      }
+
+      throw 'Invalid request';
+    });
+
+    await command.action(logger, {
+      options: {
+        displayName: 'Custom Role',
+        description: 'Allows creating and deleting unified groups',
+        allowedResourceActions: "microsoft.directory/groups.unified/create,microsoft.directory/groups.unified/delete",
+        enabled: false,
+        version: "1",
+        verbose: true
+      }
+    });
+    assert(loggerLogSpy.calledOnceWithExactly(roleDefinitionWithDeatilsResponse));
+  });
+
+  it('correctly handles API OData error', async () => {
+    sinon.stub(request, 'post').rejects({
+      error: {
+        'odata.error': {
+          code: '-1, InvalidOperationException',
+          message: {
+            value: 'Invalid request'
+          }
+        }
+      }
+    });
+
+    await assert.rejects(command.action(logger, {
+      options: {
+        displayName: 'Custom Role',
+        allowedResourceActions: "microsoft.directory/groups.unified/create"
+      }
+    }), new CommandError('Invalid request'));
+  });
+});
\ No newline at end of file
diff --git a/src/m365/entra/commands/roledefinition/roledefinition-add.ts b/src/m365/entra/commands/roledefinition/roledefinition-add.ts
new file mode 100644
index 0000000000..b385b41d2c
--- /dev/null
+++ b/src/m365/entra/commands/roledefinition/roledefinition-add.ts
@@ -0,0 +1,73 @@
+import { z } from 'zod';
+import { globalOptionsZod } from '../../../../Command.js';
+import { zod } from '../../../../utils/zod.js';
+import GraphCommand from '../../../base/GraphCommand.js';
+import commands from '../../commands.js';
+import { Logger } from '../../../../cli/Logger.js';
+import request, { CliRequestOptions } from '../../../../request.js';
+import { UnifiedRoleDefinition } from '@microsoft/microsoft-graph-types';
+
+const options = globalOptionsZod
+  .extend({
+    displayName: zod.alias('n', z.string()),
+    allowedResourceActions: z.string().transform((value) => value.split(',').map(String)),
+    description: z.string().optional(),
+    enabled: z.boolean().optional(),
+    version: z.string().optional()
+  })
+  .strict();
+
+declare type Options = z.infer<typeof options>;
+
+interface CommandArgs {
+  options: Options;
+}
+
+class EntraRoleDefinitionAddCommand extends GraphCommand {
+  public get name(): string {
+    return commands.ROLEDEFINITION_ADD;
+  }
+
+  public get description(): string {
+    return 'Creates a custom Microsoft Entra ID role definition';
+  }
+
+  public get schema(): z.ZodTypeAny | undefined {
+    return options;
+  }
+
+  public async commandAction(logger: Logger, args: CommandArgs): Promise<void> {
+    if (args.options.verbose) {
+      await logger.logToStderr(`Creating custom role definition with name ${args.options.displayName}...`);
+    }
+
+    const requestOptions: CliRequestOptions = {
+      url: `${this.resource}/v1.0/roleManagement/directory/roleDefinitions`,
+      headers: {
+        accept: 'application/json;odata.metadata=none'
+      },
+      data: {
+        displayName: args.options.displayName,
+        rolePermissions: [
+          {
+            allowedResourceActions: args.options.allowedResourceActions
+          }
+        ],
+        description: args.options.description,
+        isEnabled: args.options.enabled !== undefined ? args.options.enabled : true,
+        version: args.options.version
+      },
+      responseType: 'json'
+    };
+
+    try {
+      const result = await request.post<UnifiedRoleDefinition>(requestOptions);
+      await logger.log(result);
+    }
+    catch (err: any) {
+      this.handleRejectedODataJsonPromise(err);
+    }
+  }
+}
+
+export default new EntraRoleDefinitionAddCommand();
\ No newline at end of file

From d6d47bfcfa561a64f3df8f5bdd2a60c6870c5672 Mon Sep 17 00:00:00 2001
From: Martin Machacek <machacek@edhouse.cz>
Date: Tue, 7 Jan 2025 09:44:11 +0100
Subject: [PATCH 2/4] New command: entra roledefinition add

---
 .../roledefinition/roledefinition-add.spec.ts | 33 +++++++++++--------
 1 file changed, 20 insertions(+), 13 deletions(-)

diff --git a/src/m365/entra/commands/roledefinition/roledefinition-add.spec.ts b/src/m365/entra/commands/roledefinition/roledefinition-add.spec.ts
index af4d326a53..e88997d62d 100644
--- a/src/m365/entra/commands/roledefinition/roledefinition-add.spec.ts
+++ b/src/m365/entra/commands/roledefinition/roledefinition-add.spec.ts
@@ -130,7 +130,12 @@ describe(commands.ROLEDEFINITION_ADD, () => {
       throw 'Invalid request';
     });
 
-    await command.action(logger, { options: { displayName: 'Custom Role', allowedResourceActions: "microsoft.directory/groups.unified/create,microsoft.directory/groups.unified/delete" } });
+    const parsedSchema = commandOptionsSchema.safeParse(
+      {
+        displayName: 'Custom Role',
+        allowedResourceActions: "microsoft.directory/groups.unified/create,microsoft.directory/groups.unified/delete"
+      });
+    await command.action(logger, { options: parsedSchema.data });
     assert(loggerLogSpy.calledOnceWithExactly(roleDefinitionResponse));
   });
 
@@ -143,15 +148,16 @@ describe(commands.ROLEDEFINITION_ADD, () => {
       throw 'Invalid request';
     });
 
+    const parsedSchema = commandOptionsSchema.safeParse({
+      displayName: 'Custom Role',
+      description: 'Allows creating and deleting unified groups',
+      allowedResourceActions: "microsoft.directory/groups.unified/create,microsoft.directory/groups.unified/delete",
+      enabled: false,
+      version: "1",
+      verbose: true
+    });
     await command.action(logger, {
-      options: {
-        displayName: 'Custom Role',
-        description: 'Allows creating and deleting unified groups',
-        allowedResourceActions: "microsoft.directory/groups.unified/create,microsoft.directory/groups.unified/delete",
-        enabled: false,
-        version: "1",
-        verbose: true
-      }
+      options: parsedSchema.data
     });
     assert(loggerLogSpy.calledOnceWithExactly(roleDefinitionWithDeatilsResponse));
   });
@@ -168,11 +174,12 @@ describe(commands.ROLEDEFINITION_ADD, () => {
       }
     });
 
+    const parsedSchema = commandOptionsSchema.safeParse({
+      displayName: 'Custom Role',
+      allowedResourceActions: "microsoft.directory/groups.unified/create"
+    });
     await assert.rejects(command.action(logger, {
-      options: {
-        displayName: 'Custom Role',
-        allowedResourceActions: "microsoft.directory/groups.unified/create"
-      }
+      options: parsedSchema.data
     }), new CommandError('Invalid request'));
   });
 });
\ No newline at end of file

From bceb0474c17bb6c778a46a74e91bd751463e42e0 Mon Sep 17 00:00:00 2001
From: Martin Machacek <machacek@edhouse.cz>
Date: Fri, 10 Jan 2025 07:50:26 +0100
Subject: [PATCH 3/4] New command: entra roledefinition add

---
 .../roledefinition/roledefinition-add.mdx     | 218 +++++++++++++++++-
 .../roledefinition/roledefinition-add.spec.ts |   9 +-
 .../roledefinition/roledefinition-add.ts      |   8 +-
 3 files changed, 218 insertions(+), 17 deletions(-)

diff --git a/docs/docs/cmd/entra/roledefinition/roledefinition-add.mdx b/docs/docs/cmd/entra/roledefinition/roledefinition-add.mdx
index 5a61d82087..1fdfd1e3d2 100644
--- a/docs/docs/cmd/entra/roledefinition/roledefinition-add.mdx
+++ b/docs/docs/cmd/entra/roledefinition/roledefinition-add.mdx
@@ -18,21 +18,223 @@ m365 entra roledefinition add [options]
 `-n, --displayName <displayName>`
 : The display name for the role definition.
 
-`--allowedResourceActions <allowedResourceActions>`	
+`-a, --allowedResourceActions <allowedResourceActions>`	
 : Comma-separated list of resource actions allowed for the role.
 
-`--description [description]`
+`-d, --description [description]`
 : The description for the role definition.
 
-`--enabled [enabled]`
+`-e, --enabled [enabled]`
 : Indicates if the role is enabled for the assignment. If not specified, the role is enabled by default.
 
-`--version [version]`
+`-v, --version [version]`
 : The version of the role definition.
 ```
 
 <Global />
 
+## Remarks
+
+The following resource actions (permissions) can be assigned to a custom Entra ID role definition:
+
+|Permission|Description|
+|-|-|
+|microsoft.directory/applicationPolicies/allProperties/read| Read all properties (including privileged properties) on application policies|
+|microsoft.directory/applicationPolicies/allProperties/update| Update all properties (including privileged properties) on application policies|
+|microsoft.directory/applicationPolicies/basic/update| Update standard properties of application policies|
+|microsoft.directory/applicationPolicies/create| Create application policies|
+|microsoft.directory/applicationPolicies/createAsOwner| Create application policies, and creator is added as the first owner|
+|microsoft.directory/applicationPolicies/delete| Delete application policies|
+|microsoft.directory/applicationPolicies/owners/read| Read owners on application policies|
+|microsoft.directory/applicationPolicies/owners/update| Update the owner property of application policies|
+|microsoft.directory/applicationPolicies/policyAppliedTo/read| Read application policies applied to objects list|
+|microsoft.directory/applicationPolicies/standard/read| Read standard properties of application policies|
+|microsoft.directory/applications.myOrganization/allProperties/read| Read all properties (including privileged properties) on single-directory applications|
+|microsoft.directory/applications.myOrganization/allProperties/update| Update all properties (including privileged properties) on single-directory applications|
+|microsoft.directory/applications.myOrganization/audience/update| Update audience on single-directory applications|
+|microsoft.directory/applications.myOrganization/authentication/update| Update authentication on single-directory applications|
+|microsoft.directory/applications.myOrganization/basic/update| Update basic properties on single-directory applications|
+|microsoft.directory/applications.myOrganization/credentials/update| Update credentials on single-directory applications|
+|microsoft.directory/applications.myOrganization/delete| Delete single-directory applications|
+|microsoft.directory/applications.myOrganization/owners/read| Read owners on single-directory applications|
+|microsoft.directory/applications.myOrganization/owners/update| Update owners on single-directory applications|
+|microsoft.directory/applications.myOrganization/permissions/update| Update exposed permissions and required permissions on single-tenant applications|
+|microsoft.directory/applications.myOrganization/standard/read| Read basic properties on single-directory applications|
+|microsoft.directory/applications/allProperties/read| Read all properties (including privileged properties) on all types of applications|
+|microsoft.directory/applications/allProperties/update| Update all properties (including privileged properties) on all types of applications|
+|microsoft.directory/applications/applicationProxy/read| Read all application proxy properties|
+|microsoft.directory/applications/applicationProxy/update| Update all application proxy properties|
+|microsoft.directory/applications/applicationProxyAuthentication/update| Update authentication on all types of applications|
+|microsoft.directory/applications/applicationProxySslCertificate/update| Update SSL certificate settings for application proxy|
+|microsoft.directory/applications/applicationProxyUrlSettings/update| Update URL settings for application proxy|
+|microsoft.directory/applications/appRoles/update| Update the appRoles property on all types of applications|
+|microsoft.directory/applications/audience/update| Update the audience property for applications|
+|microsoft.directory/applications/authentication/update| Update authentication on all types of applications|
+|microsoft.directory/applications/basic/update| Update basic properties for applications|
+|microsoft.directory/applications/create| Create all types of applications|
+|microsoft.directory/applications/createAsOwner| Create all types of applications, and creator is added as the first owner|
+|microsoft.directory/applications/credentials/update| Update application credentials|
+|microsoft.directory/applications/delete| Delete all types of applications|
+|microsoft.directory/applications/owners/read| Read owners of applications|
+|microsoft.directory/applications/owners/update| Update owners of applications|
+|microsoft.directory/applications/permissions/update| Update exposed permissions and required permissions on all types of applications|
+|microsoft.directory/applications/standard/read| Read standard properties of applications|
+|microsoft.directory/applications/synchronization/standard/read| Read provisioning settings associated with the application object|
+|microsoft.directory/applicationTemplates/instantiate| Instantiate gallery applications from application templates|
+|microsoft.directory/auditLogs/allProperties/read| Read all properties on audit logs, excluding custom security attributes audit logs|
+|microsoft.directory/bitlockerKeys/key/read| Read bitlocker metadata and key on devices|
+|microsoft.directory/bitlockerKeys/metadata/read| Read bitlocker key metadata on devices|
+|microsoft.directory/connectorGroups/allProperties/read| Read all properties of application proxy connector groups|
+|microsoft.directory/connectorGroups/allProperties/update| Update all properties of application proxy connector groups|
+|microsoft.directory/connectorGroups/create| Create application proxy connector groups|
+|microsoft.directory/connectorGroups/delete| Delete application proxy connector groups|
+|microsoft.directory/connectors/allProperties/read| Read all properties of application proxy connectors|
+|microsoft.directory/connectors/create| Create application proxy connectors|
+|microsoft.directory/crossTenantAccessPolicy/allowedCloudEndpoints/update| Update allowed cloud endpoints of cross-tenant access policy|
+|microsoft.directory/crossTenantAccessPolicy/basic/update| Update basic settings of cross-tenant access policy|
+|microsoft.directory/crossTenantAccessPolicy/default/b2bCollaboration/update| Update Microsoft Entra B2B collaboration settings of the default cross-tenant access policy|
+|microsoft.directory/crossTenantAccessPolicy/default/b2bDirectConnect/update| Update Microsoft Entra B2B direct connect settings of the default cross-tenant access policy|
+|microsoft.directory/crossTenantAccessPolicy/default/crossCloudMeetings/update| Update cross-cloud Teams meeting settings of the default cross-tenant access policy|
+|microsoft.directory/crossTenantAccessPolicy/default/standard/read| Read basic properties of the default cross-tenant access policy|
+|microsoft.directory/crossTenantAccessPolicy/default/tenantRestrictions/update| Update tenant restrictions of the default cross-tenant access policy|
+|microsoft.directory/crossTenantAccessPolicy/partners/b2bCollaboration/update| Update Microsoft Entra B2B collaboration settings of cross-tenant access policy for partners|
+|microsoft.directory/crossTenantAccessPolicy/partners/b2bDirectConnect/update| Update Microsoft Entra B2B direct connect settings of cross-tenant access policy for partners|
+|microsoft.directory/crossTenantAccessPolicy/partners/create| Create cross-tenant access policy for partners|
+|microsoft.directory/crossTenantAccessPolicy/partners/crossCloudMeetings/update| Update cross-cloud Teams meeting settings of cross-tenant access policy for partners|
+|microsoft.directory/crossTenantAccessPolicy/partners/delete| Delete cross-tenant access policy for partners|
+|microsoft.directory/crossTenantAccessPolicy/partners/identitySynchronization/basic/update| Update basic settings of cross-tenant sync policy|
+|microsoft.directory/crossTenantAccessPolicy/partners/identitySynchronization/create| Create cross-tenant sync policy for partners|
+|microsoft.directory/crossTenantAccessPolicy/partners/identitySynchronization/standard/read| Read basic properties of cross-tenant sync policy|
+|microsoft.directory/crossTenantAccessPolicy/partners/standard/read| Read basic properties of cross-tenant access policy for partners|
+|microsoft.directory/crossTenantAccessPolicy/partners/tenantRestrictions/update| Update tenant restrictions of cross-tenant access policy for partners|
+|microsoft.directory/crossTenantAccessPolicy/standard/read| Read basic properties of cross-tenant access policy|
+|microsoft.directory/deviceLocalCredentials/password/read| Read all properties of the backed up local administrator account credentials for Microsoft Entra joined devices, including the password|
+|microsoft.directory/deviceLocalCredentials/standard/read| Read all properties of the backed up local administrator account credentials for Microsoft Entra joined devices, except the password|
+|microsoft.directory/deviceManagementPolicies/basic/update| Update basic properties on device management application policies|
+|microsoft.directory/deviceManagementPolicies/standard/read| Read standard properties on device management application policies|
+|microsoft.directory/deviceRegistrationPolicy/basic/update| Update basic properties on device registration policies|
+|microsoft.directory/deviceRegistrationPolicy/standard/read| Read standard properties on device registration policies|
+|microsoft.directory/devices/createdFrom/read| Read created from Internet of Things (IoT) device template links|
+|microsoft.directory/devices/delete| Delete devices from Microsoft Entra ID|
+|microsoft.directory/devices/disable| Disable devices in Microsoft Entra ID|
+|microsoft.directory/devices/enable| Enable devices in Microsoft Entra ID|
+|microsoft.directory/devices/registeredOwners/read| Read registered owners of devices|
+|microsoft.directory/devices/registeredOwners/update| Update registered owners of devices|
+|microsoft.directory/devices/registeredUsers/read| Read registered users of devices|
+|microsoft.directory/devices/registeredUsers/update| Update registered users of devices|
+|microsoft.directory/devices/standard/read| Read basic properties on devices|
+|microsoft.directory/groups.security.assignedMembership/allProperties/update| Update all properties (including privileged properties) on Security groups of assigned membership type, excluding role-assignable groups|
+|microsoft.directory/groups.security.assignedMembership/basic/update| Update basic properties on Security groups of assigned membership type, excluding role-assignable groups|
+|microsoft.directory/groups.security.assignedMembership/classification/update| Update the classification property on Security groups of assigned membership type, excluding role-assignable groups|
+|microsoft.directory/groups.security.assignedMembership/create| Create Security groups of assigned membership type, excluding role-assignable groups|
+|microsoft.directory/groups.security.assignedMembership/createAsOwner| Create Security groups of assigned membership type, excluding role-assignable groups. Creator is added as the first owner.|
+|microsoft.directory/groups.security.assignedMembership/delete| Delete Security groups of assigned membership type, excluding role-assignable groups|
+|microsoft.directory/groups.security.assignedMembership/members/update| Update members of Security groups of assigned membership type, excluding role-assignable groups|
+|microsoft.directory/groups.security.assignedMembership/owners/update| Update owners of Security groups of assigned membership type, excluding role-assignable groups|
+|microsoft.directory/groups.security.assignedMembership/visibility/update| Update the visibility property on Security groups of assigned membership type, excluding role-assignable groups|
+|microsoft.directory/groups.security/allProperties/update| Update all properties (including privileged properties) on Security groups, excluding role-assignable groups|
+|microsoft.directory/groups.security/basic/update| Update basic properties on Security groups, excluding role-assignable groups|
+|microsoft.directory/groups.security/classification/update| Update the classification property on Security groups, excluding role-assignable groups|
+|microsoft.directory/groups.security/create| Create Security groups, excluding role-assignable groups|
+|microsoft.directory/groups.security/createAsOwner| Create Security groups, excluding role-assignable groups. Creator is added as the first owner.|
+|microsoft.directory/groups.security/delete| Delete Security groups, excluding role-assignable groups|
+|microsoft.directory/groups.security/dynamicMembershipRule/update| Update the dynamic membership rule on Security groups, excluding role-assignable groups|
+|microsoft.directory/groups.security/members/update| Update members of Security groups, excluding role-assignable groups|
+|microsoft.directory/groups.security/owners/update| Update owners of Security groups, excluding role-assignable groups|
+|microsoft.directory/groups.security/visibility/update| Update the visibility property on Security groups, excluding role-assignable groups|
+|microsoft.directory/groups.unified.assignedMembership/allProperties/update| Update all properties (including privileged properties) on Microsoft 365 groups of assigned membership type, excluding role-assignable groups|
+|microsoft.directory/groups.unified.assignedMembership/basic/update| Update basic properties on Microsoft 365 groups of assigned membership type, excluding role-assignable groups|
+|microsoft.directory/groups.unified.assignedMembership/classification/update| Update the classification property on Microsoft 365 groups of assigned membership type, excluding role-assignable groups|
+|microsoft.directory/groups.unified.assignedMembership/create| Create Microsoft 365 groups of assigned membership type, excluding role-assignable groups|
+|microsoft.directory/groups.unified.assignedMembership/createAsOwner| Create Microsoft 365 groups of assigned membership type, excluding role-assignable groups. Creator is added as the first owner.|
+|microsoft.directory/groups.unified.assignedMembership/delete| Delete Microsoft 365 groups of assigned membership type, excluding role-assignable groups|
+|microsoft.directory/groups.unified.assignedMembership/members/update| Update members of Microsoft 365 groups of assigned membership type, excluding role-assignable groups|
+|microsoft.directory/groups.unified.assignedMembership/owners/update| Update owners of Microsoft 365 groups of assigned membership type, excluding role-assignable groups|
+|microsoft.directory/groups.unified.assignedMembership/visibility/update| Update the visibility property on Microsoft 365 groups of assigned membership type, excluding role-assignable groups|
+|microsoft.directory/groups.unified/allProperties/update| Update all properties (including privileged properties) on Microsoft 365 groups, excluding role-assignable groups|
+|microsoft.directory/groups.unified/basic/update| Update basic properties on Microsoft 365 groups, excluding role-assignable groups|
+|microsoft.directory/groups.unified/classification/update| Update the classification property on Microsoft 365 groups, excluding role-assignable groups|
+|microsoft.directory/groups.unified/create| Create Microsoft 365 groups, excluding role-assignable groups|
+|microsoft.directory/groups.unified/createAsOwner| Create Microsoft 365 groups, excluding role-assignable groups. Creator is added as the first owner.|
+|microsoft.directory/groups.unified/delete| Delete Microsoft 365 groups, excluding role-assignable groups|
+|microsoft.directory/groups.unified/dynamicMembershipRule/update| Update the dynamic membership rule on Microsoft 365 groups, excluding role-assignable groups|
+|microsoft.directory/groups.unified/members/update| Update members of Microsoft 365 groups, excluding role-assignable groups|
+|microsoft.directory/groups.unified/owners/update| Update owners of Microsoft 365 groups, excluding role-assignable groups|
+|microsoft.directory/groups.unified/visibility/update| Update the visibility property on Microsoft 365 groups, excluding role-assignable groups|
+|microsoft.directory/groups/allProperties/read| Read all properties (including privileged properties) on Security groups and Microsoft 365 groups, including role-assignable groups|
+|microsoft.directory/groups/allProperties/update| Update all properties (including privileged properties) on Security groups and Microsoft 365 groups, excluding role-assignable groups|
+|microsoft.directory/groups/assignLicense| Assign product licenses to groups for group-based licensing|
+|microsoft.directory/groups/basic/update| Update basic properties on Security groups and Microsoft 365 groups, excluding role-assignable groups|
+|microsoft.directory/groups/classification/update| Update the classification property on Security groups and Microsoft 365 groups, excluding role-assignable groups|
+|microsoft.directory/groups/create| Create Security groups and Microsoft 365 groups, excluding role-assignable groups|
+|microsoft.directory/groups/createAsOwner| Create Security groups and Microsoft 365 groups, excluding role-assignable groups. Creator is added as the first owner.|
+|microsoft.directory/groups/delete| Delete Security groups and Microsoft 365 groups, excluding role-assignable groups|
+|microsoft.directory/groups/dynamicMembershipRule/update| Update the dynamic membership rule on Security groups and Microsoft 365 groups, excluding role-assignable groups|
+|microsoft.directory/groups/groupType/update| Update properties that would affect the group type of Security groups and Microsoft 365 groups, excluding role-assignable groups|
+|microsoft.directory/groups/memberOf/read| Read the memberOf property on Security groups and Microsoft 365 groups, including role-assignable groups|
+|microsoft.directory/groups/members/read| Read members of Security groups and Microsoft 365 groups, including role-assignable groups|
+|microsoft.directory/groups/members/update| Update members of Security groups and Microsoft 365 groups, excluding role-assignable groups|
+|microsoft.directory/groups/owners/read| Read owners of Security groups and Microsoft 365 groups, including role-assignable groups|
+|microsoft.directory/groups/owners/update| Update owners of Security groups and Microsoft 365 groups, excluding role-assignable groups|
+|microsoft.directory/groups/reprocessLicenseAssignment Reprocess license assignments for group-based licensing|
+|microsoft.directory/groups/standard/read| Read standard properties of Security groups and Microsoft 365 groups, including role-assignable groups|
+|microsoft.directory/groups/visibility/update| Update the visibility property of Security groups and Microsoft 365 groups, excluding role-assignable groups|
+|microsoft.directory/provisioningLogs/allProperties/read| Read all properties of provisioning logs|
+|microsoft.directory/servicePrincipals/allProperties/read| Read all properties (including privileged properties) on servicePrincipals|
+|microsoft.directory/servicePrincipals/allProperties/update| Update all properties (including privileged properties) on servicePrincipals|
+|microsoft.directory/servicePrincipals/appRoleAssignedTo/read| Read service principal role assignments|
+|microsoft.directory/servicePrincipals/appRoleAssignedTo/update| Update service principal role assignments|
+|microsoft.directory/servicePrincipals/appRoleAssignments/read| Read role assignments assigned to service principals|
+|microsoft.directory/servicePrincipals/audience/update| Update audience properties on service principals|
+|microsoft.directory/servicePrincipals/authentication/update| Update authentication properties on service principals|
+|microsoft.directory/servicePrincipals/basic/update| Update basic properties on service principals|
+|microsoft.directory/servicePrincipals/create| Create service principals|
+|microsoft.directory/servicePrincipals/createAsOwner| Create service principals, with creator as the first owner|
+|microsoft.directory/servicePrincipals/credentials/update| Update credentials of service principals|
+|microsoft.directory/servicePrincipals/delete| Delete service principals|
+|microsoft.directory/servicePrincipals/disable| Disable service principals|
+|microsoft.directory/servicePrincipals/enable| Enable service principals|
+|microsoft.directory/servicePrincipals/getPasswordSingleSignOnCredentials| Manage password single sign-on credentials on service principals|
+|microsoft.directory/servicePrincipals/managePasswordSingleSignOnCredentials| Read password single sign-on credentials on service principals|
+|microsoft.directory/servicePrincipals/oAuth2PermissionGrants/read| Read delegated permission grants on service principals|
+|microsoft.directory/servicePrincipals/owners/read| Read owners of service principals|
+|microsoft.directory/servicePrincipals/owners/update| Update owners of service principals|
+|microsoft.directory/servicePrincipals/permissions/update| Update permissions of service principals|
+|microsoft.directory/servicePrincipals/policies/read| Read policies of service principals|
+|microsoft.directory/servicePrincipals/policies/update| Update policies of service principals|
+|microsoft.directory/servicePrincipals/standard/read| Read basic properties of service principals|
+|microsoft.directory/servicePrincipals/synchronization/standard/read| Read provisioning settings associated with your service principal|
+|microsoft.directory/servicePrincipals/synchronizationCredentials/manage| Manage application provisioning secrets and credentials|
+|microsoft.directory/servicePrincipals/synchronizationJobs/manage| Start, restart, and pause application provisioning synchronization jobs|
+|microsoft.directory/servicePrincipals/synchronizationSchema/manage| Create and manage application provisioning synchronization jobs and schema|
+|microsoft.directory/servicePrincipals/tag/update| Update the tag property for service principals|
+|microsoft.directory/signInReports/allProperties/read| Read all properties on sign-in reports, including privileged properties|
+|microsoft.directory/tenantRelationships/standard/read| Read standard tenant relationship information|
+|microsoft.directory/users/appRoleAssignments/read| Read application role assignments for users|
+|microsoft.directory/users/assignLicense| Manage user licenses|
+|microsoft.directory/users/basic/update| Update basic properties on users|
+|microsoft.directory/users/contactInfo/update| Update contact properties on users|
+|microsoft.directory/users/deviceForResourceAccount/read| Read deviceForResourceAccount of users|
+|microsoft.directory/users/directReports/read| Read the direct reports for users|
+|microsoft.directory/users/extensionProperties/update| Update extension properties of users|
+|microsoft.directory/users/identities/read| Read identities of users|
+|microsoft.directory/users/jobInfo/update| Update job information of users|
+|microsoft.directory/users/licenseDetails/read| Read license details of users|
+|microsoft.directory/users/manager/read| Read manager of users|
+|microsoft.directory/users/manager/update| Update manager for users|
+|microsoft.directory/users/memberOf/read| Read the group memberships of users|
+|microsoft.directory/users/ownedDevices/read| Read owned devices of users|
+|microsoft.directory/users/parentalControls/update| Update parental controls of users|
+|microsoft.directory/users/passwordPolicies/update| Update password policies of users|
+|microsoft.directory/users/registeredDevices/read| Read registered devices of users|
+|microsoft.directory/users/reprocessLicenseAssignment| Reprocess license assignments for users|
+|microsoft.directory/users/reprocessLicenseAssignment| Reprocess license assignments for users|
+|microsoft.directory/users/scopedRoleMemberOf/read| Read user's membership of a Microsoft Entra role, that is scoped to an administrative unit|
+|microsoft.directory/users/sponsors/read| Read sponsors of users|
+|microsoft.directory/users/sponsors/update| Update sponsors of users|
+|microsoft.directory/users/standard/read| Read basic properties on users|
+|microsoft.directory/users/usageLocation/update| Update usage location of users|
+
 ## Examples
 
 Create a custom Microsoft Entra ID role
@@ -44,7 +246,7 @@ m365 entra roledefinition add --displayName 'Application Remover' --description
 Create a custom Microsoft Entra ID role, but disable it for the assignment
 
 ```sh
-m365 entra roledefinition add --displayName 'Application Remover' --version '1.0' --enabled false --allowedResourceActions 'microsoft.directory/applications/delete,microsoft.directory/applications/owners/update'
+m365 entra roledefinition add --displayName 'Application Remover' --version '1.0' --enabled false --allowedResourceActions 'microsoft.directory/applications/delete,microsoft.directory/applications/owners/update|'
 ```
 
 ## Response
@@ -67,7 +269,7 @@ m365 entra roledefinition add --displayName 'Application Remover' --version '1.0
     "rolePermissions": [
       {
         "allowedResourceActions": [
-          "microsoft.directory/groups.unified/create",
+          "microsoft.directory/groups.unified/create|",
           "microsoft.directory/groups.unified/delete"
         ],
         "condition": null
@@ -86,7 +288,7 @@ m365 entra roledefinition add --displayName 'Application Remover' --version '1.0
   isBuiltIn      : false
   isEnabled      : true
   resourceScopes : ["/"]
-  rolePermissions: [{"allowedResourceActions":["microsoft.directory/groups.unified/create","microsoft.directory/groups.unified/delete"],"condition":null}]
+  rolePermissions: [{"allowedResourceActions":["microsoft.directory/groups.unified/create|","microsoft.directory/groups.unified/delete"],"condition":null}]
   templateId     : 3844129d-f748-4c03-8165-4412ee9b4ceb
   version        : 1
   ```
@@ -103,7 +305,7 @@ m365 entra roledefinition add --displayName 'Application Remover' --version '1.0
   <TabItem value="Markdown">
 
   ```md
-  # entra roledefinition add --displayName "Custom Role" --allowedResourceActions "microsoft.directory/groups.unified/create,microsoft.directory/groups.unified/delete" --version 1
+  # entra roledefinition add --displayName "Custom Role" --allowedResourceActions "microsoft.directory/groups.unified/create|,microsoft.directory/groups.unified/delete" --version 1
 
   Date: 12/15/2024
 
diff --git a/src/m365/entra/commands/roledefinition/roledefinition-add.spec.ts b/src/m365/entra/commands/roledefinition/roledefinition-add.spec.ts
index e88997d62d..be1cb6f4de 100644
--- a/src/m365/entra/commands/roledefinition/roledefinition-add.spec.ts
+++ b/src/m365/entra/commands/roledefinition/roledefinition-add.spec.ts
@@ -37,7 +37,7 @@ describe(commands.ROLEDEFINITION_ADD, () => {
     ]
   };
 
-  const roleDefinitionWithDeatilsResponse = {
+  const roleDefinitionWithDetailsResponse = {
     "id": "abcde50a-487c-49b3-a43e-cda270d3341f",
     "description": "Allows creating and deleting unified groups",
     "displayName": "Custom Role",
@@ -93,8 +93,7 @@ describe(commands.ROLEDEFINITION_ADD, () => {
 
   afterEach(() => {
     sinonUtil.restore([
-      request.post,
-      cli.promptForConfirmation
+      request.post
     ]);
   });
 
@@ -142,7 +141,7 @@ describe(commands.ROLEDEFINITION_ADD, () => {
   it('creates a custom role definition with a specific display name, description, version and resource actions', async () => {
     sinon.stub(request, 'post').callsFake(async (opts) => {
       if (opts.url === 'https://graph.microsoft.com/v1.0/roleManagement/directory/roleDefinitions') {
-        return roleDefinitionWithDeatilsResponse;
+        return roleDefinitionWithDetailsResponse;
       }
 
       throw 'Invalid request';
@@ -159,7 +158,7 @@ describe(commands.ROLEDEFINITION_ADD, () => {
     await command.action(logger, {
       options: parsedSchema.data
     });
-    assert(loggerLogSpy.calledOnceWithExactly(roleDefinitionWithDeatilsResponse));
+    assert(loggerLogSpy.calledOnceWithExactly(roleDefinitionWithDetailsResponse));
   });
 
   it('correctly handles API OData error', async () => {
diff --git a/src/m365/entra/commands/roledefinition/roledefinition-add.ts b/src/m365/entra/commands/roledefinition/roledefinition-add.ts
index b385b41d2c..5af5e48527 100644
--- a/src/m365/entra/commands/roledefinition/roledefinition-add.ts
+++ b/src/m365/entra/commands/roledefinition/roledefinition-add.ts
@@ -10,10 +10,10 @@ import { UnifiedRoleDefinition } from '@microsoft/microsoft-graph-types';
 const options = globalOptionsZod
   .extend({
     displayName: zod.alias('n', z.string()),
-    allowedResourceActions: z.string().transform((value) => value.split(',').map(String)),
-    description: z.string().optional(),
-    enabled: z.boolean().optional(),
-    version: z.string().optional()
+    allowedResourceActions: zod.alias('a', z.string().transform((value) => value.split(',').map(String))),
+    description: zod.alias('d', z.string().optional()),
+    enabled: zod.alias('e', z.boolean().optional()),
+    version: zod.alias('v', z.string().optional())
   })
   .strict();
 

From cd16885f4c1bf0fcc4f369964c778bd804b7cdf2 Mon Sep 17 00:00:00 2001
From: Martin Machacek <machacek@edhouse.cz>
Date: Tue, 14 Jan 2025 07:07:23 +0100
Subject: [PATCH 4/4] New command: entra roledefinition add

---
 .../roledefinition/roledefinition-add.mdx     | 210 +-----------------
 1 file changed, 4 insertions(+), 206 deletions(-)

diff --git a/docs/docs/cmd/entra/roledefinition/roledefinition-add.mdx b/docs/docs/cmd/entra/roledefinition/roledefinition-add.mdx
index 1fdfd1e3d2..93b3c0d7e8 100644
--- a/docs/docs/cmd/entra/roledefinition/roledefinition-add.mdx
+++ b/docs/docs/cmd/entra/roledefinition/roledefinition-add.mdx
@@ -33,208 +33,6 @@ m365 entra roledefinition add [options]
 
 <Global />
 
-## Remarks
-
-The following resource actions (permissions) can be assigned to a custom Entra ID role definition:
-
-|Permission|Description|
-|-|-|
-|microsoft.directory/applicationPolicies/allProperties/read| Read all properties (including privileged properties) on application policies|
-|microsoft.directory/applicationPolicies/allProperties/update| Update all properties (including privileged properties) on application policies|
-|microsoft.directory/applicationPolicies/basic/update| Update standard properties of application policies|
-|microsoft.directory/applicationPolicies/create| Create application policies|
-|microsoft.directory/applicationPolicies/createAsOwner| Create application policies, and creator is added as the first owner|
-|microsoft.directory/applicationPolicies/delete| Delete application policies|
-|microsoft.directory/applicationPolicies/owners/read| Read owners on application policies|
-|microsoft.directory/applicationPolicies/owners/update| Update the owner property of application policies|
-|microsoft.directory/applicationPolicies/policyAppliedTo/read| Read application policies applied to objects list|
-|microsoft.directory/applicationPolicies/standard/read| Read standard properties of application policies|
-|microsoft.directory/applications.myOrganization/allProperties/read| Read all properties (including privileged properties) on single-directory applications|
-|microsoft.directory/applications.myOrganization/allProperties/update| Update all properties (including privileged properties) on single-directory applications|
-|microsoft.directory/applications.myOrganization/audience/update| Update audience on single-directory applications|
-|microsoft.directory/applications.myOrganization/authentication/update| Update authentication on single-directory applications|
-|microsoft.directory/applications.myOrganization/basic/update| Update basic properties on single-directory applications|
-|microsoft.directory/applications.myOrganization/credentials/update| Update credentials on single-directory applications|
-|microsoft.directory/applications.myOrganization/delete| Delete single-directory applications|
-|microsoft.directory/applications.myOrganization/owners/read| Read owners on single-directory applications|
-|microsoft.directory/applications.myOrganization/owners/update| Update owners on single-directory applications|
-|microsoft.directory/applications.myOrganization/permissions/update| Update exposed permissions and required permissions on single-tenant applications|
-|microsoft.directory/applications.myOrganization/standard/read| Read basic properties on single-directory applications|
-|microsoft.directory/applications/allProperties/read| Read all properties (including privileged properties) on all types of applications|
-|microsoft.directory/applications/allProperties/update| Update all properties (including privileged properties) on all types of applications|
-|microsoft.directory/applications/applicationProxy/read| Read all application proxy properties|
-|microsoft.directory/applications/applicationProxy/update| Update all application proxy properties|
-|microsoft.directory/applications/applicationProxyAuthentication/update| Update authentication on all types of applications|
-|microsoft.directory/applications/applicationProxySslCertificate/update| Update SSL certificate settings for application proxy|
-|microsoft.directory/applications/applicationProxyUrlSettings/update| Update URL settings for application proxy|
-|microsoft.directory/applications/appRoles/update| Update the appRoles property on all types of applications|
-|microsoft.directory/applications/audience/update| Update the audience property for applications|
-|microsoft.directory/applications/authentication/update| Update authentication on all types of applications|
-|microsoft.directory/applications/basic/update| Update basic properties for applications|
-|microsoft.directory/applications/create| Create all types of applications|
-|microsoft.directory/applications/createAsOwner| Create all types of applications, and creator is added as the first owner|
-|microsoft.directory/applications/credentials/update| Update application credentials|
-|microsoft.directory/applications/delete| Delete all types of applications|
-|microsoft.directory/applications/owners/read| Read owners of applications|
-|microsoft.directory/applications/owners/update| Update owners of applications|
-|microsoft.directory/applications/permissions/update| Update exposed permissions and required permissions on all types of applications|
-|microsoft.directory/applications/standard/read| Read standard properties of applications|
-|microsoft.directory/applications/synchronization/standard/read| Read provisioning settings associated with the application object|
-|microsoft.directory/applicationTemplates/instantiate| Instantiate gallery applications from application templates|
-|microsoft.directory/auditLogs/allProperties/read| Read all properties on audit logs, excluding custom security attributes audit logs|
-|microsoft.directory/bitlockerKeys/key/read| Read bitlocker metadata and key on devices|
-|microsoft.directory/bitlockerKeys/metadata/read| Read bitlocker key metadata on devices|
-|microsoft.directory/connectorGroups/allProperties/read| Read all properties of application proxy connector groups|
-|microsoft.directory/connectorGroups/allProperties/update| Update all properties of application proxy connector groups|
-|microsoft.directory/connectorGroups/create| Create application proxy connector groups|
-|microsoft.directory/connectorGroups/delete| Delete application proxy connector groups|
-|microsoft.directory/connectors/allProperties/read| Read all properties of application proxy connectors|
-|microsoft.directory/connectors/create| Create application proxy connectors|
-|microsoft.directory/crossTenantAccessPolicy/allowedCloudEndpoints/update| Update allowed cloud endpoints of cross-tenant access policy|
-|microsoft.directory/crossTenantAccessPolicy/basic/update| Update basic settings of cross-tenant access policy|
-|microsoft.directory/crossTenantAccessPolicy/default/b2bCollaboration/update| Update Microsoft Entra B2B collaboration settings of the default cross-tenant access policy|
-|microsoft.directory/crossTenantAccessPolicy/default/b2bDirectConnect/update| Update Microsoft Entra B2B direct connect settings of the default cross-tenant access policy|
-|microsoft.directory/crossTenantAccessPolicy/default/crossCloudMeetings/update| Update cross-cloud Teams meeting settings of the default cross-tenant access policy|
-|microsoft.directory/crossTenantAccessPolicy/default/standard/read| Read basic properties of the default cross-tenant access policy|
-|microsoft.directory/crossTenantAccessPolicy/default/tenantRestrictions/update| Update tenant restrictions of the default cross-tenant access policy|
-|microsoft.directory/crossTenantAccessPolicy/partners/b2bCollaboration/update| Update Microsoft Entra B2B collaboration settings of cross-tenant access policy for partners|
-|microsoft.directory/crossTenantAccessPolicy/partners/b2bDirectConnect/update| Update Microsoft Entra B2B direct connect settings of cross-tenant access policy for partners|
-|microsoft.directory/crossTenantAccessPolicy/partners/create| Create cross-tenant access policy for partners|
-|microsoft.directory/crossTenantAccessPolicy/partners/crossCloudMeetings/update| Update cross-cloud Teams meeting settings of cross-tenant access policy for partners|
-|microsoft.directory/crossTenantAccessPolicy/partners/delete| Delete cross-tenant access policy for partners|
-|microsoft.directory/crossTenantAccessPolicy/partners/identitySynchronization/basic/update| Update basic settings of cross-tenant sync policy|
-|microsoft.directory/crossTenantAccessPolicy/partners/identitySynchronization/create| Create cross-tenant sync policy for partners|
-|microsoft.directory/crossTenantAccessPolicy/partners/identitySynchronization/standard/read| Read basic properties of cross-tenant sync policy|
-|microsoft.directory/crossTenantAccessPolicy/partners/standard/read| Read basic properties of cross-tenant access policy for partners|
-|microsoft.directory/crossTenantAccessPolicy/partners/tenantRestrictions/update| Update tenant restrictions of cross-tenant access policy for partners|
-|microsoft.directory/crossTenantAccessPolicy/standard/read| Read basic properties of cross-tenant access policy|
-|microsoft.directory/deviceLocalCredentials/password/read| Read all properties of the backed up local administrator account credentials for Microsoft Entra joined devices, including the password|
-|microsoft.directory/deviceLocalCredentials/standard/read| Read all properties of the backed up local administrator account credentials for Microsoft Entra joined devices, except the password|
-|microsoft.directory/deviceManagementPolicies/basic/update| Update basic properties on device management application policies|
-|microsoft.directory/deviceManagementPolicies/standard/read| Read standard properties on device management application policies|
-|microsoft.directory/deviceRegistrationPolicy/basic/update| Update basic properties on device registration policies|
-|microsoft.directory/deviceRegistrationPolicy/standard/read| Read standard properties on device registration policies|
-|microsoft.directory/devices/createdFrom/read| Read created from Internet of Things (IoT) device template links|
-|microsoft.directory/devices/delete| Delete devices from Microsoft Entra ID|
-|microsoft.directory/devices/disable| Disable devices in Microsoft Entra ID|
-|microsoft.directory/devices/enable| Enable devices in Microsoft Entra ID|
-|microsoft.directory/devices/registeredOwners/read| Read registered owners of devices|
-|microsoft.directory/devices/registeredOwners/update| Update registered owners of devices|
-|microsoft.directory/devices/registeredUsers/read| Read registered users of devices|
-|microsoft.directory/devices/registeredUsers/update| Update registered users of devices|
-|microsoft.directory/devices/standard/read| Read basic properties on devices|
-|microsoft.directory/groups.security.assignedMembership/allProperties/update| Update all properties (including privileged properties) on Security groups of assigned membership type, excluding role-assignable groups|
-|microsoft.directory/groups.security.assignedMembership/basic/update| Update basic properties on Security groups of assigned membership type, excluding role-assignable groups|
-|microsoft.directory/groups.security.assignedMembership/classification/update| Update the classification property on Security groups of assigned membership type, excluding role-assignable groups|
-|microsoft.directory/groups.security.assignedMembership/create| Create Security groups of assigned membership type, excluding role-assignable groups|
-|microsoft.directory/groups.security.assignedMembership/createAsOwner| Create Security groups of assigned membership type, excluding role-assignable groups. Creator is added as the first owner.|
-|microsoft.directory/groups.security.assignedMembership/delete| Delete Security groups of assigned membership type, excluding role-assignable groups|
-|microsoft.directory/groups.security.assignedMembership/members/update| Update members of Security groups of assigned membership type, excluding role-assignable groups|
-|microsoft.directory/groups.security.assignedMembership/owners/update| Update owners of Security groups of assigned membership type, excluding role-assignable groups|
-|microsoft.directory/groups.security.assignedMembership/visibility/update| Update the visibility property on Security groups of assigned membership type, excluding role-assignable groups|
-|microsoft.directory/groups.security/allProperties/update| Update all properties (including privileged properties) on Security groups, excluding role-assignable groups|
-|microsoft.directory/groups.security/basic/update| Update basic properties on Security groups, excluding role-assignable groups|
-|microsoft.directory/groups.security/classification/update| Update the classification property on Security groups, excluding role-assignable groups|
-|microsoft.directory/groups.security/create| Create Security groups, excluding role-assignable groups|
-|microsoft.directory/groups.security/createAsOwner| Create Security groups, excluding role-assignable groups. Creator is added as the first owner.|
-|microsoft.directory/groups.security/delete| Delete Security groups, excluding role-assignable groups|
-|microsoft.directory/groups.security/dynamicMembershipRule/update| Update the dynamic membership rule on Security groups, excluding role-assignable groups|
-|microsoft.directory/groups.security/members/update| Update members of Security groups, excluding role-assignable groups|
-|microsoft.directory/groups.security/owners/update| Update owners of Security groups, excluding role-assignable groups|
-|microsoft.directory/groups.security/visibility/update| Update the visibility property on Security groups, excluding role-assignable groups|
-|microsoft.directory/groups.unified.assignedMembership/allProperties/update| Update all properties (including privileged properties) on Microsoft 365 groups of assigned membership type, excluding role-assignable groups|
-|microsoft.directory/groups.unified.assignedMembership/basic/update| Update basic properties on Microsoft 365 groups of assigned membership type, excluding role-assignable groups|
-|microsoft.directory/groups.unified.assignedMembership/classification/update| Update the classification property on Microsoft 365 groups of assigned membership type, excluding role-assignable groups|
-|microsoft.directory/groups.unified.assignedMembership/create| Create Microsoft 365 groups of assigned membership type, excluding role-assignable groups|
-|microsoft.directory/groups.unified.assignedMembership/createAsOwner| Create Microsoft 365 groups of assigned membership type, excluding role-assignable groups. Creator is added as the first owner.|
-|microsoft.directory/groups.unified.assignedMembership/delete| Delete Microsoft 365 groups of assigned membership type, excluding role-assignable groups|
-|microsoft.directory/groups.unified.assignedMembership/members/update| Update members of Microsoft 365 groups of assigned membership type, excluding role-assignable groups|
-|microsoft.directory/groups.unified.assignedMembership/owners/update| Update owners of Microsoft 365 groups of assigned membership type, excluding role-assignable groups|
-|microsoft.directory/groups.unified.assignedMembership/visibility/update| Update the visibility property on Microsoft 365 groups of assigned membership type, excluding role-assignable groups|
-|microsoft.directory/groups.unified/allProperties/update| Update all properties (including privileged properties) on Microsoft 365 groups, excluding role-assignable groups|
-|microsoft.directory/groups.unified/basic/update| Update basic properties on Microsoft 365 groups, excluding role-assignable groups|
-|microsoft.directory/groups.unified/classification/update| Update the classification property on Microsoft 365 groups, excluding role-assignable groups|
-|microsoft.directory/groups.unified/create| Create Microsoft 365 groups, excluding role-assignable groups|
-|microsoft.directory/groups.unified/createAsOwner| Create Microsoft 365 groups, excluding role-assignable groups. Creator is added as the first owner.|
-|microsoft.directory/groups.unified/delete| Delete Microsoft 365 groups, excluding role-assignable groups|
-|microsoft.directory/groups.unified/dynamicMembershipRule/update| Update the dynamic membership rule on Microsoft 365 groups, excluding role-assignable groups|
-|microsoft.directory/groups.unified/members/update| Update members of Microsoft 365 groups, excluding role-assignable groups|
-|microsoft.directory/groups.unified/owners/update| Update owners of Microsoft 365 groups, excluding role-assignable groups|
-|microsoft.directory/groups.unified/visibility/update| Update the visibility property on Microsoft 365 groups, excluding role-assignable groups|
-|microsoft.directory/groups/allProperties/read| Read all properties (including privileged properties) on Security groups and Microsoft 365 groups, including role-assignable groups|
-|microsoft.directory/groups/allProperties/update| Update all properties (including privileged properties) on Security groups and Microsoft 365 groups, excluding role-assignable groups|
-|microsoft.directory/groups/assignLicense| Assign product licenses to groups for group-based licensing|
-|microsoft.directory/groups/basic/update| Update basic properties on Security groups and Microsoft 365 groups, excluding role-assignable groups|
-|microsoft.directory/groups/classification/update| Update the classification property on Security groups and Microsoft 365 groups, excluding role-assignable groups|
-|microsoft.directory/groups/create| Create Security groups and Microsoft 365 groups, excluding role-assignable groups|
-|microsoft.directory/groups/createAsOwner| Create Security groups and Microsoft 365 groups, excluding role-assignable groups. Creator is added as the first owner.|
-|microsoft.directory/groups/delete| Delete Security groups and Microsoft 365 groups, excluding role-assignable groups|
-|microsoft.directory/groups/dynamicMembershipRule/update| Update the dynamic membership rule on Security groups and Microsoft 365 groups, excluding role-assignable groups|
-|microsoft.directory/groups/groupType/update| Update properties that would affect the group type of Security groups and Microsoft 365 groups, excluding role-assignable groups|
-|microsoft.directory/groups/memberOf/read| Read the memberOf property on Security groups and Microsoft 365 groups, including role-assignable groups|
-|microsoft.directory/groups/members/read| Read members of Security groups and Microsoft 365 groups, including role-assignable groups|
-|microsoft.directory/groups/members/update| Update members of Security groups and Microsoft 365 groups, excluding role-assignable groups|
-|microsoft.directory/groups/owners/read| Read owners of Security groups and Microsoft 365 groups, including role-assignable groups|
-|microsoft.directory/groups/owners/update| Update owners of Security groups and Microsoft 365 groups, excluding role-assignable groups|
-|microsoft.directory/groups/reprocessLicenseAssignment Reprocess license assignments for group-based licensing|
-|microsoft.directory/groups/standard/read| Read standard properties of Security groups and Microsoft 365 groups, including role-assignable groups|
-|microsoft.directory/groups/visibility/update| Update the visibility property of Security groups and Microsoft 365 groups, excluding role-assignable groups|
-|microsoft.directory/provisioningLogs/allProperties/read| Read all properties of provisioning logs|
-|microsoft.directory/servicePrincipals/allProperties/read| Read all properties (including privileged properties) on servicePrincipals|
-|microsoft.directory/servicePrincipals/allProperties/update| Update all properties (including privileged properties) on servicePrincipals|
-|microsoft.directory/servicePrincipals/appRoleAssignedTo/read| Read service principal role assignments|
-|microsoft.directory/servicePrincipals/appRoleAssignedTo/update| Update service principal role assignments|
-|microsoft.directory/servicePrincipals/appRoleAssignments/read| Read role assignments assigned to service principals|
-|microsoft.directory/servicePrincipals/audience/update| Update audience properties on service principals|
-|microsoft.directory/servicePrincipals/authentication/update| Update authentication properties on service principals|
-|microsoft.directory/servicePrincipals/basic/update| Update basic properties on service principals|
-|microsoft.directory/servicePrincipals/create| Create service principals|
-|microsoft.directory/servicePrincipals/createAsOwner| Create service principals, with creator as the first owner|
-|microsoft.directory/servicePrincipals/credentials/update| Update credentials of service principals|
-|microsoft.directory/servicePrincipals/delete| Delete service principals|
-|microsoft.directory/servicePrincipals/disable| Disable service principals|
-|microsoft.directory/servicePrincipals/enable| Enable service principals|
-|microsoft.directory/servicePrincipals/getPasswordSingleSignOnCredentials| Manage password single sign-on credentials on service principals|
-|microsoft.directory/servicePrincipals/managePasswordSingleSignOnCredentials| Read password single sign-on credentials on service principals|
-|microsoft.directory/servicePrincipals/oAuth2PermissionGrants/read| Read delegated permission grants on service principals|
-|microsoft.directory/servicePrincipals/owners/read| Read owners of service principals|
-|microsoft.directory/servicePrincipals/owners/update| Update owners of service principals|
-|microsoft.directory/servicePrincipals/permissions/update| Update permissions of service principals|
-|microsoft.directory/servicePrincipals/policies/read| Read policies of service principals|
-|microsoft.directory/servicePrincipals/policies/update| Update policies of service principals|
-|microsoft.directory/servicePrincipals/standard/read| Read basic properties of service principals|
-|microsoft.directory/servicePrincipals/synchronization/standard/read| Read provisioning settings associated with your service principal|
-|microsoft.directory/servicePrincipals/synchronizationCredentials/manage| Manage application provisioning secrets and credentials|
-|microsoft.directory/servicePrincipals/synchronizationJobs/manage| Start, restart, and pause application provisioning synchronization jobs|
-|microsoft.directory/servicePrincipals/synchronizationSchema/manage| Create and manage application provisioning synchronization jobs and schema|
-|microsoft.directory/servicePrincipals/tag/update| Update the tag property for service principals|
-|microsoft.directory/signInReports/allProperties/read| Read all properties on sign-in reports, including privileged properties|
-|microsoft.directory/tenantRelationships/standard/read| Read standard tenant relationship information|
-|microsoft.directory/users/appRoleAssignments/read| Read application role assignments for users|
-|microsoft.directory/users/assignLicense| Manage user licenses|
-|microsoft.directory/users/basic/update| Update basic properties on users|
-|microsoft.directory/users/contactInfo/update| Update contact properties on users|
-|microsoft.directory/users/deviceForResourceAccount/read| Read deviceForResourceAccount of users|
-|microsoft.directory/users/directReports/read| Read the direct reports for users|
-|microsoft.directory/users/extensionProperties/update| Update extension properties of users|
-|microsoft.directory/users/identities/read| Read identities of users|
-|microsoft.directory/users/jobInfo/update| Update job information of users|
-|microsoft.directory/users/licenseDetails/read| Read license details of users|
-|microsoft.directory/users/manager/read| Read manager of users|
-|microsoft.directory/users/manager/update| Update manager for users|
-|microsoft.directory/users/memberOf/read| Read the group memberships of users|
-|microsoft.directory/users/ownedDevices/read| Read owned devices of users|
-|microsoft.directory/users/parentalControls/update| Update parental controls of users|
-|microsoft.directory/users/passwordPolicies/update| Update password policies of users|
-|microsoft.directory/users/registeredDevices/read| Read registered devices of users|
-|microsoft.directory/users/reprocessLicenseAssignment| Reprocess license assignments for users|
-|microsoft.directory/users/reprocessLicenseAssignment| Reprocess license assignments for users|
-|microsoft.directory/users/scopedRoleMemberOf/read| Read user's membership of a Microsoft Entra role, that is scoped to an administrative unit|
-|microsoft.directory/users/sponsors/read| Read sponsors of users|
-|microsoft.directory/users/sponsors/update| Update sponsors of users|
-|microsoft.directory/users/standard/read| Read basic properties on users|
-|microsoft.directory/users/usageLocation/update| Update usage location of users|
-
 ## Examples
 
 Create a custom Microsoft Entra ID role
@@ -246,7 +44,7 @@ m365 entra roledefinition add --displayName 'Application Remover' --description
 Create a custom Microsoft Entra ID role, but disable it for the assignment
 
 ```sh
-m365 entra roledefinition add --displayName 'Application Remover' --version '1.0' --enabled false --allowedResourceActions 'microsoft.directory/applications/delete,microsoft.directory/applications/owners/update|'
+m365 entra roledefinition add --displayName 'Application Remover' --version '1.0' --enabled false --allowedResourceActions 'microsoft.directory/applications/delete,microsoft.directory/applications/owners/update'
 ```
 
 ## Response
@@ -269,7 +67,7 @@ m365 entra roledefinition add --displayName 'Application Remover' --version '1.0
     "rolePermissions": [
       {
         "allowedResourceActions": [
-          "microsoft.directory/groups.unified/create|",
+          "microsoft.directory/groups.unified/create",
           "microsoft.directory/groups.unified/delete"
         ],
         "condition": null
@@ -288,7 +86,7 @@ m365 entra roledefinition add --displayName 'Application Remover' --version '1.0
   isBuiltIn      : false
   isEnabled      : true
   resourceScopes : ["/"]
-  rolePermissions: [{"allowedResourceActions":["microsoft.directory/groups.unified/create|","microsoft.directory/groups.unified/delete"],"condition":null}]
+  rolePermissions: [{"allowedResourceActions":["microsoft.directory/groups.unified/create","microsoft.directory/groups.unified/delete"],"condition":null}]
   templateId     : 3844129d-f748-4c03-8165-4412ee9b4ceb
   version        : 1
   ```
@@ -305,7 +103,7 @@ m365 entra roledefinition add --displayName 'Application Remover' --version '1.0
   <TabItem value="Markdown">
 
   ```md
-  # entra roledefinition add --displayName "Custom Role" --allowedResourceActions "microsoft.directory/groups.unified/create|,microsoft.directory/groups.unified/delete" --version 1
+  # entra roledefinition add --displayName "Custom Role" --allowedResourceActions "microsoft.directory/groups.unified/create,microsoft.directory/groups.unified/delete" --version 1
 
   Date: 12/15/2024