Skip to main content
The Ops Playbook

Closing USB Exception Tickets With Self-Expiring Device Control

Replace manual USB exception approvals with time-boxed Entra ID groups, Defender device control, and an auto-expiry runbook that closes the loop itself.

Closing USB Exception Tickets With Self-Expiring Device Control
Sarah LiangSarah Liang10 min readTier L245 min

This playbook covers

Share

Removable media requests are one of the most predictable tickets in any Security & Compliance queue. A contractor needs to copy a CAD file to a USB drive. A field engineer needs to load firmware onto a stick. A finance analyst needs to hand over an encrypted drive to an auditor. Every one of these requests currently forces a human to make a risk decision, edit a policy, and then somehow remember to undo it.

The Old Way: the user emails the helpdesk. L1 cannot approve a security exception, so it escalates to L2 or the security team. Someone opens a Group Policy

Object or an endpoint protection console, adds the user’s device to an allow-list group, and closes the ticket as resolved. Nobody sets a calendar reminder to remove that access. Six months later, an internal audit or a SOC 2 evidence pull finds forty accounts with standing USB write access and nobody can explain why half of them still need it. The ticket is closed, but the risk is still open.

The New Way: the exception is time-boxed at the moment it is granted. A self-service form triggers an approval, the approval adds the requester to a security group with an expiry timestamp attached, a device control policy reads that group in near real time, and a scheduled automation removes the membership the second the clock runs out. No technician has to remember anything, and the audit trail writes itself. This article shows exactly how to build that pipeline using Microsoft Entra ID

custom security attributes, Microsoft Defender for Endpoint device control, and an Azure Automation runbook.

#Prerequisites and Permissions

Confirm the following before you touch a production device control profile:

  • Entra ID role: Privileged Role Administrator or Security Administrator to create groups and define custom security attributes. Attribute definition requires the Attribute Definition Administrator role specifically; do not assign Global Administrator for this task.
  • Defender for Endpoint / Intune role: Endpoint Security Manager (or a custom role with microsoft.intune/deviceConfigurations/create and update permissions) to publish and assign the device control profile.
  • Automation permissions: an Automation Account with a system-assigned managed identity granted GroupMember.ReadWrite.All and CustomSecAttributeAssignment.ReadWrite.All Graph application permissions, consented by a Global Administrator, scoped only to the two groups this workflow touches via Administrative Units where possible.
  • Log Analytics: a workspace with a custom table (or the Defender XDR advanced hunting connector) to receive grant and revoke events for audit evidence.
  • Test scope: a pilot Entra ID group of no more than 25 users on Windows 11 devices, tagged pilot-usb-exception, before this touches the production device control baseline.
  • Blast radius: changes only affect removable storage read/write permission for members of the exception group. It does not alter Conditional Access, does not touch BitLocker, and does not affect users outside the pilot tag during the test window.

#Implementation Steps

#
Step 1 — Create the two control groups

Action: create SG-USB-Exception-Requested and SG-USB-Exception-Approved as security groups via Graph.

1POST https://graph.microsoft.com/v1.0/groups
2{
3  "displayName": "SG-USB-Exception-Approved",
4  "mailEnabled": false,
5  "mailNickname": "sg-usb-exception-approved",
6  "securityEnabled": true,
7  "description": "Time-boxed removable storage exception - do not add members manually"
8}

Expected result: HTTP 204 on both calls. Evidence: Entra ID audit log shows Add member to group initiated by the Automation service principal, not a human account.

#
Step 5 — Publish the Device Control policy in Intune / Defender for Endpoint

Action: create a Removable Storage Access Control profile that denies write access by default and grants read/write to the exception group. This is delivered as an Intune Settings Catalog device control profile referencing the group ID from Step 1.

