Review guest access to your Microsoft 365 groups using the access reviews API in Microsoft Graph
Article
07/06/2023
5 contributors
Feedback
In this article
The access reviews API in Microsoft Graph enables organizations to audit and attest to the access that identities (also called principals ) are assigned to resources in the organization. In cross-tenant collaboration, external users can have access resources such as files, notes, calendars, and even Teams conversations. This access can be efficiently managed through Microsoft 365 groups. Using the access reviews API, organizations can therefore periodically attest to principals that have access to such groups and by extension, other resources in the organization.
Let's assume that you've granted access to external users (also called guest users ) to resources in your organization through Microsoft 365 groups. This tutorial will guide you to review their access to the Microsoft 365 groups in your tenant.
Note
The response objects shown in this tutorial might be shortened for readability.
Prerequisites
To complete this tutorial, you need the following resources and privileges:
A working Microsoft Entra tenant with a Microsoft Entra ID P2 or EMS E5 license enabled.
An account in a different Microsoft Entra tenant or a social identity that you can invite as a guest user (B2B user).
Sign in to an API client such as Graph Explorer , Postman, or create your own client app to call Microsoft Graph. To call Microsoft Graph APIs in this tutorial, you need to use an account with the Global Administrator role.
Grant yourself the following delegated permissions: User.Invite.All
, AccessReview.ReadWrite.All
, Group.ReadWrite.All
, User.ReadWrite.All
.
Step 1: Create a test user in your tenant
Request
POST https://graph.microsoft.com/v1.0/users
Content-Type: application/json
{
"accountEnabled": true,
"displayName": "Aline Dupuy",
"mailNickname": "AlineD",
"userPrincipalName": "AlineD@contoso.com",
"passwordProfile": {
"forceChangePasswordNextSignIn": true,
"password": "xWwvJ]6NMw+bWH-d"
}
}
// Code snippets are only available for the latest version. Current version is 5.x
// Dependencies
using Microsoft.Graph.Models;
var requestBody = new User
{
AccountEnabled = true,
DisplayName = "Aline Dupuy",
MailNickname = "AlineD",
UserPrincipalName = "AlineD@contoso.com",
PasswordProfile = new PasswordProfile
{
ForceChangePasswordNextSignIn = true,
Password = "xWwvJ]6NMw+bWH-d",
},
};
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.Users.PostAsync(requestBody);
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
// THE CLI IS IN PREVIEW. NON-PRODUCTION USE ONLY
mgc users create --body '{\
"accountEnabled": true,\
"displayName": "Aline Dupuy",\
"mailNickname": "AlineD",\
"userPrincipalName": "AlineD@contoso.com",\
"passwordProfile": {\
"forceChangePasswordNextSignIn": true,\
"password": "xWwvJ]6NMw+bWH-d"\
}\
}\
'
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
graphmodels "github.com/microsoftgraph/msgraph-sdk-go/models"
//other-imports
)
graphClient := msgraphsdk.NewGraphServiceClientWithCredentials(cred, scopes)
requestBody := graphmodels.NewUser()
accountEnabled := true
requestBody.SetAccountEnabled(&accountEnabled)
displayName := "Aline Dupuy"
requestBody.SetDisplayName(&displayName)
mailNickname := "AlineD"
requestBody.SetMailNickname(&mailNickname)
userPrincipalName := "AlineD@contoso.com"
requestBody.SetUserPrincipalName(&userPrincipalName)
passwordProfile := graphmodels.NewPasswordProfile()
forceChangePasswordNextSignIn := true
passwordProfile.SetForceChangePasswordNextSignIn(&forceChangePasswordNextSignIn)
password := "xWwvJ]6NMw+bWH-d"
passwordProfile.SetPassword(&password)
requestBody.SetPasswordProfile(passwordProfile)
users, err := graphClient.Users().Post(context.Background(), requestBody, nil)
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
GraphServiceClient graphClient = GraphServiceClient.builder().authenticationProvider( authProvider ).buildClient();
User user = new User();
user.accountEnabled = true;
user.displayName = "Aline Dupuy";
user.mailNickname = "AlineD";
user.userPrincipalName = "AlineD@contoso.com";
PasswordProfile passwordProfile = new PasswordProfile();
passwordProfile.forceChangePasswordNextSignIn = true;
passwordProfile.password = "xWwvJ]6NMw+bWH-d";
user.passwordProfile = passwordProfile;
graphClient.users()
.buildRequest()
.post(user);
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
const options = {
authProvider,
};
const client = Client.init(options);
const user = {
accountEnabled: true,
displayName: 'Aline Dupuy',
mailNickname: 'AlineD',
userPrincipalName: 'AlineD@contoso.com',
passwordProfile: {
forceChangePasswordNextSignIn: true,
password: 'xWwvJ]6NMw+bWH-d'
}
};
await client.api('/users')
.post(user);
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
<?php
// THIS SNIPPET IS A PREVIEW VERSION OF THE SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$requestBody = new User();
$requestBody->setAccountEnabled(true);
$requestBody->setDisplayName('Aline Dupuy');
$requestBody->setMailNickname('AlineD');
$requestBody->setUserPrincipalName('AlineD@contoso.com');
$passwordProfile = new PasswordProfile();
$passwordProfile->setForceChangePasswordNextSignIn(true);
$passwordProfile->setPassword('xWwvJ]6NMw+bWH-d');
$requestBody->setPasswordProfile($passwordProfile);
$result = $graphServiceClient->users()->post($requestBody)->wait();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
Import-Module Microsoft.Graph.Users
$params = @{
accountEnabled = $true
displayName = "Aline Dupuy"
mailNickname = "AlineD"
userPrincipalName = "AlineD@contoso.com"
passwordProfile = @{
forceChangePasswordNextSignIn = $true
password = "xWwvJ]6NMw+bWH-d"
}
}
New-MgUser -BodyParameter $params
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
# THE PYTHON SDK IS IN PREVIEW. FOR NON-PRODUCTION USE ONLY
graph_client = GraphServiceClient(credentials, scopes)
request_body = User(
account_enabled = True,
display_name = "Aline Dupuy",
mail_nickname = "AlineD",
user_principal_name = "AlineD@contoso.com",
password_profile = PasswordProfile(
force_change_password_next_sign_in = True,
password = "xWwvJ]6NMw+bWH-d",
),
)
result = await graph_client.users.post(request_body)
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
Response
HTTP/1.1 201 Created
Content-type: application/json
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users/$entity",
"id": "c9a5aff7-9298-4d71-adab-0a222e0a05e4",
"displayName": "Aline Dupuy",
"userPrincipalName": "AlineD@contoso.com",
"userType": "Member"
}
Step 2: Invite a guest user into your tenant
Invite a guest user with the email address john@tailspintoys.com to your tenant.
Request
POST https://graph.microsoft.com/v1.0/invitations
Content-Type: application/json
{
"invitedUserDisplayName": "John Doe (Tailspin Toys)",
"invitedUserEmailAddress": "john@tailspintoys.com",
"sendInvitationMessage": false,
"inviteRedirectUrl": "https://myapps.microsoft.com"
}
// Code snippets are only available for the latest version. Current version is 5.x
// Dependencies
using Microsoft.Graph.Models;
var requestBody = new Invitation
{
InvitedUserDisplayName = "John Doe (Tailspin Toys)",
InvitedUserEmailAddress = "john@tailspintoys.com",
SendInvitationMessage = false,
InviteRedirectUrl = "https://myapps.microsoft.com",
};
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.Invitations.PostAsync(requestBody);
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
// THE CLI IS IN PREVIEW. NON-PRODUCTION USE ONLY
mgc invitations create --body '{\
"invitedUserDisplayName": "John Doe (Tailspin Toys)",\
"invitedUserEmailAddress": "john@tailspintoys.com",\
"sendInvitationMessage": false,\
"inviteRedirectUrl": "https://myapps.microsoft.com"\
}\
'
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
graphmodels "github.com/microsoftgraph/msgraph-sdk-go/models"
//other-imports
)
graphClient := msgraphsdk.NewGraphServiceClientWithCredentials(cred, scopes)
requestBody := graphmodels.NewInvitation()
invitedUserDisplayName := "John Doe (Tailspin Toys)"
requestBody.SetInvitedUserDisplayName(&invitedUserDisplayName)
invitedUserEmailAddress := "john@tailspintoys.com"
requestBody.SetInvitedUserEmailAddress(&invitedUserEmailAddress)
sendInvitationMessage := false
requestBody.SetSendInvitationMessage(&sendInvitationMessage)
inviteRedirectUrl := "https://myapps.microsoft.com"
requestBody.SetInviteRedirectUrl(&inviteRedirectUrl)
invitations, err := graphClient.Invitations().Post(context.Background(), requestBody, nil)
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
GraphServiceClient graphClient = GraphServiceClient.builder().authenticationProvider( authProvider ).buildClient();
Invitation invitation = new Invitation();
invitation.invitedUserDisplayName = "John Doe (Tailspin Toys)";
invitation.invitedUserEmailAddress = "john@tailspintoys.com";
invitation.sendInvitationMessage = false;
invitation.inviteRedirectUrl = "https://myapps.microsoft.com";
graphClient.invitations()
.buildRequest()
.post(invitation);
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
const options = {
authProvider,
};
const client = Client.init(options);
const invitation = {
invitedUserDisplayName: 'John Doe (Tailspin Toys)',
invitedUserEmailAddress: 'john@tailspintoys.com',
sendInvitationMessage: false,
inviteRedirectUrl: 'https://myapps.microsoft.com'
};
await client.api('/invitations')
.post(invitation);
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
<?php
// THIS SNIPPET IS A PREVIEW VERSION OF THE SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$requestBody = new Invitation();
$requestBody->setInvitedUserDisplayName('John Doe (Tailspin Toys)');
$requestBody->setInvitedUserEmailAddress('john@tailspintoys.com');
$requestBody->setSendInvitationMessage(false);
$requestBody->setInviteRedirectUrl('https://myapps.microsoft.com');
$result = $graphServiceClient->invitations()->post($requestBody)->wait();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
Import-Module Microsoft.Graph.Identity.SignIns
$params = @{
invitedUserDisplayName = "John Doe (Tailspin Toys)"
invitedUserEmailAddress = "john@tailspintoys.com"
sendInvitationMessage = $false
inviteRedirectUrl = "https://myapps.microsoft.com"
}
New-MgInvitation -BodyParameter $params
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
# THE PYTHON SDK IS IN PREVIEW. FOR NON-PRODUCTION USE ONLY
graph_client = GraphServiceClient(credentials, scopes)
request_body = Invitation(
invited_user_display_name = "John Doe (Tailspin Toys)",
invited_user_email_address = "john@tailspintoys.com",
send_invitation_message = False,
invite_redirect_url = "https://myapps.microsoft.com",
)
result = await graph_client.invitations.post(request_body)
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
Response
HTTP/1.1 201 Created
Content-type: application/json
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#invitations/$entity",
"invitedUser": {
"id": "baf1b0a0-1f9a-4a56-9884-6a30824f8d20"
}
}
Step 3: Create a new Microsoft 365 group and add the guest user
In this step:
Create a new Microsoft 365 group named Feel good marketing campaign .
Assign yourself as the group owner.
Add john@tailspintoys.com as a group member. Their access to the group is the subject of review by you, the group owner.
Request
In this call, replace:
cdb555e3-b33e-4fd5-a427-17fadacbdfa7
with your ID. To retrieve your ID, run GET
on https://graph.microsoft.com/v1.0/me
.
baf1b0a0-1f9a-4a56-9884-6a30824f8d20
with john@tailspintoys.com 's ID from the response in Step 2.
POST https://graph.microsoft.com/v1.0/groups
Content-Type: application/json
{
"description": "Feelgood Marketing Campaign with external partners and vendors.",
"displayName": "Feelgood Marketing Campaign",
"groupTypes": [
"Unified"
],
"mailEnabled": true,
"mailNickname": "FeelGoodCampaign",
"securityEnabled": true,
"owners@odata.bind": [
"https://graph.microsoft.com/v1.0/users/cdb555e3-b33e-4fd5-a427-17fadacbdfa7"
],
"members@odata.bind": [
"https://graph.microsoft.com/v1.0/users/baf1b0a0-1f9a-4a56-9884-6a30824f8d20"
]
}
// Code snippets are only available for the latest version. Current version is 5.x
// Dependencies
using Microsoft.Graph.Models;
var requestBody = new Group
{
Description = "Feelgood Marketing Campaign with external partners and vendors.",
DisplayName = "Feelgood Marketing Campaign",
GroupTypes = new List<string>
{
"Unified",
},
MailEnabled = true,
MailNickname = "FeelGoodCampaign",
SecurityEnabled = true,
AdditionalData = new Dictionary<string, object>
{
{
"owners@odata.bind" , new List<string>
{
"https://graph.microsoft.com/v1.0/users/cdb555e3-b33e-4fd5-a427-17fadacbdfa7",
}
},
{
"members@odata.bind" , new List<string>
{
"https://graph.microsoft.com/v1.0/users/baf1b0a0-1f9a-4a56-9884-6a30824f8d20",
}
},
},
};
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.Groups.PostAsync(requestBody);
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
// THE CLI IS IN PREVIEW. NON-PRODUCTION USE ONLY
mgc groups create --body '{\
"description": "Feelgood Marketing Campaign with external partners and vendors.",\
"displayName": "Feelgood Marketing Campaign",\
"groupTypes": [\
"Unified"\
],\
"mailEnabled": true,\
"mailNickname": "FeelGoodCampaign",\
"securityEnabled": true,\
"owners@odata.bind": [\
"https://graph.microsoft.com/v1.0/users/cdb555e3-b33e-4fd5-a427-17fadacbdfa7"\
],\
"members@odata.bind": [\
"https://graph.microsoft.com/v1.0/users/baf1b0a0-1f9a-4a56-9884-6a30824f8d20"\
]\
}\
'
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
graphmodels "github.com/microsoftgraph/msgraph-sdk-go/models"
//other-imports
)
graphClient := msgraphsdk.NewGraphServiceClientWithCredentials(cred, scopes)
requestBody := graphmodels.NewGroup()
description := "Feelgood Marketing Campaign with external partners and vendors."
requestBody.SetDescription(&description)
displayName := "Feelgood Marketing Campaign"
requestBody.SetDisplayName(&displayName)
groupTypes := []string {
"Unified",
}
requestBody.SetGroupTypes(groupTypes)
mailEnabled := true
requestBody.SetMailEnabled(&mailEnabled)
mailNickname := "FeelGoodCampaign"
requestBody.SetMailNickname(&mailNickname)
securityEnabled := true
requestBody.SetSecurityEnabled(&securityEnabled)
additionalData := map[string]interface{}{
odataBind := []string {
"https://graph.microsoft.com/v1.0/users/cdb555e3-b33e-4fd5-a427-17fadacbdfa7",
}
odataBind := []string {
"https://graph.microsoft.com/v1.0/users/baf1b0a0-1f9a-4a56-9884-6a30824f8d20",
}
}
requestBody.SetAdditionalData(additionalData)
groups, err := graphClient.Groups().Post(context.Background(), requestBody, nil)
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
GraphServiceClient graphClient = GraphServiceClient.builder().authenticationProvider( authProvider ).buildClient();
Group group = new Group();
group.description = "Feelgood Marketing Campaign with external partners and vendors.";
group.displayName = "Feelgood Marketing Campaign";
LinkedList<String> groupTypesList = new LinkedList<String>();
groupTypesList.add("Unified");
group.groupTypes = groupTypesList;
group.mailEnabled = true;
group.mailNickname = "FeelGoodCampaign";
group.securityEnabled = true;
group.additionalDataManager().put("owners@odata.bind", new JsonPrimitive("[ \"https://graph.microsoft.com/v1.0/users/cdb555e3-b33e-4fd5-a427-17fadacbdfa7\"]"));
group.additionalDataManager().put("members@odata.bind", new JsonPrimitive("[ \"https://graph.microsoft.com/v1.0/users/baf1b0a0-1f9a-4a56-9884-6a30824f8d20\"]"));
graphClient.groups()
.buildRequest()
.post(group);
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
const options = {
authProvider,
};
const client = Client.init(options);
const group = {
description: 'Feelgood Marketing Campaign with external partners and vendors.',
displayName: 'Feelgood Marketing Campaign',
groupTypes: [
'Unified'
],
mailEnabled: true,
mailNickname: 'FeelGoodCampaign',
securityEnabled: true,
'owners@odata.bind': [
'https://graph.microsoft.com/v1.0/users/cdb555e3-b33e-4fd5-a427-17fadacbdfa7'
],
'members@odata.bind': [
'https://graph.microsoft.com/v1.0/users/baf1b0a0-1f9a-4a56-9884-6a30824f8d20'
]
};
await client.api('/groups')
.post(group);
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
<?php
// THIS SNIPPET IS A PREVIEW VERSION OF THE SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$requestBody = new Group();
$requestBody->setDescription('Feelgood Marketing Campaign with external partners and vendors.');
$requestBody->setDisplayName('Feelgood Marketing Campaign');
$requestBody->setGroupTypes(['Unified', ]);
$requestBody->setMailEnabled(true);
$requestBody->setMailNickname('FeelGoodCampaign');
$requestBody->setSecurityEnabled(true);
$additionalData = [
'owners@odata.bind' => [
'https://graph.microsoft.com/v1.0/users/cdb555e3-b33e-4fd5-a427-17fadacbdfa7', ],
'members@odata.bind' => [
'https://graph.microsoft.com/v1.0/users/baf1b0a0-1f9a-4a56-9884-6a30824f8d20', ],
];
$requestBody->setAdditionalData($additionalData);
$result = $graphServiceClient->groups()->post($requestBody)->wait();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
Import-Module Microsoft.Graph.Groups
$params = @{
description = "Feelgood Marketing Campaign with external partners and vendors."
displayName = "Feelgood Marketing Campaign"
groupTypes = @(
"Unified"
)
mailEnabled = $true
mailNickname = "FeelGoodCampaign"
securityEnabled = $true
"owners@odata.bind" = @(
"https://graph.microsoft.com/v1.0/users/cdb555e3-b33e-4fd5-a427-17fadacbdfa7"
)
"members@odata.bind" = @(
"https://graph.microsoft.com/v1.0/users/baf1b0a0-1f9a-4a56-9884-6a30824f8d20"
)
}
New-MgGroup -BodyParameter $params
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
# THE PYTHON SDK IS IN PREVIEW. FOR NON-PRODUCTION USE ONLY
graph_client = GraphServiceClient(credentials, scopes)
request_body = Group(
description = "Feelgood Marketing Campaign with external partners and vendors.",
display_name = "Feelgood Marketing Campaign",
group_types = [
"Unified",
],
mail_enabled = True,
mail_nickname = "FeelGoodCampaign",
security_enabled = True,
additional_data = {
"owners@odata_bind" : [
"https://graph.microsoft.com/v1.0/users/cdb555e3-b33e-4fd5-a427-17fadacbdfa7",
],
"members@odata_bind" : [
"https://graph.microsoft.com/v1.0/users/baf1b0a0-1f9a-4a56-9884-6a30824f8d20",
],
}
)
result = await graph_client.groups.post(request_body)
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
Response
HTTP/1.1 201 Created
Content-type: application/json
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#groups/$entity",
"id": "59ab642a-2776-4e32-9b68-9ff7a47b7f6a",
"displayName": "Feelgood Marketing Campaign",
"groupTypes": [
"Unified"
]
}
You now have a Microsoft 365 group with a guest user.
Step 4: Create an access review for all Microsoft 365 groups with guest users
When you create a recurring access review series for all Microsoft 365 groups with guest users, you schedule a periodic review of the guests' access to the Microsoft 365 group. In this case, the Feel good Marketing Campaign group.
The access review series uses following settings:
It's a recurring access review and reviewed quarterly.
The group owners decide whether guest users should maintain their access.
The review scope is limited to only Microsoft 365 groups with guest users .
A backup reviewer. They can be a fallback user or a group that can review the access in case the group doesn't have any owners assigned.
autoApplyDecisionsEnabled is set to true
. In this case, decisions are applied automatically once the reviewer completes the access review or the access review duration ends. If not enabled, a user must apply the decisions manually after the review completes.
Apply the removeAccessApplyAction action to denied guest users to remove them from the group. The guest user can still sign in to your tenant, but won't access the group.
Request
In this call, replace the following values:
c9a5aff7-9298-4d71-adab-0a222e0a05e4
with the ID of Aline who you're designating as a backup reviewer.
Value of startDate with today's date and value of endDate with a date one year from the start date.
POST https://graph.microsoft.com/v1.0/identityGovernance/accessReviews/definitions
Content-type: application/json
{
"displayName": "Group owners review guest across Microsoft 365 groups in the tenant (Quarterly)",
"descriptionForAdmins": "",
"descriptionForReviewers": "",
"scope": {
"query": "./members/microsoft.graph.user/?$count=true&$filter=(userType eq 'Guest')",
"queryType": "MicrosoftGraph"
},
"instanceEnumerationScope": {
"query": "/groups?$filter=(groupTypes/any(c:c+eq+'Unified'))&$count=true",
"queryType": "MicrosoftGraph"
},
"reviewers": [
{
"query": "./owners",
"queryType": "MicrosoftGraph",
"queryRoot": null
}
],
"fallbackReviewers": [
{
"query": "/users/c9a5aff7-9298-4d71-adab-0a222e0a05e4",
"queryType": "MicrosoftGraph",
"queryRoot": null
}
],
"settings": {
"mailNotificationsEnabled": true,
"reminderNotificationsEnabled": true,
"justificationRequiredOnApproval": true,
"defaultDecisionEnabled": true,
"defaultDecision": "Approve",
"instanceDurationInDays": 0,
"autoApplyDecisionsEnabled": true,
"recommendationsEnabled": true,
"recurrence": {
"pattern": {
"type": "absoluteMonthly",
"interval": 3,
"month": 0,
"dayOfMonth": 0,
"daysOfWeek": [],
"firstDayOfWeek": "sunday",
"index": "first"
},
"range": {
"type": "numbered",
"numberOfOccurrences": 0,
"recurrenceTimeZone": null,
"startDate": "2021-02-10",
"endDate": "2022-12-21"
}
},
"applyActions": [
{
"@odata.type": "#microsoft.graph.removeAccessApplyAction"
}
]
}
}
// Code snippets are only available for the latest version. Current version is 5.x
// Dependencies
using Microsoft.Graph.Models;
var requestBody = new AccessReviewScheduleDefinition
{
DisplayName = "Group owners review guest across Microsoft 365 groups in the tenant (Quarterly)",
DescriptionForAdmins = "",
DescriptionForReviewers = "",
Scope = new AccessReviewScope
{
AdditionalData = new Dictionary<string, object>
{
{
"query" , "./members/microsoft.graph.user/?$count=true&$filter=(userType eq 'Guest')"
},
{
"queryType" , "MicrosoftGraph"
},
},
},
InstanceEnumerationScope = new AccessReviewScope
{
AdditionalData = new Dictionary<string, object>
{
{
"query" , "/groups?$filter=(groupTypes/any(c:c+eq+'Unified'))&$count=true"
},
{
"queryType" , "MicrosoftGraph"
},
},
},
Reviewers = new List<AccessReviewReviewerScope>
{
new AccessReviewReviewerScope
{
Query = "./owners",
QueryType = "MicrosoftGraph",
QueryRoot = null,
},
},
FallbackReviewers = new List<AccessReviewReviewerScope>
{
new AccessReviewReviewerScope
{
Query = "/users/c9a5aff7-9298-4d71-adab-0a222e0a05e4",
QueryType = "MicrosoftGraph",
QueryRoot = null,
},
},
Settings = new AccessReviewScheduleSettings
{
MailNotificationsEnabled = true,
ReminderNotificationsEnabled = true,
JustificationRequiredOnApproval = true,
DefaultDecisionEnabled = true,
DefaultDecision = "Approve",
InstanceDurationInDays = 0,
AutoApplyDecisionsEnabled = true,
RecommendationsEnabled = true,
Recurrence = new PatternedRecurrence
{
Pattern = new RecurrencePattern
{
Type = RecurrencePatternType.AbsoluteMonthly,
Interval = 3,
Month = 0,
DayOfMonth = 0,
DaysOfWeek = new List<DayOfWeekObject>
{
},
FirstDayOfWeek = DayOfWeekObject.Sunday,
Index = WeekIndex.First,
},
Range = new RecurrenceRange
{
Type = RecurrenceRangeType.Numbered,
NumberOfOccurrences = 0,
RecurrenceTimeZone = null,
StartDate = new Date(DateTime.Parse("2021-02-10")),
EndDate = new Date(DateTime.Parse("2022-12-21")),
},
},
ApplyActions = new List<AccessReviewApplyAction>
{
new RemoveAccessApplyAction
{
OdataType = "#microsoft.graph.removeAccessApplyAction",
},
},
},
};
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.IdentityGovernance.AccessReviews.Definitions.PostAsync(requestBody);
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
// THE CLI IS IN PREVIEW. NON-PRODUCTION USE ONLY
mgc identity-governance access-reviews definitions create --body '{\
"displayName": "Group owners review guest across Microsoft 365 groups in the tenant (Quarterly)",\
"descriptionForAdmins": "",\
"descriptionForReviewers": "",\
"scope": {\
"query": "./members/microsoft.graph.user/?$count=true&$filter=(userType eq 'Guest')",\
"queryType": "MicrosoftGraph"\
},\
"instanceEnumerationScope": {\
"query": "/groups?$filter=(groupTypes/any(c:c+eq+'Unified'))&$count=true",\
"queryType": "MicrosoftGraph"\
},\
"reviewers": [\
{\
"query": "./owners",\
"queryType": "MicrosoftGraph",\
"queryRoot": null\
}\
],\
"fallbackReviewers": [\
{\
"query": "/users/c9a5aff7-9298-4d71-adab-0a222e0a05e4",\
"queryType": "MicrosoftGraph",\
"queryRoot": null\
}\
],\
"settings": {\
"mailNotificationsEnabled": true,\
"reminderNotificationsEnabled": true,\
"justificationRequiredOnApproval": true,\
"defaultDecisionEnabled": true,\
"defaultDecision": "Approve",\
"instanceDurationInDays": 0,\
"autoApplyDecisionsEnabled": true,\
"recommendationsEnabled": true,\
"recurrence": {\
"pattern": {\
"type": "absoluteMonthly",\
"interval": 3,\
"month": 0,\
"dayOfMonth": 0,\
"daysOfWeek": [],\
"firstDayOfWeek": "sunday",\
"index": "first"\
},\
"range": {\
"type": "numbered",\
"numberOfOccurrences": 0,\
"recurrenceTimeZone": null,\
"startDate": "2021-02-10",\
"endDate": "2022-12-21"\
}\
},\
"applyActions": [\
{\
"@odata.type": "#microsoft.graph.removeAccessApplyAction"\
}\
]\
}\
}\
'
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
graphmodels "github.com/microsoftgraph/msgraph-sdk-go/models"
//other-imports
)
graphClient := msgraphsdk.NewGraphServiceClientWithCredentials(cred, scopes)
requestBody := graphmodels.NewAccessReviewScheduleDefinition()
displayName := "Group owners review guest across Microsoft 365 groups in the tenant (Quarterly)"
requestBody.SetDisplayName(&displayName)
descriptionForAdmins := ""
requestBody.SetDescriptionForAdmins(&descriptionForAdmins)
descriptionForReviewers := ""
requestBody.SetDescriptionForReviewers(&descriptionForReviewers)
scope := graphmodels.NewAccessReviewScope()
additionalData := map[string]interface{}{
"query" : "./members/microsoft.graph.user/?$count=true&$filter=(userType eq 'Guest')",
"queryType" : "MicrosoftGraph",
}
scope.SetAdditionalData(additionalData)
requestBody.SetScope(scope)
instanceEnumerationScope := graphmodels.NewAccessReviewScope()
additionalData := map[string]interface{}{
"query" : "/groups?$filter=(groupTypes/any(c:c+eq+'Unified'))&$count=true",
"queryType" : "MicrosoftGraph",
}
instanceEnumerationScope.SetAdditionalData(additionalData)
requestBody.SetInstanceEnumerationScope(instanceEnumerationScope)
accessReviewReviewerScope := graphmodels.NewAccessReviewReviewerScope()
query := "./owners"
accessReviewReviewerScope.SetQuery(&query)
queryType := "MicrosoftGraph"
accessReviewReviewerScope.SetQueryType(&queryType)
queryRoot := null
accessReviewReviewerScope.SetQueryRoot(&queryRoot)
reviewers := []graphmodels.AccessReviewReviewerScopeable {
accessReviewReviewerScope,
}
requestBody.SetReviewers(reviewers)
accessReviewReviewerScope := graphmodels.NewAccessReviewReviewerScope()
query := "/users/c9a5aff7-9298-4d71-adab-0a222e0a05e4"
accessReviewReviewerScope.SetQuery(&query)
queryType := "MicrosoftGraph"
accessReviewReviewerScope.SetQueryType(&queryType)
queryRoot := null
accessReviewReviewerScope.SetQueryRoot(&queryRoot)
fallbackReviewers := []graphmodels.AccessReviewReviewerScopeable {
accessReviewReviewerScope,
}
requestBody.SetFallbackReviewers(fallbackReviewers)
settings := graphmodels.NewAccessReviewScheduleSettings()
mailNotificationsEnabled := true
settings.SetMailNotificationsEnabled(&mailNotificationsEnabled)
reminderNotificationsEnabled := true
settings.SetReminderNotificationsEnabled(&reminderNotificationsEnabled)
justificationRequiredOnApproval := true
settings.SetJustificationRequiredOnApproval(&justificationRequiredOnApproval)
defaultDecisionEnabled := true
settings.SetDefaultDecisionEnabled(&defaultDecisionEnabled)
defaultDecision := "Approve"
settings.SetDefaultDecision(&defaultDecision)
instanceDurationInDays := int32(0)
settings.SetInstanceDurationInDays(&instanceDurationInDays)
autoApplyDecisionsEnabled := true
settings.SetAutoApplyDecisionsEnabled(&autoApplyDecisionsEnabled)
recommendationsEnabled := true
settings.SetRecommendationsEnabled(&recommendationsEnabled)
recurrence := graphmodels.NewPatternedRecurrence()
pattern := graphmodels.NewRecurrencePattern()
type := graphmodels.ABSOLUTEMONTHLY_RECURRENCEPATTERNTYPE
pattern.SetType(&type)
interval := int32(3)
pattern.SetInterval(&interval)
month := int32(0)
pattern.SetMonth(&month)
dayOfMonth := int32(0)
pattern.SetDayOfMonth(&dayOfMonth)
daysOfWeek := []graphmodels.DayOfWeekable {
}
pattern.SetDaysOfWeek(daysOfWeek)
firstDayOfWeek := graphmodels.SUNDAY_DAYOFWEEK
pattern.SetFirstDayOfWeek(&firstDayOfWeek)
index := graphmodels.FIRST_WEEKINDEX
pattern.SetIndex(&index)
recurrence.SetPattern(pattern)
range := graphmodels.NewRecurrenceRange()
type := graphmodels.NUMBERED_RECURRENCERANGETYPE
range.SetType(&type)
numberOfOccurrences := int32(0)
range.SetNumberOfOccurrences(&numberOfOccurrences)
recurrenceTimeZone := null
range.SetRecurrenceTimeZone(&recurrenceTimeZone)
startDate := 2021-02-10
range.SetStartDate(&startDate)
endDate := 2022-12-21
range.SetEndDate(&endDate)
recurrence.SetRange(range)
settings.SetRecurrence(recurrence)
accessReviewApplyAction := graphmodels.NewRemoveAccessApplyAction()
applyActions := []graphmodels.AccessReviewApplyActionable {
accessReviewApplyAction,
}
settings.SetApplyActions(applyActions)
requestBody.SetSettings(settings)
definitions, err := graphClient.IdentityGovernance().AccessReviews().Definitions().Post(context.Background(), requestBody, nil)
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
GraphServiceClient graphClient = GraphServiceClient.builder().authenticationProvider( authProvider ).buildClient();
AccessReviewScheduleDefinition accessReviewScheduleDefinition = new AccessReviewScheduleDefinition();
accessReviewScheduleDefinition.displayName = "Group owners review guest across Microsoft 365 groups in the tenant (Quarterly)";
accessReviewScheduleDefinition.descriptionForAdmins = "";
accessReviewScheduleDefinition.descriptionForReviewers = "";
AccessReviewScope scope = new AccessReviewScope();
scope.query = "./members/microsoft.graph.user/?$count=true&$filter=(userType eq 'Guest')";
scope.queryType = "MicrosoftGraph";
accessReviewScheduleDefinition.scope = scope;
AccessReviewScope instanceEnumerationScope = new AccessReviewScope();
instanceEnumerationScope.query = "/groups?$filter=(groupTypes/any(c:c+eq+'Unified'))&$count=true";
instanceEnumerationScope.queryType = "MicrosoftGraph";
accessReviewScheduleDefinition.instanceEnumerationScope = instanceEnumerationScope;
LinkedList<AccessReviewReviewerScope> reviewersList = new LinkedList<AccessReviewReviewerScope>();
AccessReviewReviewerScope reviewers = new AccessReviewReviewerScope();
reviewers.query = "./owners";
reviewers.queryType = "MicrosoftGraph";
reviewers.queryRoot = null;
reviewersList.add(reviewers);
accessReviewScheduleDefinition.reviewers = reviewersList;
LinkedList<AccessReviewReviewerScope> fallbackReviewersList = new LinkedList<AccessReviewReviewerScope>();
AccessReviewReviewerScope fallbackReviewers = new AccessReviewReviewerScope();
fallbackReviewers.query = "/users/c9a5aff7-9298-4d71-adab-0a222e0a05e4";
fallbackReviewers.queryType = "MicrosoftGraph";
fallbackReviewers.queryRoot = null;
fallbackReviewersList.add(fallbackReviewers);
accessReviewScheduleDefinition.fallbackReviewers = fallbackReviewersList;
AccessReviewScheduleSettings settings = new AccessReviewScheduleSettings();
settings.mailNotificationsEnabled = true;
settings.reminderNotificationsEnabled = true;
settings.justificationRequiredOnApproval = true;
settings.defaultDecisionEnabled = true;
settings.defaultDecision = "Approve";
settings.instanceDurationInDays = 0;
settings.autoApplyDecisionsEnabled = true;
settings.recommendationsEnabled = true;
PatternedRecurrence recurrence = new PatternedRecurrence();
RecurrencePattern pattern = new RecurrencePattern();
pattern.type = RecurrencePatternType.ABSOLUTE_MONTHLY;
pattern.interval = 3;
pattern.month = 0;
pattern.dayOfMonth = 0;
LinkedList<DayOfWeek> daysOfWeekList = new LinkedList<DayOfWeek>();
pattern.daysOfWeek = daysOfWeekList;
pattern.firstDayOfWeek = DayOfWeek.SUNDAY;
pattern.index = WeekIndex.FIRST;
recurrence.pattern = pattern;
RecurrenceRange range = new RecurrenceRange();
range.type = RecurrenceRangeType.NUMBERED;
range.numberOfOccurrences = 0;
range.recurrenceTimeZone = null;
range.startDate = new DateOnly(1900,1,1);
range.endDate = new DateOnly(1900,1,1);
recurrence.range = range;
settings.recurrence = recurrence;
LinkedList<AccessReviewApplyAction> applyActionsList = new LinkedList<AccessReviewApplyAction>();
RemoveAccessApplyAction applyActions = new RemoveAccessApplyAction();
applyActionsList.add(applyActions);
settings.applyActions = applyActionsList;
accessReviewScheduleDefinition.settings = settings;
graphClient.identityGovernance().accessReviews().definitions()
.buildRequest()
.post(accessReviewScheduleDefinition);
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
const options = {
authProvider,
};
const client = Client.init(options);
const accessReviewScheduleDefinition = {
displayName: 'Group owners review guest across Microsoft 365 groups in the tenant (Quarterly)',
descriptionForAdmins: '',
descriptionForReviewers: '',
scope: {
query: './members/microsoft.graph.user/?$count=true&$filter=(userType eq \'Guest\')',
queryType: 'MicrosoftGraph'
},
instanceEnumerationScope: {
query: '/groups?$filter=(groupTypes/any(c:c+eq+\'Unified\'))&$count=true',
queryType: 'MicrosoftGraph'
},
reviewers: [
{
query: './owners',
queryType: 'MicrosoftGraph',
queryRoot: null
}
],
fallbackReviewers: [
{
query: '/users/c9a5aff7-9298-4d71-adab-0a222e0a05e4',
queryType: 'MicrosoftGraph',
queryRoot: null
}
],
settings: {
mailNotificationsEnabled: true,
reminderNotificationsEnabled: true,
justificationRequiredOnApproval: true,
defaultDecisionEnabled: true,
defaultDecision: 'Approve',
instanceDurationInDays: 0,
autoApplyDecisionsEnabled: true,
recommendationsEnabled: true,
recurrence: {
pattern: {
type: 'absoluteMonthly',
interval: 3,
month: 0,
dayOfMonth: 0,
daysOfWeek: [],
firstDayOfWeek: 'sunday',
index: 'first'
},
range: {
type: 'numbered',
numberOfOccurrences: 0,
recurrenceTimeZone: null,
startDate: '2021-02-10',
endDate: '2022-12-21'
}
},
applyActions: [
{
'@odata.type': '#microsoft.graph.removeAccessApplyAction'
}
]
}
};
await client.api('/identityGovernance/accessReviews/definitions')
.post(accessReviewScheduleDefinition);
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
<?php
// THIS SNIPPET IS A PREVIEW VERSION OF THE SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$requestBody = new AccessReviewScheduleDefinition();
$requestBody->setDisplayName('Group owners review guest across Microsoft 365 groups in the tenant (Quarterly)');
$requestBody->setDescriptionForAdmins('');
$requestBody->setDescriptionForReviewers('');
$scope = new AccessReviewScope();
$additionalData = [
'query' => './members/microsoft.graph.user/?$count=true&$filter=(userType eq \'Guest\')',
'queryType' => 'MicrosoftGraph',
];
$scope->setAdditionalData($additionalData);
$requestBody->setScope($scope);
$instanceEnumerationScope = new AccessReviewScope();
$additionalData = [
'query' => '/groups?$filter=(groupTypes/any(c:c+eq+\'Unified\'))&$count=true',
'queryType' => 'MicrosoftGraph',
];
$instanceEnumerationScope->setAdditionalData($additionalData);
$requestBody->setInstanceEnumerationScope($instanceEnumerationScope);
$reviewersAccessReviewReviewerScope1 = new AccessReviewReviewerScope();
$reviewersAccessReviewReviewerScope1->setQuery('./owners');
$reviewersAccessReviewReviewerScope1->setQueryType('MicrosoftGraph');
$reviewersAccessReviewReviewerScope1->setQueryRoot(null);
$reviewersArray []= $reviewersAccessReviewReviewerScope1;
$requestBody->setReviewers($reviewersArray);
$fallbackReviewersAccessReviewReviewerScope1 = new AccessReviewReviewerScope();
$fallbackReviewersAccessReviewReviewerScope1->setQuery('/users/c9a5aff7-9298-4d71-adab-0a222e0a05e4');
$fallbackReviewersAccessReviewReviewerScope1->setQueryType('MicrosoftGraph');
$fallbackReviewersAccessReviewReviewerScope1->setQueryRoot(null);
$fallbackReviewersArray []= $fallbackReviewersAccessReviewReviewerScope1;
$requestBody->setFallbackReviewers($fallbackReviewersArray);
$settings = new AccessReviewScheduleSettings();
$settings->setMailNotificationsEnabled(true);
$settings->setReminderNotificationsEnabled(true);
$settings->setJustificationRequiredOnApproval(true);
$settings->setDefaultDecisionEnabled(true);
$settings->setDefaultDecision('Approve');
$settings->setInstanceDurationInDays(0);
$settings->setAutoApplyDecisionsEnabled(true);
$settings->setRecommendationsEnabled(true);
$settingsRecurrence = new PatternedRecurrence();
$settingsRecurrencePattern = new RecurrencePattern();
$settingsRecurrencePattern->setType(new RecurrencePatternType('absoluteMonthly'));
$settingsRecurrencePattern->setInterval(3);
$settingsRecurrencePattern->setMonth(0);
$settingsRecurrencePattern->setDayOfMonth(0);
$settingsRecurrencePattern->setDaysOfWeek([]);
$settingsRecurrencePattern->setFirstDayOfWeek(new DayOfWeek('sunday'));
$settingsRecurrencePattern->setIndex(new WeekIndex('first'));
$settingsRecurrence->setPattern($settingsRecurrencePattern);
$settingsRecurrenceRange = new RecurrenceRange();
$settingsRecurrenceRange->setType(new RecurrenceRangeType('numbered'));
$settingsRecurrenceRange->setNumberOfOccurrences(0);
$settingsRecurrenceRange->setRecurrenceTimeZone(null);
$settingsRecurrenceRange->setStartDate(new Date('2021-02-10'));
$settingsRecurrenceRange->setEndDate(new Date('2022-12-21'));
$settingsRecurrence->setRange($settingsRecurrenceRange);
$settings->setRecurrence($settingsRecurrence);
$applyActionsAccessReviewApplyAction1 = new RemoveAccessApplyAction();
$applyActionsAccessReviewApplyAction1->setOdataType('#microsoft.graph.removeAccessApplyAction');
$applyActionsArray []= $applyActionsAccessReviewApplyAction1;
$settings->setApplyActions($applyActionsArray);
$requestBody->setSettings($settings);
$result = $graphServiceClient->identityGovernance()->accessReviews()->definitions()->post($requestBody)->wait();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
Import-Module Microsoft.Graph.Identity.Governance
$params = @{
displayName = "Group owners review guest across Microsoft 365 groups in the tenant (Quarterly)"
descriptionForAdmins = ""
descriptionForReviewers = ""
scope = @{
query = "./members/microsoft.graph.user/?$count=true&$filter=(userType eq 'Guest')"
queryType = "MicrosoftGraph"
}
instanceEnumerationScope = @{
query = "/groups?$filter=(groupTypes/any(c:c+eq+'Unified'))&$count=true"
queryType = "MicrosoftGraph"
}
reviewers = @(
@{
query = "./owners"
queryType = "MicrosoftGraph"
queryRoot = $null
}
)
fallbackReviewers = @(
@{
query = "/users/c9a5aff7-9298-4d71-adab-0a222e0a05e4"
queryType = "MicrosoftGraph"
queryRoot = $null
}
)
settings = @{
mailNotificationsEnabled = $true
reminderNotificationsEnabled = $true
justificationRequiredOnApproval = $true
defaultDecisionEnabled = $true
defaultDecision = "Approve"
instanceDurationInDays = 0
autoApplyDecisionsEnabled = $true
recommendationsEnabled = $true
recurrence = @{
pattern = @{
type = "absoluteMonthly"
interval = 3
month = 0
dayOfMonth = 0
daysOfWeek = @(
)
firstDayOfWeek = "sunday"
index = "first"
}
range = @{
type = "numbered"
numberOfOccurrences = 0
recurrenceTimeZone = $null
startDate = "2021-02-10"
endDate = "2022-12-21"
}
}
applyActions = @(
@{
"@odata.type" = "#microsoft.graph.removeAccessApplyAction"
}
)
}
}
New-MgIdentityGovernanceAccessReviewDefinition -BodyParameter $params
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
# THE PYTHON SDK IS IN PREVIEW. FOR NON-PRODUCTION USE ONLY
graph_client = GraphServiceClient(credentials, scopes)
request_body = AccessReviewScheduleDefinition(
display_name = "Group owners review guest across Microsoft 365 groups in the tenant (Quarterly)",
description_for_admins = "",
description_for_reviewers = "",
scope = AccessReviewScope(
additional_data = {
"query" : "./members/microsoft.graph.user/?$count=true&$filter=(userType eq 'Guest')",
"query_type" : "MicrosoftGraph",
}
),
instance_enumeration_scope = AccessReviewScope(
additional_data = {
"query" : "/groups?$filter=(groupTypes/any(c:c+eq+'Unified'))&$count=true",
"query_type" : "MicrosoftGraph",
}
),
reviewers = [
AccessReviewReviewerScope(
query = "./owners",
query_type = "MicrosoftGraph",
query_root = None,
),
],
fallback_reviewers = [
AccessReviewReviewerScope(
query = "/users/c9a5aff7-9298-4d71-adab-0a222e0a05e4",
query_type = "MicrosoftGraph",
query_root = None,
),
],
settings = AccessReviewScheduleSettings(
mail_notifications_enabled = True,
reminder_notifications_enabled = True,
justification_required_on_approval = True,
default_decision_enabled = True,
default_decision = "Approve",
instance_duration_in_days = 0,
auto_apply_decisions_enabled = True,
recommendations_enabled = True,
recurrence = PatternedRecurrence(
pattern = RecurrencePattern(
type = RecurrencePatternType.AbsoluteMonthly,
interval = 3,
month = 0,
day_of_month = 0,
days_of_week = [
],
first_day_of_week = DayOfWeek.Sunday,
index = WeekIndex.First,
),
range = RecurrenceRange(
type = RecurrenceRangeType.Numbered,
number_of_occurrences = 0,
recurrence_time_zone = None,
start_date = "2021-02-10",
end_date = "2022-12-21",
),
),
apply_actions = [
RemoveAccessApplyAction(
odata_type = "#microsoft.graph.removeAccessApplyAction",
),
],
),
)
result = await graph_client.identity_governance.access_reviews.definitions.post(request_body)
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
Response
HTTP/1.1 201 Created
Content-type: application/json
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#identityGovernance/accessReviews/definitions/$entity",
"id": "c22ae540-b89a-4d24-bac0-4ef35e6591ea",
"displayName": "Group owners review guest across Microsoft 365 groups in the tenant (Quarterly)",
"status": "NotStarted",
"createdBy": {
"id": "cdb555e3-b33e-4fd5-a427-17fadacbdfa7",
"displayName": "MOD Administrator",
"userPrincipalName": "admin@contoso.com"
},
"scope": {
"query": "./members/microsoft.graph.user/?$count=true&$filter=(userType eq 'Guest')",
"queryType": "MicrosoftGraph"
},
"instanceEnumerationScope": {
"query": "/groups?$filter=(groupTypes/any(c:c+eq+'Unified'))&$count=true",
"queryType": "MicrosoftGraph"
},
"reviewers": [
{
"query": "./owners",
"queryType": "MicrosoftGraph",
"queryRoot": null
}
],
"fallbackReviewers": [
{
"query": "/users/c9a5aff7-9298-4d71-adab-0a222e0a05e4",
"queryType": "MicrosoftGraph",
"queryRoot": null
}
],
"settings": {
"defaultDecisionEnabled": true,
"defaultDecision": "Approve",
"autoApplyDecisionsEnabled": true,
"recommendationsEnabled": true,
"recurrence": {
"pattern": {
"type": "absoluteMonthly",
"interval": 3,
"month": 0,
"dayOfMonth": 0,
"daysOfWeek": [],
"firstDayOfWeek": "sunday",
"index": "first"
},
"range": {
"type": "numbered",
"numberOfOccurrences": 0,
"recurrenceTimeZone": null,
"startDate": "2021-02-10",
"endDate": "2022-12-21"
}
},
"applyActions": [
{
"@odata.type": "#microsoft.graph.removeAccessApplyAction"
}
]
}
}
Step 5: List instances of the access review
The following query lists all instances of the access review definition. If there are more than one Microsoft 365 groups with guest users in your tenant, this request will return one instance for every Microsoft 365 group with guest users .
Request
In this call, replace c22ae540-b89a-4d24-bac0-4ef35e6591ea
with the ID of your access review definition returned in Step 4.
GET https://graph.microsoft.com/v1.0/identityGovernance/accessReviews/definitions/c22ae540-b89a-4d24-bac0-4ef35e6591ea/instances
// Code snippets are only available for the latest version. Current version is 5.x
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.IdentityGovernance.AccessReviews.Definitions["{accessReviewScheduleDefinition-id}"].Instances.GetAsync();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
// THE CLI IS IN PREVIEW. NON-PRODUCTION USE ONLY
mgc identity-governance access-reviews definitions instances list --access-review-schedule-definition-id {accessReviewScheduleDefinition-id}
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
//other-imports
)
graphClient := msgraphsdk.NewGraphServiceClientWithCredentials(cred, scopes)
instances, err := graphClient.IdentityGovernance().AccessReviews().Definitions().ByAccessReviewScheduleDefinitionId("accessReviewScheduleDefinition-id").Instances().Get(context.Background(), nil)
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
GraphServiceClient graphClient = GraphServiceClient.builder().authenticationProvider( authProvider ).buildClient();
AccessReviewInstanceCollectionPage instances = graphClient.identityGovernance().accessReviews().definitions("c22ae540-b89a-4d24-bac0-4ef35e6591ea").instances()
.buildRequest()
.get();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
const options = {
authProvider,
};
const client = Client.init(options);
let instances = await client.api('/identityGovernance/accessReviews/definitions/c22ae540-b89a-4d24-bac0-4ef35e6591ea/instances')
.get();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
<?php
// THIS SNIPPET IS A PREVIEW VERSION OF THE SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$result = $graphServiceClient->identityGovernance()->accessReviews()->definitions()->byAccessReviewScheduleDefinitionId('accessReviewScheduleDefinition-id')->instances()->get()->wait();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
Import-Module Microsoft.Graph.Identity.Governance
Get-MgIdentityGovernanceAccessReviewDefinitionInstance -AccessReviewScheduleDefinitionId $accessReviewScheduleDefinitionId
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
# THE PYTHON SDK IS IN PREVIEW. FOR NON-PRODUCTION USE ONLY
graph_client = GraphServiceClient(credentials, scopes)
result = await graph_client.identity_governance.access_reviews.definitions.by_access_review_schedule_definition_id('accessReviewScheduleDefinition-id').instances.get()
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
Response
In this response, the scope includes a group identified by 59ab642a-2776-4e32-9b68-9ff7a47b7f6a
(the Feel good marketing campaign group created in Step 3) because it has a guest user.
HTTP/1.1 200 OK
Content-type: application/json
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#identityGovernance/accessReviews/definitions('c22ae540-b89a-4d24-bac0-4ef35e6591ea')/instances",
"value": [
{
"id": "6392b1a7-9c25-4844-83e5-34e23c88e16a",
"startDateTime": "2021-02-10T17:00:36.96Z",
"endDateTime": "2021-02-10T17:00:36.96Z",
"status": "InProgress",
"scope": {
"query": "/groups/59ab642a-2776-4e32-9b68-9ff7a47b7f6a/members/microsoft.graph.user/?$count=true&$filter=(userType eq 'Guest')",
"queryType": "MicrosoftGraph"
}
}
]
}
In this response, the access review instance is currently InProgress
. Because it's a quarterly review, a new review instance is created automatically every three months and the reviewers can apply new decisions.
Step 6: Get decisions
Get the decisions taken for the instance of an access review.
Request
In this call:
Replace c22ae540-b89a-4d24-bac0-4ef35e6591ea
with the ID of your access review definition returned in Step 4.
Replace 6392b1a7-9c25-4844-83e5-34e23c88e16a
with the ID of your access review instance returned in Step 5.
GET https://graph.microsoft.com/v1.0/identityGovernance/accessReviews/definitions/c22ae540-b89a-4d24-bac0-4ef35e6591ea/instances/6392b1a7-9c25-4844-83e5-34e23c88e16a/decisions
// Code snippets are only available for the latest version. Current version is 5.x
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.IdentityGovernance.AccessReviews.Definitions["{accessReviewScheduleDefinition-id}"].Instances["{accessReviewInstance-id}"].Decisions.GetAsync();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
// THE CLI IS IN PREVIEW. NON-PRODUCTION USE ONLY
mgc identity-governance access-reviews definitions instances decisions list --access-review-schedule-definition-id {accessReviewScheduleDefinition-id} --access-review-instance-id {accessReviewInstance-id}
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
//other-imports
)
graphClient := msgraphsdk.NewGraphServiceClientWithCredentials(cred, scopes)
decisions, err := graphClient.IdentityGovernance().AccessReviews().Definitions().ByAccessReviewScheduleDefinitionId("accessReviewScheduleDefinition-id").Instances().ByAccessReviewInstanceId("accessReviewInstance-id").Decisions().Get(context.Background(), nil)
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
GraphServiceClient graphClient = GraphServiceClient.builder().authenticationProvider( authProvider ).buildClient();
AccessReviewInstanceDecisionItemCollectionPage decisions = graphClient.identityGovernance().accessReviews().definitions("c22ae540-b89a-4d24-bac0-4ef35e6591ea").instances("6392b1a7-9c25-4844-83e5-34e23c88e16a").decisions()
.buildRequest()
.get();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
const options = {
authProvider,
};
const client = Client.init(options);
let decisions = await client.api('/identityGovernance/accessReviews/definitions/c22ae540-b89a-4d24-bac0-4ef35e6591ea/instances/6392b1a7-9c25-4844-83e5-34e23c88e16a/decisions')
.get();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
<?php
// THIS SNIPPET IS A PREVIEW VERSION OF THE SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$result = $graphServiceClient->identityGovernance()->accessReviews()->definitions()->byAccessReviewScheduleDefinitionId('accessReviewScheduleDefinition-id')->instances()->byAccessReviewInstanceId('accessReviewInstance-id')->decisions()->get()->wait();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
Import-Module Microsoft.Graph.Identity.Governance
Get-MgIdentityGovernanceAccessReviewDefinitionInstanceDecision -AccessReviewScheduleDefinitionId $accessReviewScheduleDefinitionId -AccessReviewInstanceId $accessReviewInstanceId
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
# THE PYTHON SDK IS IN PREVIEW. FOR NON-PRODUCTION USE ONLY
graph_client = GraphServiceClient(credentials, scopes)
result = await graph_client.identity_governance.access_reviews.definitions.by_access_review_schedule_definition_id('accessReviewScheduleDefinition-id').instances.by_access_review_instance_id('accessReviewInstance-id').decisions.get()
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
Response
The following response shows the decision taken for the instance of the review.
HTTP/1.1 200 OK
Content-type: application/json
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#identityGovernance/accessReviews/definitions('c22ae540-b89a-4d24-bac0-4ef35e6591ea')/instances('6392b1a7-9c25-4844-83e5-34e23c88e16a')/decisions",
"@odata.count": 1,
"value": [
{
"id": "0e76ee07-b4c6-469e-bc9d-e73fc9a8d660",
"accessReviewId": "6392b1a7-9c25-4844-83e5-34e23c88e16a",
"reviewedDateTime": "2021-02-10T17:06:26.147Z",
"decision": "Approve",
"justification": "",
"appliedDateTime": null,
"applyResult": "New",
"recommendation": "Deny",
"reviewedBy": {
"id": "00000000-0000-0000-0000-000000000000",
"displayName": "AAD Access Reviews",
"userPrincipalName": "AAD Access Reviews"
},
"appliedBy": {
"id": "00000000-0000-0000-0000-000000000000",
"displayName": "",
"userPrincipalName": ""
},
"target": {
"@odata.type": "#microsoft.graph.accessReviewInstanceDecisionItemUserTarget",
"userId": "baf1b0a0-1f9a-4a56-9884-6a30824f8d20",
"userDisplayName": "John Doe (Tailspin Toys)",
"userPrincipalName": "john@tailspintoys.com"
},
"principal": {
"@odata.type": "#microsoft.graph.userIdentity",
"id": "baf1b0a0-1f9a-4a56-9884-6a30824f8d20",
"displayName": "John Doe (Tailspin Toys)",
"userPrincipalName": "john@tailspintoys.com"
}
}
]
}
In a quarterly review like this one, and as long as the access review is still active:
Every three months a new review instance will be created.
Reviewers will be required to apply new decisions for new instances.
Step 7: Clean up resources
Delete the resources that you created for this tutorial—Feel good marketing campaign group, the access review schedule definition, the guest user, and the test user.
Delete the Microsoft 365 group
Request
In this call, replace 59ab642a-2776-4e32-9b68-9ff7a47b7f6a
with the ID of your Feel good marketing campaign Microsoft 365 group.
DELETE https://graph.microsoft.com/v1.0/groups/59ab642a-2776-4e32-9b68-9ff7a47b7f6a
// Code snippets are only available for the latest version. Current version is 5.x
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
await graphClient.Groups["{group-id}"].DeleteAsync();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
//other-imports
)
graphClient := msgraphsdk.NewGraphServiceClientWithCredentials(cred, scopes)
graphClient.Groups().ByGroupId("group-id").Delete(context.Background(), nil)
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
GraphServiceClient graphClient = GraphServiceClient.builder().authenticationProvider( authProvider ).buildClient();
graphClient.groups("59ab642a-2776-4e32-9b68-9ff7a47b7f6a")
.buildRequest()
.delete();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
const options = {
authProvider,
};
const client = Client.init(options);
await client.api('/groups/59ab642a-2776-4e32-9b68-9ff7a47b7f6a')
.delete();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
<?php
// THIS SNIPPET IS A PREVIEW VERSION OF THE SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$graphServiceClient->groups()->byGroupId('group-id')->delete()->wait();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
# THE PYTHON SDK IS IN PREVIEW. FOR NON-PRODUCTION USE ONLY
graph_client = GraphServiceClient(credentials, scopes)
await graph_client.groups.by_group_id('group-id').delete()
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
Response
HTTP/1.1 204 No Content
Content-type: text/plain
Delete the access review definition
In this call, replace c22ae540-b89a-4d24-bac0-4ef35e6591ea
with the ID of your access review definition. Since the access review schedule definition is the blueprint for the access review, deleting the definition will remove the related settings, instances, and decisions.
Request
DELETE https://graph.microsoft.com/v1.0/identityGovernance/accessReviews/definitions/c22ae540-b89a-4d24-bac0-4ef35e6591ea
// Code snippets are only available for the latest version. Current version is 5.x
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
await graphClient.IdentityGovernance.AccessReviews.Definitions["{accessReviewScheduleDefinition-id}"].DeleteAsync();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
// THE CLI IS IN PREVIEW. NON-PRODUCTION USE ONLY
mgc identity-governance access-reviews definitions delete --access-review-schedule-definition-id {accessReviewScheduleDefinition-id}
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
//other-imports
)
graphClient := msgraphsdk.NewGraphServiceClientWithCredentials(cred, scopes)
graphClient.IdentityGovernance().AccessReviews().Definitions().ByAccessReviewScheduleDefinitionId("accessReviewScheduleDefinition-id").Delete(context.Background(), nil)
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
GraphServiceClient graphClient = GraphServiceClient.builder().authenticationProvider( authProvider ).buildClient();
graphClient.identityGovernance().accessReviews().definitions("c22ae540-b89a-4d24-bac0-4ef35e6591ea")
.buildRequest()
.delete();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
const options = {
authProvider,
};
const client = Client.init(options);
await client.api('/identityGovernance/accessReviews/definitions/c22ae540-b89a-4d24-bac0-4ef35e6591ea')
.delete();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
<?php
// THIS SNIPPET IS A PREVIEW VERSION OF THE SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$graphServiceClient->identityGovernance()->accessReviews()->definitions()->byAccessReviewScheduleDefinitionId('accessReviewScheduleDefinition-id')->delete()->wait();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
Import-Module Microsoft.Graph.Identity.Governance
Remove-MgIdentityGovernanceAccessReviewDefinition -AccessReviewScheduleDefinitionId $accessReviewScheduleDefinitionId
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
# THE PYTHON SDK IS IN PREVIEW. FOR NON-PRODUCTION USE ONLY
graph_client = GraphServiceClient(credentials, scopes)
await graph_client.identity_governance.access_reviews.definitions.by_access_review_schedule_definition_id('accessReviewScheduleDefinition-id').delete()
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
Response
HTTP/1.1 204 No Content
Content-type: text/plain
Remove the guest user
In this call, replace baf1b0a0-1f9a-4a56-9884-6a30824f8d20
with the ID of the guest user, john@tailspintoys.com.
Request
DELETE https://graph.microsoft.com/v1.0/users/baf1b0a0-1f9a-4a56-9884-6a30824f8d20
// Code snippets are only available for the latest version. Current version is 5.x
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
await graphClient.Users["{user-id}"].DeleteAsync();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
//other-imports
)
graphClient := msgraphsdk.NewGraphServiceClientWithCredentials(cred, scopes)
graphClient.Users().ByUserId("user-id").Delete(context.Background(), nil)
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
GraphServiceClient graphClient = GraphServiceClient.builder().authenticationProvider( authProvider ).buildClient();
graphClient.users("baf1b0a0-1f9a-4a56-9884-6a30824f8d20")
.buildRequest()
.delete();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
const options = {
authProvider,
};
const client = Client.init(options);
await client.api('/users/baf1b0a0-1f9a-4a56-9884-6a30824f8d20')
.delete();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
<?php
// THIS SNIPPET IS A PREVIEW VERSION OF THE SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$graphServiceClient->users()->byUserId('user-id')->delete()->wait();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
# THE PYTHON SDK IS IN PREVIEW. FOR NON-PRODUCTION USE ONLY
graph_client = GraphServiceClient(credentials, scopes)
await graph_client.users.by_user_id('user-id').delete()
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
Response
HTTP/1.1 204 No Content
Content-type: text/plain
Delete the test user
In this call, replace c9a5aff7-9298-4d71-adab-0a222e0a05e4
with the ID of your test user.
Request
DELETE https://graph.microsoft.com/v1.0/users/c9a5aff7-9298-4d71-adab-0a222e0a05e4
// Code snippets are only available for the latest version. Current version is 5.x
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
await graphClient.Users["{user-id}"].DeleteAsync();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
//other-imports
)
graphClient := msgraphsdk.NewGraphServiceClientWithCredentials(cred, scopes)
graphClient.Users().ByUserId("user-id").Delete(context.Background(), nil)
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
GraphServiceClient graphClient = GraphServiceClient.builder().authenticationProvider( authProvider ).buildClient();
graphClient.users("c9a5aff7-9298-4d71-adab-0a222e0a05e4")
.buildRequest()
.delete();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
const options = {
authProvider,
};
const client = Client.init(options);
await client.api('/users/c9a5aff7-9298-4d71-adab-0a222e0a05e4')
.delete();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
<?php
// THIS SNIPPET IS A PREVIEW VERSION OF THE SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$graphServiceClient->users()->byUserId('user-id')->delete()->wait();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
# THE PYTHON SDK IS IN PREVIEW. FOR NON-PRODUCTION USE ONLY
graph_client = GraphServiceClient(credentials, scopes)
await graph_client.users.by_user_id('user-id').delete()
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
Response
HTTP/1.1 204 No Content
Content-type: text/plain
Congratulations! You've created an access review for guest users in Microsoft 365 groups in your tenant, and scheduled it quarterly. The group owners will review access during these cycles, choosing either to approve or deny access.
See also