Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
alirezarezvani avatar

Ms365 Tenant Manager

  • 776 installs
  • 23.5k repo stars
  • Updated July 17, 2026
  • alirezarezvani/claude-skills

ms365-tenant-manager is a Claude Code skill that automates Microsoft 365 tenant setup, DNS configuration, security baselines, and compliance checklists for developers who ship business SaaS products on M365 identity and

About

ms365-tenant-manager is a Claude Code skill that guides Microsoft 365 tenant provisioning through a structured 5-phase checklist totaling about 3.5 hours. Phase 1 covers initial tenant configuration (3 tasks, ~30 minutes); phase 2 handles custom domain DNS (4 tasks, ~45 minutes); phase 3 applies a security baseline (5 tasks, ~60 minutes); later phases continue service and compliance setup. Developers reach for it when standing up Entra ID, Exchange Online, and policy guardrails for a SaaS product rather than clicking through the M365 admin center ad hoc. The skill encodes priority-tagged tasks so agents can execute tenant hardening in the right order.

  • 5-phase setup checklist with 17 total tasks across critical and high priority items
  • Generates 3 PowerShell scripts including Initial_Tenant_Setup.ps1 and Enable_Security_Baseline.ps1
  • Configures 11 DNS records (1 MX, 2 TXT, 6 CNAME, 2 SRV)
  • Recommends E3/E5 licensing mix with per-user monthly cost breakdowns
  • Delivers complete tenant, domain, security, service and compliance configuration

Ms365 Tenant Manager by the numbers

  • 776 all-time installs (skills.sh)
  • +5 installs in the week ending Jul 28, 2026 (Skillselion tracking)
  • Ranked #330 of 1,039 Cloud & Infrastructure skills by installs in the Skillselion catalog
  • Security screen: HIGH risk (skills.sh audit)
  • Data as of Jul 31, 2026 (Skillselion catalog sync)
npx skills add https://github.com/alirezarezvani/claude-skills --skill ms365-tenant-manager

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs776
repo stars23.5k
Security audit2 / 3 scanners passed
Last updatedJuly 17, 2026
Repositoryalirezarezvani/claude-skills

How do you automate Microsoft 365 tenant security setup?

Automate Microsoft 365 tenant setup, DNS configuration, security baseline, and compliance for business SaaS products.

Who is it for?

Developers or platform engineers provisioning a production Microsoft 365 tenant with DNS, Entra ID, and security baselines for a business SaaS product.

Skip if: Developers who only need a single OAuth app registration and already have a fully hardened enterprise tenant managed by IT.

When should I use this skill?

A developer asks to set up, harden, or configure a Microsoft 365 tenant with custom domains and security baselines.

What you get

Configured M365 tenant, verified custom domain DNS, applied security baseline policies, and a completed compliance checklist.

  • configured tenant
  • DNS records documentation
  • security baseline checklist

By the numbers

  • 5 setup phases with ~3.5 hours estimated total
  • Phase 3 security baseline includes 5 tasks (~60 minutes)
  • Phase 2 custom domain configuration includes 4 tasks (~45 minutes)

Files

SKILL.mdMarkdownGitHub ↗

Microsoft 365 Tenant Manager

Expert guidance and automation for Microsoft 365 Global Administrators managing tenant setup, user lifecycle, security policies, and organizational optimization.

---

Quick Start

Run a Security Audit

Connect-MgGraph -Scopes "Directory.Read.All","Policy.Read.All","AuditLog.Read.All"
Get-MgSubscribedSku | Select-Object SkuPartNumber, ConsumedUnits, @{N="Total";E={$_.PrepaidUnits.Enabled}}
Get-MgPolicyAuthorizationPolicy | Select-Object AllowInvitesFrom, DefaultUserRolePermissions

Bulk Provision Users from CSV

