PowerShellMicrosoft Graph APIAzure Entra ID
Managing user identities manually in Azure Entra ID and Microsoft 365 is time-consuming, error-prone, and introduces security risks. This project demonstrates how the Joiner–Mover–Leaver (JML) lifecycle can be fully automated using PowerShell with Microsoft Graph REST API.
The solution is designed to be API-first, secure, scalable, and aligned with Microsoft's current best practices.
This automation uses Azure Entra ID App Registration with application permissions. All actions are non-interactive and fully auditable.
| Permission | Purpose |
|---|---|
User.ReadWrite.All |
Manage users |
Group.ReadWrite.All |
Manage groups and memberships |
Directory.Read.All |
Query directory objects |
AuditLog.Read.All |
Read audit logs |
$TenantId = "<TenantId>"
$ClientId = "<AppRegistrationClientId>"
$ClientSecret = "<ClientSecret>"
$Body = @{
grant_type = "client_credentials"
scope = "https://graph.microsoft.com/.default"
client_id = $ClientId
client_secret = $ClientSecret
}
$TokenResponse = Invoke-RestMethod -Method Post `
-Uri "https://login.microsoftonline.com/$TenantId/oauth2/v2.0/token" `
-Body $Body
$AccessToken = $TokenResponse.access_token
$Headers = @{
Authorization = "Bearer $AccessToken"
"Content-Type" = "application/json"
}
$UserBody = @{
accountEnabled = $true
displayName = "John Doe"
mailNickname = "johndoe"
userPrincipalName = "johndoe@domain.com"
passwordProfile = @{
forceChangePasswordNextSignIn = $true
password = "TempP@ssw0rd!"
}
} | ConvertTo-Json -Depth 4
Invoke-RestMethod -Method Post `
-Uri "https://graph.microsoft.com/v1.0/users" `
-Headers $Headers -Body $UserBody
$GroupId = "<GroupObjectId>"
$UserId = "<UserId>"
$GroupBody = @{
"@odata.id" = "https://graph.microsoft.com/v1.0/directoryObjects/$UserId"
} | ConvertTo-Json
Invoke-RestMethod -Method Post `
-Uri "https://graph.microsoft.com/v1.0/groups/$GroupId/members/`$ref" `
-Headers $Headers -Body $GroupBody
# Update user attributes
$UpdateBody = @{
department = "Engineering"
jobTitle = "Senior Engineer"
} | ConvertTo-Json
Invoke-RestMethod -Method Patch `
-Uri "https://graph.microsoft.com/v1.0/users/$UserId" `
-Headers $Headers -Body $UpdateBody
# Remove from old group
Invoke-RestMethod -Method Delete `
-Uri "https://graph.microsoft.com/v1.0/groups/$OldGroupId/members/$UserId/`$ref" `
-Headers $Headers
# Add to new group
$NewGroupBody = @{
"@odata.id" = "https://graph.microsoft.com/v1.0/directoryObjects/$UserId"
} | ConvertTo-Json
Invoke-RestMethod -Method Post `
-Uri "https://graph.microsoft.com/v1.0/groups/$NewGroupId/members/`$ref" `
-Headers $Headers -Body $NewGroupBody
# Disable account
$DisableBody = @{
accountEnabled = $false
} | ConvertTo-Json
Invoke-RestMethod -Method Patch `
-Uri "https://graph.microsoft.com/v1.0/users/$UserId" `
-Headers $Headers -Body $DisableBody
# Revoke all sessions
Invoke-RestMethod -Method Post `
-Uri "https://graph.microsoft.com/v1.0/users/$UserId/revokeSignInSessions" `
-Headers $Headers
All operations can be logged:
GitHub: Azure Entra Office 365 Automation
This project demonstrates a production-ready, Graph API–first identity lifecycle automation approach using PowerShell REST calls, suitable for enterprise Azure environments. It is fully aligned with security, scalability, and compliance best practices, making it a strong portfolio example.