1{
2  "name": "Removable-Storage-Default-Deny",
3  "platform": "windows10",
4  "technologies": "mdm",
5  "settings": [
6    {
7      "settingInstance": {
8        "settingDefinitionId": "device_vendor_msft_policy_config_defender_removablediskdenywriteaccess",
9        "choiceSettingValue": { "value": "1" }
10      }
11    }
12  ],
13  "assignments": [
14    { "target": { "groupId": "{allDevicesExcludingExceptionGroupId}" } }
15  ]
16}

The exception profile mirrors this with value: 0 (deny disabled) assigned to SG-USB-Exception-Approved, and Intune’s conflict resolution ensures the exception profile wins by assignment priority. Expected result: policy shows as Succeeded on the pilot devices within 15 minutes of the next check-in. Evidence: device configuration profile status report exported from Intune, and a matching DeviceEvents row in Defender advanced hunting with ActionType == "RemovableStoragePolicyTriggered".

#
Step 6 — Deploy the auto-expiry runbook

Action: publish a PowerShell 7.2 runbook in Azure Automation, scheduled every 15 minutes, using the managed identity to remove expired members and log the eviction.

1Connect-MgGraph -Identity
2Select-MgProfile -Name "v1.0"
3
4$groupId = "<approved-group-object-id>"
5$now = [datetime]::UtcNow
6$members = Get-MgGroupMember -GroupId $groupId -All
7
8foreach ($member in $members) {
9    $user = Get-MgUser -UserId $member.Id -Property "customSecurityAttributes"
10    $expiryRaw = $user.CustomSecurityAttributes.AdditionalProperties.SecurityOps.usbExceptionExpiryUtc
11    if (-not $expiryRaw) { continue }
12
13    $expiry = [datetime]::Parse($expiryRaw).ToUniversalTime()
14    if ($expiry -lt $now) {
15        Remove-MgGroupMemberByRef -GroupId $groupId -DirectoryObjectId $member.Id
16
17        $logBody = @{
18            userId    = $member.Id
19            groupId   = $groupId
20            expiredAt = $expiryRaw
21            evictedAt = $now.ToString("o")
22            action    = "AutoRevoked"
23        } | ConvertTo-Json
24
25        Invoke-RestMethod -Method Post -Uri $env:LOG_ANALYTICS_INGESTION_URI -Body $logBody -ContentType "application/json"
26        Write-Output "Revoked USB exception for $($member.Id) at $now"
27    }
28}

Expected result: expired users are removed within one 15-minute cycle of their expiry timestamp. Expected output example: Revoked USB exception for 3f1a2b4c-... at 01/15/2025 18:04:11. Evidence: runbook job history (Succeeded status) and the corresponding Log Analytics ingestion row.

#
Step 7 — Wire up monitoring

Action: build a saved KQL query against the custom log table and Defender advanced hunting to correlate grants, device events, and revocations.

1query: |
2  USBExceptionEvents_CL
3  | where TimeGenerated > ago(7d)
4  | summarize Grants = countif(Action_s == "Granted"), Revokes = countif(Action_s == "AutoRevoked") by bin(TimeGenerated, 1d)
5  | order by TimeGenerated desc

Expected result: a daily count of grants versus automatic revocations, used both for the health check in Step 8 and for the deflection metrics in the final section.

USB exception device control automation

#
Step 8 — Pilot for five business days

Action: run the full loop against the pilot group only. Watch for orphaned members (users still in the group past their expiry) and for policy application failures.

Expected result: zero orphaned members after 15 minutes past expiry, and 100% policy application success on pilot devices. Evidence: a daily export of group membership compared against the expiry attribute, retained as pilot sign-off evidence.

#
Step 9 — Expand to production

Action: extend the device control assignment from the pilot device group to the full managed device population, and open the self-service form to all employees rather than the pilot cohort.

Expected result: ticket volume for the category USB Exception Request drops toward zero within one reporting cycle. Evidence: ITSM category trend report, covered in the deflection section below.

