Conversation
|
I'm excited to see these in action, @HenrikPiecha! As you noted above, these will not work in some contexts. Can you add checks to the beginning of the Pester test for these so it will fail gracefully and return a relevant SkippedBecause reason to the results report? Let us know if you'd like any help with that!
|
There was a problem hiding this comment.
Pull request overview
This pull request adds 7 new SharePoint Online (SPO) tests based on CIS Microsoft 365 v5.0.0 benchmark recommendations. These tests validate SPO tenant configuration settings related to external sharing, guest access, custom scripts, and malware protection. All tests use the Microsoft.Online.SharePoint.PowerShell module and require interactive connection via Connect-SPOService.
Changes:
- Added 7 PowerShell test functions (Test-MtSpo*) for SPO tenant security checks
- Added corresponding Pester tests tagged with 'SpoTenant'
- Added website and PowerShell documentation for all 7 tests
- Updated maester-config.json with test metadata (MT.1113-MT.1119)
- Exported new functions in Maester.psd1 module manifest
Reviewed changes
Copilot reviewed 24 out of 24 changed files in this pull request and generated 16 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/Maester/Spo/Test-SpoTenant.Tests.ps1 | New Pester test file containing 7 SPO tenant configuration tests (MT.1113-MT.1119) |
| powershell/public/maester/spo/Test-MtSpoB2BIntegration.ps1 | Tests Microsoft Entra B2B integration (CIS 7.2.2) |
| powershell/public/maester/spo/Test-MtSpoCustomScriptExecutionOnSiteCollection.ps1 | Tests custom script restrictions on site collections (CIS 7.3.4) |
| powershell/public/maester/spo/Test-MtSpoDefaultSharingLink.ps1 | Tests default sharing link type restrictions (CIS 7.2.7) |
| powershell/public/maester/spo/Test-MtSpoDefaultSharingLinkPermission.ps1 | Tests default sharing link permissions (CIS 7.2.11) |
| powershell/public/maester/spo/Test-MtSpoGuestAccessExpiry.ps1 | Tests guest access expiration settings (CIS 7.2.9) |
| powershell/public/maester/spo/Test-MtSpoGuestCannotShareUnownedItem.ps1 | Tests guest resharing restrictions (CIS 7.2.5) |
| powershell/public/maester/spo/Test-MtSpoPreventDownloadMaliciousFile.ps1 | Tests malicious file download prevention (CIS 7.3.1) |
| powershell/public/maester/spo/*.md | Documentation files for each test function |
| website/docs/tests/maester/MT.111*.md | Website documentation for each test with CIS benchmark details |
| tests/maester-config.json | Configuration entries for all 7 new tests with severity levels |
| powershell/Maester.psd1 | Module manifest updated to export 7 new SPO functions |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| [CmdletBinding()] | ||
| [OutputType([bool])] | ||
| param() | ||
| Write-Verbose "Testing default sharing link type in SharePoint Online..." |
There was a problem hiding this comment.
The verbose message says "Testing default sharing link type" but this function tests custom script execution on site collections. The message should be updated to reflect the actual test being performed, such as "Testing custom script execution restrictions on site collections..."
| Write-Verbose "Testing default sharing link type in SharePoint Online..." | |
| Write-Verbose "Testing custom script execution restrictions on SharePoint Online site collections..." |
|
|
||
| $return = $true | ||
| try { | ||
| $noncompliantSites = Get-SPOSite | Where-Object { $_.DenyAddAndCustomizePages -eq "Disabled" -and $_.Url -notlike "*-my.sharepoint.com/" } |
There was a problem hiding this comment.
The URL filter $_.Url -notlike "*-my.sharepoint.com/" has a trailing slash that may not match URLs consistently. SharePoint URLs may or may not have trailing slashes. Consider using $_.Url -notlike "*-my.sharepoint.com/*" with a wildcard after the slash, or remove the slash entirely: $_.Url -notlike "*-my.sharepoint.com*".
| $noncompliantSites = Get-SPOSite | Where-Object { $_.DenyAddAndCustomizePages -eq "Disabled" -and $_.Url -notlike "*-my.sharepoint.com/" } | |
| $noncompliantSites = Get-SPOSite | Where-Object { $_.DenyAddAndCustomizePages -eq "Disabled" -and $_.Url -notlike "*-my.sharepoint.com*" } |
There was a problem hiding this comment.
A -match operator with a regex pattern could also be used to check for an optional trailing slash.
| It 'MT.1118: Ensure that SharePoint guest users cannot share items they dont own' -Tag 'MT.1118', 'CIS', 'CIS M365v5', 'CIS 7.2.5', 'Severity:High' { | ||
| $result = Test-MtSpoGuestCannotShareUnownedItem | ||
| if ($null -ne $result) { | ||
| $result | Should -Be $true -Because 'SharePoint guest users cannot share items they dont own.' |
There was a problem hiding this comment.
The word "dont" should be "don't" (with apostrophe) in the Because message.
| $result | Should -Be $true -Because 'SharePoint guest users cannot share items they dont own.' | |
| $result | Should -Be $true -Because 'SharePoint guest users cannot share items they don't own.' |
There was a problem hiding this comment.
@copilot, the suggested fix would break quoting because this string already uses single quotes. It should be don''t or wrap the whole string in double quotes and then add the apostrophe to "don't."
| $return = $true | ||
| try { | ||
| $spoTenant = Get-SPOTenant | ||
| if ($spoTenant.ExternalUserExpirationRequired -eq $true -and $spoTenant.ExternalUserExpireInDays -le 30) { |
There was a problem hiding this comment.
The condition checks if ExternalUserExpireInDays is less than or equal to 30, but doesn't handle the case where ExternalUserExpirationRequired is true but ExternalUserExpireInDays might be 0 or negative (if such values are possible). Consider adding validation for positive values or documenting the expected behavior when the value is 0.
| if ($spoTenant.ExternalUserExpirationRequired -eq $true -and $spoTenant.ExternalUserExpireInDays -le 30) { | |
| if ($spoTenant.ExternalUserExpirationRequired -eq $true -and $spoTenant.ExternalUserExpireInDays -gt 0 -and $spoTenant.ExternalUserExpireInDays -le 30) { |
| It 'MT.1118: Ensure that SharePoint guest users cannot share items they dont own' -Tag 'MT.1118', 'CIS', 'CIS M365v5', 'CIS 7.2.5', 'Severity:High' { | ||
| $result = Test-MtSpoGuestCannotShareUnownedItem | ||
| if ($null -ne $result) { | ||
| $result | Should -Be $true -Because 'SharePoint guest users cannot share items they dont own.' |
There was a problem hiding this comment.
The word "dont" should be "don't" (with apostrophe) in the test description.
| It 'MT.1118: Ensure that SharePoint guest users cannot share items they dont own' -Tag 'MT.1118', 'CIS', 'CIS M365v5', 'CIS 7.2.5', 'Severity:High' { | |
| $result = Test-MtSpoGuestCannotShareUnownedItem | |
| if ($null -ne $result) { | |
| $result | Should -Be $true -Because 'SharePoint guest users cannot share items they dont own.' | |
| It 'MT.1118: Ensure that SharePoint guest users cannot share items they don't own' -Tag 'MT.1118', 'CIS', 'CIS M365v5', 'CIS 7.2.5', 'Severity:High' { | |
| $result = Test-MtSpoGuestCannotShareUnownedItem | |
| if ($null -ne $result) { | |
| $result | Should -Be $true -Because 'SharePoint guest users cannot share items they don't own.' |
There was a problem hiding this comment.
@copilot, the suggested fix would break quoting because this string already uses single quotes. It should be don''t or wrap the whole string in double quotes and then add the apostrophe to "don't."
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
BTW, you do not need to specify a severity tag in the Pester test files if they are added to the |
|
@HenrikPiecha one catch I noticed with the SPO cmdlets is they don't work on non Windows devices like macOS. Do you know if these tests can make use of PnP PowerShell? I believe that module has been updated PS7. https://learn.microsoft.com/en-us/powershell/sharepoint/sharepoint-pnp/sharepoint-pnp-cmdlets I believe this would also solve the interactive issue because PnP supports app only as well. Do you know off the top of your head if these cmdlets are only available in SPO. Another addition we need to make is to If not, folks would never know that they need to connect to SPO/PnP to run thes |
Description
Added SharePoint Online admin center tests from CIS Microsoft 365 v5.0.0
All the tests are related to the PowerShell module Microsoft.Online.SharePoint.PowerShell.
@merill please check the invocation as discussed.
The tests with Tag
SpoTenantshould only be executed when running interactivly as the ps module currently does not support read-only permission or service principal authentication from powershell 7.Running the connection is mandatory:
Contribution Checklist
Before submitting this PR, please confirm you have completed the following:
/powershell/tests/pester.ps1on your local system.Join us at the Maester repository discussions 💬 or Entra Discord 🧑💻 for more help and conversations!