Detect the PowerShell edition once and read failed HTTP responses the way it allows - #49
Merged
Merged
Conversation
…es the way it allows Windows PowerShell 5.1 stays, because a freshly built domain controller has nothing else; the REST providers are better served by PowerShell 7.4. Get-TestRuntime in Core reads the edition at import and detects each capability on the cmdlet that has it - a parameter that exists on Invoke-WebRequest is one that works - and everything that differs by edition reads that object instead of testing $PSVersionTable for itself. Get-TestEnvironmentRuntime shows the decision. Invoke-TestWebRequest asks for a failed response with -SkipHttpErrorCheck where the cmdlet has it and reads the body like any other; without it the cmdlet throws and the body is read once from the exception's response stream. Either way the caller gets one shape, built by New-TestWebRequestError: an integer Response.StatusCode, a Response.Headers table with each value one string, the body in ErrorDetails. The four Get-<Provider>ErrorDetail helpers no longer read a stream. A transport failure with no response propagates untouched. Measured and not kept: HTTP/2 (a core-tier PingOne seed took 25 s with it and 25 s without, twice each), and the AD user and device steps on the runspace pool (270 of 310 manager assignments failed and the device step took ten times longer on the lab DC, because the RSAT module keeps one ADWS session per process). Both findings are in CLAUDE.md and the changelog.
Preferred and Recommendation on Get-TestEnvironmentRuntime: 7.4 or later for every provider, Windows PowerShell 5.1 supported because a freshly built domain controller has nothing else. Said in the object so a run on the slower edition sees it without reading the help; the docs page, the about topic and the changelog say the same.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The module runs on Windows PowerShell 5.1, because a freshly built domain controller has nothing else, and on PowerShell 7.4, which the REST providers are better served by. This makes the edition something the module reads once and acts on, rather than something seven places tested for themselves.
Detection
Core/Get-TestRuntime.ps1reads$PSVersionTableat import and detects each capability on the cmdlet that has it:SkipHttpErrorCheck,HttpTimeouts,JsonAsHashtable,ModernTls,NativeUtf8. A parameter that exists onInvoke-WebRequestis one that works, whatever the build, so nothing is inferred from a version number. The result is cached in module scope;Get-TestEnvironmentRuntime(new export, documented) shows it, so a run that behaves differently on two hosts can be explained by its first line.What differs by edition today
Invoke-TestWebRequestis the one place:-SkipHttpErrorCheckbrings a 4xx or 5xx back as a response and its body is decoded like any other; TLS is left to negotiate.Core/New-TestWebRequestError.ps1: an integerResponse.StatusCode, aResponse.Headershashtable with each value one string, the body inErrorDetails. The fourGet-<Provider>ErrorDetailhelpers no longer read a stream, and the retry loops read one header table on both editions. A transport failure with no response propagates untouched.Verified live against PingOne from both editions: the same 404 and the same validation refusal, word for word, headers present on both.
Measured and not kept
-HttpVersion 2.0exists from 7.3 and was tried: a core-tier PingOne seed took 25 s with it and 25 s without, twice each. Not requested; a capability that changes nothing is noise.CLAUDE.mdnow says why.Lessons pinned in the suite
WebHeaderCollectionassigned from anifexpression arrives as an array of its key names (a statement's output is enumerated on the way out).Responsethrows anErrorRecord.HttpStatusCodehas no 429 member; a real response carries the unnamed value and is read as an integer.Checks
Invoke-Pester ./Tests/Unit: 2,752 passed on PowerShell 7 (one skipped, the Desktop-only TLS test) and 2,753 passed on Windows PowerShell 5.1, none failed.Invoke-ScriptAnalyzer -Recurse -Severity Error, Warning: clean../Build/Build-Help.ps1rebuilt;Publish-Module.ps1 -WhatIfpasses.