From fc9ff5757606cd532bf77041e90ccb960cc7e13e Mon Sep 17 00:00:00 2001 From: DrIOS <58635327+DrIOSX@users.noreply.github.com> Date: Sun, 30 Jun 2024 10:11:25 -0500 Subject: [PATCH] fix: Add parameter for approved storage providers for 8.1.1 --- source/Private/Get-CISMSTeamsOutput.ps1 | 1 + source/Private/Invoke-TestFunction.ps1 | 9 +++-- source/Public/Invoke-M365SecurityAudit.ps1 | 32 ++++++++++----- .../tests/Test-TeamsExternalFileSharing.ps1 | 40 +++++++++++++------ 4 files changed, 58 insertions(+), 24 deletions(-) diff --git a/source/Private/Get-CISMSTeamsOutput.ps1 b/source/Private/Get-CISMSTeamsOutput.ps1 index 6c157cb..58a69e2 100644 --- a/source/Private/Get-CISMSTeamsOutput.ps1 +++ b/source/Private/Get-CISMSTeamsOutput.ps1 @@ -49,6 +49,7 @@ function Get-CISMSTeamsOutput { # Assuming that 'approvedProviders' is a list of approved cloud storage service names # This list must be defined according to your organization's approved cloud storage services + # Add option for approved providers. $clientConfig = Get-CsTeamsClientConfiguration return $clientConfig } diff --git a/source/Private/Invoke-TestFunction.ps1 b/source/Private/Invoke-TestFunction.ps1 index ac5ca2c..f1021ed 100644 --- a/source/Private/Invoke-TestFunction.ps1 +++ b/source/Private/Invoke-TestFunction.ps1 @@ -3,9 +3,10 @@ function Invoke-TestFunction { param ( [Parameter(Mandatory = $true)] [PSObject]$FunctionFile, - [Parameter(Mandatory = $false)] - [string]$DomainName + [string]$DomainName, + [Parameter(Mandatory = $false)] + [string[]]$ApprovedCloudStorageProvider ) $functionName = $FunctionFile.BaseName @@ -16,7 +17,9 @@ function Invoke-TestFunction { if ('DomainName' -in $functionCmd.Parameters.Keys) { $paramList.DomainName = $DomainName } - + if ('ApprovedCloudStorageProvider' -in $functionCmd.Parameters.Keys) { + $paramList.ApprovedCloudStorageProvider = $ApprovedCloudStorageProvider + } # Use splatting to pass parameters Write-Verbose "Running $functionName..." try { diff --git a/source/Public/Invoke-M365SecurityAudit.ps1 b/source/Public/Invoke-M365SecurityAudit.ps1 index feea04b..ca10872 100644 --- a/source/Public/Invoke-M365SecurityAudit.ps1 +++ b/source/Public/Invoke-M365SecurityAudit.ps1 @@ -21,6 +21,8 @@ Specifies specific recommendations to include in the audit. Accepts an array of recommendation numbers. .PARAMETER SkipRecommendation Specifies specific recommendations to exclude from the audit. Accepts an array of recommendation numbers. + .PARAMETER ApprovedCloudStorageProvider + Specifies the approved cloud storage providers for the audit. Accepts an array of cloud storage provider names. .PARAMETER DoNotConnect If specified, the cmdlet will not establish a connection to Microsoft 365 services. .PARAMETER DoNotDisconnect @@ -134,26 +136,26 @@ function Invoke-M365SecurityAudit { [string]$DomainName, # E-Level with optional ProfileLevel selection - [Parameter(Mandatory = $true, ParameterSetName = 'ELevelFilter')] + [Parameter(Mandatory = $true, ParameterSetName = 'ELevelFilter', HelpMessage = "Specifies the E-Level (E3 or E5) for the audit.")] [ValidateSet('E3', 'E5')] [string]$ELevel, - [Parameter(Mandatory = $true, ParameterSetName = 'ELevelFilter')] + [Parameter(Mandatory = $true, ParameterSetName = 'ELevelFilter', HelpMessage = "Specifies the profile level (L1 or L2) for the audit.")] [ValidateSet('L1', 'L2')] [string]$ProfileLevel, # IG Filters, one at a time - [Parameter(Mandatory = $true, ParameterSetName = 'IG1Filter')] + [Parameter(Mandatory = $true, ParameterSetName = 'IG1Filter', HelpMessage = "Includes tests where IG1 is true.")] [switch]$IncludeIG1, - [Parameter(Mandatory = $true, ParameterSetName = 'IG2Filter')] + [Parameter(Mandatory = $true, ParameterSetName = 'IG2Filter', HelpMessage = "Includes tests where IG2 is true.")] [switch]$IncludeIG2, - [Parameter(Mandatory = $true, ParameterSetName = 'IG3Filter')] + [Parameter(Mandatory = $true, ParameterSetName = 'IG3Filter', HelpMessage = "Includes tests where IG3 is true.")] [switch]$IncludeIG3, # Inclusion of specific recommendation numbers - [Parameter(Mandatory = $true, ParameterSetName = 'RecFilter')] + [Parameter(Mandatory = $true, ParameterSetName = 'RecFilter', HelpMessage = "Specifies specific recommendations to include in the audit. Accepts an array of recommendation numbers.")] [ValidateSet( '1.1.1', '1.1.3', '1.2.1', '1.2.2', '1.3.1', '1.3.3', '1.3.6', '2.1.1', '2.1.2', ` '2.1.3', '2.1.4', '2.1.5', '2.1.6', '2.1.7', '2.1.9', '3.1.1', '5.1.2.3', ` @@ -166,7 +168,7 @@ function Invoke-M365SecurityAudit { [string[]]$IncludeRecommendation, # Exclusion of specific recommendation numbers - [Parameter(Mandatory = $true, ParameterSetName = 'SkipRecFilter')] + [Parameter(Mandatory = $true, ParameterSetName = 'SkipRecFilter', HelpMessage = "Specifies specific recommendations to exclude from the audit. Accepts an array of recommendation numbers.")] [ValidateSet( '1.1.1', '1.1.3', '1.2.1', '1.2.2', '1.3.1', '1.3.3', '1.3.6', '2.1.1', '2.1.2', ` '2.1.3', '2.1.4', '2.1.5', '2.1.6', '2.1.7', '2.1.9', '3.1.1', '5.1.2.3', ` @@ -179,12 +181,24 @@ function Invoke-M365SecurityAudit { [string[]]$SkipRecommendation, # Common parameters for all parameter sets + [Parameter(Mandatory = $false, HelpMessage = "Specifies the approved cloud storage providers for the audit. Accepts an array of cloud storage provider names.")] + [ValidateSet( + 'GoogleDrive', 'ShareFile', 'Box', 'DropBox', 'Egnyte' + )] + [string[]]$ApprovedCloudStorageProvider = @(), + + [Parameter(Mandatory = $false, HelpMessage = "Specifies that the cmdlet will not establish a connection to Microsoft 365 services.")] [switch]$DoNotConnect, + + [Parameter(Mandatory = $false, HelpMessage = "Specifies that the cmdlet will not disconnect from Microsoft 365 services after execution.")] [switch]$DoNotDisconnect, + + [Parameter(Mandatory = $false, HelpMessage = "Specifies that the cmdlet will not check for the presence of required modules.")] [switch]$NoModuleCheck, + + [Parameter(Mandatory = $false, HelpMessage = "Specifies that the cmdlet will not prompt for confirmation before proceeding with established connections and will disconnect from all of them.")] [switch]$DoNotConfirmConnections ) - Begin { if ($script:MaximumFunctionCount -lt 8192) { $script:MaximumFunctionCount = 8192 @@ -286,7 +300,7 @@ function Invoke-M365SecurityAudit { Write-Progress -Activity "Executing Tests" -Status "Executing $($currentTestIndex) of $($totalTests): $($testFunction.Name)" -PercentComplete (($currentTestIndex / $totalTests) * 100) $functionName = $testFunction.BaseName if ($PSCmdlet.ShouldProcess($functionName, "Execute test")) { - $auditResult = Invoke-TestFunction -FunctionFile $testFunction -DomainName $DomainName + $auditResult = Invoke-TestFunction -FunctionFile $testFunction -DomainName $DomainName -ApprovedCloudStorageProvider $ApprovedCloudStorageProvider # Add the result to the collection [void]$allAuditResults.Add($auditResult) } diff --git a/source/tests/Test-TeamsExternalFileSharing.ps1 b/source/tests/Test-TeamsExternalFileSharing.ps1 index a830713..f4e48ec 100644 --- a/source/tests/Test-TeamsExternalFileSharing.ps1 +++ b/source/tests/Test-TeamsExternalFileSharing.ps1 @@ -2,17 +2,15 @@ function Test-TeamsExternalFileSharing { [CmdletBinding()] [OutputType([CISAuditResult])] param ( - # Aligned - # Parameters can be added here if needed + [Parameter(Mandatory = $false)] + [string[]]$ApprovedCloudStorageProvider ) - begin { # Dot source the class script if necessary # . .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed $recnum = "8.1.1" } - process { try { # 8.1.1 (L2) Ensure external file sharing in Teams is enabled for only approved cloud storage services @@ -26,25 +24,44 @@ function Test-TeamsExternalFileSharing { # Assuming that 'approvedProviders' is a list of approved cloud storage service names # This list must be defined according to your organization's approved cloud storage services + # Retrieve the current Teams client configuration $clientConfig = Get-CISMSTeamsOutput -Rec $recnum - $unapprovedProviders = @("AllowDropBox", "AllowBox", "AllowGoogleDrive", "AllowShareFile", "AllowEgnyte") + # Testing + #$clientconfig.AllowGoogleDrive = $false + #$clientconfig.AllowBox = $false + #$clientconfig.AllowShareFile = $false + #$clientconfig.AllowEgnyte = $false + #$clientconfig.AllowDropBox = $false + # Define all possible cloud storage providers + $allProviders = @("AllowDropBox", "AllowBox", "AllowGoogleDrive", "AllowShareFile", "AllowEgnyte") + # If ApprovedCloudStorageProvider is provided, map it to the corresponding settings + if ($PSBoundParameters.ContainsKey('ApprovedCloudStorageProvider')) { + $approvedProviders = @() + foreach ($provider in $ApprovedCloudStorageProvider) { + $approvedProviders += "Allow$provider" + } + } else { + # Default approved providers + $approvedProviders = @() + } $isCompliant = $true $nonCompliantProviders = @() - - foreach ($provider in $unapprovedProviders) { - if ($clientConfig.$provider) { + foreach ($provider in $allProviders) { + if ($clientConfig.$provider -and -not $approvedProviders.Contains($provider)) { $isCompliant = $false $nonCompliantProviders += $provider } } - - # Create an instance of CISAuditResult and populate it + $basePassDetails = "All cloud storage services are approved providers" + if ($ApprovedCloudStorageProvider) { + $basePassDetails = "Approved cloud storage services: $($ApprovedCloudStorageProvider -join ', ')" + } # Create an instance of CISAuditResult and populate it $params = @{ Rec = $recnum Result = $isCompliant Status = if ($isCompliant) { "Pass" } else { "Fail" } - Details = if (-not $isCompliant) { "Non-approved providers enabled: $($nonCompliantProviders -join ', ')" } else { "All cloud storage services are approved providers" } + Details = if (-not $isCompliant) { "Non-approved providers enabled: $($nonCompliantProviders -join ', ')" } else { $basePassDetails } FailureReason = if (-not $isCompliant) { "The following non-approved providers are enabled: $($nonCompliantProviders -join ', ')" } else { "N/A" } } $auditResult = Initialize-CISAuditResult @params @@ -54,7 +71,6 @@ function Test-TeamsExternalFileSharing { $auditResult = Get-TestError -LastError $LastError -recnum $recnum } } - end { # Return auditResult return $auditResult