From c066cd85aa5c0dec8bb4a7007f86431693bf0542 Mon Sep 17 00:00:00 2001 From: MartinGC94 <42123497+MartinGC94@users.noreply.github.com> Date: Mon, 30 Dec 2024 20:06:28 +0100 Subject: [PATCH] Add ExcludeModule parameter to Get-Command (#18955) --- .../CommandCompletion/CompletionCompleters.cs | 10 ++++- .../engine/GetCommandCommand.cs | 38 +++++++++++++++++++ .../TabCompletion/TabCompletion.Tests.ps1 | 1 + .../Get-Command.Tests.ps1 | 5 +++ 4 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs b/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs index 5471cedbb1..1e23c43f99 100644 --- a/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs +++ b/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs @@ -2173,6 +2173,12 @@ namespace System.Management.Automation break; } + if (parameterName.Equals("ExcludeModule", StringComparison.OrdinalIgnoreCase)) + { + NativeCompletionGetCommand(context, moduleName: null, parameterName, result); + break; + } + if (parameterName.Equals("Name", StringComparison.OrdinalIgnoreCase)) { var moduleNames = NativeCommandArgumentCompletion_ExtractSecondaryArgument(boundArguments, "Module"); @@ -3072,7 +3078,9 @@ namespace System.Management.Automation result.Add(CompletionResult.Null); } - else if (!string.IsNullOrEmpty(paramName) && paramName.Equals("Module", StringComparison.OrdinalIgnoreCase)) + else if (!string.IsNullOrEmpty(paramName) + && (paramName.Equals("Module", StringComparison.OrdinalIgnoreCase) + || paramName.Equals("ExcludeModule", StringComparison.OrdinalIgnoreCase))) { CompleteModule(context, result); } diff --git a/src/System.Management.Automation/engine/GetCommandCommand.cs b/src/System.Management.Automation/engine/GetCommandCommand.cs index db6ce736bb..a941ce0f2b 100644 --- a/src/System.Management.Automation/engine/GetCommandCommand.cs +++ b/src/System.Management.Automation/engine/GetCommandCommand.cs @@ -140,6 +140,28 @@ namespace Microsoft.PowerShell.Commands private string[] _modules = Array.Empty(); private bool _isModuleSpecified = false; + /// + /// Gets or sets the ExcludeModule parameter to the cmdlet. + /// + [Parameter()] + public string[] ExcludeModule + { + get + { + return _excludedModules; + } + + set + { + value ??= Array.Empty(); + + _excludedModules = value; + _excludedModulePatterns = null; + } + } + + private string[] _excludedModules = Array.Empty(); + /// /// Gets or sets the FullyQualifiedModule parameter to the cmdlet. /// @@ -404,6 +426,7 @@ namespace Microsoft.PowerShell.Commands // Initialize the module patterns _modulePatterns ??= SessionStateUtilities.CreateWildcardsFromStrings(Module, WildcardOptions.IgnoreCase | WildcardOptions.CultureInvariant); + _excludedModulePatterns ??= SessionStateUtilities.CreateWildcardsFromStrings(ExcludeModule, WildcardOptions.IgnoreCase | WildcardOptions.CultureInvariant); switch (ParameterSetName) { @@ -702,6 +725,13 @@ namespace Microsoft.PowerShell.Commands if (!string.IsNullOrEmpty(command.ModuleName)) { + if (_excludedModulePatterns is not null + && _excludedModulePatterns.Count > 0 + && SessionStateUtilities.MatchesAnyWildcardPattern(command.ModuleName, _excludedModulePatterns, true)) + { + break; + } + if (_isFullyQualifiedModuleSpecified) { if (!_moduleSpecifications.Any( @@ -1271,6 +1301,13 @@ namespace Microsoft.PowerShell.Commands } else { + if (_excludedModulePatterns is not null + && _excludedModulePatterns.Count > 0 + && SessionStateUtilities.MatchesAnyWildcardPattern(current.ModuleName, _excludedModulePatterns, true)) + { + return false; + } + if (_isFullyQualifiedModuleSpecified) { bool foundModuleMatch = false; @@ -1530,6 +1567,7 @@ namespace Microsoft.PowerShell.Commands private Collection _verbPatterns; private Collection _nounPatterns; private Collection _modulePatterns; + private Collection _excludedModulePatterns; #if LEGACYTELEMETRY private Stopwatch _timer = new Stopwatch(); diff --git a/test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1 b/test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1 index a4044a9da5..e41a2a2fe3 100644 --- a/test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1 +++ b/test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1 @@ -1674,6 +1674,7 @@ class InheritedClassTest : System.Attribute @{ inputStr = 'gmo Microsoft.PowerShell.U'; expected = 'Microsoft.PowerShell.Utility'; setup = $null } @{ inputStr = 'rmo Microsoft.PowerShell.U'; expected = 'Microsoft.PowerShell.Utility'; setup = $null } @{ inputStr = 'gcm -Module Microsoft.PowerShell.U'; expected = 'Microsoft.PowerShell.Utility'; setup = $null } + @{ inputStr = 'gcm -ExcludeModule Microsoft.PowerShell.U'; expected = 'Microsoft.PowerShell.Utility'; setup = $null } @{ inputStr = 'gmo -list PackageM'; expected = 'PackageManagement'; setup = $null } @{ inputStr = 'gcm -Module PackageManagement Find-Pac'; expected = 'Find-Package'; setup = $null } @{ inputStr = 'ipmo PackageM'; expected = 'PackageManagement'; setup = $null } diff --git a/test/powershell/Modules/Microsoft.PowerShell.Core/Get-Command.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Core/Get-Command.Tests.ps1 index 600d04cef6..1fa33efbf0 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Core/Get-Command.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Core/Get-Command.Tests.ps1 @@ -269,4 +269,9 @@ Describe "Get-Command Tests" -Tags "CI" { $result.Count | Should -Be 2 $result.Name | Should -Be "Add-Content","Get-Content" } + + It "Excluding modules works" { + $result = Get-Command -Name Get-Command -ExcludeModule Microsoft.PowerShell.Core + $result | Should -Be $null + } }