Private/Connect-SPCSiteInternal.ps1
|
function Connect-SPCSiteInternal { <# .SYNOPSIS Private helper establishing a site-specific PnP connection reusing active session credentials. .DESCRIPTION Consolidates per-site authentication across SPClean cmdlets. Supports Interactive token reuse and AppOnly authentication via certificate file, certificate thumbprint, or client secret (with secure in-memory BSTR memory clearing). .PARAMETER SiteUrl The full URL of the SharePoint Online site collection to connect to. .PARAMETER Context The session context object. Defaults to $script:SPCContext. .OUTPUTS [PnP.PowerShell.Commands.Base.PnPConnection] or connection object #> [CmdletBinding()] [OutputType([object])] param( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$SiteUrl, [Parameter()] [PSCustomObject]$Context = $script:SPCContext ) begin { Write-Verbose "Connect-SPCSiteInternal: Connecting to site collection '$SiteUrl'" if ($null -eq $Context) { throw 'ERR-AUTH-005: Connect-SPCSiteInternal: No active SPClean session context provided.' } } process { $tenantId = if ($Context.TenantName -match '\.') { $Context.TenantName } else { "$($Context.TenantName).onmicrosoft.com" } $authMode = if ($Context.AuthMode) { $Context.AuthMode } else { $Context.AuthMethod } switch ($authMode) { 'Interactive' { $token = $null try { $token = if ($Context.PnPContext) { Get-PnPAccessToken -ResourceTypeName SharePoint -Connection $Context.PnPContext -ErrorAction Stop } else { Get-PnPAccessToken -ResourceTypeName SharePoint -ErrorAction Stop } } catch { $token = $Context.GraphAccessToken } if (-not [string]::IsNullOrWhiteSpace($token)) { Connect-PnPOnline -Url $SiteUrl -AccessToken $token -ReturnConnection } elseif ($Context._ClientId) { Connect-PnPOnline -Url $SiteUrl -Interactive -ClientId $Context._ClientId -ReturnConnection } else { Connect-PnPOnline -Url $SiteUrl -AccessToken $Context.GraphAccessToken -ReturnConnection } } 'AppOnly' { $clientId = if ($Context.ClientId) { $Context.ClientId } else { $Context._ClientId } $certPath = if ($Context.CertificatePath) { $Context.CertificatePath } else { $Context._CertificatePath } $certPass = if ($Context.CertificatePassword) { $Context.CertificatePassword } else { $Context._CertificatePassword } $thumbprint = if ($Context.CertificateThumbprint) { $Context.CertificateThumbprint } elseif ($Context.Thumbprint) { $Context.Thumbprint } else { $Context._CertificateThumbprint } $clientSecret = if ($Context.ClientSecret) { $Context.ClientSecret } else { $Context._ClientSecret } if ($certPath) { $pnpParams = @{ Url = $SiteUrl ClientId = $clientId Tenant = $tenantId CertificatePath = $certPath ReturnConnection = $true } if ($null -ne $certPass) { $pnpParams['CertificatePassword'] = $certPass } Connect-PnPOnline @pnpParams } elseif ($thumbprint) { Connect-PnPOnline -Url $SiteUrl -ClientId $clientId ` -Tenant $tenantId ` -Thumbprint $thumbprint -ReturnConnection } elseif ($null -ne $clientSecret) { $secSecret = if ($clientSecret -is [System.Security.SecureString]) { $clientSecret } else { ConvertTo-SecureString $clientSecret -AsPlainText -Force } $bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secSecret) try { $plain = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr) Connect-PnPOnline -Url $SiteUrl -ClientId $clientId ` -ClientSecret $plain -Tenant $tenantId -ReturnConnection } finally { [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr) $plain = $null } } else { throw 'ERR-AUTH-003: Connect-SPCSiteInternal: Incomplete AppOnly credentials in context.' } } Default { throw "ERR-AUTH-001: Connect-SPCSiteInternal: Unsupported AuthMethod '$authMode'." } } } end { Write-Verbose "Connect-SPCSiteInternal: Completed connection for '$SiteUrl'" } } |