Workloads/Get-SharePointData.ps1

# Get-SharePointData.ps1
# Spawns Get-SPOData.ps1 in Windows PowerShell 5.1, merges results into Assessment.
# Part of the M365-QuickAssess module -- not exported.

function Get-SharePointData
{
    param
    (
        $Assessment
    )

    Write-Log "Starting SharePoint collection"

    # -------------------------------------------------------------------
    # Resolve paths
    # -------------------------------------------------------------------
    $tempFile   = Join-Path $env:TEMP "spo-$( $script:Context.RunStamp ).json"
    $errFile    = Join-Path $env:TEMP "spo-$( $script:Context.RunStamp ).err"
    $scriptPath = Join-Path $PSScriptRoot "..\Tools\Get-SPOData.ps1"
    $ps5        = "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe"

    if ( -not ( Test-Path $scriptPath ) )
    {
        Write-Log "Get-SPOData.ps1 not found at $scriptPath" "ERROR"
        return
    }

    if ( -not ( Test-Path $ps5 ) )
    {
        Write-Log "Windows PowerShell 5.1 not found at $ps5" "ERROR"
        return
    }

    # -------------------------------------------------------------------
    # Ensure SPO Admin URL is resolved
    # -------------------------------------------------------------------
    if ( -not $script:Context.SPOAdminUrl )
    {
        try
        {
            Connect-SharePointService
        }
        catch
        {
            Write-Log "Could not resolve SharePoint Admin URL -- skipping SharePoint collection" "ERROR"
            return
        }
    }

    # -------------------------------------------------------------------
    # Spawn PS5 process to run Get-SPOData.ps1
    # -------------------------------------------------------------------
    Write-Log "Spawning PowerShell 5.1 for SharePoint collection"
    Write-Log "Admin URL: $( $script:Context.SPOAdminUrl )"

    try
    {
        $process = Start-Process $ps5 -ArgumentList @(
            "-NoProfile",
            "-ExecutionPolicy Bypass",
            "-File `"$scriptPath`"",
            "-OutputFile `"$tempFile`"",
            "-AdminUrl `"$( $script:Context.SPOAdminUrl )`""
        ) -Wait -PassThru -RedirectStandardError $errFile

        # -------------------------------------------------------------------
        # Capture and log stderr regardless of exit code
        # -------------------------------------------------------------------
        if ( Test-Path $errFile )
        {
            $errContent = Get-Content $errFile -Raw -ErrorAction SilentlyContinue
            if ( -not [string]::IsNullOrWhiteSpace( $errContent ) )
            {
                Write-Log "Get-SPOData.ps1 stderr: $errContent" "WARN"
            }
            Remove-Item $errFile -Force -ErrorAction SilentlyContinue
        }

        if ( $process.ExitCode -ne 0 )
        {
            Write-Log "Get-SPOData.ps1 exited with code $( $process.ExitCode ) -- see stderr above for details" "ERROR"
            return
        }
    }
    catch
    {
        Write-Log "Failed to spawn SharePoint collection process: $( $_.Exception.Message )" "ERROR"
        return
    }

    # -------------------------------------------------------------------
    # Validate output file
    # -------------------------------------------------------------------
    if ( -not ( Test-Path $tempFile ) )
    {
        Write-Log "SharePoint output file not found after collection: $tempFile" "ERROR"
        return
    }

    # -------------------------------------------------------------------
    # Parse and merge
    # -------------------------------------------------------------------
    try
    {
        Write-Log "Merging SharePoint data"

        $spoData = Get-Content $tempFile -Raw | ConvertFrom-Json

        # Core metrics
        $Assessment.SharePoint.SharePointSiteCount            = $spoData.SharePoint.SharePointSiteCount
        $Assessment.SharePoint.SharePointTotalStorageGB       = $spoData.SharePoint.SharePointTotalStorageGB
        $Assessment.SharePoint.LargeSiteCount                 = $spoData.SharePoint.LargeSiteCount
        $Assessment.SharePoint.HasExternalSharing             = $spoData.SharePoint.HasExternalSharing
        $Assessment.SharePoint.HasUniquePermissions           = $spoData.SharePoint.HasUniquePermissions
        $Assessment.SharePoint.HasSharePointRetentionPolicies = $false
        $Assessment.SharePoint.HasAppCatalog                  = $spoData.SharePoint.HasAppCatalog
        $Assessment.SharePoint.HasSharePointCustomApps        = $spoData.SharePoint.HasSharePointCustomApps
        $Assessment.SharePoint.SharePointCustomAppCount       = $spoData.SharePoint.SharePointCustomAppCount

        # Summary rollup
        $Assessment.Summary.SharePointSiteCount      = $spoData.SharePoint.SharePointSiteCount
        $Assessment.Summary.SharePointTotalStorageGB = $spoData.SharePoint.SharePointTotalStorageGB

        Write-Log "SharePoint: Sites=$( $spoData.SharePoint.SharePointSiteCount ) StorageGB=$( $spoData.SharePoint.SharePointTotalStorageGB ) LargeSites=$( $spoData.SharePoint.LargeSiteCount )"

        # -------------------------------------------------------------------
        # Merge findings from SPO script
        # -------------------------------------------------------------------
        foreach ( $finding in $spoData.Findings )
        {
            switch ( $finding.Type )
            {
                "LargeSharePointSite"
                {
                    $Assessment.Findings += New-Finding `
                        -Type           "LargeSharePointSite" `
                        -Summary        "Large SharePoint site detected" `
                        -Category       "SharePoint" `
                        -Severity       "Medium" `
                        -Details        @( "$( $finding.Title ) - $( $finding.Url ) ($( $finding.SizeGB ) GB)" ) `
                        -Impact         "Large sites increase migration time and risk." `
                        -Recommendation "Review storage usage and archive or delete unnecessary content before migration."
                }

                "ExternalSharing"
                {
                    $Assessment.Findings += New-Finding `
                        -Type           "SharePointExternalSharing" `
                        -Summary        "External sharing enabled on one or more SharePoint sites" `
                        -Category       "Security" `
                        -Severity       "Medium" `
                        -Details        @( $finding.Url ) `
                        -Impact         "External users may retain access to data post-migration if sharing is not reviewed." `
                        -Recommendation "Review and document external sharing settings before migration."
                }

                "StorageUsage"
                {
                    $Assessment.Findings += New-Finding `
                        -Type           "SharePointStorageUsage" `
                        -Summary        $finding.Description `
                        -Category       "SharePoint" `
                        -Severity       $finding.Severity `
                        -Impact         "High storage volumes increase migration time and cost." `
                        -Recommendation "Review site storage, archive stale data, and implement lifecycle policies."
                }

                default
                {
                    # Intentionally skip unknown finding types
                }
            }
        }
    }
    catch
    {
        Write-Log "SharePoint data merge failed: $( $_.Exception.Message )" "ERROR"
    }
    finally
    {
        Remove-Item $tempFile -Force -ErrorAction SilentlyContinue
    }
}