Microsoft Entra ID (formerly Azure AD) is Microsoft’s cloud identity service for centralized management of users, groups and resources in a Microsoft 365 environment.
Installation and connection
Action PowerShell Command Install Microsoft Graph Install-Module Microsoft.Graph -ForceInstall Entra (preview) Install-Module Microsoft.Graph.Entra -AllowPrereleaseConnect (Graph) Connect-MgGraph -Scopes "User.ReadWrite.All","Group.ReadWrite.All"Connect (Entra) Connect-EntraVerify connection Get-MgContextDisconnect Disconnect-MgGraph
User management
Action Microsoft Graph Command List all users Get-MgUser -AllSearch user Get-MgUser -Filter "DisplayName eq 'John Doe'"Full details Get-MgUser -UserId "jdoe@domain.com" -Property *Search by UPN Get-MgUser -Filter "UserPrincipalName eq 'jdoe@domain.com'"Partial search Get-MgUser -Filter "startswith(DisplayName,'John')"Users with email Get-MgUser -Filter "Mail ne null"
Creating and modifying users
Action Command Create simple user New-MgUser -DisplayName "John Doe" -UserPrincipalName "jdoe@domain.com" -MailNickname "jdoe" -AccountEnabledCreate with password $PasswordProfile = @{ Password = "TempPass123!" ; ForceChangePasswordNextSignIn = $true } New-MgUser -DisplayName "John Doe" -UserPrincipalName "jdoe@domain.com" -PasswordProfile $PasswordProfileModify display name Update-MgUser -UserId "jdoe@domain.com" -DisplayName "John Smith"Modify email Update-MgUser -UserId "jdoe@domain.com" -Mail "john.smith@domain.com"Modify department Update-MgUser -UserId "jdoe@domain.com" -Department "IT"Modify phone Update-MgUser -UserId "jdoe@domain.com" -BusinessPhones @("+1-555-123-4567")
Account states
Action Command Disable account Update-MgUser -UserId "jdoe@domain.com" -AccountEnabled:$falseEnable account Update-MgUser -UserId "jdoe@domain.com" -AccountEnabled:$trueReset password Update-MgUser -UserId "jdoe@domain.com" -PasswordProfile @{ Password = "NewPass123!" ; ForceChangePasswordNextSignIn = $true }Delete user Remove-MgUser -UserId "jdoe@domain.com"Revoke sessions Revoke-MgUserSignInSession -UserId "jdoe@domain.com"
MFA and authentication management
Action Command View auth methods Get-MgUserAuthenticationMethod -UserId "jdoe@domain.com"View MFA phones Get-MgUserAuthenticationPhoneMethod -UserId "jdoe@domain.com"View MFA emails Get-MgUserAuthenticationEmailMethod -UserId "jdoe@domain.com"Reset all MFA methods Get-MgUserAuthenticationMethod -UserId "jdoe@domain.com" | Remove-MgUserAuthenticationMethod -UserId "jdoe@domain.com"Force MFA re-registration Reset-MgUserAuthenticationMethodRegistration -UserId "jdoe@domain.com"Add MFA phone New-MgUserAuthenticationPhoneMethod -UserId "jdoe@domain.com" -PhoneNumber "+15551234567" -PhoneType "mobile"
Note
Important difference :
Reset all methods = PHYSICALLY DELETES all methods (phones, apps, etc.) - User must reconfigure everything
Force re-registration = KEEPS methods but forces revalidation on next login - Less destructive
Group management
Action Command List groups Get-MgGroup -AllSearch group Get-MgGroup -Filter "DisplayName eq 'IT Team'"Group members Get-MgGroupMember -GroupId "group-id"Create security group New-MgGroup -DisplayName "IT Team" -SecurityEnabled -MailEnabled:$falseCreate Office 365 group New-MgGroup -DisplayName "Marketing" -GroupTypes @("Unified") -MailEnabled -SecurityEnabledAdd member New-MgGroupMember -GroupId "group-id" -DirectoryObjectId "user-id"Remove member Remove-MgGroupMember -GroupId "group-id" -DirectoryObjectId "user-id"Delete group Remove-MgGroup -GroupId "group-id"
Microsoft 365 Licenses
Action Command View available licenses Get-MgSubscribedSkuUser’s licenses Get-MgUserLicenseDetail -UserId "jdoe@domain.com"Assign license Set-MgUserLicense -UserId "jdoe@domain.com" -AddLicenses @{SkuId = "sku-id"} -RemoveLicenses @()Remove license Set-MgUserLicense -UserId "jdoe@domain.com" -AddLicenses @() -RemoveLicenses @("sku-id")Unlicensed users Get-MgUser -Filter "assignedLicenses/$count eq 0” -ConsistencyLevel eventual -CountVariable unlicensed`
Common licenses and their SKUs
SKU = Stock Keeping Unit, unique identifier for each Microsoft license in the system
License SKU PartNumber Type Description Microsoft 365 E3 SPE_E3Enterprise Complete license with Office, Teams, SharePoint Microsoft 365 E5 SPE_E5Enterprise E3 + advanced security, compliance, analytics Microsoft 365 F3 SPE_F1Frontline For frontline workers (no desktop Office) Copilot for M365 Microsoft_365_CopilotAdd-on Generative AI (requires E3/E5/Business Premium) Power BI Pro POWER_BI_PROAnalytics Reports and dashboards
Practical examples
# Count assigned E3 licenses
( Get-MgUser - Filter " assignedLicenses/any(x:x/skuId eq (Get-MgSubscribedSku | Where SkuPartNumber -eq 'SPE_E3').SkuId) " - ConsistencyLevel eventual).Count
# Assign E5 license to a user
$E5Sku = ( Get-MgSubscribedSku | Where SkuPartNumber -eq ' SPE_E5 ' ).SkuId
Set-MgUserLicense - UserId " jdoe@domain.com " - AddLicenses @ {SkuId = $E5Sku} - RemoveLicenses @ ()
# List users with Copilot
Get-MgUser - Filter " assignedLicenses/any(x:x/skuId eq (Get-MgSubscribedSku | Where SkuPartNumber -eq 'Microsoft_365_Copilot').SkuId) " - ConsistencyLevel eventual
Useful export scripts
Export active users
Get-MgUser - Filter " AccountEnabled eq true " - Property DisplayName , UserPrincipalName , Department , JobTitle , CreatedDateTime |
Export-Csv - Path " ActiveUsers.csv " - NoTypeInformation - Encoding UTF8
Export groups and members
$Groups = Get-MgGroup - All
$Results = foreach ($Group in $Groups) {
$Members = Get-MgGroupMember - GroupId $Group.Id
foreach ($Member in $Members) {
[ PSCustomObject ] @ {
GroupName = $Group.DisplayName
GroupId = $Group.Id
MemberName = ( Get-MgUser - UserId $Member.Id).DisplayName
MemberUPN = ( Get-MgUser - UserId $Member.Id).UserPrincipalName
}
}
}
$Results | Export-Csv - Path " GroupsAndMembers.csv " - NoTypeInformation - Encoding UTF8
Export users with licenses
$Users = Get-MgUser - All - Property DisplayName , UserPrincipalName , AssignedLicenses
$Results = foreach ($User in $Users) {
$Licenses = $User.AssignedLicenses | ForEach-Object {
( Get-MgSubscribedSku | Where-Object SkuId -eq $_ .SkuId ).SkuPartNumber
}
[ PSCustomObject ] @ {
DisplayName = $User.DisplayName
UserPrincipalName = $User.UserPrincipalName
Licenses = $Licenses -join " ; "
}
}
$Results | Export-Csv - Path " UsersLicenses.csv " - NoTypeInformation - Encoding UTF8
Export last sign-ins
Get-MgUser - All - Property DisplayName , UserPrincipalName , SignInActivity |
Select-Object DisplayName , UserPrincipalName , @ {Name = " LastSignIn " ;Expression = { $_ .SignInActivity.LastSignInDateTime }} |
Export-Csv - Path " LastSignIns.csv " - NoTypeInformation - Encoding UTF8
Bulk user creation script
Script
# Microsoft Graph installation and connection
if ( ! ( Get-Module - ListAvailable - Name Microsoft.Graph)) {
Write-Host " Installing Microsoft.Graph module... " - ForegroundColor Green
Install-Module - Name Microsoft.Graph - Force - Scope CurrentUser
}
# Install ImportExcel module for CSV processing
if ( ! ( Get-Module - ListAvailable - Name ImportExcel)) {
Write-Host " Installing ImportExcel module... " - ForegroundColor Green
Install-Module - Name ImportExcel - Force - Scope CurrentUser
}
# Connect with required permissions
Write-Host " Connecting to Microsoft Graph... " - ForegroundColor Green
Connect-MgGraph - Scopes " User.ReadWrite.All " , " Group.ReadWrite.All "
# General configuration (adapt to your environment)
$csvPath = " C:\temp\NewUsers.csv "
$logPath = " C:\temp\user_creation_log.txt "
$mainDomain = " mycompany.com "
$defaultDepartment = " IT "
$defaultCountry = " United States "
$usageLocation = " US "
# Create log file
New-Item - Path $logPath - ItemType File - Force
Write-Host " Log file created: $logPath " - ForegroundColor Yellow
# Import CSV data (expected columns: FirstName, LastName, JobTitle, Department)
if ( Test-Path $csvPath) {
$users = Import-Csv - Path $csvPath - Delimiter " ; "
Write-Host " CSV file imported: $ ( $users.Count ) users found " - ForegroundColor Green
} else {
Write-Host " CSV file not found: $csvPath " - ForegroundColor Red
exit
}
# Function to generate a secure password
function New-RandomPassword {
param ([ int ]$Length = 12 )
$chars = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$% "
return -join (( 1 .. $Length) | ForEach-Object { $chars[( Get-Random - Maximum $chars.Length)] })
}
# User creation loop
foreach ($user in $users) {
# Check required fields
if ([ string ]::IsNullOrWhiteSpace($user.FirstName) -or [ string ]::IsNullOrWhiteSpace($user.LastName)) {
$message = " ERROR: First name or last name missing for user on line $ ( $users.IndexOf ( $user ) + 2 ) "
Write-Host $message - ForegroundColor Red
Add-Content - Path $logPath - Value " $ ( Get-Date - Format ' yyyy-MM-dd HH:mm:ss ' ) - $message "
continue
}
# Generate user information
$firstName = $user.FirstName.Trim()
$lastName = $user.LastName.Trim()
$displayName = " $firstName $lastName "
$mailNickname = " $ ( $firstName.ToLower ()) . $ ( $lastName.ToLower ()) "
$email = " $mailNickname @ $mainDomain "
$password = New-RandomPassword
$jobTitle = if ( ! [ string ]::IsNullOrWhiteSpace($user.JobTitle)) { $user.JobTitle } else { " User " }
$department = if ( ! [ string ]::IsNullOrWhiteSpace($user.Department)) { $user.Department } else { $defaultDepartment }
Write-Host " Creating user: $displayName ( $email ) " - ForegroundColor Cyan
try {
# Check if user already exists
$existingUser = Get-MgUser - Filter " UserPrincipalName eq ' $email ' " - ErrorAction SilentlyContinue
if ($existingUser) {
$message = " WARNING: User $email already exists "
Write-Host $message - ForegroundColor Yellow
Add-Content - Path $logPath - Value " $ ( Get-Date - Format ' yyyy-MM-dd HH:mm:ss ' ) - $message "
continue
}
# Create user
$passwordProfile = @ {
Password = $password
ForceChangePasswordNextSignIn = $true
}
$newUser = @ {
DisplayName = $displayName
UserPrincipalName = $email
MailNickname = $mailNickname
GivenName = $firstName
Surname = $lastName
JobTitle = $jobTitle
Department = $department
Country = $defaultCountry
UsageLocation = $usageLocation
PasswordProfile = $passwordProfile
AccountEnabled = $true
}
$userCreated = New-MgUser @newUser
# Success log with password
$successMessage = " SUCCESS: User $displayName created | Email: $email | Password: $password "
Write-Host " User created successfully " - ForegroundColor Green
Add-Content - Path $logPath - Value " $ ( Get-Date - Format ' yyyy-MM-dd HH:mm:ss ' ) - $successMessage "
# Pause to avoid rate limiting
Start-Sleep - Milliseconds 500
} catch {
# Error log
$errorMessage = " ERROR: Failed to create $displayName ( $email ) - $ ( $_ .Exception.Message ) "
Write-Host " Error during creation: $ ( $_ .Exception.Message ) " - ForegroundColor Red
Add-Content - Path $logPath - Value " $ ( Get-Date - Format ' yyyy-MM-dd HH:mm:ss ' ) - $errorMessage "
}
}
Write-Host " `n === SUMMARY === " - ForegroundColor Magenta
Write-Host " Script completed. Check the log file for details: $logPath " - ForegroundColor Yellow
Write-Host " To assign licenses, use: Set-MgUserLicense " - ForegroundColor Yellow
# Disconnect
Disconnect-MgGraph
Create a CSV file with these columns (; delimiter):
FirstName;LastName;JobTitle;Department
John;Doe;System Administrator;IT
Jane;Smith;Developer;IT
Peter;Johnson;Project Manager;Marketing
Sarah;Williams;Accountant;Finance
Script key points
Secure : Robust random password generation
Complete logging : All successes/failures are tracked
Rate limiting : Pause between creations to avoid API errors
Validation : Checks if user exists before creation
Licenses
License assignment
# View available licenses
Get-MgSubscribedSku
# Set location (required)
Update-MgUser - UserId " john@domain.com " - UsageLocation " US "
# Assign a license
$SkuId = ( Get-MgSubscribedSku | Where-Object { $_ .SkuPartNumber -eq " SPE_E3 " }).SkuId
Set-MgUserLicense - UserId " john@domain.com " - AddLicenses @ ( @ {SkuId = $SkuId}) - RemoveLicenses @ ()
Microsoft Entra ID Admin Center