NL Dutch
FR French
IT Italian
JP Japanese
DE German
US English (US)
ES Spanish

Contact Us

If you still have questions or prefer to get help directly from an agent, please submit a request.
We’ll get back to you as soon as possible.

  • Contact Us
English (US)
NL Dutch
FR French
IT Italian
JP Japanese
DE German
US English (US)
ES Spanish
  • Home
  • CyberFOX Optimize365
  • Remediation

Manually Assign Remediation Roles to Optimize365

Written by Owen Parry

Updated at November 12th, 2026

Contact Us

If you still have questions or prefer to get help directly from an agent, please submit a request.
We’ll get back to you as soon as possible.

  • CyberFOX AutoElevate
    Getting Started with AutoElevate AutoElevate Concepts Admin Portal & Settings Elevation & Blocker Rules Technician Mode & Approvals Deploying via RMM Tools PSA & Ticketing Integrations Other Integrations Troubleshooting AutoElevate FAQ Selling AutoElevate
  • CyberFOX Optimize365
    Getting Started Integrations Assessing Client Security Remediation Account & Administration
  • CyberFOX Password Manager
    Using CyberFOX Password Manager Administrating CyberFOX Password Manager Legacy Password Boss
  • CyberFOX DNS Filtering
    Getting Started with DNS Filtering DNS Filtering Concepts Network Requirements for DNS Filtering DNS Filtering Company and Location Setup Managing your DNS Filtering Policies Using Roaming Clients for DNS Filtering DNS Filtering Reports & Logs DNS Filtering Troubleshooting FAQ
  • Marketing Toolkit
    MSP Marketing & Education Toolkit
  • Changelogs for Autoelevate and Password Boss
  • CyberFOX Product Roadmap
  • Current Status
+ More

Overview


Optimize365's remediation features use a separate app registration, Optimize365-Write, which needs elevated Microsoft Entra roles beyond Global Reader. These roles let Optimize365 fix misconfigurations, enforce baselines, and apply security and compliance changes automatically. Use this article when the in-app Optimize Role Granter isn't an option and you need to assign the roles yourself, either in the Microsoft Entra admin center or with a PowerShell script.

 

Why These Roles Are Required


Remediation goes beyond visibility: it needs write permissions to enforce security and compliance changes across Microsoft 365 services. Without these roles, Optimize365 is limited to read-only scanning.

The required roles are:

  • Exchange Administrator
  • Security Administrator
  • Compliance Administrator
  • Conditional Access Administrator
  • Authentication Administrator
  • SharePoint Administrator
  • Teams Administrator
  • User Administrator
  • Application Administrator
  • Privileged Role Administrator
  • Authentication Policy Administrator
  • Cloud Application Administrator
  • Groups Administrator
  • Privileged Authentication Administrator
  • Security Operator
  • Azure Information Protection Administrator
  • Cloud Device Administrator
  • Global Secure Access Administrator
  • Compliance Data Administrator

 

Prerequisites


  • A Global Administrator user with access to Microsoft Entra ID
  • Assign the roles in each client tenant (per tenant)

 

Assign the Remediation Roles


Option 1: Microsoft Entra admin center

Sign in to the Microsoft Entra admin center.

