/// <summary> /// Gets a list of matching commands /// </summary> /// <param name="pattern">command pattern</param> /// <param name="commandOrigin"></param> /// <param name="context"></param> /// <param name="rediscoverImportedModules"></param> /// <param name="moduleVersionRequired"></param> /// <returns></returns> internal static IEnumerable<CommandInfo> GetMatchingCommands(string pattern, ExecutionContext context, CommandOrigin commandOrigin, bool rediscoverImportedModules = false, bool moduleVersionRequired = false) { // Otherwise, if it had wildcards, just return the "AvailableCommand" // type of command info. WildcardPattern commandPattern = WildcardPattern.Get(pattern, WildcardOptions.IgnoreCase); CmdletInfo cmdletInfo = context.SessionState.InvokeCommand.GetCmdlet("Microsoft.PowerShell.Core\\Get-Module"); PSModuleAutoLoadingPreference moduleAutoLoadingPreference = CommandDiscovery.GetCommandDiscoveryPreference(context, SpecialVariables.PSModuleAutoLoadingPreferenceVarPath, "PSModuleAutoLoadingPreference"); if ((moduleAutoLoadingPreference != PSModuleAutoLoadingPreference.None) && ((commandOrigin == CommandOrigin.Internal) || ((cmdletInfo != null) && (cmdletInfo.Visibility == SessionStateEntryVisibility.Public)) ) ) { foreach (string modulePath in GetDefaultAvailableModuleFiles(true, false, context)) { // Skip modules that have already been loaded so that we don't expose private commands. string moduleName = Path.GetFileNameWithoutExtension(modulePath); var modules = context.Modules.GetExactMatchModules(moduleName, all: false, exactMatch: true); PSModuleInfo tempModuleInfo = null; if (modules.Count != 0) { // 1. We continue to the next module path if we don't want to re-discover those imported modules // 2. If we want to re-discover the imported modules, but one or more commands from the module were made private, // then we don't do re-discovery if (!rediscoverImportedModules || modules.Exists(module => module.ModuleHasPrivateMembers)) { continue; } if (modules.Count == 1) { PSModuleInfo psModule = modules[0]; tempModuleInfo = new PSModuleInfo(psModule.Name, psModule.Path, null, null); tempModuleInfo.SetModuleBase(psModule.ModuleBase); foreach (var entry in psModule.ExportedCommands) { if (commandPattern.IsMatch(entry.Value.Name)) { CommandInfo current = null; switch (entry.Value.CommandType) { case CommandTypes.Alias: current = new AliasInfo(entry.Value.Name, null, context); break; case CommandTypes.Workflow: current = new WorkflowInfo(entry.Value.Name, ScriptBlock.EmptyScriptBlock, context); break; case CommandTypes.Function: current = new FunctionInfo(entry.Value.Name, ScriptBlock.EmptyScriptBlock, context); break; case CommandTypes.Filter: current = new FilterInfo(entry.Value.Name, ScriptBlock.EmptyScriptBlock, context); break; case CommandTypes.Configuration: current = new ConfigurationInfo(entry.Value.Name, ScriptBlock.EmptyScriptBlock, context); break; case CommandTypes.Cmdlet: current = new CmdletInfo(entry.Value.Name, null, null, null, context); break; default: Dbg.Assert(false, "cannot be hit"); break; } current.Module = tempModuleInfo; yield return current; } } continue; } } string moduleShortName = System.IO.Path.GetFileNameWithoutExtension(modulePath); var exportedCommands = AnalysisCache.GetExportedCommands(modulePath, false, context); if (exportedCommands == null) { continue; } tempModuleInfo = new PSModuleInfo(moduleShortName, modulePath, null, null); if (InitialSessionState.IsEngineModule(moduleShortName)) { tempModuleInfo.SetModuleBase(Utils.GetApplicationBase(Utils.DefaultPowerShellShellID)); } //moduleVersionRequired is bypassed by FullyQualifiedModule from calling method. This is the only place where guid will be involved. if (moduleVersionRequired && modulePath.EndsWith(StringLiterals.PowerShellDataFileExtension, StringComparison.OrdinalIgnoreCase)) { tempModuleInfo.SetVersion(ModuleIntrinsics.GetManifestModuleVersion(modulePath)); tempModuleInfo.SetGuid(ModuleIntrinsics.GetManifestGuid(modulePath)); } foreach (var pair in exportedCommands) { var commandName = pair.Key; var commandTypes = pair.Value; if (commandPattern.IsMatch(commandName)) { bool shouldExportCommand = true; // Verify that we don't already have it represented in the initial session state. if ((context.InitialSessionState != null) && (commandOrigin == CommandOrigin.Runspace)) { foreach (SessionStateCommandEntry commandEntry in context.InitialSessionState.Commands[commandName]) { string moduleCompareName = null; if (commandEntry.Module != null) { moduleCompareName = commandEntry.Module.Name; } else if (commandEntry.PSSnapIn != null) { moduleCompareName = commandEntry.PSSnapIn.Name; } if (String.Equals(moduleShortName, moduleCompareName, StringComparison.OrdinalIgnoreCase)) { if (commandEntry.Visibility == SessionStateEntryVisibility.Private) { shouldExportCommand = false; } } } } if (shouldExportCommand) { if ((commandTypes & CommandTypes.Alias) == CommandTypes.Alias) { yield return new AliasInfo(commandName, null, context) { Module = tempModuleInfo }; } if ((commandTypes & CommandTypes.Cmdlet) == CommandTypes.Cmdlet) { yield return new CmdletInfo(commandName, implementingType: null, helpFile: null, PSSnapin: null, context: context) { Module = tempModuleInfo }; } if ((commandTypes & CommandTypes.Function) == CommandTypes.Function) { yield return new FunctionInfo(commandName, ScriptBlock.EmptyScriptBlock, context) { Module = tempModuleInfo }; } if ((commandTypes & CommandTypes.Configuration) == CommandTypes.Configuration) { yield return new ConfigurationInfo(commandName, ScriptBlock.EmptyScriptBlock, context) { Module = tempModuleInfo }; } if ((commandTypes & CommandTypes.Workflow) == CommandTypes.Workflow) { yield return new WorkflowInfo(commandName, ScriptBlock.EmptyScriptBlock, context) { Module = tempModuleInfo }; } } } } } } }
/// <summary> /// Telepathy callback when a alias has changed on a contact /// </summary> private void OnAliasesChanged(AliasInfo[] aliases) { ProviderUser user; foreach (AliasInfo info in aliases) { user = ProviderUserManager.GetProviderUser (info.ContactHandle); if (user != null) user.Alias = info.NewAlias; } }
/// <summary> /// Gets a list of matching commands /// </summary> /// <param name="pattern">command pattern</param> /// <param name="commandOrigin"></param> /// <param name="context"></param> /// <param name="rediscoverImportedModules"></param> /// <param name="moduleVersionRequired"></param> /// <returns></returns> internal static IEnumerable <CommandInfo> GetMatchingCommands(string pattern, ExecutionContext context, CommandOrigin commandOrigin, bool rediscoverImportedModules = false, bool moduleVersionRequired = false) { // Otherwise, if it had wildcards, just return the "AvailableCommand" // type of command info. WildcardPattern commandPattern = WildcardPattern.Get(pattern, WildcardOptions.IgnoreCase); CmdletInfo cmdletInfo = context.SessionState.InvokeCommand.GetCmdlet("Microsoft.PowerShell.Core\\Get-Module"); PSModuleAutoLoadingPreference moduleAutoLoadingPreference = CommandDiscovery.GetCommandDiscoveryPreference(context, SpecialVariables.PSModuleAutoLoadingPreferenceVarPath, "PSModuleAutoLoadingPreference"); if ((moduleAutoLoadingPreference != PSModuleAutoLoadingPreference.None) && ((commandOrigin == CommandOrigin.Internal) || ((cmdletInfo != null) && (cmdletInfo.Visibility == SessionStateEntryVisibility.Public)) ) ) { foreach (string modulePath in GetDefaultAvailableModuleFiles(isForAutoDiscovery: false, context)) { // Skip modules that have already been loaded so that we don't expose private commands. string moduleName = Path.GetFileNameWithoutExtension(modulePath); List <PSModuleInfo> modules = context.Modules.GetExactMatchModules(moduleName, all: false, exactMatch: true); PSModuleInfo tempModuleInfo = null; if (modules.Count != 0) { // 1. We continue to the next module path if we don't want to re-discover those imported modules // 2. If we want to re-discover the imported modules, but one or more commands from the module were made private, // then we don't do re-discovery if (!rediscoverImportedModules || modules.Exists(module => module.ModuleHasPrivateMembers)) { continue; } if (modules.Count == 1) { PSModuleInfo psModule = modules[0]; tempModuleInfo = new PSModuleInfo(psModule.Name, psModule.Path, context: null, sessionState: null); tempModuleInfo.SetModuleBase(psModule.ModuleBase); foreach (KeyValuePair <string, CommandInfo> entry in psModule.ExportedCommands) { if (commandPattern.IsMatch(entry.Value.Name)) { CommandInfo current = null; switch (entry.Value.CommandType) { case CommandTypes.Alias: current = new AliasInfo(entry.Value.Name, definition: null, context); break; case CommandTypes.Function: current = new FunctionInfo(entry.Value.Name, ScriptBlock.EmptyScriptBlock, context); break; case CommandTypes.Filter: current = new FilterInfo(entry.Value.Name, ScriptBlock.EmptyScriptBlock, context); break; case CommandTypes.Configuration: current = new ConfigurationInfo(entry.Value.Name, ScriptBlock.EmptyScriptBlock, context); break; case CommandTypes.Cmdlet: current = new CmdletInfo(entry.Value.Name, implementingType: null, helpFile: null, PSSnapin: null, context); break; default: Dbg.Assert(false, "cannot be hit"); break; } current.Module = tempModuleInfo; yield return(current); } } continue; } } string moduleShortName = System.IO.Path.GetFileNameWithoutExtension(modulePath); IDictionary <string, CommandTypes> exportedCommands = AnalysisCache.GetExportedCommands(modulePath, testOnly: false, context); if (exportedCommands == null) { continue; } tempModuleInfo = new PSModuleInfo(moduleShortName, modulePath, sessionState: null, context: null); if (InitialSessionState.IsEngineModule(moduleShortName)) { tempModuleInfo.SetModuleBase(Utils.DefaultPowerShellAppBase); } //moduleVersionRequired is bypassed by FullyQualifiedModule from calling method. This is the only place where guid will be involved. if (moduleVersionRequired && modulePath.EndsWith(StringLiterals.PowerShellDataFileExtension, StringComparison.OrdinalIgnoreCase)) { tempModuleInfo.SetVersion(ModuleIntrinsics.GetManifestModuleVersion(modulePath)); tempModuleInfo.SetGuid(ModuleIntrinsics.GetManifestGuid(modulePath)); } foreach (KeyValuePair <string, CommandTypes> pair in exportedCommands) { string commandName = pair.Key; CommandTypes commandTypes = pair.Value; if (commandPattern.IsMatch(commandName)) { bool shouldExportCommand = true; // Verify that we don't already have it represented in the initial session state. if ((context.InitialSessionState != null) && (commandOrigin == CommandOrigin.Runspace)) { foreach (SessionStateCommandEntry commandEntry in context.InitialSessionState.Commands[commandName]) { string moduleCompareName = null; if (commandEntry.Module != null) { moduleCompareName = commandEntry.Module.Name; } else if (commandEntry.PSSnapIn != null) { moduleCompareName = commandEntry.PSSnapIn.Name; } if (String.Equals(moduleShortName, moduleCompareName, StringComparison.OrdinalIgnoreCase)) { if (commandEntry.Visibility == SessionStateEntryVisibility.Private) { shouldExportCommand = false; } } } } if (shouldExportCommand) { if ((commandTypes & CommandTypes.Alias) == CommandTypes.Alias) { yield return(new AliasInfo(commandName, null, context) { Module = tempModuleInfo }); } if ((commandTypes & CommandTypes.Cmdlet) == CommandTypes.Cmdlet) { yield return(new CmdletInfo(commandName, implementingType: null, helpFile: null, PSSnapin: null, context: context) { Module = tempModuleInfo }); } if ((commandTypes & CommandTypes.Function) == CommandTypes.Function) { yield return(new FunctionInfo(commandName, ScriptBlock.EmptyScriptBlock, context) { Module = tempModuleInfo }); } if ((commandTypes & CommandTypes.Configuration) == CommandTypes.Configuration) { yield return(new ConfigurationInfo(commandName, ScriptBlock.EmptyScriptBlock, context) { Module = tempModuleInfo }); } } } } } } }
public static string GetHelpUri(PSObject commandInfoPSObject) { if (null == commandInfoPSObject) { return(string.Empty); } CommandInfo cmdInfo = PSObject.Base(commandInfoPSObject) as CommandInfo; // GetHelpUri helper method is expected to be used only by System.Management.Automation.CommandInfo // objects from types.ps1xml if ((null == cmdInfo) || (string.IsNullOrEmpty(cmdInfo.Name))) { return(string.Empty); } // The type checking is needed to avoid a try..catch exception block as // the CommandInfo.CommandMetadata throws an InvalidOperationException // instead of returning null. if ((cmdInfo is CmdletInfo) || (cmdInfo is FunctionInfo) || (cmdInfo is ExternalScriptInfo) || (cmdInfo is ScriptInfo)) { if (!string.IsNullOrEmpty(cmdInfo.CommandMetadata.HelpUri)) { return(cmdInfo.CommandMetadata.HelpUri); } } AliasInfo aliasInfo = cmdInfo as AliasInfo; if ((null != aliasInfo) && (null != aliasInfo.ExternalCommandMetadata) && (!string.IsNullOrEmpty(aliasInfo.ExternalCommandMetadata.HelpUri))) { return(aliasInfo.ExternalCommandMetadata.HelpUri); } // if everything else fails..depend on Get-Help infrastructure to get us the Uri. string cmdName = cmdInfo.Name; if (!string.IsNullOrEmpty(cmdInfo.ModuleName)) { cmdName = string.Format(CultureInfo.InvariantCulture, "{0}\\{1}", cmdInfo.ModuleName, cmdInfo.Name); } if (DoesCurrentRunspaceIncludeCoreHelpCmdlet()) { // Win8: 651300 if core get-help is present in the runspace (and it is the only get-help command), use // help system directly and avoid perf penalty. var currentContext = System.Management.Automation.Runspaces.LocalPipeline.GetExecutionContextFromTLS(); if ((null != currentContext) && (null != currentContext.HelpSystem)) { HelpRequest helpRequest = new HelpRequest(cmdName, cmdInfo.HelpCategory); helpRequest.ProviderContext = new ProviderContext( string.Empty, currentContext, currentContext.SessionState.Path); helpRequest.CommandOrigin = CommandOrigin.Runspace; foreach ( Uri result in currentContext.HelpSystem.ExactMatchHelp(helpRequest).Select( helpInfo => helpInfo.GetUriForOnlineHelp()).Where(result => null != result)) { return(result.OriginalString); } } } else { // win8: 546025. Using Get-Help as command, instead of calling HelpSystem.ExactMatchHelp // for the following reasons: // 1. Exchange creates proxies for Get-Command and Get-Help in their scenario // 2. This method is primarily used to get uri faster while serializing the CommandInfo objects (from Get-Command) // 3. Exchange uses Get-Help proxy to not call Get-Help cmdlet at-all while serializing CommandInfo objects // 4. Using HelpSystem directly will not allow Get-Help proxy to do its job. System.Management.Automation.PowerShell getHelpPS = System.Management.Automation.PowerShell.Create( RunspaceMode.CurrentRunspace).AddCommand("get-help"). AddParameter("Name", cmdName).AddParameter("Category", cmdInfo.HelpCategory.ToString()); try { Collection <PSObject> helpInfos = getHelpPS.Invoke(); if (null != helpInfos) { for (int index = 0; index < helpInfos.Count; index++) { HelpInfo helpInfo; if (LanguagePrimitives.TryConvertTo <HelpInfo>(helpInfos[index], out helpInfo)) { Uri result = helpInfo.GetUriForOnlineHelp(); if (null != result) { return(result.OriginalString); } } else { Uri result = BaseCommandHelpInfo.GetUriFromCommandPSObject(helpInfos[index]); return((result != null) ? result.OriginalString : string.Empty); } } } } finally { getHelpPS.Dispose(); } } return(string.Empty); }
/// <summary> /// The main processing loop of the command. /// </summary> protected override void ProcessRecord() { // If not force, then see if the alias already exists if (!Force) { AliasInfo existingAlias = null; if (string.IsNullOrEmpty(Scope)) { existingAlias = SessionState.Internal.GetAlias(Name); } else { existingAlias = SessionState.Internal.GetAliasAtScope(Name, Scope); } if (existingAlias != null) { // Throw if alias exists and is private... SessionState.ThrowIfNotVisible(this.CommandOrigin, existingAlias); // Since the alias already exists, write an error. SessionStateException aliasExists = new SessionStateException( Name, SessionStateCategory.Alias, "AliasAlreadyExists", SessionStateStrings.AliasAlreadyExists, ErrorCategory.ResourceExists); WriteError( new ErrorRecord( aliasExists.ErrorRecord, aliasExists)); return; } } // Create the alias info AliasInfo newAlias = new AliasInfo( Name, Value, Context, Option); newAlias.Description = Description; string action = AliasCommandStrings.NewAliasAction; string target = StringUtil.Format(AliasCommandStrings.NewAliasTarget, Name, Value); if (ShouldProcess(target, action)) { // Set the alias in the specified scope or the // current scope. AliasInfo result = null; try { if (string.IsNullOrEmpty(Scope)) { result = SessionState.Internal.SetAliasItem(newAlias, Force, MyInvocation.CommandOrigin); } else { result = SessionState.Internal.SetAliasItemAtScope(newAlias, Scope, Force, MyInvocation.CommandOrigin); } } catch (SessionStateException sessionStateException) { WriteError( new ErrorRecord( sessionStateException.ErrorRecord, sessionStateException)); return; } catch (PSArgumentOutOfRangeException argOutOfRange) { WriteError( new ErrorRecord( argOutOfRange.ErrorRecord, argOutOfRange)); return; } catch (PSArgumentException argException) { WriteError( new ErrorRecord( argException.ErrorRecord, argException)); return; } // Write the alias to the pipeline if PassThru was specified if (PassThru && result != null) { WriteObject(result); } } }
} // GetValueOfItem /// <summary> /// Sets the alias of the specified name to the specified value /// </summary> /// /// <param name="name"> /// The name of the alias to set. /// </param> /// /// <param name="value"> /// The new value for the alias. /// </param> /// /// <param name="writeItem"> /// If true, the item that was set should be written to WriteItemObject. /// </param> /// #pragma warning disable 0162 internal override void SetSessionStateItem(string name, object value, bool writeItem) { Dbg.Diagnostics.Assert( !String.IsNullOrEmpty(name), "The caller should verify this parameter"); AliasProviderDynamicParameters dynamicParameters = DynamicParameters as AliasProviderDynamicParameters; AliasInfo item = null; bool dynamicParametersSpecified = dynamicParameters != null && dynamicParameters.OptionsSet; if (value == null) { if (dynamicParametersSpecified) { item = (AliasInfo)GetSessionStateItem(name); if (item != null) { item.SetOptions(dynamicParameters.Options, Force); } } else { RemoveSessionStateItem(name); } } else { do // false loop { string stringValue = value as string; if (stringValue != null) { if (dynamicParametersSpecified) { item = SessionState.Internal.SetAliasValue(name, stringValue, dynamicParameters.Options, Force, Context.Origin); } else { item = SessionState.Internal.SetAliasValue(name, stringValue, Force, Context.Origin); } break; } AliasInfo alias = value as AliasInfo; if (alias != null) { AliasInfo newAliasInfo = new AliasInfo( name, alias.Definition, this.Context.ExecutionContext, alias.Options); if (dynamicParametersSpecified) { newAliasInfo.SetOptions(dynamicParameters.Options, Force); } item = SessionState.Internal.SetAliasItem(newAliasInfo, Force, Context.Origin); break; } throw PSTraceSource.NewArgumentException("value"); } while (false); } if (writeItem && item != null) { WriteItemObject(item, item.Name, false); } } // SetSessionStateItem
private Collection <AliasInfo> GetAliasesFromFile(bool isLiteralPath) { Collection <AliasInfo> result = new Collection <AliasInfo>(); string filePath = null; using (StreamReader reader = OpenFile(out filePath, isLiteralPath)) { CSVHelper csvHelper = new CSVHelper(','); Int64 lineNumber = 0; string line = null; while ((line = reader.ReadLine()) != null) { ++lineNumber; // Ignore blank lines if (line.Length == 0) { continue; } // Ignore lines that only contain whitespace if (OnlyContainsWhitespace(line)) { continue; } // Ignore comment lines if (line[0] == '#') { continue; } Collection <string> values = csvHelper.ParseCsv(line); if (values.Count != 4) { string message = StringUtil.Format(AliasCommandStrings.ImportAliasFileInvalidFormat, filePath, lineNumber); FormatException formatException = new FormatException(message); ErrorRecord errorRecord = new ErrorRecord( formatException, "ImportAliasFileFormatError", ErrorCategory.ReadError, filePath); errorRecord.ErrorDetails = new ErrorDetails(message); ThrowTerminatingError(errorRecord); } ScopedItemOptions options = ScopedItemOptions.None; try { options = (ScopedItemOptions)Enum.Parse(typeof(ScopedItemOptions), values[3], true); } catch (ArgumentException argException) { string message = StringUtil.Format(AliasCommandStrings.ImportAliasOptionsError, filePath, lineNumber); ErrorRecord errorRecord = new ErrorRecord( argException, "ImportAliasOptionsError", ErrorCategory.ReadError, filePath); errorRecord.ErrorDetails = new ErrorDetails(message); WriteError(errorRecord); continue; } AliasInfo newAlias = new AliasInfo( values[0], values[1], Context, options); if (!String.IsNullOrEmpty(values[2])) { newAlias.Description = values[2]; } result.Add(newAlias); } reader.Dispose(); } return(result); }
/// <summary> /// The main processing loop of the command. /// </summary> /// protected override void ProcessRecord() { Collection <AliasInfo> importedAliases = GetAliasesFromFile(this.ParameterSetName.Equals(LiteralPathParameterSetName, StringComparison.OrdinalIgnoreCase)); CommandOrigin origin = MyInvocation.CommandOrigin; foreach (AliasInfo alias in importedAliases) { // If not force, then see if the alias already exists // NTRAID#Windows Out Of Band Releases-906910-2006/03/17-JonN string action = AliasCommandStrings.ImportAliasAction; string target = StringUtil.Format(AliasCommandStrings.ImportAliasTarget, alias.Name, alias.Definition); if (!ShouldProcess(target, action)) { continue; } if (!Force) { AliasInfo existingAlias = null; if (String.IsNullOrEmpty(Scope)) { existingAlias = SessionState.Internal.GetAlias(alias.Name); } else { existingAlias = SessionState.Internal.GetAliasAtScope(alias.Name, Scope); } if (existingAlias != null) { // Write an error for aliases that aren't visible... try { SessionState.ThrowIfNotVisible(origin, existingAlias); } catch (SessionStateException sessionStateException) { WriteError( new ErrorRecord( sessionStateException.ErrorRecord, sessionStateException)); // Only report the error once... continue; } // Since the alias already exists, write an error. SessionStateException aliasExists = new SessionStateException( alias.Name, SessionStateCategory.Alias, "AliasAlreadyExists", SessionStateStrings.AliasAlreadyExists, ErrorCategory.ResourceExists); WriteError( new ErrorRecord( aliasExists.ErrorRecord, aliasExists)); continue; } if (VerifyShadowingExistingCommandsAndWriteError(alias.Name)) { continue; } } // if (!Force) // Set the alias in the specified scope or the // current scope. AliasInfo result = null; try { if (String.IsNullOrEmpty(Scope)) { result = SessionState.Internal.SetAliasItem(alias, Force, MyInvocation.CommandOrigin); } else { result = SessionState.Internal.SetAliasItemAtScope(alias, Scope, Force, MyInvocation.CommandOrigin); } } catch (SessionStateException sessionStateException) { WriteError( new ErrorRecord( sessionStateException.ErrorRecord, sessionStateException)); continue; } catch (PSArgumentOutOfRangeException argOutOfRange) { WriteError( new ErrorRecord( argOutOfRange.ErrorRecord, argOutOfRange)); continue; } catch (PSArgumentException argException) { WriteError( new ErrorRecord( argException.ErrorRecord, argException)); continue; } // Write the alias to the pipeline if PassThru was specified if (PassThru && result != null) { WriteObject(result); } } } // ProcessRecord
public static IEnumerable <CommandInfo> GetReferencedCommands(ScriptBlock scriptBlock, EngineIntrinsics executionContext, PSCmdlet cmdlet) { Dictionary <CommandInfo, bool> resolvedCommandCache = new Dictionary <CommandInfo, bool>(); Queue <PSToken> tokenQueue = new Queue <PSToken>(); Collection <PSParseError> errors; foreach (PSToken token in PSParser.Tokenize(new object[] { scriptBlock }, out errors)) { tokenQueue.Enqueue(token); } if (tokenQueue.Count == 0) { yield return(null); } while (tokenQueue.Count > 0) { PSToken token = tokenQueue.Dequeue(); if (token.Type == PSTokenType.Command) { CommandInfo cmd = null; cmd = executionContext.SessionState.InvokeCommand.GetCommand(token.Content, CommandTypes.Alias); if (cmd == null) { cmd = executionContext.SessionState.InvokeCommand.GetCommand(token.Content, CommandTypes.Function); if (cmd == null) { cmd = executionContext.SessionState.InvokeCommand.GetCommand(token.Content, CommandTypes.Cmdlet); } } else { while (cmd != null && cmd is AliasInfo) { AliasInfo alias = cmd as AliasInfo; if (!resolvedCommandCache.ContainsKey(alias)) { yield return(alias); resolvedCommandCache.Add(alias, true); } cmd = alias.ReferencedCommand; } } if (cmd == null) { continue; } if (cmd is FunctionInfo) { if (!resolvedCommandCache.ContainsKey(cmd)) { FunctionInfo func = cmd as FunctionInfo; yield return(cmd); foreach (PSToken t in PSParser.Tokenize(new object[] { func.ScriptBlock }, out errors)) { tokenQueue.Enqueue(t); } resolvedCommandCache.Add(cmd, true); } } else { if (!resolvedCommandCache.ContainsKey(cmd)) { yield return(cmd); resolvedCommandCache.Add(cmd, true); } } } } }