How do you automate PIM for Groups? (Part 2. Playing with PIM for Groups via API)
Tags: powershell, microsoftgraph, entraid, pim
Published: 2024-04-21 15:16:29

In my previous text, we sufficiently discussed the PIM for Group's technology. In the first part of this article [How do you automate PIM for Groups? (Part 1 - Setup)](https://dev.to/rokicool/how-do-you-automate-pim-for-groups-part-1-setup-pl5) we prepared our 'infrastructure' and defined our plans.

Let us start with something meaningful! :)

### How do we make the user (pim-user-play-01) PIM eligible to activate membership in the PIM Group (PIM-GROUP-PLAY-01)?

You remember that "PIM eligible" means "provided with the ability to activate something via PIM," right? 

Here is a .gif video of this action performed 'manually', using Azure Portal:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tfink0weuj5dn9qqo6nq.gif)

Now, let's take the same action via Microsoft Graph API. 

Here is the link to the API call documentation: [Create eligibilityScheduleRequest](https://learn.microsoft.com/en-us/graph/api/privilegedaccessgroup-post-eligibilityschedulerequests?view=graph-rest-1.0&tabs=powershell) and the PowerShell module documentation: [New-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest](https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.identity.governance/new-mgidentitygovernanceprivilegedaccessgroupeligibilityschedulerequest?view=graph-powershell-1.0)

``` PowerShell 
pwsh> $u01                                                             

DisplayName      Id                                   Mail UserPrincipalName
-----------      --                                   ---- -----------------
pim-user-play-01 c8816325-d172-44f5-b72d-a1b8de5673c2      pim-user-play-01@Selflearning527.onmicrosoft.com


pwsh> $pg01 

DisplayName       Id                                   MailNickname      Description          GroupTypes
-----------       --                                   ------------      -----------          ----------
PIM-GROUP-PLAY-01 853d7402-51b4-4cd4-9b8d-9f159311859d PIM-GROUP-PLAY-01 PIM for Groups tests {}

pwsh> $params = @{
	accessId = "member"
	principalId = "$($u01.Id)"
	groupId = "$($pg01.Id)"
	action = "AdminAssign"
	scheduleInfo = @{
		startDateTime = $(Get-Date)
		expiration = @{
			type = "AfterDateTime"
			endDateTime = $((Get-date).AddDays(7))
		}
	}
	justification = "$($u01.DisplayName) always deserved to be part of $($pg01.DisplayName)! Stand up, Sir $($u01.DisplayName). You have time until $((Get-date).AddDays(7))!"
}

pwsh> New-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -BodyParameter $params

Action      ApprovalId CompletedDateTime     CreatedDateTime       CustomData Id                                   IsValidationOnly Justification
------      ---------- -----------------     ---------------       ---------- --                                   ---------------- -------------                                                                                             
adminAssign            4/20/2024 11:18:51 PM 4/20/2024 11:18:51 PM            55067776-3b6d-44eb-8337-b0a2ad101bae False            pim-user-play-01 always deserved to be part of PIM-GROUP-PLAY-01! Stand up, Sir pim-user-play-01. You hav…


```
Let's look at the PIM interface in the Azure Portal:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dhlo8jq0u188zd0tbpfg.gif)

## How do we make ALL security group members (GROUP-PLAY-01) be PIM eligible to activate membership in the PIM Group (PIM-GROUP-PLAY-01)?

That operation is very similar to the previous one. However, instead of assigning PIM eligibility to a User, you can do the same to a Group. 

Here is how the 'manual' process looks like:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rp0p4c19783apgglsmuy.gif)

We will use the same API call.

