Skip to content

Use CommandInfo within Command.CreateCommandProcessor() if available.#27674

Open
mjr4077au wants to merge 1 commit into
PowerShell:masterfrom
devicie:fix/commandInfo
Open

Use CommandInfo within Command.CreateCommandProcessor() if available.#27674
mjr4077au wants to merge 1 commit into
PowerShell:masterfrom
devicie:fix/commandInfo

Conversation

@mjr4077au

@mjr4077au mjr4077au commented Jul 11, 2026

Copy link
Copy Markdown

PR Summary

Use CommandInfo within Command.CreateCommandProcessor() if available.

PR Context

During testing of PowerShell.GetSteppablePipeline(), I found that I could not reference internal-scoped cmdlets of my module despite providing a proper CmdletInfo object to PowerShell.AddCommand(). Further review found that Command.CreateCommandProcessor() is eschewing the CommandInfo object it has a hold of for the text representing the command instead.

This PR tests whether Command.CommandInfo is null and if not, uses the CommandInfo overload of CommandDiscovery.LookupCommandProcessor() instead, which not only addresses this problem, but also addresses what I consider to be a security concern where I might be explicitly using a CommandInfo object of a trusted command to not be subject to command/function re-definition.

Test function for validation of this PR before/after:

function Get-CommandSteppable {
    [CmdletBinding()]
    param
    (
    )

    begin
    {
        $pwsh = [System.Management.Automation.PowerShell]::Create([System.Management.Automation.RunspaceMode]::CurrentRunspace)
        try
        {
            $steppablePipeline = $pwsh.AddCommand([System.Management.Automation.CmdletInfo]::new("Get-CommandWithUnresolvableName", [Microsoft.PowerShell.Commands.GetCommandCommand])).GetSteppablePipeline()
        }
        catch
        {
            $PSCmdlet.ThrowTerminatingError($_)
        }
        finally
        {
            $pwsh.Dispose();
            Remove-Variable -Name pwsh
        }
        $steppablePipeline.Begin($PSCmdlet)
    }

    process
    {
        $null = $steppablePipeline.Process()
    }

    end
    {
        $null = $steppablePipeline.End()
        $steppablePipeline.Dispose()
    }
}

Before:

PS C:\Repos\PowerShell> Get-CommandSteppable
Get-CommandSteppable: Exception calling "GetSteppablePipeline" with "0" argument(s): "The term 'Get-CommandWithUnresolvableName' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again."
PS C:\Repos\PowerShell>

After:

PS C:\Repos\PowerShell> Get-CommandSteppable

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           Add-AppPackage ->                                  2.0.1.0    Appx
Alias           Add-AppPackageVolume ->                            2.0.1.0    Appx
Alias           Add-AppProvisionedPackage ->                       3.0        Dism
Alias           Add-AssertionOperator ->                           5.7.1      Pester
Alias           Add-MsixPackage ->                                 2.0.1.0    Appx
Alias           Add-MsixPackageVolume ->                           2.0.1.0    Appx
...

PS C:\Repos\PowerShell>

This is also my first PR to the project so if I've done anything wrong, just let me know and I'll get it fixed up.

PR Checklist

…ble.

During testing of `PowerShell.GetSteppablePipeline()`, I found that I could not reference internal-scoped cmdlets of my module despite providing a proper CmdletInfo object to `PowerShell.AddCommand()`. Further review found that `Command.CreateCommandProcessor()` is eschewing the `CommandInfo` object it has a hold of for the text representing the command instead.

This PR tests whether `Command.CommandInfo` is null and if not, uses the `CommandInfo` overload of `CommandDiscovery.LookupCommandProcessor()` instead, which not only addresses this problem, but also addresses what I consider to be a security concern where I might be explicitly using a `CommandInfo` object of a trusted command to not be subject to command/function re-definition.
Copilot AI review requested due to automatic review settings July 11, 2026 05:24
@mjr4077au
mjr4077au requested a review from a team as a code owner July 11, 2026 05:24
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR updates Command.CreateCommandProcessor() to prefer an existing CommandInfo instance (when available) instead of re-resolving by CommandText, improving correctness for scenarios like PowerShell.AddCommand(CmdletInfo).GetSteppablePipeline() where the provided CmdletInfo should be authoritative.

Changes:

  • Use the CommandDiscovery.LookupCommandProcessor(CommandInfo, ...) overload when Command.CommandInfo is present.
  • Continue using the CommandText-based lookup as a fallback when CommandInfo is not available.

Comment on lines +530 to +533
// Favour a ComamndInfo object if one is available.
commandProcessorBase = CommandInfo is CommandInfo commandInfo
? executionContext.CommandDiscovery.LookupCommandProcessor(commandInfo, origin, _useLocalScope, null)
: executionContext.CommandDiscovery.LookupCommandProcessor(CommandText, origin, _useLocalScope);

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I'll need a team member with more knowledge of the engine than I have to advise whether this suggestion has valid merit or not.

@kilasuit kilasuit added WG-Engine core PowerShell engine, interpreter, and runtime CL-Engine Indicates that a PR should be marked as an engine change in the Change Log WG-NeedsReview Needs a review by the labeled Working Group labels Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CL-Engine Indicates that a PR should be marked as an engine change in the Change Log WG-Engine core PowerShell engine, interpreter, and runtime WG-NeedsReview Needs a review by the labeled Working Group

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants