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'