Users & Groups¶
User Settings¶
Entra admin center → Users → User settings
| Setting | Recommended value | Reason |
|---|---|---|
| Users can register applications | No | Prevents OAuth app abuse |
| Restrict access to Entra admin portal | Yes | Non-admins shouldn't browse the directory |
| LinkedIn account connections | No | Reduces data leakage |
| Users can create security groups | No | Centralise group management |
| Users can create Microsoft 365 groups | No | Control sprawl; use group naming policies |
| Guest invite settings | Admins and users with Guest Inviter role only | Reduce unsanctioned guest access |
| Guest user access | Limited access (default restricted) |
Group Settings¶
Entra admin center → Groups → General
| Setting | Recommended value |
|---|---|
| Owners can manage group membership requests | Yes |
| Restrict user ability to access groups features | No |
| Users can create Microsoft 365 groups in Azure portals, API or PowerShell | No |
| Users can create security groups | No |
Group Expiration Policy¶
Set an expiration on Microsoft 365 groups to clean up abandoned teams and sites:
Entra admin center → Groups → Expiration
| Setting | Value |
|---|---|
| Group lifetime (days) | 180 |
| Email contact for groups with no owners | IT alias or helpdesk |
| Enable expiration for | All groups |
Group Naming Policy¶
Enforce a consistent naming convention:
Entra admin center → Groups → Naming policy
Example prefix: GRP-, TEAM-, DL- (distribution lists), SEC- (security groups)
External / Guest Users¶
Entra admin center → External Identities → External collaboration settings
| Setting | Recommended value |
|---|---|
| Guest user access | Limited (most restrictive): guests can only see their own directory objects |
| Guest invite settings | Only users assigned to specific admin roles |
| Enable guest self-service sign-up via user flows | No (unless business need) |
| Allow external users to leave | Yes |
| Collaboration restrictions | Allow invitations only to specified domains (allowlist) |
Reviewing Guest Access¶
Connect-MgGraph -Scopes "User.Read.All","AuditLog.Read.All"
# List all guest users
Get-MgUser -Filter "userType eq 'Guest'" -All |
Select-Object DisplayName, UserPrincipalName, CreatedDateTime |
Sort-Object CreatedDateTime -Descending
# Find guests who haven't signed in for 90+ days
$cutoff = (Get-Date).AddDays(-90).ToString("o")
Get-MgUser -Filter "userType eq 'Guest'" -All -Property DisplayName,UserPrincipalName,SignInActivity |
Where-Object { $_.SignInActivity.LastSignInDateTime -lt $cutoff -or $null -eq $_.SignInActivity } |
Select-Object DisplayName, UserPrincipalName, @{N="LastSignIn";E={$_.SignInActivity.LastSignInDateTime}}
Privileged Identity Management (PIM)¶
Requires Entra ID P2
Entra admin center → Identity Governance → Privileged Identity Management
Setup for Global Administrator Role¶
- Navigate to PIM → Entra roles → Roles → Global Administrator → Settings
- Configure:
| Setting | Value |
|---|---|
| Activation maximum duration | 8 hours |
| Require justification on activation | Yes |
| Require ticket information on activation | Yes (link to service desk) |
| Require MFA on activation | Yes |
| Require approval to activate | Yes (approver = existing Global Admin) |
| Assignment — allow permanent active | No (require eligible assignments only) |
| Eligible assignment expiration | 1 year |
- Convert existing permanent Global Admins to eligible assignments.
Useful Admin Operations¶
# Bulk create users from CSV
# CSV columns: DisplayName, UserPrincipalName, Department, JobTitle, UsageLocation
Connect-MgGraph -Scopes "User.ReadWrite.All"
Import-Csv .\users.csv | ForEach-Object {
$passwordProfile = @{
forceChangePasswordNextSignIn = $true
password = "TempPass$(Get-Random -Minimum 1000 -Maximum 9999)!"
}
$params = @{
displayName = $_.DisplayName
userPrincipalName = $_.UserPrincipalName
department = $_.Department
jobTitle = $_.JobTitle
usageLocation = $_.UsageLocation
passwordProfile = $passwordProfile
accountEnabled = $true
mailNickname = $_.UserPrincipalName.Split('@')[0]
}
New-MgUser -BodyParameter $params
Write-Output "Created: $($_.UserPrincipalName)"
}
# Assign licence to a user (e.g., Microsoft 365 Business Premium)
# Get SKU IDs
Get-MgSubscribedSku | Select-Object SkuPartNumber, SkuId
# Assign
$skuId = "<sku-guid>"
Set-MgUserLicense -UserId "user@domain.com" `
-AddLicenses @{ SkuId = $skuId } `
-RemoveLicenses @()