skip to content

Search

Syspirit
EN

Azure AD / Entra ID

Azure AD / Entra ID administration with Microsoft Graph PowerShell - users, groups, MFA and daily tasks!

365
Published on
Updated on

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

ActionPowerShell Command
Install Microsoft GraphInstall-Module Microsoft.Graph -Force
Install Entra (preview)Install-Module Microsoft.Graph.Entra -AllowPrerelease
Connect (Graph)Connect-MgGraph -Scopes "User.ReadWrite.All","Group.ReadWrite.All"
Connect (Entra)Connect-Entra
Verify connectionGet-MgContext
DisconnectDisconnect-MgGraph

User management

ActionMicrosoft Graph Command
List all usersGet-MgUser -All
Search userGet-MgUser -Filter "DisplayName eq 'John Doe'"
Full detailsGet-MgUser -UserId "jdoe@domain.com" -Property *
Search by UPNGet-MgUser -Filter "UserPrincipalName eq 'jdoe@domain.com'"
Partial searchGet-MgUser -Filter "startswith(DisplayName,'John')"
Users with emailGet-MgUser -Filter "Mail ne null"

Creating and modifying users

ActionCommand
Create simple userNew-MgUser -DisplayName "John Doe" -UserPrincipalName "jdoe@domain.com" -MailNickname "jdoe" -AccountEnabled
Create with password$PasswordProfile = @{ Password = "TempPass123!" ; ForceChangePasswordNextSignIn = $true }
New-MgUser -DisplayName "John Doe" -UserPrincipalName "jdoe@domain.com" -PasswordProfile $PasswordProfile
Modify display nameUpdate-MgUser -UserId "jdoe@domain.com" -DisplayName "John Smith"
Modify emailUpdate-MgUser -UserId "jdoe@domain.com" -Mail "john.smith@domain.com"
Modify departmentUpdate-MgUser -UserId "jdoe@domain.com" -Department "IT"
Modify phoneUpdate-MgUser -UserId "jdoe@domain.com" -BusinessPhones @("+1-555-123-4567")

Account states

ActionCommand
Disable accountUpdate-MgUser -UserId "jdoe@domain.com" -AccountEnabled:$false
Enable accountUpdate-MgUser -UserId "jdoe@domain.com" -AccountEnabled:$true
Reset passwordUpdate-MgUser -UserId "jdoe@domain.com" -PasswordProfile @{ Password = "NewPass123!" ; ForceChangePasswordNextSignIn = $true }
Delete userRemove-MgUser -UserId "jdoe@domain.com"
Revoke sessionsRevoke-MgUserSignInSession -UserId "jdoe@domain.com"

MFA and authentication management

ActionCommand
View auth methodsGet-MgUserAuthenticationMethod -UserId "jdoe@domain.com"
View MFA phonesGet-MgUserAuthenticationPhoneMethod -UserId "jdoe@domain.com"
View MFA emailsGet-MgUserAuthenticationEmailMethod -UserId "jdoe@domain.com"
Reset all MFA methodsGet-MgUserAuthenticationMethod -UserId "jdoe@domain.com" | Remove-MgUserAuthenticationMethod -UserId "jdoe@domain.com"
Force MFA re-registrationReset-MgUserAuthenticationMethodRegistration -UserId "jdoe@domain.com"
Add MFA phoneNew-MgUserAuthenticationPhoneMethod -UserId "jdoe@domain.com" -PhoneNumber "+15551234567" -PhoneType "mobile"

Group management

ActionCommand
List groupsGet-MgGroup -All
Search groupGet-MgGroup -Filter "DisplayName eq 'IT Team'"
Group membersGet-MgGroupMember -GroupId "group-id"
Create security groupNew-MgGroup -DisplayName "IT Team" -SecurityEnabled -MailEnabled:$false
Create Office 365 groupNew-MgGroup -DisplayName "Marketing" -GroupTypes @("Unified") -MailEnabled -SecurityEnabled
Add memberNew-MgGroupMember -GroupId "group-id" -DirectoryObjectId "user-id"
Remove memberRemove-MgGroupMember -GroupId "group-id" -DirectoryObjectId "user-id"
Delete groupRemove-MgGroup -GroupId "group-id"

Microsoft 365 Licenses

ActionCommand
View available licensesGet-MgSubscribedSku
User’s licensesGet-MgUserLicenseDetail -UserId "jdoe@domain.com"
Assign licenseSet-MgUserLicense -UserId "jdoe@domain.com" -AddLicenses @{SkuId = "sku-id"} -RemoveLicenses @()
Remove licenseSet-MgUserLicense -UserId "jdoe@domain.com" -AddLicenses @() -RemoveLicenses @("sku-id")
Unlicensed usersGet-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

LicenseSKU PartNumberTypeDescription
Microsoft 365 E3SPE_E3EnterpriseComplete license with Office, Teams, SharePoint
Microsoft 365 E5SPE_E5EnterpriseE3 + advanced security, compliance, analytics
Microsoft 365 F3SPE_F1FrontlineFor frontline workers (no desktop Office)
Copilot for M365Microsoft_365_CopilotAdd-onGenerative AI (requires E3/E5/Business Premium)
Power BI ProPOWER_BI_PROAnalyticsReports 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

Expected CSV format

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 @()