Microsoft 365 Security Check Tool

<#
.SYNOPSIS
Microsoft 365 Security Check Tool

.DESCRIPTION
This script analyzes and audits various security aspects of a Microsoft 365 environment,
providing insights into user accounts, licenses, Exchange Online, SharePoint Online,
Teams, and other security settings.

.NOTES
File Name      : M365SecurityCheckTool.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, Microsoft 365 PowerShell modules, and appropriate admin permissions
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\M365SecurityCheckTool.ps1
#>

# Check and install required modules
$requiredModules = @("MSOnline", "ExchangeOnlineManagement", "Microsoft.Online.SharePoint.PowerShell", "MicrosoftTeams", "AzureAD")
foreach ($module in $requiredModules) {
    if (!(Get-Module -ListAvailable -Name $module)) {
        Write-Host "Installing $module module..." -ForegroundColor Yellow
        Install-Module -Name $module -Force -AllowClobber
    }
}

# Import required modules
Import-Module MSOnline
Import-Module ExchangeOnlineManagement
Import-Module Microsoft.Online.SharePoint.PowerShell
Import-Module MicrosoftTeams
Import-Module AzureAD

# Global variables
$global:reportPath = "$env:USERPROFILE\Desktop\M365_Security_Analysis_Report_$(Get-Date -Format 'yyyyMMdd_HHmmss').html"

<#
.SYNOPSIS
Displays the main menu of the tool.
#>
function Show-Menu {
    Clear-Host
    Write-Host "=== Microsoft 365 Security Check Tool ===" -ForegroundColor Cyan
    Write-Host "1. Analyze User Accounts and MFA Status"
    Write-Host "2. Check License Assignments"
    Write-Host "3. Analyze Exchange Online Security Settings"
    Write-Host "4. Check SharePoint Online and OneDrive Security"
    Write-Host "5. Analyze Teams Security Settings"
    Write-Host "6. Check Azure AD Security Configuration"
    Write-Host "7. Analyze Conditional Access Policies"
    Write-Host "8. Check Data Loss Prevention Policies"
    Write-Host "9. Analyze Audit Log Settings"
    Write-Host "10. Generate Comprehensive HTML Report"
    Write-Host "11. Exit"
}

<#
.SYNOPSIS
Connects to Microsoft 365 services.
#>
function Connect-M365Services {
    Write-Host "Connecting to Microsoft 365 services..." -ForegroundColor Yellow
    Connect-MsolService
    Connect-ExchangeOnline
    $orgName = (Get-MsolCompanyInformation).DisplayName
    $adminSiteUrl = "https://$($orgName.Replace(' ', ''))-admin.sharepoint.com"
    Connect-SPOService -Url $adminSiteUrl
    Connect-MicrosoftTeams
    Connect-AzureAD
}

<#
.SYNOPSIS
Analyzes user accounts and MFA status.

