diff --git a/x-pack/platform/plugins/shared/stack_connectors/common/microsoft_defender_endpoint/schema.ts b/x-pack/platform/plugins/shared/stack_connectors/common/microsoft_defender_endpoint/schema.ts
index a6063340211fc..0daf547de21fa 100644
--- a/x-pack/platform/plugins/shared/stack_connectors/common/microsoft_defender_endpoint/schema.ts
+++ b/x-pack/platform/plugins/shared/stack_connectors/common/microsoft_defender_endpoint/schema.ts
@@ -203,6 +203,8 @@ export const GetActionsParamsSchema = schema.object({
   ),
   page: schema.maybe(schema.number({ min: 1, defaultValue: 1 })),
   pageSize: schema.maybe(schema.number({ min: 1, max: 1000, defaultValue: 20 })),
+  sortField: schema.maybe(schema.string({ minLength: 1 })),
+  sortDirection: schema.maybe(schema.oneOf([schema.literal('asc'), schema.literal('desc')])),
 });
 
 // ----------------------------------
diff --git a/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/microsoft_defender_endpoint/microsoft_defender_endpoint.test.ts b/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/microsoft_defender_endpoint/microsoft_defender_endpoint.test.ts
index 38be24e6aa224..24c84e62169a7 100644
--- a/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/microsoft_defender_endpoint/microsoft_defender_endpoint.test.ts
+++ b/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/microsoft_defender_endpoint/microsoft_defender_endpoint.test.ts
@@ -187,10 +187,13 @@ describe('Microsoft Defender for Endpoint Connector', () => {
     });
 
     it.each`
-      title                       | options                                                                           | expectedParams
-      ${'single value filters'}   | ${{ id: '123', status: 'Succeeded', machineId: 'abc', page: 2 }}                  | ${{ $count: true, $filter: 'id eq 123 AND status eq Succeeded AND machineId eq abc', $skip: 20, $top: 20 }}
-      ${'multiple value filters'} | ${{ id: ['123', '321'], type: ['Isolate', 'Unisolate'], page: 1, pageSize: 100 }} | ${{ $count: true, $filter: "id in ('123','321') AND type in ('Isolate','Unisolate')", $top: 100 }}
-      ${'page and page size'}     | ${{ id: ['123', '321'], type: ['Isolate', 'Unisolate'], page: 3, pageSize: 100 }} | ${{ $count: true, $filter: "id in ('123','321') AND type in ('Isolate','Unisolate')", $skip: 200, $top: 100 }}
+      title                                                      | options                                                                           | expectedParams
+      ${'single value filters'}                                  | ${{ id: '123', status: 'Succeeded', machineId: 'abc', page: 2 }}                  | ${{ $count: true, $filter: "id eq '123' AND status eq 'Succeeded' AND machineId eq 'abc'", $skip: 20, $top: 20 }}
+      ${'multiple value filters'}                                | ${{ id: ['123', '321'], type: ['Isolate', 'Unisolate'], page: 1, pageSize: 100 }} | ${{ $count: true, $filter: "id in ('123','321') AND type in ('Isolate','Unisolate')", $top: 100 }}
+      ${'page and page size'}                                    | ${{ id: ['123', '321'], type: ['Isolate', 'Unisolate'], page: 3, pageSize: 100 }} | ${{ $count: true, $filter: "id in ('123','321') AND type in ('Isolate','Unisolate')", $skip: 200, $top: 100 }}
+      ${'with sortDirection but no sortField'}                   | ${{ id: '123', sortDirection: 'asc' }}                                            | ${{ $count: true, $filter: "id eq '123'", $top: 20 }}
+      ${'with sortField and no sortDirection (desc is default)'} | ${{ id: '123', sortField: 'type' }}                                               | ${{ $count: true, $filter: "id eq '123'", $top: 20, $orderby: 'type desc' }}
+      ${'with sortField and sortDirection'}                      | ${{ id: '123', sortField: 'type', sortDirection: 'asc' }}                         | ${{ $count: true, $filter: "id eq '123'", $top: 20, $orderby: 'type asc' }}
     `(
       'should correctly build the oData URL params: $title',
       async ({ options, expectedParams }) => {
@@ -226,7 +229,7 @@ describe('Microsoft Defender for Endpoint Connector', () => {
       expect(connectorMock.instanceMock.request).toHaveBeenCalledWith(
         expect.objectContaining({
           url: 'https://api.mock__microsoft.com/api/machines',
-          params: { $count: true, $filter: 'id eq 1-2-3', $top: 20 },
+          params: { $count: true, $filter: "id eq '1-2-3'", $top: 20 },
         }),
         connectorMock.usageCollector
       );
diff --git a/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/microsoft_defender_endpoint/microsoft_defender_endpoint.ts b/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/microsoft_defender_endpoint/microsoft_defender_endpoint.ts
index 203b5be802a50..d06112631cf45 100644
--- a/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/microsoft_defender_endpoint/microsoft_defender_endpoint.ts
+++ b/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/microsoft_defender_endpoint/microsoft_defender_endpoint.ts
@@ -132,7 +132,7 @@ export class MicrosoftDefenderEndpointConnector extends SubActionConnector<
       const responseBody = JSON.stringify(error.response?.data ?? {});
 
       if (responseBody) {
-        return `${message}\nURL called: ${error.response?.config?.url}\nResponse body: ${responseBody}`;
+        return `${message}\nURL called:[${error.response?.config?.method}] ${error.response?.config?.url}\nResponse body: ${responseBody}`;
       }
 
       return message;
@@ -153,10 +153,14 @@ export class MicrosoftDefenderEndpointConnector extends SubActionConnector<
     filter = {},
     page = 1,
     pageSize = 20,
+    sortField = '',
+    sortDirection = 'desc',
   }: {
     filter: Record<string, string | string[]>;
-    page: number;
-    pageSize: number;
+    page?: number;
+    pageSize?: number;
+    sortField?: string;
+    sortDirection?: string;
   }): Partial<BuildODataUrlParamsResponse> {
     const oDataQueryOptions: Partial<BuildODataUrlParamsResponse> = {
       $count: true,
@@ -170,6 +174,10 @@ export class MicrosoftDefenderEndpointConnector extends SubActionConnector<
       oDataQueryOptions.$skip = page * pageSize - pageSize;
     }
 
+    if (sortField) {
+      oDataQueryOptions.$orderby = `${sortField} ${sortDirection}`;
+    }
+
     const filterEntries = Object.entries(filter);
 
     if (filterEntries.length > 0) {
@@ -185,7 +193,7 @@ export class MicrosoftDefenderEndpointConnector extends SubActionConnector<
         oDataQueryOptions.$filter += `${key} ${isArrayValue ? 'in' : 'eq'} ${
           isArrayValue
             ? '(' + value.map((valueString) => `'${valueString}'`).join(',') + ')'
-            : value
+            : `'${value}'`
         }`;
       }
     }
@@ -313,7 +321,13 @@ export class MicrosoftDefenderEndpointConnector extends SubActionConnector<
   }
 
   public async getActions(
-    { page = 1, pageSize = 20, ...filter }: MicrosoftDefenderEndpointGetActionsParams,
+    {
+      page = 1,
+      pageSize = 20,
+      sortField,
+      sortDirection = 'desc',
+      ...filter
+    }: MicrosoftDefenderEndpointGetActionsParams,
     connectorUsageCollector: ConnectorUsageCollector
   ): Promise<MicrosoftDefenderEndpointGetActionsResponse> {
     // API Reference: https://learn.microsoft.com/en-us/defender-endpoint/api/get-machineactions-collection
@@ -323,7 +337,7 @@ export class MicrosoftDefenderEndpointConnector extends SubActionConnector<
       {
         url: `${this.urls.machineActions}`,
         method: 'GET',
-        params: this.buildODataUrlParams({ filter, page, pageSize }),
+        params: this.buildODataUrlParams({ filter, page, pageSize, sortField, sortDirection }),
       },
       connectorUsageCollector
     );
@@ -342,4 +356,5 @@ interface BuildODataUrlParamsResponse {
   $top: number;
   $skip: number;
   $count: boolean;
+  $orderby: string;
 }
diff --git a/x-pack/solutions/security/plugins/security_solution/server/endpoint/services/actions/clients/lib/normalized_external_connector_client.test.ts b/x-pack/solutions/security/plugins/security_solution/server/endpoint/services/actions/clients/lib/normalized_external_connector_client.test.ts
index 4190224c592c1..c539ac4913c2d 100644
--- a/x-pack/solutions/security/plugins/security_solution/server/endpoint/services/actions/clients/lib/normalized_external_connector_client.test.ts
+++ b/x-pack/solutions/security/plugins/security_solution/server/endpoint/services/actions/clients/lib/normalized_external_connector_client.test.ts
@@ -11,7 +11,7 @@ import { loggingSystemMock } from '@kbn/core-logging-server-mocks';
 import type { Logger } from '@kbn/logging';
 import type { NormalizedExternalConnectorClientExecuteOptions } from './normalized_external_connector_client';
 import { NormalizedExternalConnectorClient } from './normalized_external_connector_client';
-import { ResponseActionsConnectorNotConfiguredError } from '../errors';
+import { ResponseActionsClientError, ResponseActionsConnectorNotConfiguredError } from '../errors';
 import type { IUnsecuredActionsClient } from '@kbn/actions-plugin/server';
 import { unsecuredActionsClientMock } from '@kbn/actions-plugin/server/unsecured_actions_client/unsecured_actions_client.mock';
 
@@ -139,6 +139,22 @@ describe('`NormalizedExternalConnectorClient` class', () => {
         params: executeInputOptions.params,
       });
     });