Go to Entra ID > Roles & admins (click Show more... if you can't see it).

Select the Exchange Administrator role to open its details.

Role-Remediation-Step01

Select Add assignments, search for "Optimize365-Write" (AppId: e5099652-03bb-4940-8490-3b3ca8e75369), and click Add.

Role-Remediation-Step02

Confirm the app now appears in the list of assignments.

Role-Remediation-Step03

Important: You must repeat steps 3–5 for every role listed above, not just Exchange Administrator. With 19 roles, Option 2 is much faster.

Option 2: PowerShell script

Download the script: assign-rem-roles.ps1, or run the PowerShell below. It connects to Microsoft Graph, finds the Optimize365-Write service principal, activates each role if needed, assigns all 19 roles, and verifies the assignments.

# Disconnect any existing sessions
Disconnect-MgGraph -ErrorAction SilentlyContinue

# Connect with required scopes
Connect-MgGraph -Scopes @(
    "RoleManagement.ReadWrite.Directory",
    "Directory.ReadWrite.All",
    "Application.Read.All"
)

$appId = "e5099652-03bb-4940-8490-3b3ca8e75369"

$rolesToAssign = @(
    "Exchange Administrator",
    "Security Administrator",
    "Compliance Administrator",
    "Conditional Access Administrator",
    "Authentication Administrator",
    "SharePoint Administrator",
    "Teams Administrator",
    "User Administrator",
    "Application Administrator",
    "Privileged Role Administrator",
    "Authentication Policy Administrator",
    "Cloud Application Administrator",
    "Groups Administrator",
    "Privileged Authentication Administrator",
    "Security Operator",
    "Azure Information Protection Administrator",
    "Cloud Device Administrator",
    "Global Secure Access Administrator",
    "Compliance Data Administrator"
)

$servicePrincipal = Get-MgServicePrincipal -Filter "appId eq '$appId'"

if (-not $servicePrincipal) {
    Write-Host "❌ Service principal not found" -ForegroundColor Red
    Disconnect-MgGraph -ErrorAction SilentlyContinue | Out-Null
    exit
}

Write-Host "✅ Found: $($servicePrincipal.DisplayName)`n" -ForegroundColor Green

$roleTemplates = Get-MgDirectoryRoleTemplate -All
$activatedRoles = Get-MgDirectoryRole -All
$assignmentResults = @()

foreach ($roleName in $rolesToAssign) {
    $result = [PSCustomObject]@{
        RoleName = $roleName
        Status = "Unknown"
        Action = ""
    }

    $roleTemplate = $roleTemplates | Where-Object { $_.DisplayName -eq $roleName }

    if (-not $roleTemplate) {
        $result.Status = "Failed"
        $result.Action = "Template not found"
        $assignmentResults += $result
        continue
    }

    $role = $activatedRoles | Where-Object { $_.RoleTemplateId -eq $roleTemplate.Id }

    if (-not $role) {
        try {
            $role = New-MgDirectoryRole -RoleTemplateId $roleTemplate.Id
            $result.Action = "Activated"
        } catch {
            $result.Status = "Failed"
            $result.Action = "Activation failed"
            $assignmentResults += $result
            continue
        }
    }

    try {
        $members = Get-MgDirectoryRoleMember -DirectoryRoleId $role.Id -All

        if ($members | Where-Object { $_.Id -eq $servicePrincipal.Id }) {
            $result.Status = "Success"
            $result.Action = "Already assigned"
        } else {
            New-MgDirectoryRoleMemberByRef -DirectoryRoleId $role.Id -BodyParameter @{
                "@odata.id" = "https://graph.microsoft.com/v1.0/directoryObjects/$($servicePrincipal.Id)"
            }
            $result.Status = "Success"
            $result.Action = "Newly assigned"
        }
    } catch {
        $result.Status = "Failed"
        $result.Action = "Assignment failed"
    }

    $assignmentResults += $result
}

Start-Sleep -Seconds 5

Write-Host "Verifying assignments...`n" -ForegroundColor Cyan

$uri = "https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments?`$filter=principalId eq '$($servicePrincipal.Id)'"
$roleAssignments = Invoke-MgGraphRequest -Method GET -Uri $uri

$verifiedRoles = @()
foreach ($assignment in $roleAssignments.value) {
    $roleDefUri = "https://graph.microsoft.com/v1.0/roleManagement/directory/roleDefinitions/$($assignment.roleDefinitionId)"
    $roleDef = Invoke-MgGraphRequest -Method GET -Uri $roleDefUri
    $verifiedRoles += $roleDef.displayName
}

$successCount = ($assignmentResults | Where-Object { $_.Status -eq "Success" }).Count
$failedCount = ($assignmentResults | Where-Object { $_.Status -eq "Failed" }).Count
$totalCount = $rolesToAssign.Count
$verifiedCount = ($verifiedRoles | Where-Object { $rolesToAssign -contains $_ }).Count

Write-Host ("=" * 60) -ForegroundColor Cyan
Write-Host "FINAL STATUS" -ForegroundColor Cyan
Write-Host ("=" * 60) -ForegroundColor Cyan
Write-Host "Total: $totalCount | Success: $successCount | Failed: $failedCount | Verified: $verifiedCount`n"

$assignmentResults | Format-Table -Property RoleName, Status, Action -AutoSize

if ($verifiedCount -eq $totalCount) {
    Write-Host "✅ All $totalCount roles assigned and verified" -ForegroundColor Green
} elseif ($verifiedCount -gt 0) {
    Write-Host "⚠️ Partial success: $verifiedCount/$totalCount verified" -ForegroundColor Yellow
} else {
    Write-Host "⚠️ Roles assigned but verification incomplete" -ForegroundColor Yellow
}

Disconnect-MgGraph -ErrorAction SilentlyContinue | Out-Null
Write-Host "`n✅ Disconnected" -ForegroundColor Green

 

Troubleshooting


The script reports "Service principal not found"

The Optimize365-Write app hasn't been consented in this tenant yet. Complete Step 1 of enabling remediation (Microsoft 365 admin consent) first, then run the script again. See Remediation.

The script reports "Partial success"

Some roles failed to assign. Check the results table the script prints for roles marked Failed, then assign those roles manually with Option 1.

Need more help

Contact support@optimize365.io.

 

Security Notes


  • These are highly privileged roles, including Privileged Role Administrator and Privileged Authentication Administrator. Assign them only in tenants where you intend to use remediation.
  • The script requests the Microsoft Graph scopes RoleManagement.ReadWrite.Directory, Directory.ReadWrite.All, and Application.Read.All for the signed-in admin's session, and disconnects when it finishes.
  • Before remediating authentication or Conditional Access controls, make sure break glass accounts are in place. See Break Glass Accounts and Lockout Risk.

 

Related Articles


  • Remediation
  • Required Permissions & Roles
  • Manually enabling the Global Reader Role for Optimize365
  • Break Glass Accounts and Lockout Risk
optimize365 remediation roles assign remediation roles optimize365-write e5099652-03bb-4940-8490-3b3ca8e75369 exchange administrator security administrator privileged role administrator conditional access administrator manual role assignment microsoft entra admin center roles & admins add assignments powershell connect-mggraph assign-rem-roles.ps1 write permissions auto-remediation

Was this article helpful?

Yes
No
Give feedback about this article

Related Articles

  • Enable, Run, and Undo Remediation in Optimize365
  • Manually Assign the Global Reader Role to Optimize365
  • Required Permissions & Roles
CyberFOX

PRACTICAL CYBERSECURITY FOR LEAN IT TEAMS

Platforms
  • Privileged Access Management
  • Password Management
  • DNS Filtering
  • SASE
Industry
  • Higher Education
  • K-12 Education
  • State and Local Government
  • Manufacturing
Company
  • About
  • Awards
  • Partnerships
  • Trust & Legal
  • Contact
  • Login
  • FAQ
  • Referral Program
  • Support
© 2026 CYBERFOX LLC ALL RIGHTS RESERVED | Privacy Policy | Terms of Service | Sitemap
Expand