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
Karl Certa
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 "[email protected]" -Property *
Search by UPNGet-MgUser -Filter "UserPrincipalName eq '[email protected]'"
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 "[email protected]" -MailNickname "jdoe" -AccountEnabled
Create with password$PasswordProfile = @{ Password = "TempPass123!" ; ForceChangePasswordNextSignIn = $true }
New-MgUser -DisplayName "John Doe" -UserPrincipalName "[email protected]" -PasswordProfile $PasswordProfile
Modify display nameUpdate-MgUser -UserId "[email protected]" -DisplayName "John Smith"
Modify emailUpdate-MgUser -UserId "[email protected]" -Mail "[email protected]"
Modify departmentUpdate-MgUser -UserId "[email protected]" -Department "IT"
Modify phoneUpdate-MgUser -UserId "[email protected]" -BusinessPhones @("+1-555-123-4567")

Account states

ActionCommand
Disable accountUpdate-MgUser -UserId "[email protected]" -AccountEnabled:$false
Enable accountUpdate-MgUser -UserId "[email protected]" -AccountEnabled:$true
Reset passwordUpdate-MgUser -UserId "[email protected]" -PasswordProfile @{ Password = "NewPass123!" ; ForceChangePasswordNextSignIn = $true }
Delete userRemove-MgUser -UserId "[email protected]"
Revoke sessionsRevoke-MgUserSignInSession -UserId "[email protected]"

MFA and authentication management

ActionCommand
View auth methodsGet-MgUserAuthenticationMethod -UserId "[email protected]"
View MFA phonesGet-MgUserAuthenticationPhoneMethod -UserId "[email protected]"
View MFA emailsGet-MgUserAuthenticationEmailMethod -UserId "[email protected]"
Reset all MFA methodsGet-MgUserAuthenticationMethod -UserId "[email protected]" | Remove-MgUserAuthenticationMethod -UserId "[email protected]"
Force MFA re-registrationReset-MgUserAuthenticationMethodRegistration -UserId "[email protected]"
Add MFA phoneNew-MgUserAuthenticationPhoneMethod -UserId "[email protected]" -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 "[email protected]"
Assign licenseSet-MgUserLicense -UserId "[email protected]" -AddLicenses @{SkuId = "sku-id"} -RemoveLicenses @()
Remove licenseSet-MgUserLicense -UserId "[email protected]" -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 "[email protected]" -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 "[email protected]" -UsageLocation "US"
 
# Assign a license
$SkuId = (Get-MgSubscribedSku | Where-Object {$_.SkuPartNumber -eq "SPE_E3"}).SkuId
Set-MgUserLicense -UserId "[email protected]" -AddLicenses @(@{SkuId=$SkuId}) -RemoveLicenses @()