+
+    it('should throw a ResponseActionClientError', async () => {
+      actionPluginConnectorClient.execute.mockImplementation(async () => {
+        throw new Error('oh oh');
+      });
+
+      const testInstance = new NormalizedExternalConnectorClient(
+        actionPluginConnectorClient,
+        logger
+      );
+      testInstance.setup('foo');
+
+      await expect(testInstance.execute(executeInputOptions)).rejects.toThrow(
+        ResponseActionsClientError
+      );
+    });
   });
 
   describe('with IUnsecuredActionsClient', () => {
@@ -150,6 +166,9 @@ describe('`NormalizedExternalConnectorClient` class', () => {
       (actionPluginConnectorClient.getAll as jest.Mock).mockResolvedValue([
         responseActionsClientMock.createConnector({ actionTypeId: 'foo' }),
       ]);
+      (actionPluginConnectorClient.execute as jest.Mock).mockResolvedValue(
+        responseActionsClientMock.createConnectorActionExecuteResponse()
+      );
     });
 
     it('should call Action Plugin client `.execute()` with expected arguments', async () => {
@@ -181,5 +200,21 @@ describe('`NormalizedExternalConnectorClient` class', () => {
         ],
       });
     });
+
+    it('should throw a ResponseActionClientError', async () => {
+      (actionPluginConnectorClient.execute as jest.Mock).mockImplementation(async () => {
+        throw new Error('oh oh');
+      });
+
+      const testInstance = new NormalizedExternalConnectorClient(
+        actionPluginConnectorClient,
+        logger
+      );
+      testInstance.setup('foo');
+
+      await expect(testInstance.execute(executeInputOptions)).rejects.toThrow(
+        ResponseActionsClientError
+      );
+    });
   });
 });
