Activate your Azure AD PIM roles with PowerShell

In the age of Zero Trust and highly sophisticated cyber attacks, you need to protect all privileged roles! In Microsoft 365 this is relatively easy but it can be daunting for the people eligible to use such roles to manage and activate them. This is my contribution to all M365 admins out there to make your work life a little bit easier.

Azure AD Privileged Identity Management (PIM) has been around for many years now. It has slowly grown in popularity and Microsoft is making it better and better. In the beginning it was slow and unpredictable but it is now a central part in any Microsoft 365 customers zero-trust journey where it helps to implement JIT/JEA for admin roles.

In my DCToolbox PowerShell module I’ve included a tool called Enable-DCAzureADPIMRole for some time. I recently released a new version with some highly requested features. This article will explain how you can activate your Azure AD roles in PIM with PowerShell, multiple roles at once, and more or less fully automated (except for authentication and MFA of course).

This image shows a screenshot from VS Code with the tool in action. I’ll explain it further down.

First you need to install DCToolbox from the PowerShell Gallery by running Install-Module. There are also two dependencies for Enable-DCAzureADPIMRole. Run one of the following installation snippets:

# Install required modules (if you are local admin) (only needed first time).
Install-Module -Name DCToolbox -Force
Install-Module -Name AzureADPreview -Force
Install-Package -AcceptLicense -Force

# Install required modules as curren user (if you're not local admin) (only needed first time).
Install-Module -Name DCToolbox -Scope CurrentUser -Force
Install-Module -Name AzureADPreview -Scope CurrentUser -Force
Install-Package -AcceptLicense -Force

The first one is for users with local admin permissions on their workstation, the second one are for users with non-admin permissions.

In some highly locked-down environments I’ve seen the package fail complaining on dependencies. If you get any error messages you can connect with Connect-AzureAD instead before running Enable-DCAzureADPIM. However, if you don’t, Enable-DCAzureADPIM will prompt for credentials automatically.

# If you want to, you can run Connect-AzureAD before running Enable-DCAzureADPIMRole, but you don't have to.

Finally, it’s time for some action! You could just simply run the command as is to interactively select a role and input activation time and reason.

# Enable one of your Azure AD PIM roles.

Or you could do the same but with multiple selected roles via the -RolesToActivate parameter. This is great for times when you need multiple roles to complete your job.

Note: This is not the same as using Privileged Access groups in PIM. Privileged Access groups are created and managed by PIM-administrators where they try to group multiple Azure AD roles to a specific work role in the organisation, for example, a service desk role. This is a great practice of course but Enable-DCAzureADPIMRole helps M365 admins where no such groups are available, or where they need to activate less roles than what’s in an Privileged Access group. They complement each other.

# Enable multiple Azure AD PIM roles.
Enable-DCAzureADPIMRole -RolesToActivate 'Exchange Administrator', 'Security Reader'

Finally you can use this tool to fully automate the role activation by specifying -Reason and -UseMaximumTimeAllowed. This can be helpful for planned changes where you need many roles and where you need to activate the same roles multiple times during the change because of activation time limits.

# Fully automate Azure AD PIM role activation.
Enable-DCAzureADPIMRole -RolesToActivate 'Exchange Administrator', 'Security Reader' -UseMaxiumTimeAllowed -Reason 'Performing some Exchange security coniguration according to change #12345.'

I hope that this tool will help all M365 admins out there. It sure has helped me!

Please follow me here, on LinkedIn and on Twitter!