.OUTPUTS
Array of PSObjects containing user account and MFA details.
#>
function Analyze-UserAccountsAndMFA {
    Write-Host "`nAnalyzing User Accounts and MFA Status..." -ForegroundColor Yellow
    $users = Get-MsolUser -All
    $results = @()
    foreach ($user in $users) {
        $mfaStatus = if ($user.StrongAuthenticationRequirements.State) { $user.StrongAuthenticationRequirements.State } else { "Disabled" }
        $results += [PSCustomObject]@{
            UserPrincipalName = $user.UserPrincipalName
            DisplayName = $user.DisplayName
            IsLicensed = $user.IsLicensed
            MFAStatus = $mfaStatus
            LastPasswordChangeTimestamp = $user.LastPasswordChangeTimestamp
            BlockCredential = $user.BlockCredential
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Checks license assignments.

.OUTPUTS
Array of PSObjects containing license assignment details.
#>
function Check-LicenseAssignments {
    Write-Host "`nChecking License Assignments..." -ForegroundColor Yellow
    $licenses = Get-MsolAccountSku
    $results = @()
    foreach ($license in $licenses) {
        $results += [PSCustomObject]@{
            AccountSkuId = $license.AccountSkuId
            ActiveUnits = $license.ActiveUnits
            ConsumedUnits = $license.ConsumedUnits
            AvailableUnits = ($license.ActiveUnits - $license.ConsumedUnits)
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Analyzes Exchange Online security settings.

.OUTPUTS
PSObject containing Exchange Online security settings.
#>
function Analyze-ExchangeOnlineSecurity {
    Write-Host "`nAnalyzing Exchange Online Security Settings..." -ForegroundColor Yellow
    $transportRules = Get-TransportRule
    $malwareFilterPolicy = Get-MalwareFilterPolicy
    $result = [PSCustomObject]@{
        TransportRuleCount = $transportRules.Count
        MalwareFilterEnabled = $malwareFilterPolicy.Enabled
        AuditLogEnabled = (Get-AdminAuditLogConfig).UnifiedAuditLogIngestionEnabled
        DefaultAuthenticationPolicy = (Get-OrganizationConfig).DefaultAuthenticationPolicy
    }
    $result | Format-List
    return $result
}

<#
.SYNOPSIS
Checks SharePoint Online and OneDrive security.

.OUTPUTS
PSObject containing SharePoint Online and OneDrive security settings.
#>
function Check-SharePointOneDriveSecurity {
    Write-Host "`nChecking SharePoint Online and OneDrive Security..." -ForegroundColor Yellow
    $sharingCapability = Get-SPOTenant | Select-Object SharingCapability
    $conditionalAccessPolicy = Get-SPOTenant | Select-Object ConditionalAccessPolicy
    $result = [PSCustomObject]@{
        SharingCapability = $sharingCapability.SharingCapability
        ConditionalAccessPolicy = $conditionalAccessPolicy.ConditionalAccessPolicy
        OneDriveForBusinessSharingCapability = (Get-SPOTenant).OneDriveForBusinessSharingCapability
    }
    $result | Format-List
    return $result
}

<#
.SYNOPSIS
Analyzes Teams security settings.

.OUTPUTS
PSObject containing Teams security settings.
#>
function Analyze-TeamsSecuritySettings {
    Write-Host "`nAnalyzing Teams Security Settings..." -ForegroundColor Yellow
    $teamsSettings = Get-CsTeamsClientConfiguration
    $result = [PSCustomObject]@{
        AllowEmailIntoChannel = $teamsSettings.AllowEmailIntoChannel
        AllowDropBox = $teamsSettings.AllowDropBox
        AllowBox = $teamsSettings.AllowBox
        AllowGoogleDrive = $teamsSettings.AllowGoogleDrive
        AllowShareFile = $teamsSettings.AllowShareFile
    }
    $result | Format-List
    return $result
}

<#
.SYNOPSIS
Checks Azure AD security configuration.

.OUTPUTS
PSObject containing Azure AD security configuration.
#>
function Check-AzureADSecurityConfig {
    Write-Host "`nChecking Azure AD Security Configuration..." -ForegroundColor Yellow
    $passwordPolicy = Get-MsolPasswordPolicy -TenantId (Get-MsolCompanyInformation).ObjectId
    $ssoState = (Get-MsolCompanyInformation).SelfServePasswordResetEnabled
    $result = [PSCustomObject]@{
        PasswordValidityPeriod = $passwordPolicy.ValidityPeriod
        MinimumPasswordLength = $passwordPolicy.MinimumPasswordLength
        PasswordComplexityEnabled = $passwordPolicy.StrongPasswordRequired
        SelfServicePasswordResetEnabled = $ssoState
    }
    $result | Format-List
    return $result
}

<#
.SYNOPSIS
Analyzes Conditional Access Policies.

.OUTPUTS
Array of PSObjects containing Conditional Access Policy details.
#>
function Analyze-ConditionalAccessPolicies {
    Write-Host "`nAnalyzing Conditional Access Policies..." -ForegroundColor Yellow
    $policies = Get-AzureADMSConditionalAccessPolicy
    $results = @()
    foreach ($policy in $policies) {
        $results += [PSCustomObject]@{
            DisplayName = $policy.DisplayName
            State = $policy.State
            IncludeUsers = $policy.Conditions.Users.IncludeUsers -join ", "
            ExcludeUsers = $policy.Conditions.Users.ExcludeUsers -join ", "
            IncludeApplications = $policy.Conditions.Applications.IncludeApplications -join ", "
            GrantControls = $policy.GrantControls.BuiltInControls -join ", "
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Checks Data Loss Prevention Policies.

.OUTPUTS
Array of PSObjects containing DLP Policy details.
#>
function Check-DLPPolicies {
    Write-Host "`nChecking Data Loss Prevention Policies..." -ForegroundColor Yellow
    $policies = Get-DlpCompliancePolicy
    $results = @()
    foreach ($policy in $policies) {
        $results += [PSCustomObject]@{
            Name = $policy.Name
            Mode = $policy.Mode
            Enabled = $policy.Enabled
            ExchangeLocation = $policy.ExchangeLocation -join ", "
            SharePointLocation = $policy.SharePointLocation -join ", "
            OneDriveLocation = $policy.OneDriveLocation -join ", "
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Analyzes Audit Log Settings.

.OUTPUTS
PSObject containing Audit Log settings.
#>
function Analyze-AuditLogSettings {
    Write-Host "`nAnalyzing Audit Log Settings..." -ForegroundColor Yellow
    $auditConfig = Get-AdminAuditLogConfig
    $result = [PSCustomObject]@{
        UnifiedAuditLogIngestionEnabled = $auditConfig.UnifiedAuditLogIngestionEnabled
        OperationsToLog = $auditConfig.AdminAuditLogCmdlets -join ", "
    }
    $result | Format-List
    return $result
}

<#
.SYNOPSIS
Generates a comprehensive HTML report of all analyses.

.PARAMETER AllResults
Hashtable containing all analysis results.

.OUTPUTS
Saves an HTML report to the desktop.
#>
function Generate-HTMLReport {
    param([hashtable]$AllResults)

    Write-Host "`nGenerating Comprehensive HTML Report..." -ForegroundColor Yellow
    $reportContent = @"
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Microsoft 365 Security Analysis Report</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 20px; }
        h1, h2, h3 { color: #0078D4; }
        table { border-collapse: collapse; width: 100%; margin-bottom: 20px; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #f2f2f2; }
        .warning { color: orange; }
        .critical { color: red; }
    </style>
</head>
<body>
    <h1>Microsoft 365 Security Analysis Report</h1>
    <p>Generated on: $(Get-Date)</p>

    <h2>User Accounts and MFA Status</h2>
    $($AllResults.UserAccountsAndMFA | ConvertTo-Html -Fragment)

    <h2>License Assignments</h2>
    $($AllResults.LicenseAssignments | ConvertTo-Html -Fragment)

    <h2>Exchange Online Security Settings</h2>
    $($AllResults.ExchangeOnlineSecurity | ConvertTo-Html -Fragment)

    <h2>SharePoint Online and OneDrive Security</h2>
    $($AllResults.SharePointOneDriveSecurity | ConvertTo-Html -Fragment)

    <h2>Teams Security Settings</h2>
    $($AllResults.TeamsSecuritySettings | ConvertTo-Html -Fragment)

    <h2>Azure AD Security Configuration</h2>
    $($AllResults.AzureADSecurityConfig | ConvertTo-Html -Fragment)

    <h2>Conditional Access Policies</h2>
    $($AllResults.ConditionalAccessPolicies | ConvertTo-Html -Fragment)

    <h2>Data Loss Prevention Policies</h2>
    $($AllResults.DLPPolicies | ConvertTo-Html -Fragment)

    <h2>Audit Log Settings</h2>
    $($AllResults.AuditLogSettings | ConvertTo-Html -Fragment)
</body>
</html>
"@

    $reportContent | Out-File -FilePath $global:reportPath
    Write-Host "Report generated and saved to: $global:reportPath" -ForegroundColor Green
}

# Main program loop
Connect-M365Services
$allResults = @{}

do {
    Show-Menu
    $choice = Read-Host "`nEnter your choice (1-11)"

    switch ($choice) {
        "1" { $allResults.UserAccountsAndMFA = Analyze-UserAccountsAndMFA }
        "2" { $allResults.LicenseAssignments = Check-LicenseAssignments }
        "3" { $allResults.ExchangeOnlineSecurity = Analyze-ExchangeOnlineSecurity }
        "4" { $allResults.SharePointOneDriveSecurity = Check-SharePointOneDriveSecurity }
        "5" { $allResults.TeamsSecuritySettings = Analyze-TeamsSecuritySettings }
        "6" { $allResults.AzureADSecurityConfig = Check-AzureADSecurityConfig }
        "7" { $allResults.ConditionalAccessPolicies = Analyze-ConditionalAccessPolicies }
        "8" { $allResults.DLPPolicies = Check-DLPPolicies }
        "9" { $allResults.AuditLogSettings = Analyze-AuditLogSettings }
        "10" { Generate-HTMLReport -AllResults $allResults }
        "11" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

    if ($choice -ne "11") {
        Read-Host "`nPress Enter to continue..."
    }
} while ($choice -ne "11")

# Disconnect from services
Disconnect-ExchangeOnline -Confirm:$false
Disconnect-SPOService
Disconnect-MicrosoftTeams
Disconnect-AzureAD

This Microsoft 365 Security Check Tool includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze various security aspects of Microsoft 365:
    • User account analysis and MFA status
    • License assignment check
    • Exchange Online security settings analysis
    • SharePoint Online and OneDrive security check
    • Teams security settings analysis
    • Azure AD security configuration check
    • Conditional Access Policies analysis
    • Data Loss Prevention Policies check
    • Audit Log settings analysis
  3. Automatic installation of required PowerShell modules.
  4. Connection to necessary Microsoft 365 services.
  5. A function to generate an HTML report of all collected data.

Key features:

  • Comprehensive analysis of user accounts, including MFA status
  • Detailed insights into license assignments and usage
  • Review of Exchange Online, SharePoint Online, and OneDrive security settings
  • Analysis of Teams security configuration
  • Azure AD security settings check
  • Examination of Conditional Access and DLP policies
  • Audit log configuration review
  • HTML report generation for easy sharing and viewing of results

This tool is particularly useful for:

  • Microsoft 365 administrators
  • IT security professionals managing Microsoft 365 environments
  • Compliance officers ensuring adherence to security standards
  • Anyone needing to perform a security audit of their Microsoft 365 environment

To use this script effectively:

  1. Run PowerShell as an administrator
  2. Ensure you have the necessary permissions to access Microsoft 365 services (Global Administrator or appropriate admin roles)
  3. Have an active internet connection
  4. Review the generated HTML report for a comprehensive overview of your Microsoft 365 environment’s security status

This script provides a comprehensive overview of the security settings in a Microsoft 365 environment, making it easier to identify potential security issues, misconfigurations, or areas that need attention across various Microsoft 365 services.

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *