GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — fix: capture cmdlet warnings to prevent stdout contamination breaking DSC JSON parsing by Gijsreyn · Pull Request #2000 · PowerShell/PSResourceGet

Conversation

@Gijsreyn

@Gijsreyn Gijs Reijn (Gijsreyn) commented May 23, 2026

Copy link
Copy Markdown
Contributor

PR Summary

Warnings emitted by Install-PSResource and Uninstall-PSResource were leaking to stdout, corrupting the JSON output that DSC parses after each set operation. This fix suppresses the warning stream globally in the DSC script and re-routes any per-cmdlet warnings through the trace (stderr) channel so they remain visible without breaking JSON parsing.

PR Context

DSC expects each resource operation to emit only valid JSON on stdout. PowerShell warning messages (e.g. from NuGet or module compatibility checks) were being written to stdout alongside the JSON output, causing DSC to fail when parsing the response. The fix sets $WarningPreference = 'SilentlyContinue' at the script level to prevent any unintentional warning output, while individually capturing -WarningVariable on Install-PSResource and Uninstall-PSResource and forwarding those through Write-Trace at warn level so they still appear in DSC's trace/stderr stream.

Note

It's difficult to reproduce a warning in the stream on the GitHub runners; thus, I added a simple regression test.

PR Checklist

  • PR has a meaningful title
    • Use the present tense and imperative mood when describing your changes
  • Summarized changes
  • Make sure all .h, .cpp, .cs, .ps1 and .psm1 files have the correct copyright header
  • This PR is ready to merge and is not Work in Progress.
    • If the PR is work in progress, please add the prefix WIP: or [ WIP ] to the beginning of the title (the WIP bot will keep its status check at Pending while the prefix is present) and remove the prefix when the PR is ready.
  • Breaking changes
    • None
  • User-facing changes
    • Not Applicable
  • Testing - New and feature
    • Make sure you've added a new test if existing tests do not effectively test the code changed
  • Tooling
    • I have considered the user experience from a tooling perspective and don't believe tooling will be impacted.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@Gijsreyn
fix: capture cmdlet warnings to prevent stdout contamination breaking…
2b18a24
… DSC JSON parsing
Copilot AI review requested due to automatic review settings May 23, 2026 11:09
@Gijsreyn
Gijs Reijn (Gijsreyn) requested review from Sydney Smith (SydneyhSmith), Aditya Patwardhan (adityapatwardhan), alerickson, Anam Navied (anamnavi) and shammu1 as code owners May 23, 2026 11:09
@Gijsreyn

Gijs Reijn (Gijsreyn) commented May 23, 2026

Copy link
Copy Markdown
Contributor Author

Aditya Patwardhan (@adityapatwardhan) - I think perhaps for future enhancements, it can use the same mechanism that was implemented in the PSScript resource sitting in DSC's repository. I guess a function like this would do:

function Invoke-IsolatedPSResource {
    param(
        [Parameter(Mandatory)]
        [scriptblock]$ScriptBlock,
        [Parameter()]
        [hashtable]$Parameters = @{}
    )

    $traceQueue = [System.Collections.Concurrent.ConcurrentQueue[string]]::new()
    $modulePath  = Join-Path $PSScriptRoot 'Microsoft.PowerShell.PSResourceGet.psd1'

    $ps = [PowerShell]::Create()
    $null = $ps.AddScript({
        param($ModulePath)
        Import-Module $ModulePath -Force -ErrorAction Stop
        $VerbosePreference = 'Continue'
        $DebugPreference   = 'Continue'
    }).AddParameter('ModulePath', $modulePath)
    $null = $ps.AddStatement().AddScript($ScriptBlock)
    foreach ($kv in $Parameters.GetEnumerator()) {
        $null = $ps.AddParameter($kv.Key, $kv.Value)
    }

    $subscribers = @(
        Register-ObjectEvent -InputObject $ps.Streams.Warning -EventName DataAdding -MessageData $traceQueue -Action {
            $Event.MessageData.Enqueue((@{ warn = $EventArgs.ItemAdded.Message } | ConvertTo-Json -Compress))
        }
        Register-ObjectEvent -InputObject $ps.Streams.Error -EventName DataAdding -MessageData $traceQueue -Action {
            $Event.MessageData.Enqueue((@{ error = [string]$EventArgs.ItemAdded } | ConvertTo-Json -Compress))
        }
        Register-ObjectEvent -InputObject $ps.Streams.Information -EventName DataAdding -MessageData $traceQueue -Action {
            if ($null -ne $EventArgs.ItemAdded.MessageData) {
                $Event.MessageData.Enqueue((@{ info = $EventArgs.ItemAdded.MessageData.ToString() } | ConvertTo-Json -Compress))
            }
        }
        Register-ObjectEvent -InputObject $ps.Streams.Verbose -EventName DataAdding -MessageData $traceQueue -Action {
            $Event.MessageData.Enqueue((@{ debug = $EventArgs.ItemAdded.Message } | ConvertTo-Json -Compress))
        }
        Register-ObjectEvent -InputObject $ps.Streams.Debug -EventName DataAdding -MessageData $traceQueue -Action {
            $Event.MessageData.Enqueue((@{ debug = $EventArgs.ItemAdded.Message } | ConvertTo-Json -Compress))
        }
    )

    function FlushTraceQueue {
        $trace = $null
        while (!$traceQueue.IsEmpty) {
            if ($traceQueue.TryDequeue([ref]$trace)) {
                $host.ui.WriteErrorLine($trace)
            }
        }
    }

    try {
        $asyncResult = $ps.BeginInvoke()
        while (-not $asyncResult.IsCompleted) {
            FlushTraceQueue
            Start-Sleep -Milliseconds 100
        }
        $output = $ps.EndInvoke($asyncResult)
        FlushTraceQueue

        if ($ps.HadErrors) {
            throw $ps.Streams.Error[0].Exception
        }

        return $output
    }
    finally {
        $ps.Dispose()
        foreach ($subscriber in $subscribers) {
            Unregister-Event -SubscriptionId $subscriber.SubscriptionId -ErrorAction SilentlyContinue
            Remove-Job -Id $subscriber.SubscriptionId -Force -ErrorAction SilentlyContinue
        }
    }
}

If that's your preference to include instantly, let me know! :)

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Copilot AI reviewed May 23, 2026
View reviewed changes

Copilot AI left a comment

Copy link
Copy Markdown

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR aims to prevent PSResourceGet warning output from contaminating DSC JSON output (stdout), which can break JSON parsing, and adds a regression test to validate stdout remains valid JSON.

Changes:

  • Added a Pester regression test ensuring dsc resource set ... -o json stdout contains only valid JSON (no warnings / ANSI escapes).
  • Captured warnings from Install-PSResource / Uninstall-PSResource via -WarningVariable and forwarded them to Write-Trace.
  • Set $WarningPreference = 'SilentlyContinue' to suppress warnings globally within the DSC entry script.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
test/DscResource/PSResourceGetDSCResource.Tests.ps1 Adds regression coverage to ensure stdout JSON isn’t polluted by warning output.
src/dsc/psresourceget.ps1 Attempts to suppress/capture PSResourceGet warnings and route them to trace instead of stdout.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/dsc/psresourceget.ps1 Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/dsc/psresourceget.ps1 Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread test/DscResource/PSResourceGetDSCResource.Tests.ps1 Resolved

Uh oh!

There was an error while loading. Please reload this page.

@Gijsreyn
Fix Copilot remark
511fb36
@SydneyhSmith Sydney Smith (SydneyhSmith) assigned Aditya Patwardhan (adityapatwardhan) Aug 4, 2026
adityapatwardhan
Aditya Patwardhan (adityapatwardhan) approved these changes Sep 9, 2026
View reviewed changes
@adityapatwardhan

Aditya Patwardhan (adityapatwardhan) commented Sep 10, 2026

Copy link
Copy Markdown
Member

Tests passing: #2026

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@adityapatwardhan
Aditya Patwardhan (adityapatwardhan) merged commit 71cf1e3 into PowerShell:master Sep 10, 2026
12 checks passed

Uh oh!

There was an error while loading. Please reload this page.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

Copilot code review Copilot
Copilot review effort
Applies to this pull request for everyone.Learn more about Copilot code review.
Copilot left review comments
@adityapatwardhan Aditya Patwardhan (adityapatwardhan) adityapatwardhan approved these changes
@anamnavi Anam Navied (anamnavi) Awaiting requested review from anamnavi anamnavi is a code owner
@alerickson alerickson Awaiting requested review from alerickson alerickson is a code owner
@SydneyhSmith Sydney Smith (SydneyhSmith) Awaiting requested review from SydneyhSmith SydneyhSmith is a code owner
@shammu1 shammu1 Awaiting requested review from shammu1 shammu1 is a code owner

Uh oh!

There was an error while loading. Please reload this page.

Assignees

@adityapatwardhan Aditya Patwardhan (adityapatwardhan)

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

3 participants

@Gijsreyn @adityapatwardhan
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.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.