25 thoughts on “Activate your Azure AD PIM roles with PowerShell

  1. Thank you! I’m afraid that is not possible right now. From Microsoft documentation: “If you require ticket system / ticket number in your role setting, there is no way to supply those as a parameter. Thus, it would not be possible to activate the role beyond the Azure portal. This feature is being rolled out to PowerShell over the next few months.”

  2. Daniel, excellent work. Manual PIM activation is cumbersome at best. Is it feasible to add support for scoped access?
    VERBOSE: Activating PIM role ‘Authentication Administrator’…
    Open-AzureADMSPrivilegedRoleAssignmentRequest : Error occurred while executing
    Code: InvalidScope
    Message: The resource scope is not valid.
    HttpStatusCode: BadRequest
    HttpStatusDescription: Bad Request
    HttpResponseStatus: Completed
    At C:\Program Files\WindowsPowerShell\Modules\DCToolbox\1.0.24\DCToolbox.psm1:1481 char:13
    + Open-AzureADMSPrivilegedRoleAssignmentRequest -ProviderId …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [Open-AzureADMSP…signmentRequest], ApiException
    + FullyQualifiedErrorId : Microsoft.Open.MSGraphBeta.Client.ApiException,Microsoft.Open.MSGraphBeta.PowerShell.Ope
    Role Scope Membership End time Action
    Authentication Administrator  (Administrative unit) Direct Permanent Activate

  3. Wow what a time saver this script has been!! Thank you for the share.

    I have one question. Once I activate a PIM Profile is there a way to NOT reactivate it ? I looked into your script and it seems to be already in there. if ($Role.AssignmentState -eq ‘Active’) is never true here all I have in the AssignmentState is the Eligible one .

    Thank you again for the script.

  4. My first comment got deleted I think. So here goes. Your script is a real time saver. Thank you. Can you tell me why I never get a message saying that my PIM is already activated. All I get is the Eligible ones. Thank you

  5. HI Daniel,
    Nice script. Can you please add the date and time if we want to put for activation in advance dates so that it is approved and get activated on future date and time.

  6. Hi,

    i love your Script. But i wonder if it is Possible to Deactivate PIM Roles the same way again. For normal Roles i let them time Out but for Higher Privileges like Sec Admin it would be great to Deactivate them after your Work.
    I’ve tried Running “Close-AzureADMSPrivilegedRoleAssignmentRequest” but it gets always an Error back. So that cant be the right Command but I dind’t find anything else…
    Appreciate xour work!

  7. Hi Jeff! That’s how PIM works. It’s the same in the GUI. You can activate already activated roles to extend its activation time. I see no point in removing this behaviour. But if I understand your question, you would like to see in my PowerShell tool if a role has been activated already. I will look into that.

  8. Hi Daniel,
    I love your Script and I’m using it everyday.
    But do you think it is Possible to end An PIM assignemt via Powershell? I think fpr High Priveleged Roles (Global Admin/Sec Reader etc) it would be nice to end them after the Specific task you needed them for.

    Have a nice day and keep up the lovely Scripts!

  9. Daniel,
    Great article. We have privileged access group. Do you know if there is a way to activate privilege access groups through PowerShell?


  10. Thanks for putting this together. Unfortunately, I am having some issues — I ran through both the admin and non-admin instructions and still receive an error indicating I need to install AzureADPreview. Not sure what I am missing,. FYSA, doing this via a Mac. Much appreciated!

    PS /Users/xxxx> Install-Module -Name DCToolbox -Force
    PS /Users/xxxx> Install-Module -Name AzureADPreview -Force
    PS /Users/xxxx> Install-Package -Force

    Name Version Source Summary
    —- ——- —— ——-
    MSAL.PS PSGallery The MSAL.PS PowerShell module wraps MSAL.NET functionality into Powe…

    PS /Users/xxxx> Enable-DCAzureADPIMRole
    Enable-DCAzureADPIMRole: The Azure AD Preview PowerShell module is not installed. Please, run ‘Install-Module AzureADPreview -Force’ as an admin and try again.

  11. Nice tool, but it would be nice to specify a explicit TimeAllowed. Now it seems that you can only automate with UseMaxiumTimeAllowed. Or am I missing something?

  12. I am getting the same error message as Derek in the comments above. Have you looked into adding support for scoped access?

    Code: InvalidScope
    Message: The resource scope is not valid.

  13. Hello Daniel,
    I tried the script, but it said “Found no eligible PIM roles to activate”
    In the portal, I go to PIM -> My roles -> Azure Resources -> ‘Contributor’
    The ‘Contributor’ I’m activating is in the ‘Tenant Root Group’ resource.
    Perhaps your module only works with “Azure AD roles” and not “Azure Resources” ?
    I’m not sure what to do.

  14. Hello Daniel,

    this is a wonderful script, it works flawlessly, but in an MFA environment, i get the below error. is there an updated script/module that I can use sir?

    PS C:\Users\a79270>09-09-22 09:59:26> Enable-DCAzureADPIMRole -RolesToActivate ‘Teams Administrator’ -UseMaxiumTimeAllowed -Reason ‘Performing some Exchange security coniguration according to change #12345.’

    *** Activate PIM Role ***

    Roles to activate:

    Teams Administrator

    VERBOSE: Activating PIM role ‘Teams Administrator’…
    Open-AzureADMSPrivilegedRoleAssignmentRequest : Error occurred while executing OpenAzureADMSPrivilegedRoleAssignmentRequest
    Code: RoleAssignmentRequestPolicyValidationFailed
    Message: The following policy rules failed: [“MfaRule”]

  15. In the last script you misspelt -UseMaxiumTimeAllowed should be -UseMaximumTimeAllowed
    caught me out at first

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s