diff --git a/docs/docs/cmd/viva/engage/engage-role-list.mdx b/docs/docs/cmd/viva/engage/engage-role-list.mdx
new file mode 100644
index 00000000000..4dd6fc0632c
--- /dev/null
+++ b/docs/docs/cmd/viva/engage/engage-role-list.mdx
@@ -0,0 +1,102 @@
+import Global from '/docs/cmd/_global.mdx';
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+# viva engage role list
+
+Lists all Viva Engage roles
+
+## Usage
+
+```sh
+m365 viva engage role list [options]
+```
+
+## Options
+
+
+
+## Remarks
+
+:::warning
+
+This command is based on an API that is currently in preview and is subject to change once the API reaches general availability.
+
+:::
+
+## Permissions
+
+
+
+
+ | Resource | Permissions |
+ |-----------------|-------------------------|
+ | Microsoft Graph | EngagementRole.Read.All |
+
+
+
+
+ | Resource | Permissions |
+ |-----------------|-------------------------|
+ | Microsoft Graph | EngagementRole.Read.All |
+
+
+
+
+## Examples
+
+List all Viva Engage roles
+
+```sh
+m365 viva engage role list
+```
+
+## Response
+
+
+
+
+ ```json
+ [
+ {
+ "id": "ec759127-089f-4f91-8dfc-03a30b51cb38",
+ "displayName": "Network Admin"
+ }
+ ]
+ ```
+
+
+
+
+ ```text
+ id displayName
+ ------------------------------------ -------------
+ ec759127-089f-4f91-8dfc-03a30b51cb38 Network Admin
+ ```
+
+
+
+
+ ```csv
+ id,displayName
+ ec759127-089f-4f91-8dfc-03a30b51cb38,Network Admin
+ ```
+
+
+
+
+ ```md
+ # viva engage role list
+
+ Date: 7/11/2025
+
+ ## Network Admin (ec759127-089f-4f91-8dfc-03a30b51cb38)
+
+ Property | Value
+ ---------|-------
+ id | ec759127-089f-4f91-8dfc-03a30b51cb38
+ displayName | Network Admin
+ ```
+
+
+
diff --git a/docs/src/config/sidebars.ts b/docs/src/config/sidebars.ts
index 1d71537c551..39c83d28353 100644
--- a/docs/src/config/sidebars.ts
+++ b/docs/src/config/sidebars.ts
@@ -4907,6 +4907,11 @@ const sidebars: SidebarsConfig = {
label: 'engage report groupsactivitygroupcounts',
id: 'cmd/viva/engage/engage-report-groupsactivitygroupcounts'
},
+ {
+ type: 'doc',
+ label: 'engage role list',
+ id: 'cmd/viva/engage/engage-role-list'
+ },
{
type: 'doc',
label: 'engage user get',
diff --git a/src/config.ts b/src/config.ts
index 0128cb1abb5..6436c64c241 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -17,6 +17,7 @@ export default {
'https://graph.microsoft.com/Community.ReadWrite.All',
'https://graph.microsoft.com/Directory.AccessAsUser.All',
'https://graph.microsoft.com/Directory.ReadWrite.All',
+ 'https://graph.microsoft.com/EngagementRole.ReadWrite.All',
'https://graph.microsoft.com/ExternalConnection.ReadWrite.All',
'https://graph.microsoft.com/ExternalItem.ReadWrite.All',
'https://graph.microsoft.com/FileStorageContainer.Selected',
diff --git a/src/m365/viva/commands.ts b/src/m365/viva/commands.ts
index aafe65d892b..b099b1e004e 100644
--- a/src/m365/viva/commands.ts
+++ b/src/m365/viva/commands.ts
@@ -28,6 +28,7 @@ export default {
ENGAGE_REPORT_GROUPSACTIVITYCOUNTS: `${prefix} engage report groupsactivitycounts`,
ENGAGE_REPORT_GROUPSACTIVITYDETAIL: `${prefix} engage report groupsactivitydetail`,
ENGAGE_REPORT_GROUPSACTIVITYGROUPCOUNTS: `${prefix} engage report groupsactivitygroupcounts`,
+ ENGAGE_ROLE_LIST: `${prefix} engage role list`,
ENGAGE_SEARCH: `${prefix} engage search`,
ENGAGE_USER_GET: `${prefix} engage user get`,
ENGAGE_USER_LIST: `${prefix} engage user list`
diff --git a/src/m365/viva/commands/engage/EngageRole.ts b/src/m365/viva/commands/engage/EngageRole.ts
new file mode 100644
index 00000000000..4986dd5ca03
--- /dev/null
+++ b/src/m365/viva/commands/engage/EngageRole.ts
@@ -0,0 +1,4 @@
+export interface EngageRole {
+ id?: string;
+ displayName?: string;
+}
diff --git a/src/m365/viva/commands/engage/engage-role-list.spec.ts b/src/m365/viva/commands/engage/engage-role-list.spec.ts
new file mode 100644
index 00000000000..6a10a272c54
--- /dev/null
+++ b/src/m365/viva/commands/engage/engage-role-list.spec.ts
@@ -0,0 +1,125 @@
+import assert from 'assert';
+import sinon from 'sinon';
+import auth from '../../../../Auth.js';
+import { Logger } from '../../../../cli/Logger.js';
+import { CommandError } from '../../../../Command.js';
+import request from '../../../../request.js';
+import { telemetry } from '../../../../telemetry.js';
+import { pid } from '../../../../utils/pid.js';
+import { session } from '../../../../utils/session.js';
+import { sinonUtil } from '../../../../utils/sinonUtil.js';
+import commands from '../../commands.js';
+import command from './engage-role-list.js';
+
+describe(commands.ENGAGE_ROLE_LIST, () => {
+ let log: string[];
+ let logger: Logger;
+ let loggerLogSpy: sinon.SinonSpy;
+
+ before(() => {
+ sinon.stub(auth, 'restoreAuth').resolves();
+ sinon.stub(telemetry, 'trackEvent').resolves();
+ sinon.stub(pid, 'getProcessName').returns('');
+ sinon.stub(session, 'getId').returns('');
+ auth.connection.active = true;
+ });
+
+ 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.get
+ ]);
+ });
+
+ after(() => {
+ sinon.restore();
+ auth.connection.active = false;
+ });
+
+ it('has correct name', () => {
+ assert.strictEqual(command.name, commands.ENGAGE_ROLE_LIST);
+ });
+
+ it('has a description', () => {
+ assert.notStrictEqual(command.description, null);
+ });
+
+ it('defines correct properties for the default output', () => {
+ assert.deepStrictEqual(command.defaultProperties(), ['id', 'displayName']);
+ });
+
+ it(`should get a list of Viva Engage roles`, async () => {
+ sinon.stub(request, 'get').callsFake(async (opts) => {
+ if (opts.url === `https://graph.microsoft.com/beta/employeeExperience/roles`) {
+ return {
+ "value": [
+ {
+ "id": "ec759127-089f-4f91-8dfc-03a30b51cb38",
+ "displayName": "Network Admin"
+ },
+ {
+ "id": "966b8ec4-6457-4f22-bd3c-5a2520e98f4a",
+ "displayName": "Verified Admin"
+ },
+ {
+ "id": "77aa47ad-96fe-4ecc-8024-fd1ac5e28f17",
+ "displayName": "Corporate Communicator"
+ }
+ ]
+ };
+ }
+
+ throw 'Invalid request';
+ });
+
+ await command.action(logger, {
+ options: { verbose: true }
+ });
+
+ assert(
+ loggerLogSpy.calledOnceWith([
+ {
+ "id": "ec759127-089f-4f91-8dfc-03a30b51cb38",
+ "displayName": "Network Admin"
+ },
+ {
+ "id": "966b8ec4-6457-4f22-bd3c-5a2520e98f4a",
+ "displayName": "Verified Admin"
+ },
+ {
+ "id": "77aa47ad-96fe-4ecc-8024-fd1ac5e28f17",
+ "displayName": "Corporate Communicator"
+ }
+ ])
+ );
+ });
+
+ it('handles error when retrieving Viva Engage roles failed', async () => {
+ sinon.stub(request, 'get').callsFake(async (opts) => {
+ if (opts.url === `https://graph.microsoft.com/beta/employeeExperience/roles`) {
+ throw { error: { message: 'An error has occurred' } };
+ }
+ throw `Invalid request`;
+ });
+
+ await assert.rejects(
+ command.action(logger, { options: {} }),
+ new CommandError('An error has occurred')
+ );
+ });
+});
\ No newline at end of file
diff --git a/src/m365/viva/commands/engage/engage-role-list.ts b/src/m365/viva/commands/engage/engage-role-list.ts
new file mode 100644
index 00000000000..af056f01da7
--- /dev/null
+++ b/src/m365/viva/commands/engage/engage-role-list.ts
@@ -0,0 +1,35 @@
+import { Logger } from '../../../../cli/Logger.js';
+import { odata } from '../../../../utils/odata.js';
+import GraphCommand from '../../../base/GraphCommand.js';
+import commands from '../../commands.js';
+import { EngageRole } from './EngageRole.js';
+
+class VivaEngageRoleListCommand extends GraphCommand {
+ public get name(): string {
+ return commands.ENGAGE_ROLE_LIST;
+ }
+
+ public get description(): string {
+ return 'Lists all Viva Engage roles';
+ }
+
+ public defaultProperties(): string[] | undefined {
+ return ['id', 'displayName'];
+ }
+
+ public async commandAction(logger: Logger): Promise {
+ if (this.verbose) {
+ await logger.logToStderr('Getting all Viva Engage roles...');
+ }
+
+ try {
+ const results = await odata.getAllItems(`${this.resource}/beta/employeeExperience/roles`);
+ await logger.log(results);
+ }
+ catch (err: any) {
+ this.handleRejectedODataJsonPromise(err);
+ }
+ }
+}
+
+export default new VivaEngageRoleListCommand();
\ No newline at end of file