#Verification and Expected Evidence

  1. Query Get-MgGroupMember -GroupId $groupId immediately after an approval and confirm the requester appears within 60 seconds of the Power Automate run completing.
  2. Query Defender advanced hunting for DeviceEvents | where ActionType == "RemovableStorageAccessRequested" on the requester’s device and confirm the action shows Allowed only during the granted window.
  3. Confirm the runbook job history in Azure Automation shows a Succeeded status every 15 minutes with zero unhandled exceptions over a rolling 24-hour period.
  4. Confirm the custom security attribute value clears or the group membership is removed within one scheduling cycle after the stamped expiry timestamp passes.
  5. Pull the Entra ID audit log filtered to the Automation service principal and confirm every add and remove action is attributable to the automation, not a manual technician edit.

#Rollback

If the device control profile misbehaves — for example, USB write access is granted organisation-wide instead of to the exception group — immediately unassign the exception profile in Intune and confirm the default-deny profile re-applies on next check-in (typically within 8 hours, or force with Sync-MgDeviceManagementManagedDevice for urgent cases). Disable the Power Automate flow trigger to stop new approvals from entering the pipeline. Do not delete the two Entra ID groups; instead, manually clear membership via Remove-MgGroupMemberByRef for every current member, and pause (not delete) the Automation runbook schedule so historical logs remain intact for the incident review. Rollback triggers include: policy applying the wrong deny value to more than one device, the runbook removing a user who has not reached expiry, or the managed identity’s Graph token being flagged for unusual application permission usage.

#Failure and Escalation Conditions

  • If the auto-expiry runbook fails three consecutive scheduled runs (monitored via an Azure Monitor alert rule on the Automation job status), page the on-call L3 security engineer immediately — this means exceptions are not expiring and standing access risk is accumulating silently.
  • If the group membership count exceeds the expected pilot or production ceiling by more than 10% without a matching volume of approved flow runs, treat this as a possible manual bypass and escalate to the security incident process; audit who added the member.
  • If the Intune device configuration report shows more than 5% of in-scope devices in an Error or Conflict state for over four hours, escalate to the Endpoint Security team, since this indicates a policy precedence problem that could either block legitimate business use or silently fail closed on the deny-by-default baseline.
  • If a Defender for Endpoint alert fires for suspicious file activity from a device during an active USB exception window, this is a live security event, not a helpdesk ticket — escalate directly to the SOC regardless of time of day.

#Measuring Ticket Deflection

Baseline the manual process for 30 days before switching this on: capture average handle time per USB exception ticket (commonly 25–40 minutes once you include the GPO or endpoint console edit and the follow-up removal task that is frequently skipped), and total monthly ticket count for the category. After rollout, track the same category using the KQL query from Step 7 alongside the ITSM export.

1Deflection % = ((Baseline monthly tickets - Post-automation monthly tickets) / Baseline monthly tickets) x 100

Most organisations running this pattern see the ticket category collapse to near zero within the first full reporting month, because the request never reaches a human queue — it resolves inside the approval card. The remaining technician time shifts from manual policy editing to reviewing the weekly grant-versus-revoke report, which is also the artefact your compliance team will ask for at the next audit cycle instead of a spreadsheet nobody trusts.

Evidence trail

Sources and verification

Primary documentation and external technical references used in this article.

  1. 01Microsoft Defender for Endpoint removable storage access control documentationlearn.microsoft.com
  2. 02Microsoft Graph groups resource referencelearn.microsoft.com
  3. 03Microsoft Entra custom security attributes overviewlearn.microsoft.com
  4. 04Azure Automation runbook execution and monitoring guidelearn.microsoft.com
Sarah Liang

Sarah Liang

Ops Playbook Architect

Sarah Liang is a Cloud Solutions Architect designing highly available, globally distributed applications.

Published
View Profile
Reader Interaction

Comments

Add a thoughtful note on Closing USB Exception Tickets With Self-Expiring Device Control. Comments are checked for spam and held for moderation before appearing.

Loading comments...
Comment submission is disabled until Cloudflare Turnstile keys are configured.

Learn More About KBY

Was this useful?

Operate smarter, with fewer recurring tickets.

Receive new operational playbooks, incident-prevention guidance, automation scripts and recovery runbooks.