# How-To: Set Up App Registrations for Automated Entra ID Administration

<table class="MsoNormalTable" id="bkmrk-field-details-docume" style="width: 84.5238%;" title=""><tbody><tr><td style="width: 25.1101%;">**Field**

</td><td style="width: 74.8899%;">**Details**

</td></tr><tr><td style="width: 25.1101%;">Document Type

</td><td style="width: 74.8899%;">How-To Guide / Runbook

</td></tr><tr><td style="width: 25.1101%;">Applies To

</td><td style="width: 74.8899%;">Microsoft Entra ID, PowerShell, Microsoft Graph SDK

</td></tr><tr><td style="width: 25.1101%;">Audience

</td><td style="width: 74.8899%;">Systems Administrators / DevOps

</td></tr><tr><td style="width: 25.1101%;">Author

</td><td style="width: 74.8899%;">AK. Udofeh

</td></tr><tr><td style="width: 25.1101%;">Last Updated

</td><td style="width: 74.8899%;">April 2026

</td></tr></tbody></table>

##### **Overview**

<div class="Y3BBE" data-complete="true" data-hveid="CAEIAhAA" data-processed="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c" id="bkmrk-this-article-provide" jsaction="rcuQ6b:&ep2ME_w|npT2md" jscontroller="zcfIf" jsuid="ep2ME_w">This article provides a structured guide on creating and configuring a Microsoft Entra ID App Registration. This setup allows for secure authentication from a local terminal or automated scripts to perform administrative tasks such as SSO configuration and directory management.</div>##### **Background**

To interact with Entra ID via automation or the command line without using personal user credentials, a Service Principal is required. Standard user accounts often have MFA or conditional access policies that interfere with headless automation; an App Registration provides a controlled, auditable, and secure method for programmatic access.

##### **Before You Start**

<div class="Fv6NCb" data-complete="true" data-processed="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c" data-ved="2ahUKEwjq_qSG1u-TAxVObEEAHahxFq8Q-q4QegYIAQgEEAA" id="bkmrk-check-where-sufficie" jsaction="rcuQ6b:&ep2ME_13|npT2md" jscontroller="kbUand" jsuid="ep2ME_13"><table class="NRefec" data-animation-nesting="" data-sae=""><tbody><tr class="cZCYO" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c"><th class="iry6k" colspan="undefined" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">**Check**</th><th class="iry6k" colspan="undefined" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">**Where**</th></tr><tr class="cZCYO" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c"><td class="cOeeGf" colspan="undefined" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">Sufficient Permissions</td><td class="cOeeGf" colspan="undefined" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">Ensure you have 'Application Developer' or 'Cloud Application Administrator' roles.</td></tr><tr class="cZCYO" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c"><td class="cOeeGf" colspan="undefined" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">Microsoft Graph SDK</td><td class="cOeeGf" colspan="undefined" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">Install the module: `Install-Module Microsoft.Graph`</td></tr><tr class="cZCYO" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c"><td class="cOeeGf" colspan="undefined" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">Client Credentials</td><td aria-owns="action-menu-parent-container" class="cOeeGf" colspan="undefined" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">Have a naming convention ready (e.g., `Svc-Entra-Config`).</td></tr></tbody></table>

</div>##### **Configuration Steps**

