/// <summary> /// Gets the CommandInfo instance for a command with a particular name. /// </summary> /// <param name="commandName">The name of the command.</param> /// <param name="powerShellContext">The PowerShellContext to use for running Get-Command.</param> /// <returns>A CommandInfo object with details about the specified command.</returns> public static async Task <CommandInfo> GetCommandInfoAsync( string commandName, PowerShellContext powerShellContext) { Validate.IsNotNull(nameof(commandName), commandName); // Make sure the command's noun isn't blacklisted. This is // currently necessary to make sure that Get-Command doesn't // load PackageManagement or PowerShellGet because they cause // a major slowdown in IntelliSense. var commandParts = commandName.Split('-'); if (commandParts.Length == 2 && NounBlackList.Contains(commandParts[1])) { return(null); } PSCommand command = new PSCommand(); command.AddCommand(@"Microsoft.PowerShell.Core\Get-Command"); command.AddArgument(commandName); command.AddParameter("ErrorAction", "Ignore"); return ((await powerShellContext .ExecuteCommandAsync <PSObject>(command, false, false)) .Select(o => o.BaseObject) .OfType <CommandInfo>() .FirstOrDefault()); }
/// <summary> /// Gets the command's "Synopsis" documentation section. /// </summary> /// <param name="commandInfo">The CommandInfo instance for the command.</param> /// <param name="powerShellContext">The PowerShellContext to use for getting command documentation.</param> /// <returns></returns> public static async Task <string> GetCommandSynopsisAsync( CommandInfo commandInfo, PowerShellContext powerShellContext) { string synopsisString = string.Empty; PSObject helpObject = null; if (commandInfo != null && (commandInfo.CommandType == CommandTypes.Cmdlet || commandInfo.CommandType == CommandTypes.Function || commandInfo.CommandType == CommandTypes.Filter)) { PSCommand command = new PSCommand(); command.AddCommand(@"Microsoft.PowerShell.Core\Get-Help"); command.AddArgument(commandInfo); command.AddParameter("ErrorAction", "Ignore"); var results = await powerShellContext.ExecuteCommandAsync <PSObject>(command, false, false); helpObject = results.FirstOrDefault(); if (helpObject != null) { // Extract the synopsis string from the object synopsisString = (string)helpObject.Properties["synopsis"].Value ?? string.Empty; // Ignore the placeholder value for this field if (string.Equals(synopsisString, "SHORT DESCRIPTION", System.StringComparison.CurrentCultureIgnoreCase)) { synopsisString = string.Empty; } } } return(synopsisString); }
/// <summary> /// Gets all aliases found in the runspace /// </summary> private async Task GetAliasesAsync() { if (_areAliasesLoaded) { return; } await _aliasHandle.WaitAsync(); try { if (_powerShellContext.IsCurrentRunspaceOutOfProcess()) { _areAliasesLoaded = true; return; } var aliases = await _powerShellContext.ExecuteCommandAsync <AliasInfo>( new PSCommand() .AddCommand("Microsoft.PowerShell.Core\\Get-Command") .AddParameter("CommandType", CommandTypes.Alias), sendOutputToHost : false, sendErrorToHost : false); foreach (AliasInfo aliasInfo in aliases) { // Using Get-Command will obtain aliases from modules not yet loaded, // these aliases will not have a definition. if (string.IsNullOrEmpty(aliasInfo.Definition)) { continue; } if (!_cmdletToAliasDictionary.ContainsKey(aliasInfo.Definition)) { _cmdletToAliasDictionary.Add(aliasInfo.Definition, new List <String> { aliasInfo.Name }); } else { _cmdletToAliasDictionary[aliasInfo.Definition].Add(aliasInfo.Name); } _aliasToCmdletDictionary.Add(aliasInfo.Name, aliasInfo.Definition); } _areAliasesLoaded = true; } catch (PSNotSupportedException e) { _logger.Write( LogLevel.Warning, $"Caught PSNotSupportedException while attempting to get aliases from remote session:\n\n{e.ToString()}"); // Prevent the aliases from being fetched again - no point if the remote doesn't support InvokeCommand. _areAliasesLoaded = true; } catch (TaskCanceledException) { // The wait for a RunspaceHandle has timed out, skip aliases for now } finally { _aliasHandle.Release(); } }