
Entra ID PIM activation is a daily ritual for anyone who operates Microsoft Entra ID. If you operate Microsoft Entra ID for a living, you know the dance. Open the portal. Sign in. PIM. My roles. Activate. Type a reason. Pick a duration. Confirm. Repeat for every role, every shift, every customer.
Honestly, I do this on most days. So does every other IT pro I know.
This week, however, I finally decided I was done with it – so I built PIM Tray, a tiny Windows tray app that activates one or more Entra ID PIM roles in a single dialog. It is free, open source under MIT, code-signed, and on GitHub at github.com/ThomasMarcussen/PIMTray.
Entra ID PIM Activation in 30 Seconds: What PIM Tray Does
- Sits in the Windows system tray as a shield icon.
- Left-click opens a small window listing every role you are eligible for. Right-click shows the same list as a context menu, plus sign-in / sign-out / about.
- Tick one or more roles, hit Activate, type a reason, pick a duration, done.
- A single Windows toast tells you which roles activated, which are pending approval, and which failed – so partial success is obvious instead of buried.
That is essentially the whole pitch. In short: no browser, no tab switching, no clicking through six blades to find the same form you used twenty minutes ago.
Why I Built an Entra ID PIM Activation Tool
First, I tried the obvious alternatives.
- The Entra portal is the canonical UX. It is fine for one role, painful for three, exhausting for ten.
- Microsoft.Graph PowerShell with a snippet works, but I do not want to keep a terminal open for a 3 second action, and reason prompts in a shell are friction.
- Microsoft Authenticator and WAM do not do PIM activation.
- A couple of community tools exist, but none were code-signed, none batched, and one of them shipped its own browser.
In the end, what I actually wanted was a tool that lived where my other always-on tools live – the notification area – and respected the fact that admins activate roles in clusters, not one at a time.
Therefore I built PIM Tray, a small tool that turns Entra ID PIM activation into a one-click workflow that lives in the Windows tray.
How Entra ID PIM Activation Works in PIM Tray
In particular, there are three moving parts: authentication, discovery, and activation.
Authentication: MSAL Interactive Sign-In
PIM Tray uses MSAL (Microsoft.Identity.Client) as a public client. The default system browser pops, you complete MFA and Conditional Access the proper way, and the token is cached encrypted to disk at %LOCALAPPDATA%\PIMTray\msal_cache.bin via DPAPI. As a result, subsequent launches go silent until the refresh token expires.
Importantly, no password is ever typed into the app, and there is no embedded browser or token-stealing surface area.
Role Discovery: One Microsoft Graph Call
After sign-in, PIM Tray queries Microsoft Graph for every PIM role you are eligible for, with the scope expanded:
GET https://graph.microsoft.com/v1.0/roleManagement/directory/roleEligibilitySchedules
?$filter=principalId eq '<your object id>'
&$expand=roleDefinition
As a result, every eligible role shows up in the list automatically, with its display name and scope (Directory or a resource path). There is no config file of role IDs to maintain.
Activation: One POST Per Checked Role
Then, for each role you tick, PIM Tray posts a self-activation request:
POST https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignmentScheduleRequests
Content-Type: application/json
{
"action": "selfActivate",
"principalId": "<user object id>",
"roleDefinitionId": "<role id>",
"directoryScopeId": "/",
"justification": "Friday change window, ticket INC0001234",
"scheduleInfo": {
"startDateTime": "2026-05-12T07:30:00Z",
"expiration": { "type": "AfterDuration", "duration": "PT4H" }
}
}
Notably, errors surface verbatim from Graph. If your role policy requires approval, the request is created in pending state and the tray balloon says so. If the policy requires ticket info that the form does not capture, the call fails clearly. No magic, no silent retries, no surprises.
Under the hood, the whole app is .NET 9 WinForms. In total, the signed exe is about 1.3 MB, while the MSI installer is under 500 KB.
Entra ID PIM Activation: The Permissions Question
PIM Tray needs three delegated Microsoft Graph scopes:
RoleEligibilitySchedule.Read.DirectoryRoleAssignmentSchedule.ReadWrite.DirectoryUser.Read
Specifically, there are two practical ways to satisfy them:
- Use the bundled default ClientId – the public Microsoft Graph PowerShell first-party app. The first sign-in shows the standard consent prompt. A Global Administrator can pre-consent at tenant level so end users never see the prompt again. Zero setup, but tenant-wide consent to a Microsoft-published app is heavier than some security teams want.
- Register your own Entra ID app. New registration, mobile and desktop platform, redirect URI
http://localhost, the three delegated scopes above, admin consent granted once. Paste the resulting TenantId and ClientId intoappsettings.json(auto-created at%APPDATA%\PIMTray\on first run). Cleaner long-term, especially if you ship the tool to other admins in your tenant.
In addition, both paths are documented in the README. For personal use, option 1 is two clicks away.
Install
PIMTray.msi -> C:\Program Files\PIM Tray\PIMTray.exe
To get started, download the signed MSI from the v1.0.0 release. The MSI is signed with our EV certificate (DigiCert, with RFC 3161 timestamp) so SmartScreen and Microsoft Defender treat it normally and Add/Remove Programs shows a real publisher instead of Unknown.
Requirements:
- Windows 10 or 11 (x64)
- .NET 9 Windows Desktop Runtime on the target machine
- At least one eligible PIM role on your signed-in account
Alternatively, to build from source, clone the repo and run dotnet publish -c Release -r win-x64 --self-contained false -p:PublishSingleFile=true. The exe lands in bin\Release\net9.0-windows\win-x64\publish\.
Frequently Asked Questions
Does PIM Tray support PIM for Groups?
Not in v1.0.0. The current release covers Entra ID directory roles via roleManagement/directory. Group-membership activations (identityGovernance/privilegedAccess/group/) are on the roadmap.
Does PIM Tray support Azure resource PIM (subscriptions, resource groups)?
Not yet. Azure RBAC PIM goes through roleManagement/rbacApplications and needs a different scope ID model. Tracking it as a roadmap item.
Does PIM Tray work with Conditional Access policies that require MFA on PIM?
Yes. In fact, authentication is interactive through MSAL using the system browser, which inherits all your Conditional Access policies, MFA prompts, and even Windows Hello / passkey flows. If your policy requires reauth for PIM, you get the standard Microsoft challenge.
Where is the token stored?
%LOCALAPPDATA%\PIMTray\msal_cache.bin, encrypted with DPAPI scoped to the current Windows user. The token never leaves your machine.
Is PIM Tray code-signed?
Yes. Both PIMTray.exe and PIMTray.msi are signed with an EV code-signing certificate from DigiCert and timestamped via RFC 3161, so the signature stays valid past certificate expiry.
Is PIM Tray open source?
Yes, MIT licensed. Source, issues and pull requests at github.com/ThomasMarcussen/PIMTray.
What is Next
The roadmap on the repo is short and honest:
- PIM for Groups (group-membership activations)
- Azure Resource PIM (subscription / resource group scopes)
- Approval-pending polling so you do not have to refresh manually
- Start at logon toggle in the About dialog
- Optional dark mode
Finally, if you use PIM Tray and it shaves five minutes off your week, that is a win for both of us. Issues and PRs welcome.
Try It
- Repo: github.com/ThomasMarcussen/PIMTray
- Download MSI (v1.0.0): github.com/ThomasMarcussen/PIMTray/releases/tag/v1.0.0
If PIM Tray fits your Entra ID PIM activation routine and you build something on top of it, ping me. I would like to hear what other patterns admins want to automate next.
Thomas Marcussen is a Microsoft MVP and Technology Architect. More notes and tools at thomasmarcussen.com.
You must be logged in to post a comment.