[BUG] Process crashes with a stack overflow in Connect-PnPOnline after Teams or EXO Module connected (3.4.0 and later)
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 52/100
Direzione di ricerca
Start with PnPAssemblyLoadContext and PnPPowerShellModuleInitializer.ResolveDependency, then run Repro-PnPStackOverflow.ps1 with an older Microsoft.Identity.Client loaded in the default context. Trace the repeated assembly-resolution path described in the issue. Done means the process survives Connect-PnPOnline and reaches the expected tenant-not-found error instead of crashing.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Reporting an Issue or Missing Feature
Issue. Since 3.4.0, the PowerShell process terminates when Connect-PnPOnline runs in a session in which another module has already loaded an older Microsoft.Identity.Client into the default AssemblyLoadContext. Connecting with MicrosoftTeams 8.0.0 (MSAL 4.82.0.0) or ExchangeOnlineManagement 3.9.2 (MSAL 4.74.1.0) causes it. PnP.PowerShell 3.4.x ships MSAL 4.85.2.0.
We found this in Microsoft365DSC, which connects to Microsoft Teams and other services from the same PowerShell 7 process.
Expected behavior
Connect-PnPOnline connects, as it does with 3.3.0.
Actual behavior
The process terminates, with no way to catch the error:
- PowerShell 7.6 (.NET 10) prints
Stack overflow.and exits with-1073741571(0xC00000FD). - PowerShell 7.4 (.NET 8) usually exits with
-1073741819(0xC0000005) and doesn't print anything. - In a PowerShell remoting host (WinRM using the Local Configuration Manager LCM), the client reports
The WSMan provider host process did not return a proper response.
Stack overflow.
Repeated 1207 times:
--------------------------------
at System.Reflection.RuntimeAssembly.InternalLoad(System.Reflection.AssemblyName, System.Threading.StackCrawlMark ByRef, System.Runtime.Loader.AssemblyLoadContext, System.Reflection.RuntimeAssembly, Boolean)
at System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyName(System.Reflection.AssemblyName)
at PnP.PowerShell.Commands.Base.PnPPowerShellModuleInitializer.ResolveDependency(System.Runtime.Loader.AssemblyLoadContext, System.Reflection.AssemblyName)
at System.Runtime.Loader.AssemblyLoadContext.GetFirstResolvedAssemblyFromResolvingEvent(System.Reflection.AssemblyName)
at System.Runtime.Loader.AssemblyLoadContext.ResolveUsingEvent(System.Reflection.AssemblyName)
--------------------------------
at PnP.PowerShell.Commands.Base.PnPConnection.CreateWithCert(System.Uri, System.String, System.String, System.String, PnP.Framework.AzureEnvironment, System.Security.Cryptography.X509Certificates.X509Certificate2, Boolean)
at PnP.PowerShell.Commands.Base.ConnectOnline.ConnectAppOnlyWithCertificate()
at PnP.PowerShell.Commands.Base.ConnectOnline.Connect(System.Threading.CancellationToken ByRef)
at PnP.PowerShell.Commands.Base.ConnectOnline.ProcessRecord()
Cause
#5393 (3.4.0) introduced PnPAssemblyLoadContext. For the boundary assemblies (Microsoft.Identity.Client* and System.Text.Json), Load returns null so that PnP reuses the host's copy whenever the default context holds an assembly with that simple name. It does not compare versions:
PnP.PowerShell.dll(default context) referencesMicrosoft.Identity.Client, Version=4.85.2.0. The default context holds 4.82.0.0, cannot bind the reference and raisesResolving.PnPPowerShellModuleInitializer.ResolveDependencyfindsCommon\Microsoft.Identity.Client.dlland callss_dependencyContext.LoadFromAssemblyName.PnPAssemblyLoadContext.Loadsees a boundary assembly that the default context holds and returnsnull, so the runtime falls back to the default context.- The default context still cannot bind 4.85.2.0 and raises
Resolvingagain, which leads back to step 2. This repeats until the stack overflows.
Importing PnP.PowerShell first does not help if the other module loads its MSAL before the first Connect-PnPOnline. The same loop also happens when any caller requests a newer MSAL than the copy in the default context, even when PnP.PowerShell did not make the request.
Steps to reproduce behavior
In a fresh PowerShell 7 session:
Connect-MicrosoftTeams -ApplicationId $appId -CertificateThumbprint $thumbprint -TenantId 'contoso.onmicrosoft.com'
Connect-PnPOnline -Url 'https://contoso-admin.sharepoint.com' -ClientId $appId -Thumbprint $thumbprint -Tenant 'contoso.onmicrosoft.com'
Connect-ExchangeOnline instead of Connect-MicrosoftTeams crashes the same way.
I have a repro PowerShell script below that loads MSAL 4.82.0 from nuget.org into the default context, then runs Connect-PnPOnline with a throw-away certificate against a tenant that doesn't exist:
pwsh -NoProfile -File .\Repro-PnPStackOverflow.ps1; "exit code $LASTEXITCODE"
Repro-PnPStackOverflow.ps1
#Requires -Version 7.4
<#
.SYNOPSIS
Reproduces the PnP.PowerShell 3.4.x process crash when the default AssemblyLoadContext already holds an older
Microsoft.Identity.Client, as it does after Connect-MicrosoftTeams or Connect-ExchangeOnline.
.DESCRIPTION
Loads Microsoft.Identity.Client 4.82.0 (downloaded from nuget.org, the version MicrosoftTeams 8.0.0 ships) into the
default load context, imports PnP.PowerShell and runs Connect-PnPOnline. No tenant, credentials or other modules are needed.
On an affected version it terminates the process.
.PARAMETER PnPModulePath
Name or path of the PnP.PowerShell module to test.
.EXAMPLE
pwsh -NoProfile -File .\Repro-PnPStackOverflow.ps1; "exit code $LASTEXITCODE"
PnP.PowerShell 3.4.0 and 3.4.1 on PowerShell 7.6: prints 'Stack overflow.' and exits with -1073741571 (0xC00000FD).
On PowerShell 7.4 it usually exits with -1073741819 (0xC0000005) without a message.
In both cases the last line 'Process survived' is missing.
PnP.PowerShell 3.3.0 or a fixed build: Connect-PnPOnline fails with AADSTS90002 (tenant not found), which is the
expected result, and the script prints 'Process survived'.
#>
param(
[Parameter()]
[System.String]
$PnPModulePath = 'PnP.PowerShell'
)
$ErrorActionPreference = 'Stop'
$msal = [System.Runtime.Loader.AssemblyLoadContext]::Default.Assemblies | Where-Object -FilterScript { $_.GetName().Name -eq 'Microsoft.Identity.Client' }
if ($null -eq $msal)
{
$msalFolder = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath 'msal-4.82.0'
$msalPath = Join-Path -Path $msalFolder -ChildPath 'lib/net8.0/Microsoft.Identity.Client.dll'
if (-not (Test-Path -Path $msalPath))
{
Invoke-WebRequest -Uri 'https://www.nuget.org/api/v2/package/Microsoft.Identity.Client/4.82.0' -OutFile "$msalFolder.zip"
Expand-Archive -Path "$msalFolder.zip" -DestinationPath $msalFolder -Force
}
$msal = [System.Runtime.Loader.AssemblyLoadContext]::Default.LoadFromAssemblyPath($msalPath)
}
Write-Host "Default load context holds Microsoft.Identity.Client $($msal.GetName().Version)"
Import-Module -Name $PnPModulePath -DisableNameChecking
Write-Host "Imported PnP.PowerShell $((Get-Module -Name 'PnP.PowerShell').Version)"
$rsa = [System.Security.Cryptography.RSA]::Create(2048)
$request = [System.Security.Cryptography.X509Certificates.CertificateRequest]::new('CN=PnPRepro', $rsa, 'SHA256', [System.Security.Cryptography.RSASignaturePadding]::Pkcs1)
$certificate = $request.CreateSelfSigned([System.DateTimeOffset]::Now.AddDays(-1), [System.DateTimeOffset]::Now.AddDays(1))
try
{
Connect-PnPOnline -Url 'https://pnprepro-invalid.sharepoint.com' -ClientId '11111111-1111-1111-1111-111111111111' -Tenant 'pnprepro-invalid.onmicrosoft.com' -CertificateBase64Encoded ([System.Convert]::ToBase64String($certificate.Export('Pfx')))
}
catch
{
Write-Host "Connect-PnPOnline: $($_.Exception.GetType().FullName): $($_.Exception.Message)"
}
Write-Host 'Process survived'
| PnP.PowerShell | PowerShell 7.6.6 | PowerShell 7.4.20 |
|---|---|---|
| 3.3.0 | survives (AADSTS90002, expected) |
survives (AADSTS90002, expected) |
| 3.4.1 | crash, 0xC00000FD | crash, 0xC0000005 |
dev at 6a978d96 |
crash, 0xC00000FD | crash, 0xC0000005 |
Workaround until a fix ships: run Connect-PnPOnline before connecting to Microsoft Teams or Exchange Online in the same process, or stay on 3.3.0.
What is the version of the Cmdlet module you are running?
3.4.0 and 3.4.1. Also reproduced with a build of dev at 6a978d96.
Which operating system/environment are you running PnP PowerShell on?
- Windows
- Linux
- MacOS
- Azure Cloud Shell
- Azure Functions
- Other : PowerShell 7 remoting host (Windows PowerShell DSC relays class-based resources to a local PowerShell 7 session)
Windows 11 10.0.26300, PowerShell 7.6.6 and 7.4.20. Not tried on Linux or macOS, but they're most likely affected as well.
- Lingua principale
- C#
- Stelle
- 906
- Fork
- 408
- Merge medio
- 2g 2h
- PR unite (30g)
- 11
Preparare l'ambiente
Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di pnp/powershell
-
enhancement
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
pnp/powershell#5476 ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 3/5 1-2 giorni Idoneità per principianti 52/100
pnp/powershell#5485 ·
I maintainer di solito rispondono entro 1 giorno
-
[FEATURE] Add ability to set ExpirationDateTime on Add-PnPFolderUserSharingLinkForse già presa @gautamdsheth l’ha presa 8 giorni fa. Apertaenhancement
Difficoltà 3/5 1-2 giorni Idoneità per principianti 62/100
pnp/powershell#5484 · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 3/5 1-2 giorni Idoneità per principianti 55/100
pnp/powershell#5477 ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 3/5 1-2 giorni Idoneità per principianti 45/100
pnp/powershell#5466 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di pnp/powershell
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
sebastienros/jint#4282 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 76/100
pyrevitlabs/pyRevit#3792 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 60/100
I maintainer di solito rispondono entro 1 giorno
-
Update the about pageAperta
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 65/100
fboucher/2d6-dungeon-app#256 ·
I maintainer di solito rispondono entro 1 giorno
-
area: design documentation
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
eyalgolan/statecraft-israel#883 ·
I maintainer di solito rispondono entro 1 giorno