# CSV columns: DisplayName, UserPrincipalName, Department, LicenseSku
Import-Csv .\new_users.csv | ForEach-Object {
    $passwordProfile = @{ Password = (New-Guid).ToString().Substring(0,16) + "!"; ForceChangePasswordNextSignIn = $true }
    New-MgUser -DisplayName $_.DisplayName -UserPrincipalName $_.UserPrincipalName `
               -Department $_.Department -AccountEnabled -PasswordProfile $passwordProfile
}

Create a Conditional Access Policy (MFA for Admins)

$adminRoles = (Get-MgDirectoryRole | Where-Object { $_.DisplayName -match "Admin" }).Id
$policy = @{
    DisplayName = "Require MFA for Admins"
    State = "enabledForReportingButNotEnforced"   # Start in report-only mode
    Conditions = @{ Users = @{ IncludeRoles = $adminRoles } }
    GrantControls = @{ Operator = "OR"; BuiltInControls = @("mfa") }
}
New-MgIdentityConditionalAccessPolicy -BodyParameter $policy

Bundled Python Generators

Three stdlib tools generate the PowerShell artifacts deterministically — prefer them over hand-writing scripts for bulk/repeatable work. Sample input: sample_input.json; expected shape: expected_output.json.

# Tenant setup: checklist + DNS records + license plan (JSON), or the full setup script
python3 scripts/tenant_setup.py --config sample_input.json --format json -o tenant_plan.json
python3 scripts/tenant_setup.py --config sample_input.json --format powershell -o tenant_setup.ps1

# User lifecycle: validate first, then generate creation/offboarding scripts
python3 scripts/user_management.py --domain acme.com --action validate --users users.json
python3 scripts/user_management.py --domain acme.com --action create --users users.json -o create_users.ps1
python3 scripts/user_management.py --domain acme.com --action offboard --user-email jane@acme.com -o offboard.ps1

# Admin scripts: CA policy / security audit / bulk licensing
python3 scripts/powershell_generator.py --tenant-domain acme.com --task conditional-access --policy-config policy.json -o ca_policy.ps1
python3 scripts/powershell_generator.py --tenant-domain acme.com --task security-audit -o audit.ps1
python3 scripts/powershell_generator.py --tenant-domain acme.com --task bulk-license --users-csv users.csv --license-sku ENTERPRISEPACK -o licenses.ps1

Gate: for user creation, run --action validate first and require every entry to report "is_valid": true before generating the creation script. Review every generated .ps1 against the workflows below before running it in the tenant.

---

Workflows

Workflow 1: New Tenant Setup

Step 1: Generate Setup Checklist

Run python3 scripts/tenant_setup.py --config tenant.json --format json and work through setup_checklist phase by phase; dns_records feeds Step 2 and license_recommendations feeds the licensing workflow.

Confirm prerequisites before provisioning:

  • Global Admin account created and secured with MFA
  • Custom domain purchased and accessible for DNS edits
  • License SKUs confirmed (E3 vs E5 feature requirements noted)

Step 2: Configure and Verify DNS Records

# After adding the domain in the M365 admin center, verify propagation before proceeding
$domain = "company.com"
Resolve-DnsName -Name "_msdcs.$domain" -Type NS -ErrorAction SilentlyContinue
# Also run from a shell prompt:
# nslookup -type=MX company.com
# nslookup -type=TXT company.com   # confirm SPF record

Wait for DNS propagation (up to 48 h) before bulk user creation.

Step 3: Apply Security Baseline

# Disable legacy authentication (blocks Basic Auth protocols)
$policy = @{
    DisplayName = "Block Legacy Authentication"
    State = "enabled"
    Conditions = @{ ClientAppTypes = @("exchangeActiveSync","other") }
    GrantControls = @{ Operator = "OR"; BuiltInControls = @("block") }
}
New-MgIdentityConditionalAccessPolicy -BodyParameter $policy

# Enable unified audit log
Set-AdminAuditLogConfig -UnifiedAuditLogIngestionEnabled $true

Step 4: Provision Users

$licenseSku = (Get-MgSubscribedSku | Where-Object { $_.SkuPartNumber -eq "ENTERPRISEPACK" }).SkuId

Import-Csv .\employees.csv | ForEach-Object {
    try {
        $user = New-MgUser -DisplayName $_.DisplayName -UserPrincipalName $_.UserPrincipalName `
                           -AccountEnabled -PasswordProfile @{ Password = (New-Guid).ToString().Substring(0,12)+"!"; ForceChangePasswordNextSignIn = $true }
        Set-MgUserLicense -UserId $user.Id -AddLicenses @(@{ SkuId = $licenseSku }) -RemoveLicenses @()
        Write-Host "Provisioned: $($_.UserPrincipalName)"
    } catch {
        Write-Warning "Failed $($_.UserPrincipalName): $_"
    }
}

Validation: Spot-check 3–5 accounts in the M365 admin portal; confirm licenses show "Active."

---

Workflow 2: Security Hardening

Step 1: Run Security Audit

Connect-MgGraph -Scopes "Directory.Read.All","Policy.Read.All","AuditLog.Read.All","Reports.Read.All"

# Export Conditional Access policy inventory
Get-MgIdentityConditionalAccessPolicy | Select-Object DisplayName, State |
    Export-Csv .\ca_policies.csv -NoTypeInformation

# Find accounts without MFA registered
$report = Get-MgReportAuthenticationMethodUserRegistrationDetail
$report | Where-Object { -not $_.IsMfaRegistered } |
    Select-Object UserPrincipalName, IsMfaRegistered |
    Export-Csv .\no_mfa_users.csv -NoTypeInformation

Write-Host "Audit complete. Review ca_policies.csv and no_mfa_users.csv."

Step 2: Create MFA Policy (report-only first)

$policy = @{
    DisplayName = "Require MFA All Users"
    State = "enabledForReportingButNotEnforced"
    Conditions = @{ Users = @{ IncludeUsers = @("All") } }
    GrantControls = @{ Operator = "OR"; BuiltInControls = @("mfa") }
}
New-MgIdentityConditionalAccessPolicy -BodyParameter $policy

