feat: add PnP.PowerShell support with all 8 CISA tests#1662
feat: add PnP.PowerShell support with all 8 CISA tests#1662DataAndGoliath wants to merge 1 commit into
Conversation
…seline controls Add SharePoint Online connectivity via PnP.PowerShell and implement all 8 CISA SCuBA SharePoint baseline controls (MS.SHAREPOINT.1.1 through 3.3). Infrastructure: - Add SharePointOnline service option and -SharePointClientId parameter - Add Get-MtSpo helper with session caching (SpoCache) - Add PnP disconnect and cache cleanup to Disconnect-Maester - Add SharePoint connection check to Test-MtConnection - Add NotConnectedSharePoint skip reason - Update module manifest and format XML - Graph connects before PnP to avoid DLL conflict Authentication uses Register-PnPEntraIDAppForInteractiveLogin for interactive login (no -Interactive flag on Connect-PnPOnline — it prompts by default when only ClientId and Url are provided). Device code flow supported via -UseDeviceCode (-DeviceLogin). New tests: - Test-MtCisaSpoOneDriveSharing (MS.SHAREPOINT.1.2) - Test-MtCisaSpoDefaultSharingScope (MS.SHAREPOINT.2.1) - Test-MtCisaSpoDefaultSharingPermission (MS.SHAREPOINT.2.2) - Test-MtCisaSpoAnyoneLinkExpiration (MS.SHAREPOINT.3.1) - Test-MtCisaSpoAnyoneLinkPermission (MS.SHAREPOINT.3.2) - Test-MtCisaSpoVerificationCodeReauth (MS.SHAREPOINT.3.3) Reworked tests (Graph → PnP): - Test-MtCisaSpoSharing (MS.SHAREPOINT.1.1) - Test-MtCisaSpoSharingAllowedDomain (MS.SHAREPOINT.1.3) Each test includes .ps1, .md result template, and .Tests.ps1 Pester file. Test logic validated against ScubaGear Rego policies.
Up to standards ✅🟢 Issues
|
|
@DataAndGoliath, thanks for the contribution! I just tagged GitHub Copilot to review to help get some early feedback. You may have noticed that @Mynster9361 and @HenrikPiecha have been working on adding support for using the PnP.PowerShell module to complete CIS checks. Would you like to collaborate with them (or review #1755) to align efforts around PnP? Thanks again! |
There was a problem hiding this comment.
Pull request overview
Adds SharePoint Online (SPO) connectivity via PnP.PowerShell and implements the CISA SCuBA SharePoint baseline controls (MS.SHAREPOINT.1.1–3.3) in Maester, including new test cmdlets, documentation, and session cleanup/caching.
Changes:
- Introduces SPO connection support in
Connect-Maester/Disconnect-Maester, plus connection detection inTest-MtConnection. - Adds
Get-MtSpohelper with session caching and clears SPO cache during module/session cleanup. - Implements the remaining CISA SharePoint baseline tests (new cmdlets + result templates + Pester wrappers) and updates website docs to list them.
Reviewed changes
Copilot reviewed 32 out of 32 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| website/versioned_docs/version-2.0.0/tests/cisa/spo.md | Updates the versioned SPO CISA test listing to include the newly implemented cmdlets. |
| website/docs/tests/cisa/spo.md | Updates the current SPO CISA test listing to include the newly implemented cmdlets. |
| website/docs/sections/create-entra-app.md | Documents optional PnP app registration + module install steps for SPO tests. |
| tests/cisa/spo/Test-MtCisaSpoVerificationCodeReauth.Tests.ps1 | Adds Pester wrapper for MS.SHAREPOINT.3.3. |
| tests/cisa/spo/Test-MtCisaSpoOneDriveSharing.Tests.ps1 | Adds Pester wrapper for MS.SHAREPOINT.1.2. |
| tests/cisa/spo/Test-MtCisaSpoDefaultSharingScope.Tests.ps1 | Adds Pester wrapper for MS.SHAREPOINT.2.1. |
| tests/cisa/spo/Test-MtCisaSpoDefaultSharingPermission.Tests.ps1 | Adds Pester wrapper for MS.SHAREPOINT.2.2. |
| tests/cisa/spo/Test-MtCisaSpoAnyoneLinkPermission.Tests.ps1 | Adds Pester wrapper for MS.SHAREPOINT.3.2. |
| tests/cisa/spo/Test-MtCisaSpoAnyoneLinkExpiration.Tests.ps1 | Adds Pester wrapper for MS.SHAREPOINT.3.1. |
| powershell/public/Disconnect-Maester.ps1 | Disconnects PnP connection and clears SPO cache on disconnect. |
| powershell/public/core/Test-MtConnection.ps1 | Adds SharePoint connection detection via Get-PnPConnection and connection detail output. |
| powershell/public/Connect-Maester.ps1 | Adds SharePointOnline connection via PnP (after Graph) with -SharePointClientId. |
| powershell/public/cisa/spo/Test-MtCisaSpoVerificationCodeReauth.ps1 | Implements MS.SHAREPOINT.3.3 using SPO tenant settings from PnP. |
| powershell/public/cisa/spo/Test-MtCisaSpoVerificationCodeReauth.md | Adds remediation/result template for MS.SHAREPOINT.3.3. |
| powershell/public/cisa/spo/Test-MtCisaSpoSharingAllowedDomain.ps1 | Reworks MS.SHAREPOINT.1.3 to use PnP tenant settings instead of Graph. |
| powershell/public/cisa/spo/Test-MtCisaSpoSharing.ps1 | Reworks MS.SHAREPOINT.1.1 to use PnP tenant settings instead of Graph. |
| powershell/public/cisa/spo/Test-MtCisaSpoOneDriveSharing.ps1 | Implements MS.SHAREPOINT.1.2 using PnP tenant settings. |
| powershell/public/cisa/spo/Test-MtCisaSpoOneDriveSharing.md | Adds remediation/result template for MS.SHAREPOINT.1.2. |
| powershell/public/cisa/spo/Test-MtCisaSpoDefaultSharingScope.ps1 | Implements MS.SHAREPOINT.2.1 using PnP tenant settings. |
| powershell/public/cisa/spo/Test-MtCisaSpoDefaultSharingScope.md | Adds remediation/result template for MS.SHAREPOINT.2.1. |
| powershell/public/cisa/spo/Test-MtCisaSpoDefaultSharingPermission.ps1 | Implements MS.SHAREPOINT.2.2 using PnP tenant settings. |
| powershell/public/cisa/spo/Test-MtCisaSpoDefaultSharingPermission.md | Adds remediation/result template for MS.SHAREPOINT.2.2. |
| powershell/public/cisa/spo/Test-MtCisaSpoAnyoneLinkPermission.ps1 | Implements MS.SHAREPOINT.3.2 using PnP tenant settings. |
| powershell/public/cisa/spo/Test-MtCisaSpoAnyoneLinkPermission.md | Adds remediation/result template for MS.SHAREPOINT.3.2. |
| powershell/public/cisa/spo/Test-MtCisaSpoAnyoneLinkExpiration.ps1 | Implements MS.SHAREPOINT.3.1 using PnP tenant settings. |
| powershell/public/cisa/spo/Test-MtCisaSpoAnyoneLinkExpiration.md | Adds remediation/result template for MS.SHAREPOINT.3.1. |
| powershell/public/cisa/spo/Get-MtSpo.ps1 | Adds cached helper for retrieving tenant config from Get-PnPTenant. |
| powershell/Maester.psm1 | Adds SpoCache to the module session state. |
| powershell/Maester.psd1 | Exports Get-MtSpo and the new SPO CISA test functions in the module manifest. |
| powershell/Maester.Format.ps1xml | Adds formatting output for SharePoint connection details in connection reporting. |
| powershell/internal/Get-MtSkippedReason.ps1 | Adds NotConnectedSharePoint skip reason text. |
| powershell/internal/Clear-ModuleVariable.ps1 | Clears SPO cache during module variable reset. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # SharePoint Online via PnP — must run AFTER Graph to avoid Microsoft.Graph.Core DLL conflict | ||
| if ($Service -contains 'SharePointOnline' -or $Service -contains 'All') { | ||
| Write-Verbose 'Connecting to SharePoint Online via PnP' | ||
|
|
||
| if (-not $SharePointClientId) { | ||
| Write-Host "`nSharePointOnline requires the -SharePointClientId parameter. Create a PnP app registration using Register-PnPEntraIDAppForInteractiveLogin.`nFor more information see https://maester.dev/docs/sections/create-entra-app" -ForegroundColor Red | ||
| } else { | ||
| try { | ||
| # Resolve the SharePoint admin URL from the tenant's initial domain | ||
| $domains = Invoke-MtGraphRequest -RelativeUri "domains" -ApiVersion "v1.0" | ||
| $initialDomain = ($domains | Where-Object { $_.isInitial -eq $true }).id | ||
| $tenantPrefix = ($initialDomain -split '\.')[0] | ||
| $spoAdminUrl = "https://$tenantPrefix-admin.sharepoint.com" |
| Import-Module PnP.PowerShell -ErrorAction Stop | ||
|
|
||
| $pnpParams = @{ | ||
| Url = $spoAdminUrl | ||
| ClientId = $SharePointClientId | ||
| } | ||
|
|
||
| if ($UseDeviceCode) { | ||
| $pnpParams['DeviceLogin'] = $true | ||
| } | ||
|
|
||
| if ($TenantId) { | ||
| $pnpParams['Tenant'] = $TenantId | ||
| } | ||
|
|
||
| Connect-PnPOnline @pnpParams | ||
|
|
||
| } catch [Management.Automation.CommandNotFoundException] { | ||
| Write-Host "`nThe PnP.PowerShell module is not installed. Please install the module using the following command.`nFor more information see https://pnp.github.io/powershell/articles/installation.html" -ForegroundColor Red | ||
| Write-Host "`nInstall-Module PnP.PowerShell -Scope CurrentUser`n" -ForegroundColor Yellow | ||
| } catch { |
| [ValidateSet('All', 'Azure', 'ExchangeOnline', 'EOP', 'Graph', 'SecurityCompliance', 'SharePoint', 'Teams')] | ||
| [Parameter(Position = 0)] | ||
| [string[]]$Service = 'Graph', | ||
|
|
| "NotConnectedSecurityCompliance" { "Not connected to Security & Compliance. See [Connecting to Security & Compliance](https://maester.dev/docs/connect-maester/#connect-to-azure-exchange-online-and-teams)"; break} | ||
| "NotConnectedTeams" { "Not connected to Teams. See [Connecting to Teams](https://maester.dev/docs/connect-maester/#connect-to-azure-exchange-online-and-teams)"; break} | ||
| "NotConnectedGraph" { "Not connected to Graph. See [Connect-Maester](https://maester.dev/docs/commands/Connect-Maester#examples)"; break} | ||
| "NotConnectedSharePoint" { "Not connected to SharePoint Online. See [Connecting to SharePoint Online](https://maester.dev/docs/connect-maester/#connect-to-sharepoint-online)"; break} |
| SharePoint Online tests require the **PnP.PowerShell** module and a dedicated PnP Entra ID app registration. The standard Maester app registration does not cover SharePoint tenant admin operations — PnP requires its own app with `Sites.FullControl.All` permissions. | ||
|
|
||
| > The SharePoint Online permissions are necessary to support tests that validate [SharePoint Online configurations](https://maester.dev/docs/tests/cisa/spo), such as the CISA SharePoint baseline controls. | ||
|
|
||
| #### Install PnP.PowerShell | ||
|
|
||
| ```powershell | ||
| Install-Module PnP.PowerShell -Scope CurrentUser | ||
| ``` | ||
|
|
||
| #### Register the PnP Entra ID app | ||
|
|
||
| PnP provides a built-in cmdlet to create the required app registration for interactive login: | ||
|
|
||
| ```powershell | ||
| Register-PnPEntraIDAppForInteractiveLogin -ApplicationName "Maester PnP" -Tenant [yourtenant].onmicrosoft.com -SharePointDelegatePermissions "AllSites.FullControl" | ||
| ``` |
| $spoAdminUrl = "https://$tenantPrefix-admin.sharepoint.com" | ||
|
|
I decided to revert my changes in regards to connection to sharepoint online and adopt the ones from maester365#1662 added @DataAndGoliath as a co-author on this adoption Only actual change between the 2 is the location for Get-MtSpo.ps1 i have chosen to place this in the powershell\public folder as it now will relate to both CIS and CISA tests. > Co-authored-by: Simon Albers <DataAndGoliath>
|
@copilot resolve the merge conflicts in this pull request |
Description
Added SharePoint Online connectivity via PnP.PowerShell and implement all 8 CISA SCuBA SharePoint baseline controls (MS.SHAREPOINT.1.1 through 3.3).
Infrastructure:
Authentication uses Register-PnPEntraIDAppForInteractiveLogin for interactive login (for now at least)
New tests:
Reworked tests:
Each test includes .ps1, .md result template, and .Tests.ps1 Pester file. Test logic validated against ScubaGear Rego policies.
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!