Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes308downloads
GetCommandCommand.cs1744 linesDownload Raw Back to engine
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System;5using System.Collections;6using System.Collections.Generic;7using System.Collections.ObjectModel;8using System.Diagnostics;9using System.Globalization;10using System.IO;11using System.Linq;12using System.Management.Automation;13using System.Management.Automation.Internal;14using System.Management.Automation.Language;15using static System.Management.Automation.Verbs;16using Dbg = System.Management.Automation.Diagnostics;17 18namespace Microsoft.PowerShell.Commands19{20    /// <summary>21    /// The get-command cmdlet.  It uses the command discovery APIs to find one or more22    /// commands of the given name.  It returns an instance of CommandInfo for each23    /// command that is found.24    /// </summary>25    [Cmdlet(VerbsCommon.Get, "Command", DefaultParameterSetName = "CmdletSet", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=2096579")]26    [OutputType(typeof(AliasInfo), typeof(ApplicationInfo), typeof(FunctionInfo),27                typeof(CmdletInfo), typeof(ExternalScriptInfo), typeof(FilterInfo),28                typeof(string), typeof(PSObject))]29    public sealed class GetCommandCommand : PSCmdlet30    {31        #region Definitions of cmdlet parameters32 33        /// <summary>34        /// Gets or sets the path(s) or name(s) of the commands to retrieve.35        /// </summary>36        [Parameter(37            Position = 0,38            ValueFromPipeline = true,39            ValueFromPipelineByPropertyName = true,40            ParameterSetName = "AllCommandSet")]41        [ValidateNotNullOrEmpty]42        public string[] Name43        {44            get45            {46                return _names;47            }48 49            set50            {51                _nameContainsWildcard = false;52                _names = value;53 54                if (value != null)55                {56                    foreach (string commandName in value)57                    {58                        if (WildcardPattern.ContainsWildcardCharacters(commandName))59                        {60                            _nameContainsWildcard = true;61                            break;62                        }63                    }64                }65            }66        }67 68        private string[] _names;69        private bool _nameContainsWildcard;70 71        /// <summary>72        /// Gets or sets the verb parameter to the cmdlet.73        /// </summary>74        [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = "CmdletSet")]75        [ArgumentCompleter(typeof(VerbArgumentCompleter))]76        public string[] Verb77        {78            get79            {80                return _verbs;81            }82 83            set84            {85                value ??= Array.Empty<string>();86 87                _verbs = value;88                _verbPatterns = null;89            }90        }91 92        private string[] _verbs = Array.Empty<string>();93 94        /// <summary>95        /// Gets or sets the noun parameter to the cmdlet.96        /// </summary>97        [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = "CmdletSet")]98        [ArgumentCompleter(typeof(NounArgumentCompleter))]99        public string[] Noun100        {101            get102            {103                return _nouns;104            }105 106            set107            {108                value ??= Array.Empty<string>();109 110                _nouns = value;111                _nounPatterns = null;112            }113        }114 115        private string[] _nouns = Array.Empty<string>();116 117        /// <summary>118        /// Gets or sets the PSSnapin/Module parameter to the cmdlet.119        /// </summary>120        [Parameter(ValueFromPipelineByPropertyName = true)]121        [Alias("PSSnapin")]122        public string[] Module123        {124            get125            {126                return _modules;127            }128 129            set130            {131                value ??= Array.Empty<string>();132 133                _modules = value;134                _modulePatterns = null;135 136                _isModuleSpecified = true;137            }138        }139 140        private string[] _modules = Array.Empty<string>();141        private bool _isModuleSpecified = false;142 143        /// <summary>144        /// Gets or sets the ExcludeModule parameter to the cmdlet.145        /// </summary>146        [Parameter()]147        public string[] ExcludeModule148        {149            get150            {151                return _excludedModules;152            }153 154            set155            {156                value ??= Array.Empty<string>();157 158                _excludedModules = value;159                _excludedModulePatterns = null;160            }161        }162 163        private string[] _excludedModules = Array.Empty<string>();164 165        /// <summary>166        /// Gets or sets the FullyQualifiedModule parameter to the cmdlet.167        /// </summary>168        [Parameter(ValueFromPipelineByPropertyName = true)]169        public ModuleSpecification[] FullyQualifiedModule170        {171            get172            {173                return _moduleSpecifications;174            }175 176            set177            {178                if (value != null)179                {180                    _moduleSpecifications = value;181                }182 183                _isFullyQualifiedModuleSpecified = true;184            }185        }186 187        private ModuleSpecification[] _moduleSpecifications = Array.Empty<ModuleSpecification>();188        private bool _isFullyQualifiedModuleSpecified = false;189 190        /// <summary>191        /// Gets or sets the type of the command to get.192        /// </summary>193        [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = "AllCommandSet")]194        [Alias("Type")]195        public CommandTypes CommandType196        {197            get198            {199                return _commandType;200            }201 202            set203            {204                _commandType = value;205                _isCommandTypeSpecified = true;206            }207        }208 209        private CommandTypes _commandType = CommandTypes.All;210        private bool _isCommandTypeSpecified = false;211 212        /// <summary>213        /// The parameter representing the total number of commands that will214        /// be returned. If negative, all matching commands that are found will215        /// be returned.216        /// </summary>217        [Parameter(ValueFromPipelineByPropertyName = true)]218        public int TotalCount { get; set; } = -1;219 220        /// <summary>221        /// The parameter that determines if the CommandInfo or the string222        /// definition of the command is output.223        /// </summary>224        [Parameter(ValueFromPipelineByPropertyName = true)]225        public SwitchParameter Syntax226        {227            get228            {229                return _usage;230            }231 232            set233            {234                _usage = value;235            }236        }237 238        private bool _usage;239 240        /// <summary>241        /// This parameter causes the output to be packaged into ShowCommandInfo PSObject types242        /// needed to display GUI command information.243        /// </summary>244        [Parameter()]245        public SwitchParameter ShowCommandInfo { get; set; }246 247        /// <summary>248        /// The parameter that all additional arguments get bound to. These arguments are used249        /// when retrieving dynamic parameters from cmdlets that support them.250        /// </summary>251        [Parameter(Position = 1, ValueFromRemainingArguments = true)]252        [AllowNull]253        [AllowEmptyCollection]254        [Alias("Args")]255        public object[] ArgumentList { get; set; }256 257        /// <summary>258        /// The parameter that determines if additional matching commands should be returned.259        /// (Additional matching functions and aliases are returned from module tables)260        /// </summary>261        [Parameter(ValueFromPipelineByPropertyName = true)]262        public SwitchParameter All263        {264            get { return _all; }265 266            set { _all = value; }267        }268 269        private bool _all;270 271        /// <summary>272        /// The parameter that determines if additional matching commands from available modules should be returned.273        /// If set to true, only those commands currently in the session are returned.274        /// </summary>275        [Parameter(ValueFromPipelineByPropertyName = true)]276        public SwitchParameter ListImported277        {278            get279            {280                return _listImported;281            }282 283            set284            {285                _listImported = value;286            }287        }288 289        private bool _listImported;290 291        /// <summary>292        /// The parameter that filters commands returned to only include commands that have a parameter with a name that matches one of the ParameterName's arguments.293        /// </summary>294        [Parameter]295        [ValidateNotNullOrEmpty]296        public string[] ParameterName297        {298            get299            {300                return _parameterNames;301            }302 303            set304            {305                ArgumentNullException.ThrowIfNull(value);306 307                _parameterNames = value;308                _parameterNameWildcards = SessionStateUtilities.CreateWildcardsFromStrings(309                    _parameterNames,310                    WildcardOptions.CultureInvariant | WildcardOptions.IgnoreCase);311            }312        }313 314        private Collection<WildcardPattern> _parameterNameWildcards;315        private string[] _parameterNames;316        private HashSet<string> _matchedParameterNames;317 318        /// <summary>319        /// The parameter that filters commands returned to only include commands that have a parameter of a type that matches one of the ParameterType's arguments.320        /// </summary>321        [Parameter]322        [ValidateNotNullOrEmpty]323        public PSTypeName[] ParameterType324        {325            get326            {327                return _parameterTypes;328            }329 330            set331            {332                ArgumentNullException.ThrowIfNull(value);333 334                // if '...CimInstance#Win32_Process' is specified, then exclude '...CimInstance'335                List<PSTypeName> filteredParameterTypes = new List<PSTypeName>(value.Length);336                for (int i = 0; i < value.Length; i++)337                {338                    PSTypeName ptn = value[i];339 340                    if (value.Any(otherPtn => otherPtn.Name.StartsWith(ptn.Name + "#", StringComparison.OrdinalIgnoreCase)))341                    {342                        continue;343                    }344 345                    if ((i != 0) && (ptn.Type != null) && (ptn.Type.Equals(typeof(object))))346                    {347                        continue;348                    }349 350                    filteredParameterTypes.Add(ptn);351                }352 353                _parameterTypes = filteredParameterTypes.ToArray();354            }355        }356 357        private PSTypeName[] _parameterTypes;358 359        /// <summary>360        /// Gets or sets the parameter that enables using fuzzy matching.361        /// </summary>362        [Parameter(ParameterSetName = "AllCommandSet")]363        public SwitchParameter UseFuzzyMatching { get; set; }364 365        /// <summary>366        /// Gets or sets the minimum fuzzy matching distance.367        /// </summary>368        [Parameter(ParameterSetName = "AllCommandSet")]369        public uint FuzzyMinimumDistance { get; set; } = 5;370 371        private FuzzyMatcher _fuzzyMatcher;372        private List<CommandScore> _commandScores;373 374        /// <summary>375        /// Gets or sets the parameter that determines if return cmdlets based on abbreviation expansion.376        /// This means it matches cmdlets where the uppercase characters for the noun match377        /// the given characters.  i.e., g-sgc would match Get-SomeGreatCmdlet.378        /// </summary>379        [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = "AllCommandSet")]380        public SwitchParameter UseAbbreviationExpansion { get; set; }381 382        #endregion Definitions of cmdlet parameters383 384        #region Overrides385 386        /// <summary>387        /// Begin Processing.388        /// </summary>389        protected override void BeginProcessing()390        {391#if LEGACYTELEMETRY392            _timer.Start();393#endif394            if (UseFuzzyMatching)395            {396                _fuzzyMatcher = new FuzzyMatcher(FuzzyMinimumDistance);397                _commandScores = new List<CommandScore>();398            }399 400            if (ShowCommandInfo.IsPresent && Syntax.IsPresent)401            {402                ThrowTerminatingError(403                    new ErrorRecord(404                        new PSArgumentException(DiscoveryExceptions.GetCommandShowCommandInfoParamError),405                        "GetCommandCannotSpecifySyntaxAndShowCommandInfoTogether",406                        ErrorCategory.InvalidArgument,407                        null));408            }409        }410 411        /// <summary>412        /// Method that implements get-command.413        /// </summary>414        protected override void ProcessRecord()415        {416            _commandsWritten.Clear();417 418            // Module and FullyQualifiedModule should not be specified at the same time.419            // Throw out terminating error if this is the case.420            if (_isModuleSpecified && _isFullyQualifiedModuleSpecified)421            {422                string errMsg = string.Format(CultureInfo.InvariantCulture, SessionStateStrings.GetContent_TailAndHeadCannotCoexist, "Module", "FullyQualifiedModule");423                ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "ModuleAndFullyQualifiedModuleCannotBeSpecifiedTogether", ErrorCategory.InvalidOperation, null);424                ThrowTerminatingError(error);425            }426 427            // Initialize the module patterns428            _modulePatterns ??= SessionStateUtilities.CreateWildcardsFromStrings(Module, WildcardOptions.IgnoreCase | WildcardOptions.CultureInvariant);429            _excludedModulePatterns ??= SessionStateUtilities.CreateWildcardsFromStrings(ExcludeModule, WildcardOptions.IgnoreCase | WildcardOptions.CultureInvariant);430 431            switch (ParameterSetName)432            {433                case "CmdletSet":434                    AccumulateMatchingCmdlets();435                    break;436 437                case "AllCommandSet":438                    AccumulateMatchingCommands();439                    break;440 441                default:442                    Dbg.Assert(443                        false,444                        "Only the valid parameter set names should be used");445                    break;446            }447        }448 449        /// <summary>450        /// Writes out the accumulated matching commands.451        /// </summary>452        protected override void EndProcessing()453        {454            // We do not show the pithy aliases (not of the format Verb-Noun) and applications by default.455            // We will show them only if the Name, All and totalCount are not specified.456            if ((this.Name == null) && (!_all) && TotalCount == -1 && !UseFuzzyMatching)457            {458                CommandTypes commandTypesToIgnore = 0;459 460                if (((this.CommandType & CommandTypes.Alias) != CommandTypes.Alias) || (!_isCommandTypeSpecified))461                {462                    commandTypesToIgnore |= CommandTypes.Alias;463                }464 465                if (((_commandType & CommandTypes.Application) != CommandTypes.Application) ||466                    (!_isCommandTypeSpecified))467                {468                    commandTypesToIgnore |= CommandTypes.Application;469                }470 471                _accumulatedResults =472                    _accumulatedResults.Where(473                        commandInfo =>474                        (((commandInfo.CommandType & commandTypesToIgnore) == 0) ||475                         (commandInfo.Name.IndexOf('-') > 0))).ToList();476            }477 478            // report not-found errors for ParameterName and ParameterType if needed479            if ((_matchedParameterNames != null) && (ParameterName != null))480            {481                foreach (string requestedParameterName in ParameterName)482                {483                    if (WildcardPattern.ContainsWildcardCharacters(requestedParameterName))484                    {485                        continue;486                    }487 488                    if (_matchedParameterNames.Contains(requestedParameterName))489                    {490                        continue;491                    }492 493                    string errorMessage = string.Format(494                        CultureInfo.InvariantCulture,495                        DiscoveryExceptions.CommandParameterNotFound,496                        requestedParameterName);497                    var exception = new ArgumentException(errorMessage, requestedParameterName);498                    var errorRecord = new ErrorRecord(exception, "CommandParameterNotFound",499                                                      ErrorCategory.ObjectNotFound, requestedParameterName);500                    WriteError(errorRecord);501                }502            }503 504            // Only sort if they didn't fully specify a name)505            if ((_names == null) || (_nameContainsWildcard))506            {507                // Use the stable sorting to sort the result list508                _accumulatedResults = _accumulatedResults.Order(new CommandInfoComparer()).ToList();509            }510 511            OutputResultsHelper(_accumulatedResults);512 513            object pssenderInfo = Context.GetVariableValue(SpecialVariables.PSSenderInfoVarPath);514            if ((pssenderInfo != null) && (pssenderInfo is System.Management.Automation.Remoting.PSSenderInfo))515            {516                // Win8: 593295. Exchange has around 1000 cmdlets. During Import-PSSession,517                // Get-Command  | select-object ..,HelpURI,... is run. HelpURI is a script property518                // which in turn runs Get-Help. Get-Help loads the help content and caches it in the process.519                // This caching is using around 190 MB. During V3, we have implemented HelpURI attribute520                // and this should solve it. In V2, we dont have this attribute and hence 3rd parties521                // run into the same issue. The fix here is to reset help cache whenever get-command is run on522                // a remote endpoint. In the worst case, this will affect get-help to run a little longer523                // after get-command is run..but that should be OK because get-help is used mainly for524                // document reading purposes and not in production.525                Context.HelpSystem.ResetHelpProviders();526            }527        }528 529        #endregion530 531        #region Private Methods532 533        private void OutputResultsHelper(IEnumerable<CommandInfo> results)534        {535            CommandOrigin origin = MyInvocation.CommandOrigin;536 537            if (UseFuzzyMatching)538            {539                _commandScores = _commandScores.OrderBy(static x => x.Score).ToList();540                results = _commandScores.Select(static x => x.Command);541            }542 543            int count = 0;544            foreach (CommandInfo result in results)545            {546                // Only write the command if it is visible to the requestor547                if (SessionState.IsVisible(origin, result))548                {549                    // If the -syntax flag was specified, write the definition as a string550                    // otherwise just return the object...551                    if (Syntax)552                    {553                        if (!string.IsNullOrEmpty(result.Syntax))554                        {555                            PSObject syntax = GetSyntaxObject(result);556 557                            WriteObject(syntax);558                        }559                    }560                    else561                    {562                        if (ShowCommandInfo.IsPresent)563                        {564                            // Write output as ShowCommandCommandInfo object.565                            WriteObject(566                                ConvertToShowCommandInfo(result));567                        }568                        else569                        {570                            if (UseFuzzyMatching)571                            {572                                PSObject obj = new PSObject(result);573                                obj.Properties.Add(new PSNoteProperty("Score", _commandScores[count].Score));574                                WriteObject(obj);575                            }576                            else577                            {578                                WriteObject(result);579                            }580                        }581                    }582                }583 584                count += 1;585            }586 587#if LEGACYTELEMETRY588            _timer.Stop();589 590            // No telemetry here - capturing the name of a command which we are not familiar with591            // may be confidential customer information592            // We want telemetry on commands people look for but don't exist - this should give us an idea593            // what sort of commands people expect but either don't exist, or maybe should be installed by default.594            // The StartsWith is to avoid logging telemetry when suggestion mode checks the595            // current directory for scripts/exes in the current directory and '.' is not in the path.596            if (count == 0 && Name != null && Name.Length > 0 && !Name[0].StartsWith(".\\", StringComparison.OrdinalIgnoreCase))597            {598                Telemetry.Internal.TelemetryAPI.ReportGetCommandFailed(Name, _timer.ElapsedMilliseconds);599            }600#endif601        }602 603        /// <summary>604        /// Creates the syntax output based on if the command is an alias, script, application or command.605        /// </summary>606        /// <param name="command">607        /// CommandInfo object containing the syntax to be output.608        /// </param>609        /// <returns>610        /// Syntax string cast as a PSObject for outputting.611        /// </returns>612        private PSObject GetSyntaxObject(CommandInfo command)613        {614            PSObject syntax = PSObject.AsPSObject(command.Syntax);615 616            // This is checking if the command name that's been passed in is one that was specified by a user,617            // if not then we have to assume they specified an alias or a wildcard and do some extra formatting for those,618            // if it is then just go with the default formatting.619            // So if a user runs Get-Command -Name del -Syntax the code will find del and the command it resolves to as Remove-Item620            // and attempt to return that, but as the user specified del we want to fiddle with the output a bit to make it clear621            // that's an alias but still give the Remove-Item syntax.622            if (this.Name != null && !Array.Exists(this.Name, name => name.Equals(command.Name, StringComparison.InvariantCultureIgnoreCase)))623            {624                string aliasName = _nameContainsWildcard ? command.Name : this.Name[0];625 626                IDictionary<string, AliasInfo> aliasTable = SessionState.Internal.GetAliasTable();627                foreach (KeyValuePair<string, AliasInfo> tableEntry in aliasTable)628                {629                    if ((Array.Exists(this.Name, name => name.Equals(tableEntry.Key, StringComparison.InvariantCultureIgnoreCase)) &&630                        tableEntry.Value.Definition == command.Name) ||631                        (_nameContainsWildcard && tableEntry.Value.Definition == command.Name))632                    {633                        aliasName = tableEntry.Key;634                        break;635                    }636                }637 638                string replacedSyntax = string.Empty;639                switch (command)640                {641                    case ExternalScriptInfo externalScript:642                        replacedSyntax = string.Format(643                            "{0} (alias) -> {1}{2}{3}",644                            aliasName,645                            string.Format("{0}{1}", externalScript.Path, Environment.NewLine),646                            Environment.NewLine,647                            command.Syntax.Replace(command.Name, aliasName));648                        break;649                    case ApplicationInfo app:650                        replacedSyntax = app.Path;651                        break;652                    default:653                        if (aliasName.Equals(command.Name))654                        {655                            replacedSyntax = command.Syntax;656                        }657                        else658                        {659                            replacedSyntax = string.Format(660                                "{0} (alias) -> {1}{2}{3}",661                                aliasName,662                                command.Name,663                                Environment.NewLine,664                                command.Syntax.Replace(command.Name, aliasName));665                        }666 667                        break;668                }669 670                syntax = PSObject.AsPSObject(replacedSyntax);671            }672 673            syntax.IsHelpObject = true;674 675            return syntax;676        }677 678        /// <summary>679        /// The comparer to sort CommandInfo objects in the result list.680        /// </summary>681        private sealed class CommandInfoComparer : IComparer<CommandInfo>682        {683            /// <summary>684            /// Compare two CommandInfo objects first by their command types, and if they685            /// are with the same command type, then we compare their names.686            /// </summary>687            /// <param name="x"></param>688            /// <param name="y"></param>689            /// <returns></returns>690            public int Compare(CommandInfo x, CommandInfo y)691            {692                if ((int)x.CommandType < (int)y.CommandType)693                {694                    return -1;695                }696                else if ((int)x.CommandType > (int)y.CommandType)697                {698                    return 1;699                }700                else701                {702                    return string.Compare(x.Name, y.Name, StringComparison.OrdinalIgnoreCase);703                }704            }705        }706 707        private void AccumulateMatchingCmdlets()708        {709            _commandType = CommandTypes.Cmdlet | CommandTypes.Function | CommandTypes.Filter | CommandTypes.Alias | CommandTypes.Configuration;710 711            Collection<string> commandNames = new Collection<string>();712            commandNames.Add("*");713            AccumulateMatchingCommands(commandNames);714        }715 716        private bool IsNounVerbMatch(CommandInfo command)717        {718            bool result = false;719 720            do // false loop721            {722                _verbPatterns ??= SessionStateUtilities.CreateWildcardsFromStrings(Verb, WildcardOptions.IgnoreCase | WildcardOptions.CultureInvariant);723 724                _nounPatterns ??= SessionStateUtilities.CreateWildcardsFromStrings(Noun, WildcardOptions.IgnoreCase | WildcardOptions.CultureInvariant);725 726                if (!string.IsNullOrEmpty(command.ModuleName))727                {728                    if (_excludedModulePatterns is not null729                        && _excludedModulePatterns.Count > 0730                        && SessionStateUtilities.MatchesAnyWildcardPattern(command.ModuleName, _excludedModulePatterns, true))731                    {732                        break;733                    }734 735                    if (_isFullyQualifiedModuleSpecified)736                    {737                        if (!_moduleSpecifications.Any(738                                moduleSpecification =>739                                ModuleIntrinsics.IsModuleMatchingModuleSpec(command.Module, moduleSpecification)))740                        {741                            break;742                        }743                    }744                    else if (!SessionStateUtilities.MatchesAnyWildcardPattern(command.ModuleName, _modulePatterns, true))745                    {746                        break;747                    }748                }749                else750                {751                    if (_modulePatterns.Count > 0 || _moduleSpecifications.Length > 0)752                    {753                        // Its not a match if we are filtering on a PSSnapin/Module name but the cmdlet doesn't have one.754                        break;755                    }756                }757 758                // Get the noun and verb to check...759                string verb;760                string noun;761                CmdletInfo cmdlet = command as CmdletInfo;762                if (cmdlet != null)763                {764                    verb = cmdlet.Verb;765                    noun = cmdlet.Noun;766                }767                else768                {769                    if (!CmdletInfo.SplitCmdletName(command.Name, out verb, out noun))770                        break;771                }772 773                if (!SessionStateUtilities.MatchesAnyWildcardPattern(verb, _verbPatterns, true))774                {775                    break;776                }777 778                if (!SessionStateUtilities.MatchesAnyWildcardPattern(noun, _nounPatterns, true))779                {780                    break;781                }782 783                result = true;784            } while (false);785 786            return result;787        }788 789        /// <summary>790        /// Writes out the commands for the AllCommandSet using the specified CommandType.791        /// </summary>792        private void AccumulateMatchingCommands()793        {794            Collection<string> commandNames =795                SessionStateUtilities.ConvertArrayToCollection<string>(this.Name);796 797            if (commandNames.Count == 0)798            {799                commandNames.Add("*");800            }801 802            AccumulateMatchingCommands(commandNames);803        }804 805        private void AccumulateMatchingCommands(IEnumerable<string> commandNames)806        {807            // First set the search options808 809            SearchResolutionOptions options = SearchResolutionOptions.None;810            if (All)811            {812                options = SearchResolutionOptions.SearchAllScopes;813            }814 815            if (UseAbbreviationExpansion)816            {817                options |= SearchResolutionOptions.UseAbbreviationExpansion;818            }819 820            if ((this.CommandType & CommandTypes.Alias) != 0)821            {822                options |= SearchResolutionOptions.ResolveAliasPatterns;823            }824 825            if ((this.CommandType & (CommandTypes.Function | CommandTypes.Filter | CommandTypes.Configuration)) != 0)826            {827                options |= SearchResolutionOptions.ResolveFunctionPatterns;828            }829 830            foreach (string commandName in commandNames)831            {832                try833                {834                    // Determine if the command name is module-qualified, and search835                    // available modules for the command.836                    string moduleName;837                    string plainCommandName = Utils.ParseCommandName(commandName, out moduleName);838                    bool isModuleQualified = (moduleName != null);839 840                    // If they've specified a module name, we can do some smarter filtering.841                    // Otherwise, we have to filter everything.842                    if ((this.Module.Length == 1) && (!WildcardPattern.ContainsWildcardCharacters(this.Module[0])))843                    {844                        moduleName = this.Module[0];845                    }846 847                    bool isPattern = WildcardPattern.ContainsWildcardCharacters(plainCommandName) || UseAbbreviationExpansion || UseFuzzyMatching;848                    if (isPattern)849                    {850                        options |= SearchResolutionOptions.CommandNameIsPattern;851                    }852 853                    // Try to initially find the command in the available commands854                    int count = 0;855                    bool isDuplicate;856                    bool resultFound = FindCommandForName(options, commandName, isPattern, true, ref count, out isDuplicate);857 858                    // If we didn't find the command, or if it had a wildcard, also see if it859                    // is in an available module860                    if (!resultFound || isPattern)861                    {862                        // If the command name had no wildcards or was module-qualified,863                        // import the module so that we can return the fully structured data.864                        // This uses the same code path as module auto-loading.865                        if ((!isPattern) || (!string.IsNullOrEmpty(moduleName)))866                        {867                            string tempCommandName = commandName;868                            if ((!isModuleQualified) && (!string.IsNullOrEmpty(moduleName)))869                            {870                                tempCommandName = moduleName + "\\" + commandName;871                            }872 873                            try874                            {875                                CommandDiscovery.LookupCommandInfo(tempCommandName, this.MyInvocation.CommandOrigin, this.Context);876                            }877                            catch (CommandNotFoundException)878                            {879                                // Ignore, LookupCommandInfo doesn't handle wildcards.880                            }881 882                            resultFound = FindCommandForName(options, commandName, isPattern, false, ref count, out isDuplicate);883                        }884                        // Show additional commands from available modules only if ListImported is not specified885                        else if (!ListImported)886                        {887                            if (TotalCount < 0 || count < TotalCount)888                            {889                                IEnumerable<CommandInfo> commands;890                                if (UseFuzzyMatching)891                                {892                                    foreach (var commandScore in ModuleUtils.GetFuzzyMatchingCommands(893                                        plainCommandName,894                                        Context,895                                        MyInvocation.CommandOrigin,896                                        _fuzzyMatcher,897                                        rediscoverImportedModules: true,898                                        moduleVersionRequired: _isFullyQualifiedModuleSpecified))899                                    {900                                        _commandScores.Add(commandScore);901                                    }902 903                                    commands = _commandScores.Select(static x => x.Command);904                                }905                                else906                                {907                                    commands = ModuleUtils.GetMatchingCommands(908                                        plainCommandName,909                                        Context,910                                        MyInvocation.CommandOrigin,911                                        rediscoverImportedModules: true,912                                        moduleVersionRequired: _isFullyQualifiedModuleSpecified,913                                        useAbbreviationExpansion: UseAbbreviationExpansion);914                                }915 916                                foreach (CommandInfo command in commands)917                                {918                                    // Cannot pass in "command" by ref (foreach iteration variable)919                                    CommandInfo current = command;920 921                                    if (IsCommandMatch(ref current, out isDuplicate) && (!IsCommandInResult(current)) && IsParameterMatch(current))922                                    {923                                        _accumulatedResults.Add(current);924 925                                        // Make sure we don't exceed the TotalCount parameter926                                        ++count;927 928                                        if (TotalCount >= 0 && count >= TotalCount)929                                        {930                                            break;931                                        }932                                    }933                                }934                            }935                        }936                    }937 938                    // If we are trying to match a single specific command name (no glob characters)939                    // then we need to write an error if we didn't find it.940                    if (!isDuplicate)941                    {942                        if (!resultFound && !isPattern)943                        {944                            CommandNotFoundException e =945                                new CommandNotFoundException(946                                    commandName,947                                    null,948                                    "CommandNotFoundException",949                                    DiscoveryExceptions.CommandNotFoundException);950 951                            WriteError(952                                new ErrorRecord(953                                    e.ErrorRecord,954                                    e));955                            continue;956                        }957                    }958                }959                catch (CommandNotFoundException exception)960                {961                    WriteError(962                        new ErrorRecord(963                            exception.ErrorRecord,964                            exception));965                }966            }967        }968 969        private bool FindCommandForName(SearchResolutionOptions options, string commandName, bool isPattern, bool emitErrors, ref int currentCount, out bool isDuplicate)970        {971            var searcher = new CommandSearcher(972                commandName,973                options,974                CommandType,975                Context,976                _fuzzyMatcher);977 978            bool resultFound = false;979            isDuplicate = false;980 981            while (true)982            {983                try984                {985                    if (!searcher.MoveNext())986                    {987                        break;988                    }989                }990                catch (ArgumentException argumentException)991                {992                    if (emitErrors)993                    {994                        WriteError(new ErrorRecord(argumentException, "GetCommandInvalidArgument", ErrorCategory.SyntaxError, null));995                    }996 997                    continue;998                }999                catch (PathTooLongException pathTooLong)1000                {1001                    if (emitErrors)1002                    {1003                        WriteError(new ErrorRecord(pathTooLong, "GetCommandInvalidArgument", ErrorCategory.SyntaxError, null));1004                    }1005 1006                    continue;1007                }1008                catch (FileLoadException fileLoadException)1009                {1010                    if (emitErrors)1011                    {1012                        WriteError(new ErrorRecord(fileLoadException, "GetCommandFileLoadError", ErrorCategory.ReadError, null));1013                    }1014 1015                    continue;1016                }1017                catch (MetadataException metadataException)1018                {1019                    if (emitErrors)1020                    {1021                        WriteError(new ErrorRecord(metadataException, "GetCommandMetadataError", ErrorCategory.MetadataError, null));1022                    }1023 1024                    continue;1025                }1026                catch (FormatException formatException)1027                {1028                    if (emitErrors)1029                    {1030                        WriteError(new ErrorRecord(formatException, "GetCommandBadFileFormat", ErrorCategory.InvalidData, null));1031                    }1032 1033                    continue;1034                }1035 1036                CommandInfo current = ((IEnumerator<CommandInfo>)searcher).Current;1037 1038                // skip private commands as early as possible1039                // (i.e. before setting "result found" flag and before trying to use ArgumentList parameter)1040                // see bugs Windows 7: #520498 and #5204701041                CommandOrigin origin = this.MyInvocation.CommandOrigin;1042                if (!SessionState.IsVisible(origin, current))1043                {1044                    continue;1045                }1046 1047                bool tempResultFound = IsCommandMatch(ref current, out isDuplicate);1048 1049                if (tempResultFound && (!IsCommandInResult(current)))1050                {1051                    resultFound = true;1052                    if (IsParameterMatch(current))1053                    {1054                        // Make sure we don't exceed the TotalCount parameter1055                        ++currentCount;1056 1057                        if (TotalCount >= 0 && currentCount > TotalCount)1058                        {1059                            break;1060                        }1061 1062                        if (UseFuzzyMatching)1063                        {1064                            if (_fuzzyMatcher.IsFuzzyMatch(current.Name, commandName, out int score))1065                            {1066                                _commandScores.Add(new CommandScore(current, score));1067                            }1068                        }1069 1070                        _accumulatedResults.Add(current);1071 1072                        if (ArgumentList != null)1073                        {1074                            // Don't iterate the enumerator any more. If -arguments was specified, then we stop at the first match1075                            break;1076                        }1077                    }1078 1079                    // Only for this case, the loop should exit1080                    // Get-Command Foo1081                    if (isPattern || All || TotalCount != -1 || _isCommandTypeSpecified || _isModuleSpecified || _isFullyQualifiedModuleSpecified)1082                    {1083                        continue;1084                    }1085                    else1086                    {1087                        break;1088                    }1089                }1090            }1091 1092            if (All)1093            {1094                // Get additional matching commands from module tables.1095                foreach (CommandInfo command in GetMatchingCommandsFromModules(commandName))1096                {1097                    CommandInfo c = command;1098                    bool tempResultFound = IsCommandMatch(ref c, out isDuplicate);1099                    if (tempResultFound)1100                    {1101                        resultFound = true;1102                        if (!IsCommandInResult(command) && IsParameterMatch(c))1103                        {1104                            ++currentCount;1105 1106                            if (TotalCount >= 0 && currentCount > TotalCount)1107                            {1108                                break;1109                            }1110 1111                            _accumulatedResults.Add(c);1112                        }1113                        // Make sure we don't exceed the TotalCount parameter1114                    }1115                }1116            }1117 1118            return resultFound;1119        }1120 1121        /// <summary>1122        /// Determines if the specific command information has already been1123        /// written out based on the path or definition.1124        /// </summary>1125        /// <param name="info">1126        /// The command information to check for duplication.1127        /// </param>1128        /// <returns>1129        /// true if the command has already been written out.1130        /// </returns>1131        private bool IsDuplicate(CommandInfo info)1132        {1133            bool result = false;1134            string key = null;1135 1136            do // false loop1137            {1138                ApplicationInfo appInfo = info as ApplicationInfo;1139                if (appInfo != null)1140                {1141                    key = appInfo.Path;1142                    break;1143                }1144 1145                CmdletInfo cmdletInfo = info as CmdletInfo;1146                if (cmdletInfo != null)1147                {1148                    key = cmdletInfo.FullName;1149                    break;1150                }1151 1152                ScriptInfo scriptInfo = info as ScriptInfo;1153                if (scriptInfo != null)1154                {1155                    key = scriptInfo.Definition;1156                    break;1157                }1158 1159                ExternalScriptInfo externalScriptInfo = info as ExternalScriptInfo;1160                if (externalScriptInfo != null)1161                {1162                    key = externalScriptInfo.Path;1163                    break;1164                }1165            } while (false);1166 1167            if (key != null)1168            {1169                if (_commandsWritten.ContainsKey(key))1170                {1171                    result = true;1172                }1173                else1174                {1175                    _commandsWritten.Add(key, info);1176                }1177            }1178 1179            return result;1180        }1181 1182        private bool IsParameterMatch(CommandInfo commandInfo)1183        {1184            if ((this.ParameterName == null) && (this.ParameterType == null))1185            {1186                return true;1187            }1188 1189            _matchedParameterNames ??= new HashSet<string>(StringComparer.OrdinalIgnoreCase);1190 1191            IEnumerable<ParameterMetadata> commandParameters = null;1192            try1193            {1194                IDictionary<string, ParameterMetadata> tmp = commandInfo.Parameters;1195                if (tmp != null)1196                {1197                    commandParameters = tmp.Values;1198                }1199            }1200            catch (Exception)

Showing the first 1,200 of 1744 lines. Download the file for the rest.