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 Lifecycle Administrator or Global Administrator Azure AD role.
Grant yourself the following LifecycleWorkflows.ReadWrite.All delegated permission.
You must have two user accounts to use for this tutorial, one for the new hire and another for their manager.
User property
Description
Set on
mail
Used to notify manager of the new employee's temporary access pass (TAP). Both the manager and employee should have active mailboxes to receive emails.
Employee, Manager
manager
This attribute that is used by the lifecycle workflow.
Employee
employeeHireDate
Used to trigger the workflow. Set to today's date.
Employee
department
Used to provide the scope for the workflow. Set to Sales.
POST https://graph.microsoft.com/beta/identityGovernance/LifecycleWorkflows/workflows
Content-type: application/json
{
"displayName":"Onboard pre-hire employee",
"description":"Configure pre-hire tasks for onboarding employees before their first day",
"isEnabled":true,
"isSchedulingEnabled": false,
"executionConditions": {
"@odata.type": "microsoft.graph.identityGovernance.triggerAndScopeBasedConditions",
"scope": {
"@odata.type": "microsoft.graph.identityGovernance.ruleBasedSubjectSet",
"rule": "(department eq 'Sales')"
},
"trigger": {
"@odata.type": "microsoft.graph.identityGovernance.timeBasedAttributeTrigger",
"timeBasedAttribute": "employeeHireDate",
"offsetInDays": -2
}
},
"tasks":[
{
"isEnabled":true,
"category": "Joiner",
"taskDefinitionId":"1b555e50-7f65-41d5-b514-5894a026d10d",
"displayName":"Generate TAP And Send Email",
"description":"Generate Temporary Access Pass and send via email to user's manager",
"arguments":[
{
"name": "tapLifetimeMinutes",
"value": "480"
},
{
"name": "tapIsUsableOnce",
"value": "true"
}
]
}
]
}
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var requestBody = new Microsoft.Graph.Beta.Models.IdentityGovernance.Workflow
{
DisplayName = "Onboard pre-hire employee",
Description = "Configure pre-hire tasks for onboarding employees before their first day",
IsEnabled = true,
IsSchedulingEnabled = false,
ExecutionConditions = new Microsoft.Graph.Beta.Models.IdentityGovernance.TriggerAndScopeBasedConditions
{
OdataType = "microsoft.graph.identityGovernance.triggerAndScopeBasedConditions",
Scope = new Microsoft.Graph.Beta.Models.IdentityGovernance.RuleBasedSubjectSet
{
OdataType = "microsoft.graph.identityGovernance.ruleBasedSubjectSet",
Rule = "(department eq 'Sales')",
},
Trigger = new Microsoft.Graph.Beta.Models.IdentityGovernance.TimeBasedAttributeTrigger
{
OdataType = "microsoft.graph.identityGovernance.timeBasedAttributeTrigger",
TimeBasedAttribute = Microsoft.Graph.Beta.Models.IdentityGovernance.WorkflowTriggerTimeBasedAttribute.EmployeeHireDate,
OffsetInDays = -2,
},
},
Tasks = new List<Microsoft.Graph.Beta.Models.IdentityGovernance.TaskObject>
{
new Microsoft.Graph.Beta.Models.IdentityGovernance.TaskObject
{
IsEnabled = true,
Category = Microsoft.Graph.Beta.Models.IdentityGovernance.LifecycleTaskCategory.Joiner,
TaskDefinitionId = "1b555e50-7f65-41d5-b514-5894a026d10d",
DisplayName = "Generate TAP And Send Email",
Description = "Generate Temporary Access Pass and send via email to user's manager",
Arguments = new List<KeyValuePair>
{
new KeyValuePair
{
Name = "tapLifetimeMinutes",
Value = "480",
},
new KeyValuePair
{
Name = "tapIsUsableOnce",
Value = "true",
},
},
},
},
};
var result = await graphClient.IdentityGovernance.LifecycleWorkflows.Workflows.PostAsync(requestBody);
<?php
// THIS SNIPPET IS A PREVIEW VERSION OF THE SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$requestBody = new Workflow();
$requestBody->setDisplayName('Onboard pre-hire employee');
$requestBody->setDescription('Configure pre-hire tasks for onboarding employees before their first day');
$requestBody->setIsEnabled(true);
$requestBody->setIsSchedulingEnabled(false);
$executionConditions = new TriggerAndScopeBasedConditions();
$executionConditions->setOdataType('microsoft.graph.identityGovernance.triggerAndScopeBasedConditions');
$executionConditionsScope = new RuleBasedSubjectSet();
$executionConditionsScope->setOdataType('microsoft.graph.identityGovernance.ruleBasedSubjectSet');
$executionConditionsScope->setRule('(department eq \'Sales\')');
$executionConditions->setScope($executionConditionsScope);
$executionConditionsTrigger = new TimeBasedAttributeTrigger();
$executionConditionsTrigger->setOdataType('microsoft.graph.identityGovernance.timeBasedAttributeTrigger');
$executionConditionsTrigger->setTimeBasedAttribute(new WorkflowTriggerTimeBasedAttribute('employeeHireDate'));
$executionConditionsTrigger->setOffsetInDays(-2);
$executionConditions->setTrigger($executionConditionsTrigger);
$requestBody->setExecutionConditions($executionConditions);
$tasksTask1 = new Task();
$tasksTask1->setIsEnabled(true);
$tasksTask1->setCategory(new LifecycleTaskCategory('joiner'));
$tasksTask1->setTaskDefinitionId('1b555e50-7f65-41d5-b514-5894a026d10d');
$tasksTask1->setDisplayName('Generate TAP And Send Email');
$tasksTask1->setDescription('Generate Temporary Access Pass and send via email to user\'s manager');
$argumentsKeyValuePair1 = new KeyValuePair();
$argumentsKeyValuePair1->setName('tapLifetimeMinutes');
$argumentsKeyValuePair1->setValue('480');
$argumentsArray []= $argumentsKeyValuePair1;
$argumentsKeyValuePair2 = new KeyValuePair();
$argumentsKeyValuePair2->setName('tapIsUsableOnce');
$argumentsKeyValuePair2->setValue('true');
$argumentsArray []= $argumentsKeyValuePair2;
$tasksTask1->setArguments($argumentsArray);
$tasksArray []= $tasksTask1;
$requestBody->setTasks($tasksArray);
$result = $graphServiceClient->identityGovernance()->lifecycleWorkflows()->workflows()->post($requestBody)->wait();
Because the workflow hasn't been scheduled to run, it must be run manually. In the following request, the user for whom the workflow will run is identified by ID 8930f0c7-cdd7-4885-9260-3b4a8111de5c.
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var requestBody = new Microsoft.Graph.Beta.IdentityGovernance.LifecycleWorkflows.Workflows.Item.MicrosoftGraphIdentityGovernanceActivate.ActivatePostRequestBody
{
Subjects = new List<User>
{
new User
{
Id = "8930f0c7-cdd7-4885-9260-3b4a8111de5c",
},
},
};
await graphClient.IdentityGovernance.LifecycleWorkflows.Workflows["{workflow-id}"].MicrosoftGraphIdentityGovernanceActivate.PostAsync(requestBody);
// THE CLI IS IN PREVIEW. NON-PRODUCTION USE ONLY
mgc-beta identity-governance lifecycle-workflows workflows microsoft-graph-identity-governance-activate post --workflow-id {workflow-id}
<?php
// THIS SNIPPET IS A PREVIEW VERSION OF THE SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$requestBody = new ActivatePostRequestBody();
$subjectsUser1 = new User();
$subjectsUser1->setId('8930f0c7-cdd7-4885-9260-3b4a8111de5c');
$subjectsArray []= $subjectsUser1;
$requestBody->setSubjects($subjectsArray);
$graphServiceClient->identityGovernance()->lifecycleWorkflows()->workflows()->byWorkflowId('workflow-id')->microsoftGraphIdentityGovernanceActivate()->post($requestBody)->wait();
# THE PYTHON SDK IS IN PREVIEW. FOR NON-PRODUCTION USE ONLY
graph_client = GraphServiceClient(request_adapter)
request_body = ActivatePostRequestBody(
subjects = [
User(
id = "8930f0c7-cdd7-4885-9260-3b4a8111de5c",
),
]
)
await graph_client.identity_governance.lifecycle_workflows.workflows.by_workflow_id('workflow-id').microsoft_graph_identity_governance_activate.post(body = request_body)
GET https://graph.microsoft.com/beta/identityGovernance/LifecycleWorkflows/workflows/ea71190c-075a-4ae7-9bca-34abf3b7b056/userProcessingResults
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var result = await graphClient.IdentityGovernance.LifecycleWorkflows.Workflows["{workflow-id}"].UserProcessingResults.GetAsync();
// THE CLI IS IN PREVIEW. NON-PRODUCTION USE ONLY
mgc-beta identity-governance lifecycle-workflows workflows user-processing-results list --workflow-id {workflow-id}
<?php
// THIS SNIPPET IS A PREVIEW VERSION OF THE SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$result = $graphServiceClient->identityGovernance()->lifecycleWorkflows()->workflows()->byWorkflowId('workflow-id')->userProcessingResults()->get()->wait();
# THE PYTHON SDK IS IN PREVIEW. FOR NON-PRODUCTION USE ONLY
graph_client = GraphServiceClient(request_adapter)
result = await graph_client.identity_governance.lifecycle_workflows.workflows.by_workflow_id('workflow-id').user_processing_results.get()
GET https://graph.microsoft.com/beta/identityGovernance/LifecycleWorkflows/workflows/ea71190c-075a-4ae7-9bca-34abf3b7b056/userProcessingResults/summary(startDateTime=2022-10-01T00:00:00Z,endDateTime=2022-10-30T00:00:00Z)
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var result = await graphClient.IdentityGovernance.LifecycleWorkflows.Workflows["{workflow-id}"].UserProcessingResults.MicrosoftGraphIdentityGovernanceSummaryWithStartDateTimeWithEndDateTime(DateTimeOffset.Parse("{endDateTime}"),DateTimeOffset.Parse("{startDateTime}")).GetAsync();
// THE CLI IS IN PREVIEW. NON-PRODUCTION USE ONLY
mgc-beta identity-governance lifecycle-workflows workflows user-processing-results microsoft-graph-identity-governance-summary-with-start-date-time-with-end-date-time get --start-date-time {start-date-time-id} --end-date-time {end-date-time-id} --workflow-id {workflow-id}
<?php
// THIS SNIPPET IS A PREVIEW VERSION OF THE SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$result = $graphServiceClient->identityGovernance()->lifecycleWorkflows()->workflows()->byWorkflowId('workflow-id')->userProcessingResults()->microsoftGraphIdentityGovernanceSummaryWithStartDateTimeWithEndDateTime(new \DateTime('{endDateTime}'),new \DateTime('{startDateTime}'))->get()->wait();
# THE PYTHON SDK IS IN PREVIEW. FOR NON-PRODUCTION USE ONLY
graph_client = GraphServiceClient(request_adapter)
result = await graph_client.identity_governance.lifecycle_workflows.workflows.by_workflow_id('workflow-id').user_processing_results.microsoft_graph_identity_governance_summary(start_date_time={start_date_time},end_date_time={end_date_time}.get()
GET https://graph.microsoft.com/beta/identityGovernance/LifecycleWorkflows/workflows/ea71190c-075a-4ae7-9bca-34abf3b7b056/userProcessingResults/5772d894-3bcf-4d1c-9cfc-8c182331215b/taskProcessingResults
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var result = await graphClient.IdentityGovernance.LifecycleWorkflows.Workflows["{workflow-id}"].UserProcessingResults["{userProcessingResult-id}"].TaskProcessingResults.GetAsync();
// THE CLI IS IN PREVIEW. NON-PRODUCTION USE ONLY
mgc-beta identity-governance lifecycle-workflows workflows user-processing-results task-processing-results list --workflow-id {workflow-id} --user-processing-result-id {userProcessingResult-id}
<?php
// THIS SNIPPET IS A PREVIEW VERSION OF THE SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$result = $graphServiceClient->identityGovernance()->lifecycleWorkflows()->workflows()->byWorkflowId('workflow-id')->userProcessingResults()->byUserProcessingResultId('userProcessingResult-id')->taskProcessingResults()->get()->wait();
# THE PYTHON SDK IS IN PREVIEW. FOR NON-PRODUCTION USE ONLY
graph_client = GraphServiceClient(request_adapter)
result = await graph_client.identity_governance.lifecycle_workflows.workflows.by_workflow_id('workflow-id').user_processing_results.by_user_processing_result_id('userProcessingResult-id').task_processing_results.get()
[Optional] Schedule the workflow to run automatically
After running your workflow on-demand and checking that everything is working fine, you may want to enable the workflow so that it can run automatically on a tenant-defined schedule. To enable the workflow schedule, you may run the following request.
// Code snippets are only available for the latest version. Current version is 5.x
var graphClient = new GraphServiceClient(requestAdapter);
var requestBody = new Microsoft.Graph.Beta.Models.IdentityGovernance.Workflow
{
IsEnabled = true,
IsSchedulingEnabled = true,
};
var result = await graphClient.IdentityGovernance.LifecycleWorkflows.Workflows["{workflow-id}"].PatchAsync(requestBody);
// THE CLI IS IN PREVIEW. NON-PRODUCTION USE ONLY
mgc-beta identity-governance lifecycle-workflows workflows patch --workflow-id {workflow-id} --body '{\
"isEnabled": true,\
"isSchedulingEnabled": true\
}\
'
<?php
// THIS SNIPPET IS A PREVIEW VERSION OF THE SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$requestBody = new Workflow();
$requestBody->setIsEnabled(true);
$requestBody->setIsSchedulingEnabled(true);
$result = $graphServiceClient->identityGovernance()->lifecycleWorkflows()->workflows()->byWorkflowId('workflow-id')->patch($requestBody)->wait();
# THE PYTHON SDK IS IN PREVIEW. FOR NON-PRODUCTION USE ONLY
graph_client = GraphServiceClient(request_adapter)
request_body = Workflow(
is_enabled = True,
is_scheduling_enabled = True,
)
result = await graph_client.identity_governance.lifecycle_workflows.workflows.by_workflow_id('workflow-id').patch(body = request_body)
When a workflow is scheduled, Lifecycle Workflows will check every three hours for users in the associated execution condition and execute the configured tasks for those users. You can customize this recurrence from between one hour to 24 hours.