Validation: After 48 h, review Sign-in logs in Entra ID; confirm expected users would be challenged, then change State to "enabled".

Step 3: Review Secure Score

# Retrieve current Secure Score and top improvement actions
Get-MgSecuritySecureScore -Top 1 | Select-Object CurrentScore, MaxScore, ActiveUserCount
Get-MgSecuritySecureScoreControlProfile | Sort-Object -Property ActionType |
    Select-Object Title, ImplementationStatus, MaxScore | Format-Table -AutoSize

---

Workflow 3: User Offboarding

Step 1: Block Sign-in and Revoke Sessions

$upn = "departing.user@company.com"
$user = Get-MgUser -Filter "userPrincipalName eq '$upn'"

# Block sign-in immediately
Update-MgUser -UserId $user.Id -AccountEnabled:$false

# Revoke all active tokens
Invoke-MgInvalidateAllUserRefreshToken -UserId $user.Id
Write-Host "Sign-in blocked and sessions revoked for $upn"

Step 2: Preview with -WhatIf (license removal)

# Identify assigned licenses
$licenses = (Get-MgUserLicenseDetail -UserId $user.Id).SkuId

# Dry-run: print what would be removed
$licenses | ForEach-Object { Write-Host "[WhatIf] Would remove SKU: $_" }

Step 3: Execute Offboarding

# Remove licenses
Set-MgUserLicense -UserId $user.Id -AddLicenses @() -RemoveLicenses $licenses

# Convert mailbox to shared (requires ExchangeOnlineManagement module)
Set-Mailbox -Identity $upn -Type Shared

# Remove from all groups
Get-MgUserMemberOf -UserId $user.Id | ForEach-Object {
    try { Remove-MgGroupMemberByRef -GroupId $_.Id -DirectoryObjectId $user.Id } catch {}
}
Write-Host "Offboarding complete for $upn"

Validation: Confirm in the M365 admin portal that the account shows "Blocked," has no active licenses, and the mailbox type is "Shared."

---

Best Practices

Tenant Setup

1. Enable MFA before adding users 2. Configure named locations for Conditional Access 3. Use separate admin accounts with PIM 4. Verify custom domains (and DNS propagation) before bulk user creation 5. Apply Microsoft Secure Score recommendations

Security Operations

1. Start Conditional Access policies in report-only mode 2. Review Sign-in logs for 48 h before enforcing a new policy 3. Never hardcode credentials in scripts — use Azure Key Vault or Get-Credential 4. Enable unified audit logging for all operations 5. Conduct quarterly security reviews and Secure Score check-ins

PowerShell Automation

1. Prefer Microsoft Graph (Microsoft.Graph module) over legacy MSOnline 2. Include try/catch blocks for error handling 3. Implement Write-Host/Write-Warning logging for audit trails 4. Use -WhatIf or dry-run output before bulk destructive operations 5. Test in a non-production tenant first

---

Reference Guides

references/powershell-templates.md

  • Ready-to-use script templates
  • Conditional Access policy examples
  • Bulk user provisioning scripts
  • Security audit scripts

references/security-policies.md

  • Conditional Access configuration
  • MFA enforcement strategies
  • DLP and retention policies
  • Security baseline settings

references/troubleshooting.md

  • Common error resolutions
  • PowerShell module issues
  • Permission troubleshooting
  • DNS propagation problems

---

Limitations

ConstraintImpact
Global Admin requiredFull tenant setup needs highest privilege
API rate limitsBulk operations may be throttled
License dependenciesE3/E5 required for advanced features
Hybrid scenariosOn-premises AD needs additional configuration
PowerShell prerequisitesMicrosoft.Graph module required

Required PowerShell Modules

Install-Module Microsoft.Graph -Scope CurrentUser
Install-Module ExchangeOnlineManagement -Scope CurrentUser
Install-Module MicrosoftTeams -Scope CurrentUser

Required Permissions

  • Global Administrator — Full tenant setup
  • User Administrator — User management
  • Security Administrator — Security policies
  • Exchange Administrator — Mailbox management

Related skills

How it compares

Use ms365-tenant-manager when you need a phased M365 hardening checklist rather than one-off PowerShell snippets for a single setting.

FAQ

How long does ms365-tenant-manager take?

ms365-tenant-manager structures Microsoft 365 setup into 5 phases with an estimated total of 3.5 hours. Early phases cover initial tenant config and custom domain DNS before a 5-task security baseline phase.

What does ms365-tenant-manager configure?

ms365-tenant-manager automates Microsoft 365 tenant setup including custom domain DNS, security baseline policies, and compliance steps for business SaaS products using Entra ID and Exchange Online.

Is Ms365 Tenant Manager safe to install?

skills.sh reports 2 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.