Collaboration/Get-FormsSecurityConfig.ps1
|
<#
.SYNOPSIS Collects Microsoft Forms tenant security and configuration settings. .DESCRIPTION Queries Microsoft Graph for Microsoft Forms admin settings including external sharing controls, phishing protection, and respondent identity recording. Returns a structured inventory of settings with current values and CIS benchmark recommendations. Requires the following Graph API permissions: OrgSettings-Forms.Read.All .PARAMETER OutputPath Optional path to export results as CSV. If not specified, results are returned to the pipeline. .EXAMPLE PS> . .\Common\Connect-Service.ps1 PS> Connect-Service -Service Graph -Scopes 'OrgSettings-Forms.Read.All' PS> .\Collaboration\Get-FormsSecurityConfig.ps1 Displays Microsoft Forms security configuration settings. .EXAMPLE PS> .\Collaboration\Get-FormsSecurityConfig.ps1 -OutputPath '.\forms-security-config.csv' Exports Forms security configuration to CSV. .NOTES Author: Daren9m Settings checked are aligned with CIS Microsoft 365 Foundations Benchmark v6.0.1 recommendations. #> [CmdletBinding()] param( [Parameter()] [ValidateNotNullOrEmpty()] [string]$OutputPath ) # Continue on errors: non-critical checks should not block remaining assessments. $ErrorActionPreference = 'Continue' # Verify Graph connection if (-not (Assert-GraphConnection)) { return } # Load shared security-config helpers $_scriptDir = if ($MyInvocation.MyCommand.Path) { Split-Path -Parent $MyInvocation.MyCommand.Path } else { $PSScriptRoot } . (Join-Path -Path $_scriptDir -ChildPath '..\Common\SecurityConfigHelper.ps1') $ctx = Initialize-SecurityConfig $settings = $ctx.Settings $checkIdCounter = $ctx.CheckIdCounter function Add-Setting { param( [string]$Category, [string]$Setting, [string]$CurrentValue, [string]$RecommendedValue, [string]$Status, [string]$CheckId = '', [string]$Remediation = '' ) $p = @{ Settings = $settings CheckIdCounter = $checkIdCounter Category = $Category Setting = $Setting CurrentValue = $CurrentValue RecommendedValue = $RecommendedValue Status = $Status CheckId = $CheckId Remediation = $Remediation } Add-SecuritySetting @p } # ------------------------------------------------------------------ # 1. Microsoft Forms Admin Settings (CIS 3.6.x) # ------------------------------------------------------------------ try { Write-Verbose "Checking Microsoft Forms admin settings..." $graphParams = @{ Method = 'GET' Uri = '/beta/admin/forms/settings' ErrorAction = 'Stop' } $formsSettings = Invoke-MgGraphRequest @graphParams if ($formsSettings) { # CIS 3.6.1 - Ensure only people in your organization can respond to forms $externalSend = $formsSettings['isExternalSendFormEnabled'] $settingParams = @{ Category = 'External Sharing' Setting = 'External Users Can Respond to Forms' CurrentValue = "$externalSend" RecommendedValue = 'False' Status = if (-not $externalSend) { 'Pass' } else { 'Fail' } CheckId = 'FORMS-CONFIG-001' Remediation = 'Microsoft 365 admin center > Settings > Org settings > Microsoft Forms > Uncheck "People outside your organization can respond".' } Add-Setting @settingParams # CIS 3.6.1 - Ensure external collaboration on forms is restricted $externalCollab = $formsSettings['isExternalShareCollaborationEnabled'] $settingParams = @{ Category = 'External Sharing' Setting = 'External Users Can Collaborate on Forms' CurrentValue = "$externalCollab" RecommendedValue = 'False' Status = if (-not $externalCollab) { 'Pass' } else { 'Fail' } CheckId = 'FORMS-CONFIG-002' Remediation = 'Microsoft 365 admin center > Settings > Org settings > Microsoft Forms > Uncheck "People outside your organization can share and collaborate on forms".' } Add-Setting @settingParams # External result sharing $externalResults = $formsSettings['isExternalShareResultEnabled'] $settingParams = @{ Category = 'External Sharing' Setting = 'External Users Can View Form Results' CurrentValue = "$externalResults" RecommendedValue = 'False' Status = if (-not $externalResults) { 'Pass' } else { 'Fail' } CheckId = 'FORMS-CONFIG-003' Remediation = 'Microsoft 365 admin center > Settings > Org settings > Microsoft Forms > Uncheck "People outside your organization can see results summary and individual responses".' } Add-Setting @settingParams # CIS 3.6.2 - Phishing protection enabled $phishingProtection = $formsSettings['isPhishingScanEnabled'] $settingParams = @{ Category = 'Security' Setting = 'Phishing Protection' CurrentValue = "$phishingProtection" RecommendedValue = 'True' Status = if ($phishingProtection) { 'Pass' } else { 'Fail' } CheckId = 'FORMS-CONFIG-004' Remediation = 'Microsoft 365 admin center > Settings > Org settings > Microsoft Forms > Enable "Internal phishing protection".' } Add-Setting @settingParams # Identity recording by default (accountability/non-repudiation) $recordIdentity = $formsSettings['isRecordIdentityByDefaultEnabled'] $settingParams = @{ Category = 'Security' Setting = 'Record Respondent Identity by Default' CurrentValue = "$recordIdentity" RecommendedValue = 'True' Status = if ($recordIdentity) { 'Pass' } else { 'Review' } CheckId = 'FORMS-CONFIG-005' Remediation = 'Microsoft 365 admin center > Settings > Org settings > Microsoft Forms > Enable "Record name by default when new forms are created".' } Add-Setting @settingParams # Bing image/video search (external content exposure) $bingSearch = $formsSettings['isBingImageVideoSearchEnabled'] $settingParams = @{ Category = 'Security' Setting = 'Bing Image and Video Search' CurrentValue = "$bingSearch" RecommendedValue = 'False' Status = if (-not $bingSearch) { 'Pass' } else { 'Review' } CheckId = 'FORMS-CONFIG-006' Remediation = 'Microsoft 365 admin center > Settings > Org settings > Microsoft Forms > Uncheck "Bing search and YouTube video".' } Add-Setting @settingParams } } catch { if ($_.Exception.Message -match '403|Forbidden|Authorization_RequestDenied|Insufficient') { Write-Warning "Insufficient permissions to read Forms settings. Requires OrgSettings-Forms.Read.All scope. Skipping Forms security checks." $settingParams = @{ Category = 'External Sharing' Setting = 'External Users Can Respond to Forms' CurrentValue = 'Permission denied -- OrgSettings-Forms.Read.All required' RecommendedValue = 'False' Status = 'Review' CheckId = 'FORMS-CONFIG-001' Remediation = 'Reconnect with the OrgSettings-Forms.Read.All permission scope to check Microsoft Forms settings.' } Add-Setting @settingParams } else { Write-Warning "Could not retrieve Microsoft Forms settings: $($_.Exception.Message)" } } # ------------------------------------------------------------------ # Output # ------------------------------------------------------------------ Export-SecurityConfigReport -Settings $settings -OutputPath $OutputPath -ServiceLabel 'Microsoft Forms' |