From 3f4166e98a671160261d10e567bd899730c35617 Mon Sep 17 00:00:00 2001 From: DrIOS <58635327+DrIOSX@users.noreply.github.com> Date: Thu, 30 May 2024 16:18:47 -0500 Subject: [PATCH] add: refactor for connect/disconnect --- source/Private/Connect-M365Suite.ps1 | 72 +++++++++++----------- source/Private/Disconnect-M365Suite.ps1 | 42 +++++++++---- source/Public/Invoke-M365SecurityAudit.ps1 | 14 ++--- source/helper/TestDefinitions.csv | 6 +- 4 files changed, 78 insertions(+), 56 deletions(-) diff --git a/source/Private/Connect-M365Suite.ps1 b/source/Private/Connect-M365Suite.ps1 index 73be107..97d9e4c 100644 --- a/source/Private/Connect-M365Suite.ps1 +++ b/source/Private/Connect-M365Suite.ps1 @@ -1,56 +1,58 @@ function Connect-M365Suite { [CmdletBinding()] param ( - # Parameter to specify the SharePoint Online Tenant Admin URL [Parameter(Mandatory)] - [string]$TenantAdminUrl + [string]$TenantAdminUrl, + + [Parameter(Mandatory)] + [string[]]$RequiredConnections ) -$VerbosePreference = "SilentlyContinue" + + $VerbosePreference = "SilentlyContinue" + try { + if ($RequiredConnections -contains "AzureAD" -or $RequiredConnections -contains "AzureAD | EXO") { + Write-Host "Connecting to Azure Active Directory..." -ForegroundColor Cyan + Connect-AzureAD | Out-Null + Write-Host "Successfully connected to Azure Active Directory." -ForegroundColor Green + } - # Attempt to connect to Azure Active Directory - Write-Host "Connecting to Azure Active Directory..." -ForegroundColor Cyan - Connect-AzureAD | Out-Null - Write-Host "Successfully connected to Azure Active Directory." -ForegroundColor Green - - # Attempt to connect to Exchange Online - Write-Host "Connecting to Exchange Online..." -ForegroundColor Cyan - Connect-ExchangeOnline | Out-Null - Write-Host "Successfully connected to Exchange Online." -ForegroundColor Green - try { - # Attempt to connect to Microsoft Graph with specified scopes + if ($RequiredConnections -contains "Microsoft Graph") { Write-Host "Connecting to Microsoft Graph with scopes: Directory.Read.All, Domain.Read.All, Policy.Read.All, Organization.Read.All" -ForegroundColor Cyan - Connect-MgGraph -Scopes "Directory.Read.All", "Domain.Read.All", "Policy.Read.All", "Organization.Read.All" -NoWelcome | Out-Null - Write-Host "Successfully connected to Microsoft Graph with specified scopes." -ForegroundColor Green - } - catch { - Write-Host "Failed to connect o MgGraph, attempting device auth." -ForegroundColor Yellow - # Attempt to connect to Microsoft Graph with specified scopes - Write-Host "Connecting to Microsoft Graph using device auth with scopes: Directory.Read.All, Domain.Read.All, Policy.Read.All, Organization.Read.All" -ForegroundColor Cyan - Connect-MgGraph -Scopes "Directory.Read.All", "Domain.Read.All", "Policy.Read.All", "Organization.Read.All" -UseDeviceCode -NoWelcome | Out-Null - Write-Host "Successfully connected to Microsoft Graph with specified scopes." -ForegroundColor Green + try { + Connect-MgGraph -Scopes "Directory.Read.All", "Domain.Read.All", "Policy.Read.All", "Organization.Read.All" -NoWelcome | Out-Null + Write-Host "Successfully connected to Microsoft Graph with specified scopes." -ForegroundColor Green + } + catch { + Write-Host "Failed to connect to MgGraph, attempting device auth." -ForegroundColor Yellow + Connect-MgGraph -Scopes "Directory.Read.All", "Domain.Read.All", "Policy.Read.All", "Organization.Read.All" -UseDeviceCode -NoWelcome | Out-Null + Write-Host "Successfully connected to Microsoft Graph with specified scopes." -ForegroundColor Green + } } - # Validate SharePoint Online Tenant Admin URL - if (-not $TenantAdminUrl) { - throw "SharePoint Online Tenant Admin URL is required." + if ($RequiredConnections -contains "EXO" -or $RequiredConnections -contains "AzureAD | EXO" -or $RequiredConnections -contains "Microsoft Teams | EXO") { + Write-Host "Connecting to Exchange Online..." -ForegroundColor Cyan + Connect-ExchangeOnline | Out-Null + Write-Host "Successfully connected to Exchange Online." -ForegroundColor Green } - # Attempt to connect to SharePoint Online - Write-Host "Connecting to SharePoint Online..." -ForegroundColor Cyan - Connect-SPOService -Url $TenantAdminUrl | Out-Null - Write-Host "Successfully connected to SharePoint Online." -ForegroundColor Green + if ($RequiredConnections -contains "SPO") { + Write-Host "Connecting to SharePoint Online..." -ForegroundColor Cyan + Connect-SPOService -Url $TenantAdminUrl | Out-Null + Write-Host "Successfully connected to SharePoint Online." -ForegroundColor Green + } - # Attempt to connect to Microsoft Teams - Write-Host "Connecting to Microsoft Teams..." -ForegroundColor Cyan - Connect-MicrosoftTeams | Out-Null - Write-Host "Successfully connected to Microsoft Teams." -ForegroundColor Green + if ($RequiredConnections -contains "Microsoft Teams" -or $RequiredConnections -contains "Microsoft Teams | EXO") { + Write-Host "Connecting to Microsoft Teams..." -ForegroundColor Cyan + Connect-MicrosoftTeams | Out-Null + Write-Host "Successfully connected to Microsoft Teams." -ForegroundColor Green + } } catch { $VerbosePreference = "Continue" Write-Host "There was an error establishing one or more connections: $_" -ForegroundColor Red throw $_ } + $VerbosePreference = "Continue" } - diff --git a/source/Private/Disconnect-M365Suite.ps1 b/source/Private/Disconnect-M365Suite.ps1 index 686a38c..8d14b89 100644 --- a/source/Private/Disconnect-M365Suite.ps1 +++ b/source/Private/Disconnect-M365Suite.ps1 @@ -1,39 +1,59 @@ function Disconnect-M365Suite { + param ( + [Parameter(Mandatory)] + [string[]]$RequiredConnections + ) + # Clean up sessions try { - Write-Host "Disconnecting from Exchange Online..." -ForegroundColor Green - Disconnect-ExchangeOnline -Confirm:$false | Out-Null + if ($RequiredConnections -contains "EXO" -or $RequiredConnections -contains "AzureAD | EXO" -or $RequiredConnections -contains "Microsoft Teams | EXO") { + Write-Host "Disconnecting from Exchange Online..." -ForegroundColor Green + Disconnect-ExchangeOnline -Confirm:$false | Out-Null + } } catch { Write-Warning "Failed to disconnect from Exchange Online: $_" } + try { - Write-Host "Disconnecting from Azure AD..." -ForegroundColor Green - Disconnect-AzureAD | Out-Null + if ($RequiredConnections -contains "AzureAD" -or $RequiredConnections -contains "AzureAD | EXO") { + Write-Host "Disconnecting from Azure AD..." -ForegroundColor Green + Disconnect-AzureAD | Out-Null + } } catch { Write-Warning "Failed to disconnect from Azure AD: $_" } + try { - Write-Host "Disconnecting from Microsoft Graph..." -ForegroundColor Green - Disconnect-MgGraph | Out-Null + if ($RequiredConnections -contains "Microsoft Graph") { + Write-Host "Disconnecting from Microsoft Graph..." -ForegroundColor Green + Disconnect-MgGraph | Out-Null + } } catch { Write-Warning "Failed to disconnect from Microsoft Graph: $_" } + try { - Write-Host "Disconnecting from SharePoint Online..." -ForegroundColor Green - Disconnect-SPOService | Out-Null + if ($RequiredConnections -contains "SPO") { + Write-Host "Disconnecting from SharePoint Online..." -ForegroundColor Green + Disconnect-SPOService | Out-Null + } } catch { Write-Warning "Failed to disconnect from SharePoint Online: $_" } + try { - Write-Host "Disconnecting from Microsoft Teams..." -ForegroundColor Green - Disconnect-MicrosoftTeams | Out-Null + if ($RequiredConnections -contains "Microsoft Teams" -or $RequiredConnections -contains "Microsoft Teams | EXO") { + Write-Host "Disconnecting from Microsoft Teams..." -ForegroundColor Green + Disconnect-MicrosoftTeams | Out-Null + } } catch { Write-Warning "Failed to disconnect from Microsoft Teams: $_" } - Write-Host "All sessions have been disconnected." -ForegroundColor Green + + Write-Host "All necessary sessions have been disconnected." -ForegroundColor Green } \ No newline at end of file diff --git a/source/Public/Invoke-M365SecurityAudit.ps1 b/source/Public/Invoke-M365SecurityAudit.ps1 index f137cfa..ad7af38 100644 --- a/source/Public/Invoke-M365SecurityAudit.ps1 +++ b/source/Public/Invoke-M365SecurityAudit.ps1 @@ -59,7 +59,6 @@ .LINK https://criticalsolutionsnetwork.github.io/M365FoundationsCISReport/#Invoke-M365SecurityAudit #> - function Invoke-M365SecurityAudit { [CmdletBinding(SupportsShouldProcess = $true, DefaultParameterSetName = 'Default')] [OutputType([CISAuditResult[]])] @@ -152,11 +151,6 @@ function Invoke-M365SecurityAudit { # Loop through each required module and assert its availability # Establishing connections - #if (!($DoNotConnect -or $DoNotTest)) { - # Establishing connections - if (!($DoNotConnect)) { - Connect-M365Suite -TenantAdminUrl $TenantAdminUrl - } # Load test definitions from CSV $testDefinitionsPath = Join-Path -Path $PSScriptRoot -ChildPath "helper\TestDefinitions.csv" @@ -174,7 +168,13 @@ function Invoke-M365SecurityAudit { } $testDefinitions = Get-TestDefinitionsObject @params # End switch ($PSCmdlet.ParameterSetName) + # Extract unique connections needed + $requiredConnections = $testDefinitions.Connection | Sort-Object -Unique + # Establishing connections if required + if (!($DoNotConnect)) { + Connect-M365Suite -TenantAdminUrl $TenantAdminUrl -RequiredConnections $requiredConnections + } # Determine which test files to load based on filtering $testsToLoad = $testDefinitions.TestFileName | ForEach-Object { $_ -replace '.ps1$', '' } @@ -226,7 +226,7 @@ function Invoke-M365SecurityAudit { End { if (!($DoNotDisconnect)) { # Clean up sessions - Disconnect-M365Suite + Disconnect-M365Suite -RequiredConnections $requiredConnections } # Return all collected audit results return $allAuditResults.ToArray() diff --git a/source/helper/TestDefinitions.csv b/source/helper/TestDefinitions.csv index 32c46b7..a284e76 100644 --- a/source/helper/TestDefinitions.csv +++ b/source/helper/TestDefinitions.csv @@ -1,5 +1,5 @@ Index,TestFileName,Rec,RecDescription,ELevel,ProfileLevel,CISControl,CISDescription,IG1,IG2,IG3,Automated,Connection -1,Test-AdministrativeAccountCompliance.ps1,1.1.1,Ensure Administrative accounts are separate and cloud-only,E3,L1,5.4,Restrict Administrator Privileges to Dedicated Administrator Accounts,TRUE,TRUE,TRUE,FALSE,AzureAD +1,Test-AdministrativeAccountCompliance.ps1,1.1.1,Ensure Administrative accounts are separate and cloud-only,E3,L1,5.4,Restrict Administrator Privileges to Dedicated Administrator Accounts,TRUE,TRUE,TRUE,FALSE,Microsoft Graph 2,Test-GlobalAdminsCount.ps1,1.1.3,Ensure that between two and four global admins are designated,E3,L1,5.1,Establish and Maintain an Inventory of Accounts,TRUE,TRUE,TRUE,TRUE,Microsoft Graph 3,Test-ManagedApprovedPublicGroups.ps1,1.2.1,Ensure that only organizationally managed/approved public groups exist,E3,L2,3.3,Configure Data Access Control Lists,TRUE,TRUE,TRUE,TRUE,Microsoft Graph 4,Test-BlockSharedMailboxSignIn.ps1,1.2.2,Ensure sign-in to shared mailboxes is blocked,E3,L1,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,AzureAD | EXO @@ -18,8 +18,8 @@ 17,Test-RestrictTenantCreation.ps1,5.1.2.3,Ensure 'Restrict non-admin users from creating tenants' is set to 'Yes',E3,L1,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,Microsoft Graph 18,Test-PasswordHashSync.ps1,5.1.8.1,Ensure password hash sync is enabled for hybrid deployments,E3,L1,6.7,Centralize Access Control,FALSE,TRUE,TRUE,TRUE,Microsoft Graph 19,Test-AuditDisabledFalse.ps1,6.1.1,Ensure 'AuditDisabled' organizationally is set to 'False',E3,L1,8.2,Collect Audit Logs,TRUE,TRUE,TRUE,TRUE,Microsoft Graph -20,Test-MailboxAuditingE3.ps1,6.1.2,Ensure mailbox auditing for Office E3 users is Enabled,E3,L1,8.2,Collect audit logs.,TRUE,TRUE,TRUE,TRUE,EXO -21,Test-MailboxAuditingE5.ps1,6.1.3,Ensure mailbox auditing for Office E5 users is Enabled,E5,L1,8.2,Collect audit logs.,TRUE,TRUE,TRUE,TRUE,EXO +20,Test-MailboxAuditingE3.ps1,6.1.2,Ensure mailbox auditing for Office E3 users is Enabled,E3,L1,8.2,Collect audit logs.,TRUE,TRUE,TRUE,TRUE,AzureAD | EXO +21,Test-MailboxAuditingE5.ps1,6.1.3,Ensure mailbox auditing for Office E5 users is Enabled,E5,L1,8.2,Collect audit logs.,TRUE,TRUE,TRUE,TRUE,AzureAD | EXO 22,Test-BlockMailForwarding.ps1,6.2.1,Ensure all forms of mail forwarding are blocked and/or disabled,E3,L1,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,EXO 23,Test-NoWhitelistDomains.ps1,6.2.2,Ensure mail transport rules do not whitelist specific domains,E3,L1,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,EXO 24,Test-IdentifyExternalEmail.ps1,6.2.3,Ensure email from external senders is identified,E3,L1,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,EXO