diff --git a/x-pack/solutions/security/plugins/security_solution/server/endpoint/services/actions/clients/lib/normalized_external_connector_client.ts b/x-pack/solutions/security/plugins/security_solution/server/endpoint/services/actions/clients/lib/normalized_external_connector_client.ts
index 43c07f0050b80..36106180044a8 100644
--- a/x-pack/solutions/security/plugins/security_solution/server/endpoint/services/actions/clients/lib/normalized_external_connector_client.ts
+++ b/x-pack/solutions/security/plugins/security_solution/server/endpoint/services/actions/clients/lib/normalized_external_connector_client.ts
@@ -115,22 +115,38 @@ export class NormalizedExternalConnectorClient {
     ActionTypeExecutorResult<TResponse>
   > {
     this.ensureSetupDone();
-    const { id: connectorId } = await this.getConnectorInstance();
+    const {
+      id: connectorId,
+      name: connectorName,
+      actionTypeId: connectorTypeId,
+    } = await this.getConnectorInstance();
+
+    const catchAndThrow = (err: Error) => {
+      throw new ResponseActionsClientError(
+        `Attempt to execute [${params.subAction}] with connector [Name: ${connectorName} | Type: ${connectorTypeId} | ID: ${connectorId})] failed with : ${err.message}`,
+        500,
+        err
+      );
+    };
 
     if (this.isUnsecuredActionsClient(this.connectorsClient)) {
-      return this.connectorsClient.execute({
-        requesterId: 'background_task',
-        id: connectorId,
-        spaceId,
-        params,
-        relatedSavedObjects: this.options?.relatedSavedObjects,
-      }) as Promise<ActionTypeExecutorResult<TResponse>>;
+      return this.connectorsClient
+        .execute({
+          requesterId: 'background_task',
+          id: connectorId,
+          spaceId,
+          params,
+          relatedSavedObjects: this.options?.relatedSavedObjects,
+        })
+        .catch(catchAndThrow) as Promise<ActionTypeExecutorResult<TResponse>>;
     }
 
-    return this.connectorsClient.execute({
-      actionId: connectorId,
-      params,
-    }) as Promise<ActionTypeExecutorResult<TResponse>>;
+    return this.connectorsClient
+      .execute({
+        actionId: connectorId,
+        params,
+      })
+      .catch(catchAndThrow) as Promise<ActionTypeExecutorResult<TResponse>>;
   }
 
   protected async getAll(spaceId: string = 'default'): ReturnType<ActionsClient['getAll']> {
diff --git a/x-pack/solutions/security/plugins/security_solution/server/endpoint/services/actions/clients/microsoft/defender/endpoint/mocks.ts b/x-pack/solutions/security/plugins/security_solution/server/endpoint/services/actions/clients/microsoft/defender/endpoint/mocks.ts
index 5c08982b9ade1..5baf18f9200d3 100644
--- a/x-pack/solutions/security/plugins/security_solution/server/endpoint/services/actions/clients/microsoft/defender/endpoint/mocks.ts
+++ b/x-pack/solutions/security/plugins/security_solution/server/endpoint/services/actions/clients/microsoft/defender/endpoint/mocks.ts
@@ -153,29 +153,32 @@ const createMicrosoftMachineActionMock = (
   };
 };
 
-const createMicrosoftGetActionsApiResponseMock =
-  (): MicrosoftDefenderEndpointGetActionsResponse => {
-    return {
-      '@odata.context': 'some-context',
-      '@odata.count': 1,
-      total: 1,
-      page: 1,
-      pageSize: 0,
-      value: [createMicrosoftMachineActionMock()],
-    };
+const createMicrosoftGetActionsApiResponseMock = (
+  overrides: Partial<MicrosoftDefenderEndpointMachineAction> = {}
+): MicrosoftDefenderEndpointGetActionsResponse => {
+  return {
+    '@odata.context': 'some-context',
+    '@odata.count': 1,
+    total: 1,
+    page: 1,
+    pageSize: 0,
+    value: [createMicrosoftMachineActionMock(overrides)],
   };
+};
 
-const createMicrosoftGetMachineListApiResponseMock =
-  (): MicrosoftDefenderEndpointAgentListResponse => {
-    return {
-      '@odata.context': 'some-context',
-      '@odata.count': 1,
-      total: 1,
-      page: 1,
-      pageSize: 0,
-      value: [createMicrosoftMachineMock()],
-    };
+const createMicrosoftGetMachineListApiResponseMock = (
+  /** Any overrides to the 1 machine action that is included in the mock response */
+  machineActionOverrides: Partial<MicrosoftDefenderEndpointMachine> = {}
+): MicrosoftDefenderEndpointAgentListResponse => {
+  return {
+    '@odata.context': 'some-context',
+    '@odata.count': 1,
+    total: 1,
+    page: 1,
+    pageSize: 0,
+    value: [createMicrosoftMachineMock(machineActionOverrides)],
   };
+};
 
 export const microsoftDefenderMock = {
   createConstructorOptions: createMsDefenderClientConstructorOptionsMock,
diff --git a/x-pack/solutions/security/plugins/security_solution/server/endpoint/services/actions/clients/mocks.ts b/x-pack/solutions/security/plugins/security_solution/server/endpoint/services/actions/clients/mocks.ts
index 1a02f780cce03..97973b0638d7a 100644
--- a/x-pack/solutions/security/plugins/security_solution/server/endpoint/services/actions/clients/mocks.ts
+++ b/x-pack/solutions/security/plugins/security_solution/server/endpoint/services/actions/clients/mocks.ts
@@ -301,10 +301,12 @@ const createConnectorActionsClientMock = ({
 } = {}): ActionsClientMock => {
   const client = actionsClientMock.create();
 
-  (client.getAll as jest.Mock).mockImplementation(async () => {
+  client.getAll.mockImplementation(async () => {
     return getAllResponse ?? [];
   });
 
+  client.execute.mockImplementation(async () => createConnectorActionExecuteResponseMock());
+
   return client;
 };
 
@@ -325,14 +327,20 @@ const createNormalizedExternalConnectorClientMock = (
 const setConnectorActionsClientExecuteResponseMock = (
   connectorActionsClient: ActionsClientMock | NormalizedExternalConnectorClientMock,
   subAction: string,
+  /**
+   * The response to be returned. If this value is a function, it will be called with the
+   * arguments passed to `.execute()` and should then return the response
+   */
   response: any
 ): void => {
   const executeMockFn = (connectorActionsClient.execute as jest.Mock).getMockImplementation();
 
   (connectorActionsClient.execute as jest.Mock).mockImplementation(async (options) => {
     if (options.params.subAction === subAction) {
+      const responseData = typeof response === 'function' ? response(options) : response;
+
       return responseActionsClientMock.createConnectorActionExecuteResponse({
-        data: response,
+        data: responseData,
       });
     }
 
diff --git a/x-pack/solutions/security/plugins/security_solution/server/endpoint/services/agent/clients/microsoft_defender_endpoint/microsoft_defender_endpoint_agent_status_client.test.ts b/x-pack/solutions/security/plugins/security_solution/server/endpoint/services/agent/clients/microsoft_defender_endpoint/microsoft_defender_endpoint_agent_status_client.test.ts
index a2c3006249e6c..3f682a4ac7dab 100644
--- a/x-pack/solutions/security/plugins/security_solution/server/endpoint/services/agent/clients/microsoft_defender_endpoint/microsoft_defender_endpoint_agent_status_client.test.ts
+++ b/x-pack/solutions/security/plugins/security_solution/server/endpoint/services/agent/clients/microsoft_defender_endpoint/microsoft_defender_endpoint_agent_status_client.test.ts
@@ -12,6 +12,8 @@ import { microsoftDefenderMock } from '../../../actions/clients/microsoft/defend
 import type { AgentStatusClientOptions } from '../lib/base_agent_status_client';
 import { HostStatus } from '../../../../../../common/endpoint/types';
 import { responseActionsClientMock } from '../../../actions/clients/mocks';
+import { MICROSOFT_DEFENDER_ENDPOINT_SUB_ACTION } from '@kbn/stack-connectors-plugin/common/microsoft_defender_endpoint/constants';
+import type { ActionsClientMock } from '@kbn/actions-plugin/server/mocks';
 
 jest.mock('../../../actions/pending_actions_summary', () => {
   const realModule = jest.requireActual('../../../actions/pending_actions_summary');
@@ -94,7 +96,7 @@ describe('Microsoft Defender Agent Status client', () => {
         agentId: '1-2-3',
         agentType: 'microsoft_defender_endpoint',
         found: true,
-        isolated: false,
+        isolated: true,
         lastSeen: '2018-08-02T14:55:03.7791856Z',
         pendingActions: {
           isolate: 1,
@@ -105,7 +107,7 @@ describe('Microsoft Defender Agent Status client', () => {
         agentId: 'foo',
         agentType: 'microsoft_defender_endpoint',
         found: false,
-        isolated: false,
+        isolated: true, // << This is only true because of the way the default mock is setup. The important value for this test data `found: false`
         lastSeen: '',
         pendingActions: {},
         status: 'unenrolled',
@@ -124,25 +126,12 @@ describe('Microsoft Defender Agent Status client', () => {
   `(
     'should correctly map MS machine healthStatus of $msHealthStatus to agent status $expectedAgentStatus',
     async ({ msHealthStatus, expectedAgentStatus }) => {
-      const priorExecuteMock = (
-        clientConstructorOptions.connectorActionsClient?.execute as jest.Mock
-      ).getMockImplementation();
-      (clientConstructorOptions.connectorActionsClient?.execute as jest.Mock).mockImplementation(
-        async (options) => {
-          if (options.params.subAction === 'getAgentList') {
-            const machineListResponse =
-              microsoftDefenderMock.createMicrosoftGetMachineListApiResponse();
-            machineListResponse.value[0].healthStatus = msHealthStatus;
-
-            return responseActionsClientMock.createConnectorActionExecuteResponse({
-              data: machineListResponse,
-            });
-          }
-
-          if (priorExecuteMock) {
-            return priorExecuteMock(options);
-          }
-        }
+      responseActionsClientMock.setConnectorActionsClientExecuteResponse(
+        clientConstructorOptions.connectorActionsClient! as ActionsClientMock,
+        MICROSOFT_DEFENDER_ENDPOINT_SUB_ACTION.GET_AGENT_LIST,
+        microsoftDefenderMock.createMicrosoftGetMachineListApiResponse({
+          healthStatus: msHealthStatus,
+        })
       );
 
       await expect(msAgentStatusClientMock.getAgentStatuses(['1-2-3'])).resolves.toEqual({
@@ -152,4 +141,50 @@ describe('Microsoft Defender Agent Status client', () => {
       });
     }
   );
+
+  it('should retrieve the last successful isolate/release action from MS', async () => {
+    await msAgentStatusClientMock.getAgentStatuses(['1-2-3']);
+
+    expect(clientConstructorOptions.connectorActionsClient?.execute).toHaveBeenCalledWith(
+      expect.objectContaining({
+        params: {
+          subAction: MICROSOFT_DEFENDER_ENDPOINT_SUB_ACTION.GET_ACTIONS,
+          subActionParams: {
+            status: 'Succeeded',
+            type: ['Isolate', 'Unisolate'],
+            machineId: '1-2-3',
+            pageSize: 1,
+            sortField: 'lastUpdateDateTimeUtc',
+            sortDirection: 'desc',
+          },
+        },
+      })
+    );
+  });
+
+  it.each`
+    title                                  | msMachineActionsResponse                                                    | expectedIsolatedValue
+    ${'last success action was Isolate'}   | ${microsoftDefenderMock.createGetActionsApiResponse({ type: 'Isolate' })}   | ${true}
+    ${'last success action was Unisolate'} | ${microsoftDefenderMock.createGetActionsApiResponse({ type: 'Unisolate' })} | ${false}
+    ${'no isolation records are found'}    | ${{ value: [] }}                                                            | ${false}
+    ${'when ms API throws an error'}       | ${new Error('foo')}                                                         | ${false}
+  `(
+    `should display isolated:$expectedIsolatedValue when $title`,
+    async ({ msMachineActionsResponse, expectedIsolatedValue }) => {
+      responseActionsClientMock.setConnectorActionsClientExecuteResponse(
+        clientConstructorOptions.connectorActionsClient! as ActionsClientMock,
+        MICROSOFT_DEFENDER_ENDPOINT_SUB_ACTION.GET_ACTIONS,
+        () => {
+          if (msMachineActionsResponse instanceof Error) {
+            throw msMachineActionsResponse;
+          }
+          return msMachineActionsResponse;
+        }
+      );
+
+      await expect(msAgentStatusClientMock.getAgentStatuses(['1-2-3'])).resolves.toEqual({
+        '1-2-3': expect.objectContaining({ isolated: expectedIsolatedValue }),
+      });
+    }
+  );
 });
diff --git a/x-pack/solutions/security/plugins/security_solution/server/endpoint/services/agent/clients/microsoft_defender_endpoint/microsoft_defender_endpoint_agent_status_client.ts b/x-pack/solutions/security/plugins/security_solution/server/endpoint/services/agent/clients/microsoft_defender_endpoint/microsoft_defender_endpoint_agent_status_client.ts
index 6f4820290aa85..e102fe3d46f64 100644
--- a/x-pack/solutions/security/plugins/security_solution/server/endpoint/services/agent/clients/microsoft_defender_endpoint/microsoft_defender_endpoint_agent_status_client.ts
+++ b/x-pack/solutions/security/plugins/security_solution/server/endpoint/services/agent/clients/microsoft_defender_endpoint/microsoft_defender_endpoint_agent_status_client.ts
@@ -12,8 +12,12 @@ import {
 import { keyBy } from 'lodash';
 import type {
   MicrosoftDefenderEndpointAgentListResponse,
+  MicrosoftDefenderEndpointGetActionsParams,
+  MicrosoftDefenderEndpointGetActionsResponse,
   MicrosoftDefenderEndpointMachine,
 } from '@kbn/stack-connectors-plugin/common/microsoft_defender_endpoint/types';
+import pMap from 'p-map';
+import { stringify } from '../../../../utils/stringify';
 import type { ResponseActionAgentType } from '../../../../../../common/endpoint/service/response_actions/constants';
 import { AgentStatusClientError } from '../errors';
 import { getPendingActionsSummary, NormalizedExternalConnectorClient } from '../../..';
@@ -66,22 +70,79 @@ export class MicrosoftDefenderEndpointAgentStatusClient extends AgentStatusClien
     }
   }
 
+  protected async calculateHostIsolatedState(agentIds: string[]): Promise<Record<string, boolean>> {
+    const response: Record<string, boolean> = {};
+    const errors: string[] = [];
+
+    await pMap(
+      agentIds,
+      async (agentId) => {
+        response[agentId] = false;
+
+        try {
+          // Microsoft's does not seem to have a public API that enables us to get the Isolation state for a machine. To
+          // get around this, we query the list of machine actions for each host and look at the last successful
+          // Isolate or Unisolate action to determine if host is isolated or not.
+          const { data: hostLastSuccessfulMachineAction } = await this.connectorActions.execute<
+            MicrosoftDefenderEndpointGetActionsResponse,
+            MicrosoftDefenderEndpointGetActionsParams
+          >({
+            params: {
+              subAction: MICROSOFT_DEFENDER_ENDPOINT_SUB_ACTION.GET_ACTIONS,
+              subActionParams: {
+                status: 'Succeeded',
+                type: ['Isolate', 'Unisolate'],
+                machineId: agentId,
+                pageSize: 1,
+                sortField: 'lastUpdateDateTimeUtc',
+                sortDirection: 'desc',
+              },
+            },
+          });
+
+          if (hostLastSuccessfulMachineAction?.value?.[0].type === 'Isolate') {
+            response[agentId] = true;
+          }
+        } catch (err) {
+          errors.push(err.message);
+        }
+      },
+      { concurrency: 2 }
+    );
+
+    if (errors.length > 0) {
+      this.log.error(
+        `Attempt to calculate isolate state for Microsoft Defender hosts generated the following errors:\n${errors.join(
+          '\n'
+        )}`
+      );
+    }
+
+    this.log.debug(() => `Microsoft agents isolated state:\n${stringify(response)}`);
+
+    return response;
+  }
+
   public async getAgentStatuses(agentIds: string[]): Promise<AgentStatusRecords> {
     const esClient = this.options.esClient;
     const metadataService = this.options.endpointService.getEndpointMetadataService();
 
     try {
-      const [{ data: msMachineListResponse }, allPendingActions] = await Promise.all([
-        this.connectorActions.execute<MicrosoftDefenderEndpointAgentListResponse>({
-          params: {
-            subAction: MICROSOFT_DEFENDER_ENDPOINT_SUB_ACTION.GET_AGENT_LIST,
-            subActionParams: { id: agentIds },
-          },
-        }),
-
-        // Fetch pending actions summary
-        getPendingActionsSummary(esClient, metadataService, this.log, agentIds),
-      ]);
+      const [{ data: msMachineListResponse }, agentIsolationState, allPendingActions] =
+        await Promise.all([
+          this.connectorActions.execute<MicrosoftDefenderEndpointAgentListResponse>({
+            params: {
+              subAction: MICROSOFT_DEFENDER_ENDPOINT_SUB_ACTION.GET_AGENT_LIST,
+              subActionParams: { id: agentIds },
+            },
+          }),
+
+          // Calculate host's current isolation state
+          this.calculateHostIsolatedState(agentIds),
+
+          // Fetch pending actions summary
+          getPendingActionsSummary(esClient, metadataService, this.log, agentIds),
+        ]);
 
       const machinesById = keyBy(msMachineListResponse?.value ?? [], 'id');
       const pendingActionsByAgentId = keyBy(allPendingActions, 'agent_id');
@@ -94,9 +155,7 @@ export class MicrosoftDefenderEndpointAgentStatusClient extends AgentStatusClien
           agentId,
           agentType: this.agentType,
           found: !!thisMachine,
-          // Unfortunately, it does not look like MS Defender has a way to determine
-          // if a host is isolated or not via API, so we just set this to false
-          isolated: false,
+          isolated: agentIsolationState[agentId] ?? false,
           lastSeen: thisMachine?.lastSeen ?? '',
           status: this.getAgentStatusFromMachineHealthStatus(thisMachine?.healthStatus),
           pendingActions: thisAgentPendingActions?.pending_actions ?? {},