``` PowerShell
pwsh> $g01                                                               

DisplayName   Id                                   MailNickname  Description          GroupTypes
-----------   --                                   ------------  -----------          ----------
GROUP-PLAY-01 d8800de8-1e79-4881-8cb3-814c0f6cd935 GROUP-PLAY-01 PIM for Groups tests {}

pwsh> $pg01 

DisplayName       Id                                   MailNickname      Description          GroupTypes
-----------       --                                   ------------      -----------          ----------
PIM-GROUP-PLAY-01 853d7402-51b4-4cd4-9b8d-9f159311859d PIM-GROUP-PLAY-01 PIM for Groups tests {}

pwsh> $params = @{
	accessId = "member"
	principalId = "$($g01.Id)"
	groupId = "$($pg01.Id)"
	action = "AdminAssign"
	scheduleInfo = @{
		startDateTime = $(Get-Date)
		expiration = @{
			type = "AfterDateTime"
			endDateTime = $((Get-date).AddDays(7))
		}
	}
	justification = "Members of $($g01.DisplayName) always deserved to be part of $($pg01.DisplayName)! You have time until $((Get-date).AddDays(7))!"
}

pwsh> New-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -BodyParameter $params

Action      ApprovalId CompletedDateTime     CreatedDateTime       CustomData Id                                   IsValidationOnly Justification
------      ---------- -----------------     ---------------       ---------- --                                   ---------------- -------------                                                                                             
adminAssign            4/20/2024 11:48:15 PM 4/20/2024 11:48:15 PM            ed7561c6-54af-4a71-8d7e-f31cee64fc19 False            Members of GROUP-PLAY-01 always deserved to be part of PIM-GROUP-PLAY-01! You have time until 04/27/2024 …

```
Let's have a look at the Azure Portal:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xlr9x0ma5vhpwwpchw4i.gif)

Nice! Both the user (pim-user-play-01) and the group (GROUP-PLAY-01) are now PIM eligible to activate membership in PIM group (PIM-GROUP-PLAY-01).

I had to open the Azure Portal and take screenshots to prove this. But is it not possible to perform that operation via Microsoft Graph API? The question urges us to the next topic!

## How do we check whether the specific user or group is PIM eligible?

To perform that, we will call to [List eligibilitySchedules](https://learn.microsoft.com/en-us/graph/api/privilegedaccessgroup-list-eligibilityschedules?view=graph-rest-1.0&tabs=powershell) using PowerShell function [Get-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule](https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.identity.governance/get-mgidentitygovernanceprivilegedaccessgroupeligibilityschedule?view=graph-powershell-1.0).

``` PowerShell
pwsh> Get-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -Filter ("groupId eq '{0}' and principalId eq '{1}'" -f $($pg01.Id), $($u01.Id))

CreatedDateTime       CreatedUsing                         Id                                                                               ModifiedDateTime    Status      AccessId GroupId                              MemberType Principal
                                                                                                                                                                                                                                     Id
---------------       ------------                         --                                                                               ----------------    ------      -------- -------                              ---------- ---------
4/20/2024 11:18:51 PM 55067776-3b6d-44eb-8337-b0a2ad101bae 853d7402-51b4-4cd4-9b8d-9f159311859d_member_55067776-3b6d-44eb-8337-b0a2ad101bae 1/1/0001 8:00:00 AM Provisioned member   853d7402-51b4-4cd4-9b8d-9f159311859d direct     c8816325…

pwsh> Get-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -Filter ("groupId eq '{0}' and principalId eq '{1}'" -f $($pg01.Id), $($g01.Id))

CreatedDateTime       CreatedUsing                         Id                                                                               ModifiedDateTime    Status      AccessId GroupId                              MemberType Principal
                                                                                                                                                                                                                                     Id
---------------       ------------                         --                                                                               ----------------    ------      -------- -------                              ---------- ---------
4/20/2024 11:48:15 PM ed7561c6-54af-4a71-8d7e-f31cee64fc19 853d7402-51b4-4cd4-9b8d-9f159311859d_member_ed7561c6-54af-4a71-8d7e-f31cee64fc19 1/1/0001 8:00:00 AM Provisioned member   853d7402-51b4-4cd4-9b8d-9f159311859d direct     d8800de8…

```
Yes! We have the same results as the 'manual' path already shown. 



## How do we activate PIM eligibility?

This is precisely why all the technology was created: temporarily activating a role or group membership.

Here is the .gif video of how a user can activate his/her PIM eligibility:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/htrv8rr7j0l5ib8zdjh6.gif)

