DanpLab · Lab NoteArchitettura operativa
Microsoft Entra ID, Azure & Intune: modern identity management
Practical guide to identity management with Microsoft Entra ID (formerly Azure AD), Intune for device management and automation with PowerShell and Graph API. Real-world examples of onboarding, Conditional Access and compliance.
4 min readBased on real operational use
microsoftentraintuneazurepowershell
The modern Microsoft identity model
Microsoft has unified identity management under Microsoft Entra ID (formerly Azure Active Directory). In a hybrid environment, Entra ID synchronizes with on-premises Active Directory via Entra Connect.
On-Premise Cloud
┌───────────────┐ ┌───────────────────────┐
│ Active │ Entra │ Microsoft Entra ID │
│ Directory │◄──Connect──►│ (ex Azure AD) │
│ Domain │ │ │
└───────────────┘ │ ┌─────────────────┐ │
│ │ Microsoft 365 │ │
│ │ Intune │ │
│ │ Azure │ │
│ └─────────────────┘ │
└───────────────────────┘
Entra Connect: hybrid configuration
Installation and synchronization
Import-Module ADSync
Get-ADSyncConnectorRunStatus
Start-ADSyncSyncCycle -PolicyType Delta
Start-ADSyncSyncCycle -PolicyType Initial
Verify synchronized users
Connect-MgGraph -Scopes "User.Read.All"
Get-MgUser -Filter "onPremisesSyncEnabled eq true" |
Select DisplayName, UserPrincipalName, OnPremisesSyncEnabled
Conditional Access: access policies
Conditional Access is the policy system that decides who can access what, from where, and under what conditions.
Base policy: MFA for external access
{
"displayName": "Require MFA - External Access",
"state": "enabled",
"conditions": {
"users": {
"includeGroups": ["All Users"]
},
"locations": {
"excludeLocations": ["Named Location - Office"]
}
},
"grantControls": {
"operator": "OR",
"builtInControls": ["mfa"]
}
}
Policy: block high-risk countries
$params = @{
"@odata.type" = "#microsoft.graph.countriesAndRegionsNamedLocation"
DisplayName = "Allowed Countries"
CountriesAndRegions = @("IT", "US", "GB", "DE")
IncludeUnknownCountriesAndRegions = $false
}
New-MgIdentityConditionalAccessNamedLocation -BodyParameter $params
Intune: Device Management
Windows automatic enrollment
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\MDM" `
-Name "AutoEnrollMDM" -Value 1 -Type DWord
Windows 10/11 Compliance Policy
Configure from Intune → Devices → Compliance policies:
{
"displayName": "Windows Compliance - Standard",
"scheduledActionsForRule": [{
"ruleName": "NonCompliant",
"scheduledActionConfigurations": [{
"actionType": "block",
"gracePeriodHours": 48
}]
}],
"settings": {
"bitLockerEnabled": true,
"codeIntegrityEnabled": true,
"secureBootEnabled": true,
"defenderEnabled": true,
"osMinimumVersion": "10.0.19041",
"passwordRequired": true,
"passwordMinimumLength": 12,
"passwordRequiredType": "alphanumeric"
}
}
Automation with PowerShell and Graph API
Script: complete onboarding
param(
[string]$Nome,
[string]$Cognome,
[string]$Reparto,
[string]$Ruolo,
[string]$Manager
)
Connect-MgGraph -Scopes "User.ReadWrite.All", "Group.ReadWrite.All"
$username = "$($Nome.ToLower()).$($Cognome.ToLower())"
$upn = "[email protected]"
$password = [System.Web.Security.Membership]::GeneratePassword(14, 3)
$newUser = New-MgUser -DisplayName "$Nome $Cognome" `
-UserPrincipalName $upn `
-MailNickname $username `
-AccountEnabled $true `
-Department $Reparto `
-JobTitle $Ruolo `
-PasswordProfile @{
Password = $password
ForceChangePasswordNextSignIn = $true
}
Write-Host "✅ Utente creato: $upn"
$skuId = (Get-MgSubscribedSku | Where {$_.SkuPartNumber -eq "SPB"}).SkuId
Set-MgUserLicense -UserId $newUser.Id `
-AddLicenses @{SkuId = $skuId} `
-RemoveLicenses @()
Write-Host "✅ Licenza assegnata"
$groupId = (Get-MgGroup -Filter "displayName eq '$Reparto'").Id
New-MgGroupMember -GroupId $groupId -DirectoryObjectId $newUser.Id
Write-Host "✅ Aggiunto al gruppo $Reparto"
Write-Host "`n=== CREDENZIALI ==="
Write-Host "Username: $upn"
Write-Host "Password temporanea: $password"
Script: license report
Connect-MgGraph -Scopes "Directory.Read.All"
Get-MgSubscribedSku | ForEach-Object {
[PSCustomObject]@{
Prodotto = $_.SkuPartNumber
Acquistate = $_.PrepaidUnits.Enabled
Assegnate = $_.ConsumedUnits
Disponibili = $_.PrepaidUnits.Enabled - $_.ConsumedUnits
}
} | Format-Table -AutoSize
BitLocker with Intune
Automatic BitLocker policy
$devices = Get-MgDeviceManagementManagedDevice -All
foreach ($device in $devices) {
if ($device.OperatingSystem -eq "Windows") {
$compliance = Get-MgDeviceManagementManagedDeviceCompliancePolicyState `
-ManagedDeviceId $device.Id
[PSCustomObject]@{
Device = $device.DeviceName
User = $device.UserDisplayName
BitLocker = ($compliance | Where {$_.DisplayName -match "BitLocker"}).State
OS = $device.OsVersion
}
}
} | Export-Csv "bitlocker-report.csv" -NoTypeInformation
Best Practices
- ✅ Entra ID P2 for Privileged Identity Management (PIM) — just-in-time privileged access
- ✅ Clear naming convention for groups and app registrations
- ✅ Breakglass account — at least 2 admin accounts excluded from Conditional Access
- ✅ Audit logs enabled and monitored (at least 90 days)
- ✅ App registrations with least necessary permissions
- ❌ Avoid Global Admin for daily operations — use specific roles
- ❌ Do not sync on-prem AD service accounts to the cloud