1. <span class="T286Pc" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">**Register the Application**:</span>
    - Navigate to [https://entra.microsoft.com](https://portal.azure.com/)&gt; Entra ID &gt; App Registrations &gt; New Registration.
    - Enter a meaningful display name (e.g. AppName SSO).
    - Under Supported account types, select Accounts in this organisational directory only (Single tenant) unless multi-tenant access is required.
    - Leave the Redirect URI blank.
    - Click Register.
2. <span class="T286Pc" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">**Generate Credentials**:</span>
    - <span class="T286Pc" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">Go to **Certificates &amp; secrets &gt; Client secrets**.</span>
    - <span class="T286Pc" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">Create a new secret.</span>
    - <span class="T286Pc" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">Give it a description for future reference.</span>

<p class="callout info"><span class="T286Pc" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">Copy the secret Value immediately; it will be masked permanently once you leave the blade.</span></p>

<span class="T286Pc" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c"> <span class="Yjhzub"> 3. </span>**Configure API Permissions**:</span>

1. - <span class="T286Pc" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">Go to **API permissions &gt; Add a permission &gt; Microsoft Graph**.</span>
    - <span class="T286Pc" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">Select **Application permissions**.</span>
    - <span class="T286Pc" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">Add `Application.ReadWrite.All` (for SSO/App config) and `Directory.Read.All`.</span>
    - <span class="T286Pc" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">Select:, G**rant admin consent for \[Tenant\]**.</span>

<span class="T286Pc" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c"> 4. </span>**Elevate via Directory Roles (Conditional)**:

<p class="callout info"><span class="T286Pc" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">Only perform this step if API permissions above result in "Access Denied" for specific administrative tasks.</span></p>

- - - <span class="T286Pc" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">Navigate to **Identity &gt; Roles &amp; admins**.</span>
        - <span class="T286Pc" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">Search for **Cloud Application Administrator**.</span>
        - <span aria-owns="action-menu-parent-container" class="T286Pc" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">Select **Add assignments** and search for the **Name** of your App Registration to assign the role directly.</span>

##### **<span aria-owns="action-menu-parent-container" class="T286Pc" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">Automated / Script Option - PowerShell</span>**

```powershell
# Define connection variables
$TenantId = "your-tenant-id"
$ClientId = "your-client-id"
$ClientSecret = "your-client-secret" | ConvertTo-SecureString -AsPlainText -Force

# Create credential object for non-interactive login
$Credential = New-Object System.Management.Automation.PSCredential($ClientId, $ClientSecret)

# Connect to Microsoft Graph using the App Registration
# This uses the Client Credentials flow
Connect-MgGraph -TenantId $TenantId -Credential $Credential

# Success Indicator: Retrieve Tenant details to verify connection
Get-MgOrganization | Select-Object DisplayName, Id

```

##### **Script Breakdown**

- <span class="T286Pc" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">**Variable Definition**: Stores the IDs and secrets generated in the portal. The secret is converted to a `SecureString` for compatibility with PowerShell credential objects.</span>
- <span class="T286Pc" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">**Connect-MgGraph**: Establishes the session. Because a `Credential` object is passed, it bypasses the interactive browser login.</span>
- <span aria-owns="action-menu-parent-container" class="T286Pc" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">**Get-MgOrganization**: A simple test command. If the terminal returns your organisation's name, the authentication was successful.</span>

##### **<span aria-owns="action-menu-parent-container" class="T286Pc" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">Automated / Script Option - zsh</span>**

```bash
export ARM_CLIENT_ID="your-app-id"
export ARM_CLIENT_SECRET="your-app-password"
export ARM_SUBSCRIPTION_ID="your-sub-id"
export ARM_TENANT_ID="your-tenant-id"

```

##### **Troubleshooting**

<div aria-level="3" class="otQkpb" data-animation-nesting="" data-complete="true" data-processed="true" data-sae="" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c" id="bkmrk-access-denied-%28403-e" jsaction="" jscontroller="a7qCn" jsuid="ep2ME_40" role="heading">**Access Denied (403 Error)**</div>- <span class="T286Pc" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">**Cause**: The App Registration lacks the specific Graph API scope or the Directory Role required for the task.</span>
- <span class="T286Pc" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">**Fix**: Ensure **Admin Consent** was clicked in the portal. If the error persists, assign the **Cloud Application Administrator** directory role to the app as detailed in the manual steps.</span>

<div aria-level="3" class="otQkpb" data-animation-nesting="" data-complete="true" data-processed="true" data-sae="" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c" id="bkmrk-conflicting-authenti" jsaction="" jscontroller="a7qCn" jsuid="ep2ME_4b" role="heading">**Conflicting Authentication Context**</div>- <span class="T286Pc" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">**Cause**: An existing interactive session is active in the terminal.</span>
- <span class="T286Pc" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c">**Fix**: Run `Disconnect-MgGraph` before attempting to connect with the App Registration credentials.</span>

##### **Expected Outcome**

<div class="Fv6NCb" data-complete="true" data-processed="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c" data-ved="2ahUKEwjq_qSG1u-TAxVObEEAHahxFq8Q-q4QegYIAQgKEAA" id="bkmrk-metric-detail-resolu" jsaction="rcuQ6b:&ep2ME_4n|npT2md" jscontroller="kbUand" jsuid="ep2ME_4n"><table class="NRefec" data-animation-nesting="" data-sae="" style="height: 105px; width: 80.8333%;"><tbody><tr class="cZCYO" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c"><th class="iry6k" colspan="undefined" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c" style="width: 10%;">Metric</th><th class="iry6k" colspan="undefined" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c" style="width: 10%;">Detail</th></tr><tr class="cZCYO" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c"><td class="cOeeGf" colspan="undefined" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c" style="width: 10%;">**Resolution Time**</td><td class="cOeeGf" colspan="undefined" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c" style="width: 10%;">10–15 Minutes</td></tr><tr class="cZCYO" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c"><td class="cOeeGf" colspan="undefined" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c" style="width: 10%;">**User Impact**</td><td class="cOeeGf" colspan="undefined" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c" style="width: 10%;">None (Backend configuration only)</td></tr><tr class="cZCYO" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c"><td class="cOeeGf" colspan="undefined" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c" style="width: 10%;">**Recurrence Risk**</td><td aria-owns="action-menu-parent-container" class="cOeeGf" colspan="undefined" data-complete="true" data-sfc-cb="" data-sfc-cp="" data-sfc-root="c" style="width: 10%;">Low (Credentials expire based on secret lifetime)</td></tr></tbody></table>

</div>