This is how activation is performed via Microsoft Graph API. Here is a link to Graph API Documentation: [Create assignmentScheduleRequest](https://learn.microsoft.com/en-us/graph/api/privilegedaccessgroup-post-assignmentschedulerequests?view=graph-rest-1.0&tabs=powershell) and PowerShell Documentation [New-MgIdentityGovernancePrivilegedAccessGroupAssignmentScheduleRequest](https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.identity.governance/new-mgidentitygovernanceprivilegedaccessgroupassignmentschedulerequest?view=graph-powershell-1.0)

``` PowerShell
pwsh> $params = @{
	accessId = "member"
	principalId = "$($u01.Id)"
	groupId = "$($pg01.Id)"
	action = "adminAssign"
	scheduleInfo = @{
		startDateTime = $(Get-Date)
		expiration = @{
			type = "afterDuration"
			duration = "PT2H"
		}
	}
	justification = "Always wanted to try this group!"
}

pwsh> New-MgIdentityGovernancePrivilegedAccessGroupAssignmentScheduleRequest -BodyParameter $params

Action      ApprovalId CompletedDateTime    CreatedDateTime      CustomData Id                                   IsValidationOnly Justification                    Status      AccessId GroupId                              PrincipalId
------      ---------- -----------------    ---------------      ---------- --                                   ---------------- -------------                    ------      -------- -------                              -----------      
adminAssign            4/21/2024 2:25:19 AM 4/21/2024 2:25:18 AM            a24ebfc9-45ac-49bc-ad81-d0d7d3eb6d51 False            Always wanted to try this group! Provisioned member   853d7402-51b4-4cd4-9b8d-9f159311859d c8816325-d172-44…

```
Here it is! The membership in PIM-GROUP-PLAY-01 is activated!


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jq1ddiqapbv3whtewihp.png)

Perfect! The next question is...

## How do we remove PIM eligibility?

What if we need to revoke the ability to activate membership? Is it possible? 

Of course! Here is how one could do it 'manually':



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xnklfw2zun7g4n9nrbr8.gif)

In automation, Microsoft Graph API call [Create eligibilityScheduleRequest](https://learn.microsoft.com/en-us/graph/api/privilegedaccessgroup-post-eligibilityschedulerequests?view=graph-rest-1.0&tabs=powershell) or PowerShell function [New-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest](https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.identity.governance/new-mgidentitygovernanceprivilegedaccessgroupeligibilityschedulerequest?view=graph-powershell-1.0) will help you. 

And yes, I have not made a mistake. The same call and PowerShell function created the PIM eligibility! The difference in the parameters of the call.

``` PowerShell
pwsh>  $params = @{
	accessId = "member"
	principalId = "$($u01.Id)"
	groupId = "$($pg01.Id)"
	action = "adminRemove"
	justification = "It is time to go."
}

pwsh> New-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -BodyParameter $params

Action      ApprovalId CompletedDateTime CreatedDateTime      CustomData Id                                   IsValidationOnly Justification     Status  AccessId GroupId                              PrincipalId                          Target ScheduleId
------      ---------- ----------------- ---------------      ---------- --                                   ---------------- -------------     ------  -------- -------                              -----------                          --
adminRemove                              4/21/2024 2:41:21 AM            9f1bd851-83a9-4a29-b1f7-ff4e8e362b14 False            It is time to go. Revoked member   853d7402-51b4-4cd4-9b8d-9f159311859d c8816325-d172-44f5-b72d-a1b8de5673c2 
```


### The exciting bonus stuff!

About that... You know the post is already embarrassingly long. 

Let's meet again in '[How do you automate PIM for Groups? (Part 3. Expiration time, Policies, and experiments)](https://dev.to/rokicool/how-do-you-automate-pim-for-groups-part-3-expiration-time-policies-and-experiments-35d2)' post! 

:)

Meanwhile, I don't pretend to cover everything; I am sure there might be mistakes or typos. Please don't hesitate to comment!


All the '.gif videos' are made with [LICEcap](https://www.cockos.com/licecap/)