Skip to content

Users & Groups

This covers some of the recommended settings to help secure the user and group in 365.

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 Stop random groups; 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

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}}

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