public override void VisitCmdlet(CmdletAttribute cmdlet) { _cmdletInfo = new CmdletInfo(CurrentType, cmdlet); _command._cmdlets.Add(_cmdletInfo); base.VisitCmdlet(cmdlet); }
public void LoadCmdInfo() { info = TestParameterCommand.CreateCmdletInfo(); }
/// <summary> /// Resolves using module to a collection of PSModuleInfos. Doesn't throw. /// PSModuleInfo objects are returned in the right order: i.e. if multiply versions of the module /// is presented on the system and user didn't specify version, we will return all of them, but newer one would go first. /// </summary> /// <param name="usingStatementAst">using statement</param> /// <param name="exception">If exception happens, return exception object.</param> /// <param name="wildcardCharactersUsed"> /// True if in the module name uses wildcardCharacter. /// We don't want to resolve any wild-cards in using module. /// </param> /// <param name="isConstant">True if module hashtable contains constant value (it's our requirement).</param> /// <returns>Modules, if can resolve it. null if any problems happens.</returns> private Collection<PSModuleInfo> GetModulesFromUsingModule(UsingStatementAst usingStatementAst, out Exception exception, out bool wildcardCharactersUsed, out bool isConstant) { exception = null; wildcardCharactersUsed = false; isConstant = true; // fullyQualifiedName can be string or hashtable object fullyQualifiedName; if (usingStatementAst.ModuleSpecification != null) { object resultObject; if (!IsConstantValueVisitor.IsConstant(usingStatementAst.ModuleSpecification, out resultObject, forAttribute: false, forRequires: true)) { isConstant = false; return null; } var hashtable = resultObject as System.Collections.Hashtable; var ms = new ModuleSpecification(); exception = ModuleSpecification.ModuleSpecificationInitHelper(ms, hashtable); if (exception != null) { return null; } if (WildcardPattern.ContainsWildcardCharacters(ms.Name)) { wildcardCharactersUsed = true; return null; } fullyQualifiedName = ms; } else { string fullyQualifiedNameStr = usingStatementAst.Name.Value; if (WildcardPattern.ContainsWildcardCharacters(fullyQualifiedNameStr)) { wildcardCharactersUsed = true; return null; } // case 1: relative path. Relative for file in the same folder should include .\ bool isPath = fullyQualifiedNameStr.Contains(@"\"); if (isPath && !LocationGlobber.IsAbsolutePath(fullyQualifiedNameStr)) { string rootPath = Path.GetDirectoryName(_parser._fileName); if (rootPath != null) { fullyQualifiedNameStr = Path.Combine(rootPath, fullyQualifiedNameStr); } } // case 2: Module by name // case 3: Absolute Path // We don't need to do anything for these cases, FullyQualifiedName already handle it. fullyQualifiedName = fullyQualifiedNameStr; } var commandInfo = new CmdletInfo("Get-Module", typeof(GetModuleCommand)); // TODO(sevoroby): we should consider an async call with cancellation here. UsingStatementResolvePowerShell.Commands.Clear(); try { return UsingStatementResolvePowerShell.AddCommand(commandInfo) .AddParameter("FullyQualifiedName", fullyQualifiedName) .AddParameter("ListAvailable", true) .Invoke<PSModuleInfo>(); } catch (Exception e) { exception = e; return null; } }
/// <summary> /// Generates a HelpInfo PSObject from a CmdletInfo object /// </summary> /// <param name="input">Command info.</param> /// <returns>HelpInfo PSObject.</returns> internal static PSObject GetPSObjectFromCmdletInfo(CommandInfo input) { // Create a copy of commandInfo for GetCommandCommand so that we can generate parameter // sets based on Dynamic Parameters (+ optional arguments) CommandInfo commandInfo = input.CreateGetCommandCopy(null); PSObject obj = new PSObject(); obj.TypeNames.Clear(); obj.TypeNames.Add(string.Format(CultureInfo.InvariantCulture, "{0}#{1}#command", DefaultCommandHelpObjectBuilder.TypeNameForDefaultHelp, commandInfo.ModuleName)); obj.TypeNames.Add(string.Format(CultureInfo.InvariantCulture, "{0}#{1}", DefaultCommandHelpObjectBuilder.TypeNameForDefaultHelp, commandInfo.ModuleName)); obj.TypeNames.Add(DefaultCommandHelpObjectBuilder.TypeNameForDefaultHelp); obj.TypeNames.Add("CmdletHelpInfo"); obj.TypeNames.Add("HelpInfo"); if (commandInfo is CmdletInfo) { CmdletInfo cmdletInfo = commandInfo as CmdletInfo; bool common = false; if (cmdletInfo.Parameters != null) { common = HasCommonParameters(cmdletInfo.Parameters); } obj.Properties.Add(new PSNoteProperty("CommonParameters", common)); AddDetailsProperties(obj, cmdletInfo.Name, cmdletInfo.Noun, cmdletInfo.Verb, TypeNameForDefaultHelp); AddSyntaxProperties(obj, cmdletInfo.Name, cmdletInfo.ParameterSets, common, TypeNameForDefaultHelp); AddParametersProperties(obj, cmdletInfo.Parameters, common, TypeNameForDefaultHelp); AddInputTypesProperties(obj, cmdletInfo.Parameters); AddRelatedLinksProperties(obj, commandInfo.CommandMetadata.HelpUri); try { AddOutputTypesProperties(obj, cmdletInfo.OutputType); } catch (PSInvalidOperationException) { AddOutputTypesProperties(obj, new ReadOnlyCollection <PSTypeName>(new List <PSTypeName>())); } AddAliasesProperties(obj, cmdletInfo.Name, cmdletInfo.Context); if (HasHelpInfoUri(cmdletInfo.Module, cmdletInfo.ModuleName)) { AddRemarksProperties(obj, cmdletInfo.Name, cmdletInfo.CommandMetadata.HelpUri); } else { obj.Properties.Add(new PSNoteProperty("remarks", HelpDisplayStrings.None)); } obj.Properties.Add(new PSNoteProperty("PSSnapIn", cmdletInfo.PSSnapIn)); } else if (commandInfo is FunctionInfo) { FunctionInfo funcInfo = commandInfo as FunctionInfo; bool common = HasCommonParameters(funcInfo.Parameters); obj.Properties.Add(new PSNoteProperty("CommonParameters", common)); AddDetailsProperties(obj, funcInfo.Name, string.Empty, string.Empty, TypeNameForDefaultHelp); AddSyntaxProperties(obj, funcInfo.Name, funcInfo.ParameterSets, common, TypeNameForDefaultHelp); AddParametersProperties(obj, funcInfo.Parameters, common, TypeNameForDefaultHelp); AddInputTypesProperties(obj, funcInfo.Parameters); AddRelatedLinksProperties(obj, funcInfo.CommandMetadata.HelpUri); try { AddOutputTypesProperties(obj, funcInfo.OutputType); } catch (PSInvalidOperationException) { AddOutputTypesProperties(obj, new ReadOnlyCollection <PSTypeName>(new List <PSTypeName>())); } AddAliasesProperties(obj, funcInfo.Name, funcInfo.Context); if (HasHelpInfoUri(funcInfo.Module, funcInfo.ModuleName)) { AddRemarksProperties(obj, funcInfo.Name, funcInfo.CommandMetadata.HelpUri); } else { obj.Properties.Add(new PSNoteProperty("remarks", HelpDisplayStrings.None)); } } obj.Properties.Add(new PSNoteProperty("alertSet", null)); obj.Properties.Add(new PSNoteProperty("description", null)); obj.Properties.Add(new PSNoteProperty("examples", null)); obj.Properties.Add(new PSNoteProperty("Synopsis", commandInfo.Syntax)); obj.Properties.Add(new PSNoteProperty("ModuleName", commandInfo.ModuleName)); obj.Properties.Add(new PSNoteProperty("nonTerminatingErrors", string.Empty)); obj.Properties.Add(new PSNoteProperty("xmlns:command", "http://schemas.microsoft.com/maml/dev/command/2004/10")); obj.Properties.Add(new PSNoteProperty("xmlns:dev", "http://schemas.microsoft.com/maml/dev/2004/10")); obj.Properties.Add(new PSNoteProperty("xmlns:maml", "http://schemas.microsoft.com/maml/2004/10")); return(obj); }
protected override void GenerateHelper() { Console.WriteLine("Generating Native PowerShell help (Get-Help) documentation file"); base.GenerateHelper(); var buildLogsPath = Path.Combine(this.Options.RootPath, "logs"); if (!Directory.Exists(buildLogsPath)) { Directory.CreateDirectory(buildLogsPath); } var logFilename = Path.Combine(buildLogsPath, Name + ".dll-Help.log"); var oldWriter = Console.Out; try { using (var consoleWriter = new StreamWriter(File.OpenWrite(logFilename))) { Console.SetOut(consoleWriter); var outputFile = Path.Combine(this.OutputFolder, Name + PsHelpFilenameTail); var settings = new XmlWriterSettings { Indent = true }; using (var psHelpWriter = new XmlTextWriter(outputFile, Encoding.UTF8)) { psHelpWriter.Formatting = Formatting.Indented; psHelpWriter.WriteStartElement("helpItems"); psHelpWriter.WriteAttributeString("schema", "maml"); Parallel.ForEach(CmdletTypes, (cmdletType) => { CmdletInfo cmdletInfo = InspectCmdletAttributes(cmdletType); using (StringWriter sectionWriter = new StringWriter()) using (var sectionXmlWriter = XmlWriter.Create(sectionWriter, new XmlWriterSettings() { OmitXmlDeclaration = true, ConformanceLevel = ConformanceLevel.Fragment, CloseOutput = true })) { string synopsis = null; if (cmdletInfo.AWSCmdletAttribute == null) { Console.WriteLine("Unable to find AWSCmdletAttribute for type " + cmdletType.FullName); } else { var cmdletReturnAttributeType = cmdletInfo.AWSCmdletAttribute.GetType(); synopsis = cmdletReturnAttributeType.GetProperty("Synopsis").GetValue(cmdletInfo.AWSCmdletAttribute, null) as string; } foreach (var cmdletAttribute in cmdletInfo.CmdletAttributes) { sectionXmlWriter.WriteStartElement("command"); sectionXmlWriter.WriteAttributeString("xmlns", "maml", null, "http://schemas.microsoft.com/maml/2004/10"); sectionXmlWriter.WriteAttributeString("xmlns", "command", null, "http://schemas.microsoft.com/maml/dev/command/2004/10"); sectionXmlWriter.WriteAttributeString("xmlns", "dev", null, "http://schemas.microsoft.com/maml/dev/2004/10"); { var typeDocumentation = DocumentationUtils.GetTypeDocumentation(cmdletType, AssemblyDocumentation); typeDocumentation = DocumentationUtils.FormatXMLForPowershell(typeDocumentation); Console.WriteLine($"Cmdlet = {cmdletType.FullName}"); Console.WriteLine($"Documentation = {typeDocumentation}"); var cmdletName = cmdletAttribute.VerbName + "-" + cmdletAttribute.NounName; var allProperties = GetRootSimpleProperties(cmdletType); var parameterPartitioning = new CmdletParameterSetPartitions(allProperties, cmdletAttribute.DefaultParameterSetName); var serviceAbbreviation = GetServiceAbbreviation(cmdletType); WriteDetails(sectionXmlWriter, cmdletAttribute, typeDocumentation, cmdletName, synopsis); WriteSyntax(sectionXmlWriter, cmdletName, parameterPartitioning); WriteParameters(sectionXmlWriter, cmdletName, allProperties); WriteReturnValues(sectionXmlWriter, cmdletInfo.AWSCmdletOutputAttributes); WriteRelatedLinks(sectionXmlWriter, serviceAbbreviation, cmdletName); WriteExamples(sectionXmlWriter, cmdletName); } sectionXmlWriter.WriteEndElement(); } sectionXmlWriter.Close(); lock (psHelpWriter) { psHelpWriter.WriteRaw(sectionWriter.ToString()); } } }); psHelpWriter.WriteEndElement(); } Console.WriteLine($"Verifying help file {outputFile} using XmlDocument..."); try { var document = new XmlDocument(); document.Load(outputFile); } catch (Exception e) { Logger.LogError(e, $"Error when loading file {outputFile} as XmlDocument"); } } } finally { Console.SetOut(oldWriter); } }
protected override ActivityImplementationContext GetPowerShell(NativeActivityContext context) { ValidateParameters(); System.Management.Automation.PowerShell invoker = null; HashSet <string> allWorkflowVarNames = new HashSet <string>(StaticPotentialUsingVariableSet, StringComparer.OrdinalIgnoreCase); Dictionary <string, object> defaults = this.ParameterDefaults.Get(context); Dictionary <string, object> activityVariables = new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase); Dictionary <string, object> activityUsingVariables = new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase); string[] streams = { "Result", "PSError", "PSWarning", "PSVerbose", "PSDebug", "PSProgress", "PSInformation" }; // First, set the variables from the user's variables foreach (System.ComponentModel.PropertyDescriptor property in context.DataContext.GetProperties()) { if (String.Equals(property.Name, "ParameterDefaults", StringComparison.OrdinalIgnoreCase)) { continue; } // Add all user-defined variables/parameters in the same scope of the InlineScript activity if (!allWorkflowVarNames.Contains(property.Name)) { allWorkflowVarNames.Add(property.Name); } Object value = property.GetValue(context.DataContext); if (value != null) { object tempValue = value; PSDataCollection <PSObject> collectionObject = value as PSDataCollection <PSObject>; if (collectionObject != null && collectionObject.Count == 1) { tempValue = collectionObject[0]; } activityVariables[property.Name] = tempValue; } } // Then, set anything we received from parameters foreach (PSActivityArgumentInfo currentArgument in GetActivityArguments()) { string @default = currentArgument.Name; if (streams.Any(item => string.Equals(item, @default, StringComparison.OrdinalIgnoreCase))) { continue; } object argumentValue = currentArgument.Value.Get(context); if (argumentValue != null && !activityVariables.ContainsKey(currentArgument.Name)) { activityVariables[currentArgument.Name] = argumentValue; } } // Then, set the variables from the host defaults if (defaults != null) { foreach (string hostDefault in defaults.Keys) { string @default = hostDefault; if (streams.Any(item => string.Equals(item, @default, StringComparison.OrdinalIgnoreCase))) { continue; } object propertyValue = defaults[hostDefault]; if (propertyValue != null && !activityVariables.ContainsKey(hostDefault)) { activityVariables[hostDefault] = propertyValue; } } } if (_commandSpecified) { string script = string.IsNullOrEmpty(Command) ? string.Empty : Command; Tracer.WriteMessage(String.Format(CultureInfo.InvariantCulture, "PowerShell activity ID={0}: Inline Script: '{1}'.", context.ActivityInstanceId, script)); if (IsBlocked(script)) { throw new PSInvalidOperationException(String.Format(CultureInfo.InvariantCulture, ActivityResources.CannotLaunchFormat, script)); } string[] targetNodes = null; if (this.PSComputerName.Expression != null) { targetNodes = this.PSComputerName.Get(context); } else { if (defaults != null && defaults.ContainsKey("PSComputerName")) { targetNodes = this.ParameterDefaults.Get(context)["PSComputerName"] as string[]; } } // See if this command will be run in process. if ((targetNodes == null || targetNodes.Length == 0) && GetRunInProc(context)) { if (_compiledScriptForInProc == null || _ci == null) { lock (Syncroot) { if (_compiledScriptForInProc == null) { if (_scriptWithoutUsing == null) { _scriptWithoutUsing = RemoveUsingPrefix(script, allWorkflowVarNames, out _usingVariables); } _compiledScriptForInProc = ScriptBlock.Create(_scriptWithoutUsing); } // Invoke using the CommandInfo for Invoke-Command directly, rather than going through // the command discovery since this is much faster. if (_ci == null) { _ci = new CmdletInfo("Invoke-Command", typeof(Microsoft.PowerShell.Commands.InvokeCommandCommand)); } } } SetAvailableUsingVariables(activityVariables, activityUsingVariables); Tracer.WriteMessage("PowerShell activity: executing InlineScript locally with ScriptBlock."); invoker = System.Management.Automation.PowerShell.Create(); invoker.AddCommand(_ci).AddParameter("NoNewScope").AddParameter("ScriptBlock", _compiledScriptForInProc); } else { // Try to convert the ScriptBlock to a powershell instance if (_compiledScriptForOutProc == null) { lock (Syncroot) { if (_compiledScriptForOutProc == null) { _compiledScriptForOutProc = ScriptBlock.Create(script); } } } try { // we trust the code inside inlinescript, set isTrusted as True. invoker = _compiledScriptForOutProc.GetPowerShell(activityVariables, out activityUsingVariables, true); Tracer.WriteMessage("PowerShell activity: executing InlineScript with ScriptBlock to powershell conversion."); } catch (Exception) { invoker = null; } if (invoker == null) { // Since scriptblocks aren't serialized with fidelity in the remote case, we need to // use AddScript instead. if (_scriptWithoutUsing == null) { lock (Syncroot) { if (_scriptWithoutUsing == null) { _scriptWithoutUsing = RemoveUsingPrefix(script, allWorkflowVarNames, out _usingVariables); } } } SetAvailableUsingVariables(activityVariables, activityUsingVariables); Tracer.WriteMessage("PowerShell activity: executing InlineScript by using AddScript."); invoker = System.Management.Automation.PowerShell.Create(); invoker.AddScript(_scriptWithoutUsing); } } } else { string commandName = CommandName.Get(context); if (String.IsNullOrEmpty(commandName)) { throw new ArgumentException(ActivityResources.CommandNameRequired); } Tracer.WriteMessage(String.Format(CultureInfo.InvariantCulture, "PowerShell activity ID={0}: Invoking command '{1}'.", context.ActivityInstanceId, commandName)); invoker = System.Management.Automation.PowerShell.Create(); invoker.AddCommand(commandName); System.Collections.Hashtable parameters = Parameters.Get(context); if (parameters != null && parameters.Count > 0) { foreach (var key in parameters.Keys) { Tracer.WriteMessage(String.Format(CultureInfo.InvariantCulture, "PowerShell activity: Adding parameter '-{0} {1}'.", key, parameters[key])); } invoker.AddParameters(parameters); } } var implementationContext = new ActivityImplementationContext { PowerShellInstance = invoker, WorkflowContext = activityUsingVariables }; return(implementationContext); }
/// <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 }); } } } } } } }
/// <summary> /// Execution of PowerShell value activity. /// PowerShell expression will be evaluated using PowerShell runspace and the value of Type T will be returned. /// </summary> /// <param name="context"></param> protected override void Execute(NativeActivityContext context) { Token[] tokens; ParseError[] errors; ScriptBlockAst exprAst = Parser.ParseInput(Expression, out tokens, out errors); bool hasErrorActionPreference = false; bool hasWarningPreference = false; bool hasInformationPreference = false; // Custom activity participant tracker for updating debugger with current variables and sequence stop points. // Regex looks for debugger sequence points like: Expression="'3:5:WFFunc1'". // We specifically disallow TimeSpan values that look like sequence points: Expression="'00:00:01'". bool isDebugSequencePoint = (!string.IsNullOrEmpty(Expression) && (System.Text.RegularExpressions.Regex.IsMatch(Expression, @"^'\d+:\d+:\S+'$")) && (typeof(T) != typeof(System.TimeSpan))); var dataProperties = context.DataContext.GetProperties(); if (isDebugSequencePoint || (dataProperties.Count > 0)) { System.Activities.Tracking.CustomTrackingRecord customRecord = new System.Activities.Tracking.CustomTrackingRecord("PSWorkflowCustomUpdateDebugVariablesTrackingRecord"); foreach (System.ComponentModel.PropertyDescriptor property in dataProperties) { if (String.Equals(property.Name, "ParameterDefaults", StringComparison.OrdinalIgnoreCase)) { continue; } Object value = property.GetValue(context.DataContext); if (value != null) { object tempValue = value; PSDataCollection <PSObject> collectionObject = value as PSDataCollection <PSObject>; if (collectionObject != null && collectionObject.Count == 1) { tempValue = collectionObject[0]; } customRecord.Data.Add(property.Name, tempValue); } } if (isDebugSequencePoint) { customRecord.Data.Add("DebugSequencePoint", Expression); } context.Track(customRecord); } if (tokens != null) { foreach (Token token in tokens) { VariableToken variable = token as VariableToken; if (variable != null) { if (variable.Name.Equals("ErrorActionPreference", StringComparison.OrdinalIgnoreCase)) { hasErrorActionPreference = true; } else if (variable.Name.Equals("WarningPreference", StringComparison.OrdinalIgnoreCase)) { hasWarningPreference = true; } else if (variable.Name.Equals("InformationPreference", StringComparison.OrdinalIgnoreCase)) { hasInformationPreference = true; } } } } if (string.IsNullOrEmpty(Expression)) { throw new ArgumentException(ActivityResources.NullArgumentExpression); } if (_ci == null) { lock (syncroot) { // Invoke using the CommandInfo for Invoke-Command directly, rather than going through // command discovery (which is very slow). if (_ci == null) { _ci = new CmdletInfo("Invoke-Command", typeof(Microsoft.PowerShell.Commands.InvokeCommandCommand)); } } } Collection <PSObject> returnedvalue; Runspace runspace = null; bool borrowedRunspace = false; PSWorkflowHost workflowHost = null; if (typeof(ScriptBlock).IsAssignableFrom(typeof(T))) { Result.Set(context, ScriptBlock.Create(Expression)); return; } else if (typeof(ScriptBlock[]).IsAssignableFrom(typeof(T))) { Result.Set(context, new ScriptBlock[] { ScriptBlock.Create(Expression) }); return; } PropertyDescriptorCollection col = context.DataContext.GetProperties(); HostParameterDefaults hostValues = context.GetExtension <HostParameterDefaults>(); // Borrow a runspace from the host if we're not trying to create a ScriptBlock. // If we are trying to create one, we need to keep it around so that it can be // invoked multiple times. if (hostValues != null) { workflowHost = hostValues.Runtime; try { runspace = workflowHost.UnboundedLocalRunspaceProvider.GetRunspace(null, 0, 0); borrowedRunspace = true; } catch (Exception) { // it is fine to catch generic exception here // if the local runspace provider does not give us // a runspace we will create one locally (fallback) } } if (runspace == null) { // Not running with the PowerShell workflow host so directly create the runspace... runspace = RunspaceFactory.CreateRunspace(InitialSessionState.CreateDefault2()); runspace.Open(); } using (System.Management.Automation.PowerShell ps = System.Management.Automation.PowerShell.Create()) { try { ps.Runspace = runspace; // Subscribe to DataAdding on the error stream so that we can add position tracking information if (hostValues != null) { HostSettingCommandMetadata sourceCommandMetadata = hostValues.HostCommandMetadata; CommandMetadataTable.TryAdd(ps.InstanceId, sourceCommandMetadata); ps.Streams.Error.DataAdding += HandleErrorDataAdding; } // First, set the variables from the host defaults if ((hostValues != null) && (hostValues.Parameters != null)) { if (hostValues.Parameters.ContainsKey("PSCurrentDirectory")) { string path = hostValues.Parameters["PSCurrentDirectory"] as string; if (path != null) { ps.Runspace.SessionStateProxy.Path.SetLocation(path); } } foreach (string hostDefault in hostValues.Parameters.Keys) { string mappedHostDefault = hostDefault; if (hostDefault.Equals("ErrorAction", StringComparison.OrdinalIgnoreCase)) { if (hasErrorActionPreference) { mappedHostDefault = "ErrorActionPreference"; } else { continue; } } else if (hostDefault.Equals("WarningAction", StringComparison.OrdinalIgnoreCase)) { if (hasWarningPreference) { mappedHostDefault = "WarningPreference"; } else { continue; } } else if (hostDefault.Equals("InformationAction", StringComparison.OrdinalIgnoreCase)) { if (hasInformationPreference) { mappedHostDefault = "InformationPreference"; } else { continue; } } object propertyValue = hostValues.Parameters[hostDefault]; if (propertyValue != null) { ps.Runspace.SessionStateProxy.PSVariable.Set(mappedHostDefault, propertyValue); } } } // Then, set the variables from the workflow foreach (PropertyDescriptor p in col) { string name = p.Name; object value = p.GetValue(context.DataContext); if (value != null) { object tempValue = value; PSDataCollection <PSObject> collectionObject = value as PSDataCollection <PSObject>; if (collectionObject != null && collectionObject.Count == 1) { tempValue = collectionObject[0]; } ps.Runspace.SessionStateProxy.PSVariable.Set(name, tempValue); } } ps.AddCommand(_ci).AddParameter("NoNewScope").AddParameter("ScriptBlock", ExpressionScriptBlock); // If this needs to consume input, take it from the host stream. PSDataCollection <PSObject> inputStream = null; if (UseDefaultInput) { // Retrieve our host overrides hostValues = context.GetExtension <HostParameterDefaults>(); if (hostValues != null) { Dictionary <string, object> incomingArguments = hostValues.Parameters; if (incomingArguments.ContainsKey("Input")) { inputStream = incomingArguments["Input"] as PSDataCollection <PSObject>; } } } // Now invoke the pipeline try { if (inputStream != null) { returnedvalue = ps.Invoke(inputStream); inputStream.Clear(); } else { returnedvalue = ps.Invoke(); } } catch (CmdletInvocationException cie) { if (cie.ErrorRecord != null && cie.ErrorRecord.Exception != null) { throw cie.InnerException; } else { throw; } } } finally { if (hostValues != null) { ps.Streams.Error.DataAdding -= HandleErrorDataAdding; HostSettingCommandMetadata removedValue; CommandMetadataTable.TryRemove(ps.InstanceId, out removedValue); } if (borrowedRunspace) { workflowHost.UnboundedLocalRunspaceProvider.ReleaseRunspace(runspace); } else { // This will be disposed when the command is done with it. runspace.Dispose(); runspace = null; } } if (ps.Streams.Error != null && ps.Streams.Error.Count > 0) { PSDataCollection <ErrorRecord> errorStream = null; // Retrieve our host overrides hostValues = context.GetExtension <HostParameterDefaults>(); if (hostValues != null) { Dictionary <string, object> incomingArguments = hostValues.Parameters; if (incomingArguments.ContainsKey("PSError")) { errorStream = incomingArguments["PSError"] as PSDataCollection <ErrorRecord>; } } if (errorStream != null && errorStream.IsOpen) { foreach (ErrorRecord record in ps.Streams.Error) { errorStream.Add(record); } } } T valueToReturn = default(T); if (returnedvalue != null && returnedvalue.Count > 0) { try { if (returnedvalue.Count == 1) { if (returnedvalue[0] != null) { Object result = returnedvalue[0]; Object baseObject = ((PSObject)result).BaseObject; if (!(baseObject is PSCustomObject)) { result = baseObject; } // Try regular PowerShell conversion valueToReturn = LanguagePrimitives.ConvertTo <T>(result); } } else { valueToReturn = LanguagePrimitives.ConvertTo <T>(returnedvalue); } } catch (PSInvalidCastException) { // Handle the special case of emitting a PSDataCollection - use its array constructor. // This special case is why we aren't using PowerShell.Invoke<T> if (typeof(T) == typeof(PSDataCollection <PSObject>)) { Object tempValueToReturn = new PSDataCollection <PSObject>( new List <PSObject> { LanguagePrimitives.ConvertTo <PSObject>(returnedvalue[0]) }); valueToReturn = (T)tempValueToReturn; } else { throw; } } Result.Set(context, valueToReturn); } } }
/// <summary> /// Take module info of module that can be already loaded or not and loads it. /// </summary> /// <param name="originalModuleInfo"></param> /// <returns>module info of the same module, but loaded</returns> private static PSModuleInfo LoadModule(PSModuleInfo originalModuleInfo) { // originalModuleInfo is created during parse time and may not contain [System.Type] types exported from the module. // At this moment, we need to actually load the module and create types. // We want to load **exactly the same module** as we used at parse time. // And avoid the module resolution logic that can lead to another module (if something changed on the file system). // So, we load the module by the file path, not by module specification (ModuleName, RequiredVersion). var modulePath = originalModuleInfo.Path; var commandInfo = new CmdletInfo("Import-Module", typeof(ImportModuleCommand)); var ps = PowerShell.Create(RunspaceMode.CurrentRunspace) .AddCommand(commandInfo) .AddParameter("Name", modulePath) .AddParameter("PassThru"); var moduleInfo = ps.Invoke<PSModuleInfo>(); if (ps.HadErrors) { var errorRecord = ps.Streams.Error[0]; throw InterpreterError.NewInterpreterException(modulePath, typeof(RuntimeException), null, errorRecord.FullyQualifiedErrorId, errorRecord.ToString()); } if (moduleInfo.Count == 1) { return moduleInfo[0]; } else { Diagnostics.Assert(false, "We should load exactly one module from the provided original module"); return null; } }
public void LoadCmdInfo() { _info = TestParameterCommand.CreateCmdletInfo(); _cmdlet = new TestParameterCommand(); _binder = new CmdletParameterBinder(_info, _cmdlet); }
///<summary> /// Helper method for asynchronous invoke ///<returns>Unhandled FlowControl exception if InvocationSettings.ExposeFlowControlExceptions is true.</returns> ///</summary> private FlowControlException InvokeHelper() { FlowControlException flowControlException = null; PipelineProcessor pipelineProcessor = null; try { #if TRANSACTIONS_SUPPORTED // 2004/11/08-JeffJon //Transactions will not be supported for the Exchange release //Add the transaction to this thread System.Transactions.Transaction.Current = this.LocalRunspace.ExecutionContext.CurrentTransaction; #endif //Raise the event for Pipeline.Running RaisePipelineStateEvents(); //Add this pipeline to history RecordPipelineStartTime(); // Add automatic transcription, but don't transcribe nested commands if (this.AddToHistory || !IsNested) { bool needToAddOutDefault = true; CommandInfo outDefaultCommandInfo = new CmdletInfo("Out-Default", typeof(Microsoft.PowerShell.Commands.OutDefaultCommand), null, null, null); foreach (Command command in this.Commands) { if (command.IsScript && (!this.IsPulsePipeline)) { // Transcribe scripts, unless they are the pulse pipeline. this.Runspace.GetExecutionContext.EngineHostInterface.UI.TranscribeCommand(command.CommandText, null); } // Don't need to add Out-Default if the pipeline already has it, or we've got a pipeline evaluating // the PSConsoleHostReadLine command. if ( String.Equals(outDefaultCommandInfo.Name, command.CommandText, StringComparison.OrdinalIgnoreCase) || String.Equals("PSConsoleHostReadLine", command.CommandText, StringComparison.OrdinalIgnoreCase) || String.Equals("TabExpansion2", command.CommandText, StringComparison.OrdinalIgnoreCase) || this.IsPulsePipeline) { needToAddOutDefault = false; } } if (this.Runspace.GetExecutionContext.EngineHostInterface.UI.IsTranscribing) { if (needToAddOutDefault) { Command outDefaultCommand = new Command(outDefaultCommandInfo); outDefaultCommand.Parameters.Add(new CommandParameter("Transcript", true)); outDefaultCommand.Parameters.Add(new CommandParameter("OutVariable", null)); Commands.Add(outDefaultCommand); } } } try { //Create PipelineProcessor to invoke this pipeline pipelineProcessor = CreatePipelineProcessor(); } catch (Exception ex) { if (this.SetPipelineSessionState) { SetHadErrors(true); Runspace.ExecutionContext.AppendDollarError(ex); } throw; } //Supply input stream to PipelineProcessor // NTRAID#Windows Out Of Band Releases-925566-2005/12/09-JonN if (_useExternalInput) { pipelineProcessor.ExternalInput = InputStream.ObjectReader; } pipelineProcessor.ExternalSuccessOutput = OutputStream.ObjectWriter; pipelineProcessor.ExternalErrorOutput = ErrorStream.ObjectWriter; // Set Informational Buffers on the host only if this is not a child. // Do not overwrite parent's informational buffers. if (!this.IsChild) LocalRunspace.ExecutionContext.InternalHost. InternalUI.SetInformationalMessageBuffers(InformationalBuffers); bool oldQuestionMarkValue = true; bool savedIgnoreScriptDebug = this.LocalRunspace.ExecutionContext.IgnoreScriptDebug; // preserve the trap behaviour state variable... bool oldTrapState = this.LocalRunspace.ExecutionContext.PropagateExceptionsToEnclosingStatementBlock; this.LocalRunspace.ExecutionContext.PropagateExceptionsToEnclosingStatementBlock = false; try { //Add this pipeline to stopper _stopper.Push(pipelineProcessor); // Preserve the last value of $? across non-interactive commands. if (!AddToHistory) { oldQuestionMarkValue = this.LocalRunspace.ExecutionContext.QuestionMarkVariableValue; this.LocalRunspace.ExecutionContext.IgnoreScriptDebug = true; } else { this.LocalRunspace.ExecutionContext.IgnoreScriptDebug = false; } // Reset the redirection only if the pipeline is neither nested nor is a pulse pipeline (created by EventManager) if (!this.IsNested && !this.IsPulsePipeline) { this.LocalRunspace.ExecutionContext.ResetRedirection(); } //Invoke the pipeline. //Note:Since we are using pipes for output, return array is //be empty. try { pipelineProcessor.SynchronousExecuteEnumerate(AutomationNull.Value); SetHadErrors(pipelineProcessor.ExecutionFailed); } catch (ExitException ee) { // The 'exit' command was run so tell the host to exit. // Use the finally clause to make sure that the call is actually made. // We'll default the exit code to 1 instead or zero so that if, for some // reason, we can't get the real error code, we'll indicate a failure. SetHadErrors(pipelineProcessor.ExecutionFailed); int exitCode = 1; if (IsNested) { // set the global LASTEXITCODE to the value passed by exit <code> try { exitCode = (int)ee.Argument; this.LocalRunspace.ExecutionContext.SetVariable(SpecialVariables.LastExitCodeVarPath, exitCode); } finally { try { this.LocalRunspace.ExecutionContext.EngineHostInterface.ExitNestedPrompt(); } catch (ExitNestedPromptException) { // Already at the top level so we just want to ignore this exception... ; } } } else { try { exitCode = (int)ee.Argument; if ((InvocationSettings != null) && (InvocationSettings.ExposeFlowControlExceptions)) { flowControlException = ee; } } finally { this.LocalRunspace.ExecutionContext.EngineHostInterface.SetShouldExit(exitCode); // close the remote runspaces available /*foreach (RemoteRunspaceInfo remoteRunspaceInfo in this.LocalRunspace.RunspaceRepository.Runspaces) { remoteRunspaceInfo.RemoteRunspace.CloseAsync(); }*/ } } } catch (ExitNestedPromptException) { } catch (FlowControlException e) { if ((InvocationSettings != null) && (InvocationSettings.ExposeFlowControlExceptions) && ((e is BreakException) || (e is ContinueException) || (e is TerminateException))) { // Save FlowControl exception for return to caller. flowControlException = e; } // Otherwise discard this type of exception generated by the debugger or from an unhandled break, continue or return. ; } catch (Exception) { // Indicate that there were errors then rethrow... SetHadErrors(true); throw; } } finally { // Call StopProcessing() for all the commands. if (pipelineProcessor != null && pipelineProcessor.Commands != null) { for (int i = 0; i < pipelineProcessor.Commands.Count; i++) { CommandProcessorBase commandProcessor = pipelineProcessor.Commands[i]; EtwActivity.SetActivityId(commandProcessor.PipelineActivityId); // Log a command terminated event MshLog.LogCommandLifecycleEvent( commandProcessor.Context, CommandState.Terminated, commandProcessor.Command.MyInvocation); } } PSLocalEventManager eventManager = LocalRunspace.Events as PSLocalEventManager; if (eventManager != null) { eventManager.ProcessPendingActions(); } // restore the trap state... this.LocalRunspace.ExecutionContext.PropagateExceptionsToEnclosingStatementBlock = oldTrapState; // clean the buffers on InternalHost only if this is not a child. // Do not clear parent's informational buffers. if (!IsChild) LocalRunspace.ExecutionContext.InternalHost.InternalUI.SetInformationalMessageBuffers(null); //Pop the pipeline processor from stopper. _stopper.Pop(false); if (!AddToHistory) { this.LocalRunspace.ExecutionContext.QuestionMarkVariableValue = oldQuestionMarkValue; } // Restore the IgnoreScriptDebug value. this.LocalRunspace.ExecutionContext.IgnoreScriptDebug = savedIgnoreScriptDebug; } } catch (FlowControlException) { // Discard this type of exception generated by the debugger or from an unhandled break, continue or return. ; } finally { // 2004/02/26-JonN added IDisposable to PipelineProcessor if (null != pipelineProcessor) { pipelineProcessor.Dispose(); pipelineProcessor = null; } } return flowControlException; }
internal static PSObject GetPSObjectFromCmdletInfo(CommandInfo input) { CommandInfo info = input.CreateGetCommandCopy(null); PSObject obj2 = new PSObject(); obj2.TypeNames.Clear(); obj2.TypeNames.Add(string.Format(CultureInfo.InvariantCulture, "{0}#{1}#command", new object[] { TypeNameForDefaultHelp, info.ModuleName })); obj2.TypeNames.Add(string.Format(CultureInfo.InvariantCulture, "{0}#{1}", new object[] { TypeNameForDefaultHelp, info.ModuleName })); obj2.TypeNames.Add(TypeNameForDefaultHelp); obj2.TypeNames.Add("CmdletHelpInfo"); obj2.TypeNames.Add("HelpInfo"); if (info is CmdletInfo) { CmdletInfo info2 = info as CmdletInfo; bool flag = false; bool flag2 = false; if (info2.Parameters != null) { flag = HasCommonParameters(info2.Parameters); flag2 = (info2.CommandType & CommandTypes.Workflow) == CommandTypes.Workflow; } obj2.Properties.Add(new PSNoteProperty("CommonParameters", flag)); obj2.Properties.Add(new PSNoteProperty("WorkflowCommonParameters", flag2)); AddDetailsProperties(obj2, info2.Name, info2.Noun, info2.Verb, TypeNameForDefaultHelp, null); AddSyntaxProperties(obj2, info2.Name, info2.ParameterSets, flag, flag2, TypeNameForDefaultHelp); AddParametersProperties(obj2, info2.Parameters, flag, flag2, TypeNameForDefaultHelp); AddInputTypesProperties(obj2, info2.Parameters); AddRelatedLinksProperties(obj2, info.CommandMetadata.HelpUri); try { AddOutputTypesProperties(obj2, info2.OutputType); } catch (PSInvalidOperationException) { AddOutputTypesProperties(obj2, new ReadOnlyCollection <PSTypeName>(new List <PSTypeName>())); } AddAliasesProperties(obj2, info2.Name, info2.Context); if (HasHelpInfoUri(info2.Module, info2.ModuleName)) { AddRemarksProperties(obj2, info2.Name, info2.CommandMetadata.HelpUri); } else { obj2.Properties.Add(new PSNoteProperty("remarks", HelpDisplayStrings.None)); } obj2.Properties.Add(new PSNoteProperty("PSSnapIn", info2.PSSnapIn)); } else if (info is FunctionInfo) { FunctionInfo info3 = info as FunctionInfo; bool flag3 = HasCommonParameters(info3.Parameters); bool flag4 = (info.CommandType & CommandTypes.Workflow) == CommandTypes.Workflow; obj2.Properties.Add(new PSNoteProperty("CommonParameters", flag3)); obj2.Properties.Add(new PSNoteProperty("WorkflowCommonParameters", flag4)); AddDetailsProperties(obj2, info3.Name, string.Empty, string.Empty, TypeNameForDefaultHelp, null); AddSyntaxProperties(obj2, info3.Name, info3.ParameterSets, flag3, flag4, TypeNameForDefaultHelp); AddParametersProperties(obj2, info3.Parameters, flag3, flag4, TypeNameForDefaultHelp); AddInputTypesProperties(obj2, info3.Parameters); AddRelatedLinksProperties(obj2, info3.CommandMetadata.HelpUri); try { AddOutputTypesProperties(obj2, info3.OutputType); } catch (PSInvalidOperationException) { AddOutputTypesProperties(obj2, new ReadOnlyCollection <PSTypeName>(new List <PSTypeName>())); } AddAliasesProperties(obj2, info3.Name, info3.Context); if (HasHelpInfoUri(info3.Module, info3.ModuleName)) { AddRemarksProperties(obj2, info3.Name, info3.CommandMetadata.HelpUri); } else { obj2.Properties.Add(new PSNoteProperty("remarks", HelpDisplayStrings.None)); } } obj2.Properties.Add(new PSNoteProperty("alertSet", null)); obj2.Properties.Add(new PSNoteProperty("description", null)); obj2.Properties.Add(new PSNoteProperty("examples", null)); obj2.Properties.Add(new PSNoteProperty("Synopsis", info.Syntax)); obj2.Properties.Add(new PSNoteProperty("ModuleName", info.ModuleName)); obj2.Properties.Add(new PSNoteProperty("nonTerminatingErrors", string.Empty)); obj2.Properties.Add(new PSNoteProperty("xmlns:command", "http://schemas.microsoft.com/maml/dev/command/2004/10")); obj2.Properties.Add(new PSNoteProperty("xmlns:dev", "http://schemas.microsoft.com/maml/dev/2004/10")); obj2.Properties.Add(new PSNoteProperty("xmlns:maml", "http://schemas.microsoft.com/maml/2004/10")); return(obj2); }
static void Main(string[] args) { var cmdlets = new List<CmdletInfo>(); var inFile = args[0]; var outFile = args[1]; var toc = new List<CmdletInfo>(); // Specify an additional (third) parameter pointing to the Solution folder to generate Markdown. The markdown // will be created in the Documentation folder underneath the solution folder. bool generateMarkdown = false; string solutionDir = null; if (args.Length > 2) { solutionDir = args[2]; generateMarkdown = true; } var doc = new XDocument(new XDeclaration("1.0", "UTF-8", string.Empty)); XNamespace ns = "http://msh"; var helpItems = new XElement(ns + "helpItems", new XAttribute("schema", "maml")); doc.Add(helpItems); XNamespace maml = "http://schemas.microsoft.com/maml/2004/10"; XNamespace command = "http://schemas.microsoft.com/maml/dev/command/2004/10"; XNamespace dev = "http://schemas.microsoft.com/maml/dev/2004/10"; var mamlNsAttr = new XAttribute(XNamespace.Xmlns + "maml", "http://schemas.microsoft.com/maml/2004/10"); var commandNsAttr = new XAttribute(XNamespace.Xmlns + "command", "http://schemas.microsoft.com/maml/dev/command/2004/10"); var devNsAttr = new XAttribute(XNamespace.Xmlns + "dev", "http://schemas.microsoft.com/maml/dev/2004/10"); var assembly = Assembly.LoadFrom(inFile); var types = assembly.GetTypes(); foreach (var t in types) { if (t.BaseType.Name == "SPOCmdlet" || t.BaseType.Name == "PSCmdlet" || t.BaseType.Name == "SPOWebCmdlet" || t.BaseType.Name == "SPOAdminCmdlet") { //XElement examples = new XElement(command + "examples"); var verb = string.Empty; var noun = string.Empty; var description = string.Empty; var detaileddescription = string.Empty; var copyright = string.Empty; var version = string.Empty; var category = string.Empty; var attrs = t.GetCustomAttributes(); var examples = new List<CmdletExampleAttribute>(); //System.Attribute.GetCustomAttributes(t); foreach (var attr in attrs) { if (attr is CmdletAttribute) { var a = (CmdletAttribute)attr; verb = a.VerbName; noun = a.NounName; } if (attr is CmdletHelpAttribute) { var a = (CmdletHelpAttribute)attr; description = a.Description; copyright = a.Copyright; version = a.Version; detaileddescription = a.DetailedDescription; category = a.Category; } if (attr is CmdletExampleAttribute) { var a = (CmdletExampleAttribute)attr; examples.Add(a); } } var cmdletInfo = new CmdletInfo(verb, noun); cmdletInfo.Description = description; cmdletInfo.DetailedDescription = detaileddescription; cmdletInfo.Version = version; cmdletInfo.Copyright = copyright; cmdletInfo.Category = category; var commandElement = new XElement(command + "command", mamlNsAttr, commandNsAttr, devNsAttr); var detailsElement = new XElement(command + "details"); commandElement.Add(detailsElement); detailsElement.Add(new XElement(command + "name", string.Format("{0}-{1}", verb, noun))); detailsElement.Add(new XElement(maml + "description", new XElement(maml + "para", description))); detailsElement.Add(new XElement(maml + "copyright", new XElement(maml + "para", copyright))); detailsElement.Add(new XElement(command + "verb", verb)); detailsElement.Add(new XElement(command + "noun", noun)); detailsElement.Add(new XElement(dev + "version", version)); commandElement.Add(new XElement(maml + "description", new XElement(maml + "para", detaileddescription))); var syntaxElement = new XElement(command + "syntax"); commandElement.Add(syntaxElement); var fields = t.GetFields(); var syntaxItems = new List<SyntaxItem>(); foreach (var field in fields) { foreach (Attribute attr in field.GetCustomAttributes(typeof(ParameterAttribute), true)) { if (attr is ParameterAttribute) { var a = (ParameterAttribute)attr; if (!a.DontShow) { if (a.ParameterSetName != ParameterAttribute.AllParameterSets) { var cmdletSyntax = cmdletInfo.Syntaxes.FirstOrDefault(c => c.ParameterSetName == a.ParameterSetName); if (cmdletSyntax == null) { cmdletSyntax = new CmdletSyntax(); cmdletSyntax.ParameterSetName = a.ParameterSetName; cmdletInfo.Syntaxes.Add(cmdletSyntax); } cmdletSyntax.Parameters.Add(new CmdletParameterInfo() {Name = field.Name, Description = a.HelpMessage, Position = a.Position, Required = a.Mandatory, Type = field.FieldType.Name}); } var syntaxItem = syntaxItems.FirstOrDefault(x => x.Name == a.ParameterSetName); if (syntaxItem == null) { syntaxItem = new SyntaxItem(a.ParameterSetName); syntaxItems.Add(syntaxItem); } syntaxItem.Parameters.Add(new SyntaxItem.Parameter() {Name = field.Name, Description = a.HelpMessage, Position = a.Position, Required = a.Mandatory, Type = field.FieldType.Name}); } } } } // all parameters foreach (var field in fields) { foreach (Attribute attr in field.GetCustomAttributes(typeof(ParameterAttribute), true)) { if (attr is ParameterAttribute) { var a = (ParameterAttribute)attr; if (!a.DontShow) { if (a.ParameterSetName == ParameterAttribute.AllParameterSets) { foreach (var si in syntaxItems) { si.Parameters.Add(new SyntaxItem.Parameter() {Name = field.Name, Description = a.HelpMessage, Position = a.Position, Required = a.Mandatory, Type = field.FieldType.Name}); } if (cmdletInfo.Syntaxes.Count == 0) { cmdletInfo.Syntaxes.Add(new CmdletSyntax() {ParameterSetName = ParameterAttribute.AllParameterSets}); } foreach (var cmdletSyntax in cmdletInfo.Syntaxes) { cmdletSyntax.Parameters.Add(new CmdletParameterInfo() {Name = field.Name, Description = a.HelpMessage, Position = a.Position, Required = a.Mandatory, Type = field.FieldType.Name}); } } } } } } // foreach (var syntaxItem in syntaxItems) { var syntaxItemElement = new XElement(command + "syntaxItem"); syntaxElement.Add(syntaxItemElement); syntaxItemElement.Add(new XElement(maml + "name", string.Format("{0}-{1}", verb, noun))); foreach (var parameter in syntaxItem.Parameters) { var parameterElement = new XElement(command + "parameter", new XAttribute("required", parameter.Required), new XAttribute("position", parameter.Position > 0 ? parameter.Position.ToString() : "named")); parameterElement.Add(new XElement(maml + "name", parameter.Name)); parameterElement.Add(new XElement(maml + "description", new XElement(maml + "para", parameter.Description))); parameterElement.Add(new XElement(command + "parameterValue", parameter.Type)); syntaxItemElement.Add(parameterElement); } } var parametersElement = new XElement(command + "parameters"); commandElement.Add(parametersElement); foreach (var field in fields) { foreach (Attribute attr in field.GetCustomAttributes(typeof(ParameterAttribute), true)) { if (attr is ParameterAttribute) { var a = (ParameterAttribute)attr; if (!a.DontShow) { cmdletInfo.Parameters.Add(new CmdletParameterInfo() {Name = field.Name, Description = a.HelpMessage, Position = a.Position, Required = a.Mandatory, Type = field.FieldType.Name}); var parameter2Element = new XElement(command + "parameter", new XAttribute("required", a.Mandatory), new XAttribute("position", a.Position > 0 ? a.Position.ToString() : "named")); parameter2Element.Add(new XElement(maml + "name", field.Name)); parameter2Element.Add(new XElement(maml + "description", new XElement(maml + "para", a.HelpMessage))); var parameterValueElement = new XElement(command + "parameterValue", field.FieldType.Name, new XAttribute("required", a.Mandatory)); parameter2Element.Add(parameterValueElement); var devElement = new XElement(dev + "type"); devElement.Add(new XElement(maml + "name", field.FieldType.Name)); devElement.Add(new XElement(maml + "uri")); parameter2Element.Add(devElement); parametersElement.Add(parameter2Element); } break; } } } commandElement.Add( new XElement(command + "inputTypes", new XElement(command + "inputType", new XElement(dev + "type", new XElement(maml + "name", "String"), new XElement(maml + "uri"), new XElement(maml + "description", new XElement(maml + "para", "description")))))); helpItems.Add(commandElement); commandElement.Add( new XElement(command + "returnValues", new XElement(command + "returnValue", new XElement(dev + "type", new XElement(maml + "name", "String"), new XElement(maml + "uri"), new XElement(maml + "description", new XElement(maml + "para", "description")))))); var examplesElement = new XElement(command + "examples"); var exampleCount = 1; foreach (var exampleAttr in examples.OrderBy(e => e.SortOrder)) { var example = new XElement(command + "example"); var title = string.Format("------------------EXAMPLE {0}---------------------", exampleCount); example.Add(new XElement(maml + "title", title)); example.Add(new XElement(maml + "introduction", new XElement(maml + "para", exampleAttr.Introduction))); example.Add(new XElement(dev + "code", exampleAttr.Code)); example.Add(new XElement(maml + "remarks", new XElement(maml + "para", exampleAttr.Remarks))); example.Add(new XElement(command + "commandLines", new XElement(command + "commandLine", new XElement(command + "commandText")))); examplesElement.Add(example); exampleCount++; } commandElement.Add(examplesElement); if (generateMarkdown) { if (!string.IsNullOrEmpty(cmdletInfo.Verb) && !string.IsNullOrEmpty(cmdletInfo.Noun)) { toc.Add(cmdletInfo); using (var docfile = new System.IO.StreamWriter(string.Format("{0}\\Documentation\\{1}{2}.md", solutionDir, cmdletInfo.Verb, cmdletInfo.Noun))) { docfile.WriteLine("#{0}", cmdletInfo.FullCommand); docfile.WriteLine("*Topic automatically generated on: {0}*", DateTime.Now.ToString("yyyy-MM-dd")); docfile.WriteLine(""); docfile.WriteLine(cmdletInfo.Description); docfile.WriteLine("##Syntax"); foreach (var cmdletSyntax in cmdletInfo.Syntaxes) { var syntaxText = new StringBuilder(); syntaxText.AppendFormat("```powershell\r\n{0}", cmdletInfo.FullCommand); foreach (var par in cmdletSyntax.Parameters.OrderBy(p => p.Position)) { syntaxText.Append(" "); if (!par.Required) { syntaxText.Append("["); } syntaxText.AppendFormat("-{0} [<{1}>]", par.Name, par.Type); if (!par.Required) { syntaxText.Append("]"); } } // Add All ParameterSet ones docfile.WriteLine(syntaxText); docfile.WriteLine("```"); docfile.WriteLine(" "); docfile.WriteLine(""); } if (!string.IsNullOrEmpty(cmdletInfo.DetailedDescription)) { docfile.WriteLine("##Detailed Description"); docfile.WriteLine(cmdletInfo.DetailedDescription); docfile.WriteLine(""); } docfile.WriteLine("##Parameters"); docfile.WriteLine("Parameter|Type|Required|Description"); docfile.WriteLine("---------|----|--------|-----------"); foreach (var par in cmdletInfo.Parameters.OrderBy(x => x.Name)) { docfile.WriteLine("{0}|{1}|{2}|{3}", par.Name, par.Type, par.Required ? "True" : "False", par.Description); } if (examples.Any()) docfile.WriteLine("##Examples"); var examplesCount = 1; foreach (var example in examples.OrderBy(e => e.SortOrder)) { docfile.WriteLine(example.Introduction); docfile.WriteLine("###Example {0}", examplesCount); docfile.WriteLine(" {0}", example.Code); docfile.WriteLine(example.Remarks); examplesCount++; } } } } } } doc.Save(outFile); if (generateMarkdown) { // Create the readme.md using (var readme = new System.IO.StreamWriter(string.Format("{0}\\Documentation\\readme.md", solutionDir))) { readme.WriteLine("# Cmdlet Documentation #"); readme.WriteLine("Below you can find a list of all the available cmdlets. Many commands provide built-in help and examples. Retrieve the detailed help with "); readme.WriteLine("\r\n```powershell\r\nGet-Help Connect-SPOnline -Detailed\r\n```\r\n\r\n"); // Get all unique categories var categories = toc.Select(c => c.Category).Distinct(); foreach (var category in categories.OrderBy(c => c)) { readme.WriteLine("##{0}",category); readme.WriteLine("Cmdlet|Description"); readme.WriteLine(":-----|:----------"); foreach (var cmdletInfo in toc.Where(c => c.Category == category).OrderBy(c => c.Noun)) { var description = cmdletInfo.Description.Replace("\r\n", " "); readme.WriteLine("**[{0}]({1}{2}.md)** |{3}", cmdletInfo.FullCommand.Replace("-", "‑"), cmdletInfo.Verb, cmdletInfo.Noun, description); } } } } }
private PipelineProcessor CreatePipelineProcessor() { PipelineProcessor processor2; CommandCollection commands = base.Commands; if ((commands == null) || (commands.Count == 0)) { throw PSTraceSource.NewInvalidOperationException("RunspaceStrings", "NoCommandInPipeline", new object[0]); } PipelineProcessor processor = new PipelineProcessor { TopLevel = true }; bool flag = false; try { foreach (Command command in commands) { CommandProcessorBase base2; if (command.CommandInfo == null) { base2 = command.CreateCommandProcessor(this.LocalRunspace.ExecutionContext, this.LocalRunspace.CommandFactory, base.AddToHistory, this.IsNested ? CommandOrigin.Internal : CommandOrigin.Runspace); } else { CmdletInfo commandInfo = (CmdletInfo)command.CommandInfo; base2 = new CommandProcessor(commandInfo, this.LocalRunspace.ExecutionContext); PSSQMAPI.IncrementData(commandInfo.CommandType); base2.Command.CommandOriginInternal = CommandOrigin.Internal; base2.Command.MyInvocation.InvocationName = commandInfo.Name; if (command.Parameters != null) { foreach (CommandParameter parameter in command.Parameters) { CommandParameterInternal internal2 = CommandParameter.ToCommandParameterInternal(parameter, false); base2.AddParameter(internal2); } } } base2.RedirectShellErrorOutputPipe = base.RedirectShellErrorOutputPipe; processor.Add(base2); } processor2 = processor; } catch (RuntimeException) { flag = true; throw; } catch (Exception exception) { flag = true; CommandProcessorBase.CheckForSevereException(exception); throw new RuntimeException(PipelineStrings.CannotCreatePipeline, exception); } finally { if (flag) { base.SetHadErrors(true); processor.Dispose(); } } return(processor2); }
static void Main(string[] args) { var cmdlets = new List<CmdletInfo>(); var inFile = args[0]; var outFile = args[1]; var toc = new List<CmdletInfo>(); // Specify an additional (third) parameter pointing to the Solution folder to generate Markdown. The markdown // will be created in the Documentation folder underneath the solution folder. bool generateMarkdown = false; string solutionDir = null; if (args.Length > 2) { solutionDir = args[2]; generateMarkdown = true; } var doc = new XDocument(new XDeclaration("1.0", "UTF-8", string.Empty)); XNamespace ns = "http://msh"; var helpItems = new XElement(ns + "helpItems", new XAttribute("schema", "maml")); doc.Add(helpItems); XNamespace maml = "http://schemas.microsoft.com/maml/2004/10"; XNamespace command = "http://schemas.microsoft.com/maml/dev/command/2004/10"; XNamespace dev = "http://schemas.microsoft.com/maml/dev/2004/10"; var mamlNsAttr = new XAttribute(XNamespace.Xmlns + "maml", "http://schemas.microsoft.com/maml/2004/10"); var commandNsAttr = new XAttribute(XNamespace.Xmlns + "command", "http://schemas.microsoft.com/maml/dev/command/2004/10"); var devNsAttr = new XAttribute(XNamespace.Xmlns + "dev", "http://schemas.microsoft.com/maml/dev/2004/10"); var assembly = Assembly.LoadFrom(inFile); var types = assembly.GetTypes(); foreach (var t in types) { if (t.BaseType.Name == "SPOCmdlet" || t.BaseType.Name == "PSCmdlet" || t.BaseType.Name == "SPOWebCmdlet" || t.BaseType.Name == "SPOAdminCmdlet") { //XElement examples = new XElement(command + "examples"); var verb = string.Empty; var noun = string.Empty; var description = string.Empty; var detaileddescription = string.Empty; var copyright = string.Empty; var version = string.Empty; var category = string.Empty; var attrs = t.GetCustomAttributes(); var examples = new List<CmdletExampleAttribute>(); //System.Attribute.GetCustomAttributes(t); // Get info from attributes foreach (var attr in attrs) { if (attr is CmdletAttribute) { var a = (CmdletAttribute)attr; verb = a.VerbName; noun = a.NounName; } if (attr is CmdletHelpAttribute) { var a = (CmdletHelpAttribute)attr; description = a.Description; copyright = a.Copyright; version = a.Version; detaileddescription = a.DetailedDescription; category = a.Category; } if (attr is CmdletExampleAttribute) { var a = (CmdletExampleAttribute)attr; examples.Add(a); } } // Store in CmdletInfo structure var cmdletInfo = new CmdletInfo(verb, noun); cmdletInfo.Description = description; cmdletInfo.DetailedDescription = detaileddescription; cmdletInfo.Version = version; cmdletInfo.Copyright = copyright; cmdletInfo.Category = category; // Build XElement for command var commandElement = new XElement(command + "command", mamlNsAttr, commandNsAttr, devNsAttr); var detailsElement = new XElement(command + "details"); commandElement.Add(detailsElement); detailsElement.Add(new XElement(command + "name", string.Format("{0}-{1}", verb, noun))); detailsElement.Add(new XElement(maml + "description", new XElement(maml + "para", description))); detailsElement.Add(new XElement(maml + "copyright", new XElement(maml + "para", copyright))); detailsElement.Add(new XElement(command + "verb", verb)); detailsElement.Add(new XElement(command + "noun", noun)); detailsElement.Add(new XElement(dev + "version", version)); if (!string.IsNullOrWhiteSpace(detaileddescription)) { commandElement.Add(new XElement(maml + "description", new XElement(maml + "para", detaileddescription))); } var syntaxElement = new XElement(command + "syntax"); commandElement.Add(syntaxElement); // Store syntaxes in CmdletInfo structure (if not AllParameterSets), and also in all syntaxItems list var fields = t.GetFields(); var syntaxItems = new List<SyntaxItem>(); foreach (var field in fields) { foreach (Attribute attr in field.GetCustomAttributes(typeof(ParameterAttribute), true)) { if (attr is ParameterAttribute) { var a = (ParameterAttribute)attr; if (!a.DontShow) { if (a.ParameterSetName != ParameterAttribute.AllParameterSets) { var cmdletSyntax = cmdletInfo.Syntaxes.FirstOrDefault(c => c.ParameterSetName == a.ParameterSetName); if (cmdletSyntax == null) { cmdletSyntax = new CmdletSyntax(); cmdletSyntax.ParameterSetName = a.ParameterSetName; cmdletInfo.Syntaxes.Add(cmdletSyntax); } cmdletSyntax.Parameters.Add(new CmdletParameterInfo() { Name = field.Name, Description = a.HelpMessage, Position = a.Position, Required = a.Mandatory, Type = field.FieldType.Name }); var syntaxItem = syntaxItems.FirstOrDefault(x => x.Name == a.ParameterSetName); if (syntaxItem == null) { syntaxItem = new SyntaxItem(a.ParameterSetName); syntaxItems.Add(syntaxItem); } syntaxItem.Parameters.Add(new SyntaxItem.Parameter() { Name = field.Name, Description = a.HelpMessage, Position = a.Position, Required = a.Mandatory, Type = field.FieldType.Name }); } } } } } // all parameters // Add AllParameterSets to all CmdletInfo syntax sets and syntaxItems sets (first checking there is at least one, i.e. if all are marked AllParameterSets) foreach (var field in fields) { foreach (Attribute attr in field.GetCustomAttributes(typeof(ParameterAttribute), true)) { if (attr is ParameterAttribute) { var a = (ParameterAttribute)attr; if (!a.DontShow) { if (a.ParameterSetName == ParameterAttribute.AllParameterSets) { if (syntaxItems.Count == 0) { syntaxItems.Add(new SyntaxItem(ParameterAttribute.AllParameterSets)); } foreach (var si in syntaxItems) { si.Parameters.Add(new SyntaxItem.Parameter() { Name = field.Name, Description = a.HelpMessage, Position = a.Position, Required = a.Mandatory, Type = field.FieldType.Name }); } if (cmdletInfo.Syntaxes.Count == 0) { cmdletInfo.Syntaxes.Add(new CmdletSyntax() { ParameterSetName = ParameterAttribute.AllParameterSets }); } foreach (var cmdletSyntax in cmdletInfo.Syntaxes) { cmdletSyntax.Parameters.Add(new CmdletParameterInfo() { Name = field.Name, Description = a.HelpMessage, Position = a.Position, Required = a.Mandatory, Type = field.FieldType.Name }); } } } } } } // Build XElement for parameters from syntaxItems list (note: syntax element is set above) foreach (var syntaxItem in syntaxItems) { var syntaxItemElement = new XElement(command + "syntaxItem"); syntaxElement.Add(syntaxItemElement); syntaxItemElement.Add(new XElement(maml + "name", string.Format("{0}-{1}", verb, noun))); foreach (var parameter in syntaxItem.Parameters) { var parameterElement = new XElement(command + "parameter", new XAttribute("required", parameter.Required), new XAttribute("position", parameter.Position > 0 ? parameter.Position.ToString() : "named")); parameterElement.Add(new XElement(maml + "name", parameter.Name)); parameterElement.Add(new XElement(maml + "description", new XElement(maml + "para", parameter.Description))); parameterElement.Add(new XElement(command + "parameterValue", new XAttribute("required", parameter.Type != "SwitchParameter"), parameter.Type)); syntaxItemElement.Add(parameterElement); } } // Also store parameters in cmdletInfo.Parameters (all parameters) and XElement parameters var parametersElement = new XElement(command + "parameters"); commandElement.Add(parametersElement); foreach (var field in fields) { foreach (Attribute attr in field.GetCustomAttributes(typeof(ParameterAttribute), true)) { if (attr is ParameterAttribute) { var a = (ParameterAttribute)attr; if (!a.DontShow) { cmdletInfo.Parameters.Add(new CmdletParameterInfo() { Name = field.Name, Description = a.HelpMessage, Position = a.Position, Required = a.Mandatory, Type = field.FieldType.Name }); var parameter2Element = new XElement(command + "parameter", new XAttribute("required", a.Mandatory), new XAttribute("position", a.Position > 0 ? a.Position.ToString() : "named")); parameter2Element.Add(new XElement(maml + "name", field.Name)); parameter2Element.Add(new XElement(maml + "description", new XElement(maml + "para", a.HelpMessage))); var parameterValueElement = new XElement(command + "parameterValue", field.FieldType.Name, new XAttribute("required", a.Mandatory)); parameter2Element.Add(parameterValueElement); var devElement = new XElement(dev + "type"); devElement.Add(new XElement(maml + "name", field.FieldType.Name)); devElement.Add(new XElement(maml + "uri")); parameter2Element.Add(devElement); parametersElement.Add(parameter2Element); } break; } } } // XElement inputTypes commandElement.Add( new XElement(command + "inputTypes", new XElement(command + "inputType", new XElement(dev + "type", new XElement(maml + "name", "String"), new XElement(maml + "uri"), new XElement(maml + "description", new XElement(maml + "para", "description")))))); helpItems.Add(commandElement); // XElement return values commandElement.Add( new XElement(command + "returnValues", new XElement(command + "returnValue", new XElement(dev + "type", new XElement(maml + "name", "String"), new XElement(maml + "uri"), new XElement(maml + "description", new XElement(maml + "para", "description")))))); // XElement examples var examplesElement = new XElement(command + "examples"); var exampleCount = 1; foreach (var exampleAttr in examples.OrderBy(e => e.SortOrder)) { var example = new XElement(command + "example"); var title = string.Format("------------------EXAMPLE {0}---------------------", exampleCount); example.Add(new XElement(maml + "title", title)); example.Add(new XElement(maml + "introduction", new XElement(maml + "para", exampleAttr.Introduction))); example.Add(new XElement(dev + "code", exampleAttr.Code)); example.Add(new XElement(maml + "remarks", new XElement(maml + "para", exampleAttr.Remarks))); example.Add(new XElement(command + "commandLines", new XElement(command + "commandLine", new XElement(command + "commandText")))); examplesElement.Add(example); exampleCount++; } commandElement.Add(examplesElement); // Markdown from CmdletInfo if (generateMarkdown) { if (!string.IsNullOrEmpty(cmdletInfo.Verb) && !string.IsNullOrEmpty(cmdletInfo.Noun)) { string mdFilePath = string.Format("{0}\\Documentation\\{1}{2}.md", solutionDir, cmdletInfo.Verb, cmdletInfo.Noun); toc.Add(cmdletInfo); var existingHashCode = string.Empty; if (System.IO.File.Exists(mdFilePath)) { // Calculate hashcode var existingFileText = System.IO.File.ReadAllText(mdFilePath); var refPosition = existingFileText.IndexOf("<!-- Ref:"); if (refPosition > -1) { var refEndPosition = existingFileText.IndexOf("-->", refPosition); if (refEndPosition > -1) { var refCode = existingFileText.Substring(refPosition + 9, refEndPosition - refPosition - 9).Trim(); if (!string.IsNullOrEmpty(refCode)) { existingHashCode = refCode; } } } } var docHeaderBuilder = new StringBuilder(); // Separate header from body to calculate the hashcode later docHeaderBuilder.AppendFormat("#{0}{1}", cmdletInfo.FullCommand, Environment.NewLine); docHeaderBuilder.AppendFormat("*Topic automatically generated on: {0}*{1}", DateTime.Now.ToString("yyyy'-'MM'-'dd"), Environment.NewLine); docHeaderBuilder.Append(Environment.NewLine); // Body var docBuilder = new StringBuilder(); docBuilder.AppendFormat("{0}{1}", cmdletInfo.Description, Environment.NewLine); docBuilder.AppendFormat("##Syntax{0}", Environment.NewLine); foreach (var cmdletSyntax in cmdletInfo.Syntaxes.OrderBy(s => s.ParameterSetName)) { var syntaxText = new StringBuilder(); syntaxText.AppendFormat("```powershell\r\n{0}", cmdletInfo.FullCommand); foreach (var par in cmdletSyntax.Parameters.OrderBy(p => p.Position)) { syntaxText.Append(" "); if (!par.Required) { syntaxText.Append("["); } if (par.Type == "SwitchParameter") { syntaxText.AppendFormat("-{0} [<{1}>]", par.Name, par.Type); } else { syntaxText.AppendFormat("-{0} <{1}>", par.Name, par.Type); } if (!par.Required) { syntaxText.Append("]"); } } // Add All ParameterSet ones docBuilder.Append(syntaxText); docBuilder.AppendFormat("\n```\n\n\n"); } if (!string.IsNullOrEmpty(cmdletInfo.DetailedDescription)) { docBuilder.Append("##Detailed Description\n"); docBuilder.AppendFormat("{0}\n\n", cmdletInfo.DetailedDescription); } docBuilder.Append("##Parameters\n"); docBuilder.Append("Parameter|Type|Required|Description\n"); docBuilder.Append("---------|----|--------|-----------\n"); foreach (var par in cmdletInfo.Parameters.OrderBy(x => x.Name)) { docBuilder.AppendFormat("|{0}|{1}|{2}|{3}|\n", par.Name, par.Type, par.Required ? "True" : "False", par.Description); } if (examples.Any()) docBuilder.Append("##Examples\n"); var examplesCount = 1; foreach (var example in examples.OrderBy(e => e.SortOrder)) { docBuilder.AppendFormat("{0}\n", example.Introduction); docBuilder.AppendFormat("###Example {0}\n", examplesCount); docBuilder.AppendFormat(" {0}\n", example.Code); docBuilder.AppendFormat("{0}\n", example.Remarks); examplesCount++; } var newHashCode = CalculateMD5Hash(docBuilder.ToString()); docBuilder.AppendFormat("<!-- Ref: {0} -->", newHashCode); // Add hashcode of generated text to the file as hidden entry if (newHashCode != existingHashCode) { System.IO.File.WriteAllText(mdFilePath, docHeaderBuilder.Append(docBuilder).ToString()); } } } } } doc.Save(outFile); if (generateMarkdown) { // Create the readme.md var existingHashCode = string.Empty; var readmePath = string.Format("{0}\\Documentation\\readme.md", solutionDir); if (System.IO.File.Exists(readmePath)) { existingHashCode = CalculateMD5Hash(System.IO.File.ReadAllText(readmePath)); } var docBuilder = new StringBuilder(); docBuilder.AppendFormat("# Cmdlet Documentation #{0}", Environment.NewLine); docBuilder.AppendFormat("Below you can find a list of all the available cmdlets. Many commands provide built-in help and examples. Retrieve the detailed help with {0}", Environment.NewLine); docBuilder.AppendFormat("{0}```powershell{0}Get-Help Connect-SPOnline -Detailed{0}```{0}{0}", Environment.NewLine); // Get all unique categories var categories = toc.Select(c => c.Category).Distinct(); foreach (var category in categories.OrderBy(c => c)) { docBuilder.AppendFormat("##{0}{1}", category, Environment.NewLine); docBuilder.AppendFormat("Cmdlet|Description{0}", Environment.NewLine); docBuilder.AppendFormat(":-----|:----------{0}", Environment.NewLine); foreach (var cmdletInfo in toc.Where(c => c.Category == category).OrderBy(c => c.Noun)) { var description = cmdletInfo.Description.Replace("\r\n", " "); docBuilder.AppendFormat("**[{0}]({1}{2}.md)** |{3}{4}", cmdletInfo.FullCommand.Replace("-", "‑"), cmdletInfo.Verb, cmdletInfo.Noun, description, Environment.NewLine); } } var newHashCode = CalculateMD5Hash(docBuilder.ToString()); if (newHashCode != existingHashCode) { System.IO.File.WriteAllText(readmePath, docBuilder.ToString()); } } }
/// <summary> /// Resolves using module to a collection of PSModuleInfos. Doesn't throw. /// PSModuleInfo objects are returned in the right order: i.e. if multiply versions of the module /// is presented on the system and user didn't specify version, we will return all of them, but newer one would go first. /// </summary> /// <param name="usingStatementAst">Using statement.</param> /// <param name="exception">If exception happens, return exception object.</param> /// <param name="wildcardCharactersUsed"> /// True if in the module name uses wildcardCharacter. /// We don't want to resolve any wild-cards in using module. /// </param> /// <param name="isConstant">True if module hashtable contains constant value (it's our requirement).</param> /// <returns>Modules, if can resolve it. null if any problems happens.</returns> private Collection <PSModuleInfo> GetModulesFromUsingModule(UsingStatementAst usingStatementAst, out Exception exception, out bool wildcardCharactersUsed, out bool isConstant) { exception = null; wildcardCharactersUsed = false; isConstant = true; // fullyQualifiedName can be string or hashtable object fullyQualifiedName; if (usingStatementAst.ModuleSpecification != null) { object resultObject; if (!IsConstantValueVisitor.IsConstant(usingStatementAst.ModuleSpecification, out resultObject, forAttribute: false, forRequires: true)) { isConstant = false; return(null); } var hashtable = resultObject as System.Collections.Hashtable; var ms = new ModuleSpecification(); exception = ModuleSpecification.ModuleSpecificationInitHelper(ms, hashtable); if (exception != null) { return(null); } if (WildcardPattern.ContainsWildcardCharacters(ms.Name)) { wildcardCharactersUsed = true; return(null); } fullyQualifiedName = ms; } else { string fullyQualifiedNameStr = usingStatementAst.Name.Value; if (WildcardPattern.ContainsWildcardCharacters(fullyQualifiedNameStr)) { wildcardCharactersUsed = true; return(null); } // case 1: relative path. Relative for file in the same folder should include .\ or ./ bool isPath = fullyQualifiedNameStr.Contains('\\') || fullyQualifiedNameStr.Contains('/'); if (isPath && !LocationGlobber.IsAbsolutePath(fullyQualifiedNameStr)) { string rootPath = Path.GetDirectoryName(_parser._fileName); if (rootPath != null) { fullyQualifiedNameStr = Path.Combine(rootPath, fullyQualifiedNameStr); } } // case 2: Module by name // case 3: Absolute Path // We don't need to do anything for these cases, FullyQualifiedName already handle it. fullyQualifiedName = fullyQualifiedNameStr; } var commandInfo = new CmdletInfo("Get-Module", typeof(GetModuleCommand)); // TODO(sevoroby): we should consider an async call with cancellation here. UsingStatementResolvePowerShell.Commands.Clear(); try { return(UsingStatementResolvePowerShell.AddCommand(commandInfo) .AddParameter("FullyQualifiedName", fullyQualifiedName) .AddParameter("ListAvailable", true) .Invoke <PSModuleInfo>()); } catch (Exception e) { exception = e; return(null); } }
public static InitialSessionState GetSessionStateForCommands(CommandInfo[] commands) { InitialSessionState iss = InitialSessionState.CreateDefault(); Dictionary <string, SessionStateCommandEntry> commandCache = new Dictionary <string, SessionStateCommandEntry>(); foreach (SessionStateCommandEntry ssce in iss.Commands) { commandCache[ssce.Name] = ssce; } iss.ApartmentState = ApartmentState.STA; iss.ThreadOptions = PSThreadOptions.ReuseThread; if (commands.Length == 0) { return(iss); } foreach (CommandInfo cmd in commands) { if (cmd.Module != null) { string manifestPath = cmd.Module.Path.Replace(".psm1", ".psd1").Replace(".dll", ".psd1"); if (System.IO.File.Exists(manifestPath)) { iss.ImportPSModule(new string[] { manifestPath }); } else { iss.ImportPSModule(new string[] { cmd.Module.Path }); } continue; } if (cmd is AliasInfo) { CommandInfo loopCommand = cmd; while (loopCommand is AliasInfo) { SessionStateAliasEntry alias = new SessionStateAliasEntry(loopCommand.Name, loopCommand.Definition); iss.Commands.Add(alias); loopCommand = (loopCommand as AliasInfo).ReferencedCommand; } if (loopCommand is FunctionInfo) { SessionStateFunctionEntry func = new SessionStateFunctionEntry(loopCommand.Name, loopCommand.Definition); iss.Commands.Add(func); } if (loopCommand is CmdletInfo) { CmdletInfo cmdletData = loopCommand as CmdletInfo; SessionStateCmdletEntry cmdlet = new SessionStateCmdletEntry(cmd.Name, cmdletData.ImplementingType, cmdletData.HelpFile); iss.Commands.Add(cmdlet); } } if (cmd is FunctionInfo) { SessionStateFunctionEntry func = new SessionStateFunctionEntry(cmd.Name, cmd.Definition); iss.Commands.Add(func); } if (cmd is CmdletInfo) { CmdletInfo cmdletData = cmd as CmdletInfo; SessionStateCmdletEntry cmdlet = new SessionStateCmdletEntry(cmd.Name, cmdletData.ImplementingType, cmdletData.HelpFile); iss.Commands.Add(cmdlet); } } return(iss); }
public bool MoveNext() { try { int num = this.__1__state; if (num != 0) { if (num == 3) { this.__1__state = 2; this.__m__Finally1e(); } if (num == 7) { this.__1__state = 5; this.__m__Finally22(); } } else { this.__1__state = -1; this._commandPattern_5__b = new WildcardPattern(this.pattern, WildcardOptions.IgnoreCase); this._cmdletInfo_5__c = this.context.SessionState.InvokeCommand.GetCmdlet(@"Microsoft.PowerShell.Core\Get-Module"); aa__ = CommandDiscovery.GetCommandDiscoveryPreference(this.context, SpecialVariables.PSModuleAutoLoadingPreferenceVarPath, "PSModuleAutoLoadingPreference"); if ((aa__ != PSModuleAutoLoadingPreference.None) && ((this.commandOrigin == CommandOrigin.Internal) || ((this._cmdletInfo_5__c != null) && (this._cmdletInfo_5__c.Visibility == SessionStateEntryVisibility.Public)))) { this.__7__wrap1b = ModuleUtils.GetDefaultAvailableModuleFiles(true, false, this.context).GetEnumerator(); this.__1__state = 1; while (this.__7__wrap1b.MoveNext()) { this._modulePath_5__e = this.__7__wrap1b.Current; this._moduleName_5__f = Path.GetFileNameWithoutExtension(this._modulePath_5__e); this._modules_5__10 = this.context.Modules.GetExactMatchModules(this._moduleName_5__f, false, true); this._tempModuleInfo_5__11 = null; if (this._modules_5__10.Count != 0) { if (!this.rediscoverImportedModules) { continue; } if (this._modules_5__10.Exists(new Predicate <PSModuleInfo>(ModuleUtils.GetMatchingCommands_b__8))) { continue; } if (this._modules_5__10.Count == 1) { this._psModule_5__12 = this._modules_5__10[0]; this._tempModuleInfo_5__11 = new PSModuleInfo(this._psModule_5__12.Name, this._psModule_5__12.Path, null, null); this._tempModuleInfo_5__11.SetModuleBase(this._psModule_5__12.ModuleBase); this.__7__wrap1d = this._psModule_5__12.ExportedCommands.GetEnumerator(); this.__1__state = 2; while (this.__7__wrap1d.MoveNext()) { this._entry_5__13 = this.__7__wrap1d.Current; if (!this._commandPattern_5__b.IsMatch(this._entry_5__13.Value.Name)) { continue; } this._current_5__14 = null; switch (this._entry_5__13.Value.CommandType) { case CommandTypes.Alias: this._current_5__14 = new AliasInfo(this._entry_5__13.Value.Name, null, this.context); break; case CommandTypes.Function: this._current_5__14 = new FunctionInfo(this._entry_5__13.Value.Name, ScriptBlock.Create(""), this.context); break; case CommandTypes.Filter: this._current_5__14 = new FilterInfo(this._entry_5__13.Value.Name, ScriptBlock.Create(""), this.context); break; case CommandTypes.Cmdlet: this._current_5__14 = new CmdletInfo(this._entry_5__13.Value.Name, null, null, null, this.context); break; case CommandTypes.Workflow: this._current_5__14 = new WorkflowInfo(this._entry_5__13.Value.Name, ScriptBlock.Create(""), this.context); break; } this._current_5__14.SetModule(this._tempModuleInfo_5__11); this.__2__current = this._current_5__14; this.__1__state = 3; return(true); this.__1__state = 2; } this.__m__Finally1e(); continue; } } this._moduleShortName_5__15 = Path.GetFileNameWithoutExtension(this._modulePath_5__e); this._exportedCommands_5__16 = AnalysisCache.GetExportedCommands(this._modulePath_5__e, false, this.context); if (this._exportedCommands_5__16 != null) { this._tempModuleInfo_5__11 = new PSModuleInfo(this._moduleShortName_5__15, this._modulePath_5__e, null, null); if (InitialSessionState.IsEngineModule(this._moduleShortName_5__15)) { this._tempModuleInfo_5__11.SetModuleBase(Utils.GetApplicationBase(Utils.DefaultPowerShellShellID)); } this.__7__wrap1f = this._exportedCommands_5__16.Keys.GetEnumerator(); this.__1__state = 4; while (this.__7__wrap1f.MoveNext()) { this._exportedCommand_5__17 = this.__7__wrap1f.Current; if (this._commandPattern_5__b.IsMatch(this._exportedCommand_5__17)) { this.__7__wrap21 = this._exportedCommands_5__16[this._exportedCommand_5__17].GetEnumerator(); this.__1__state = 5; while (this.__7__wrap21.MoveNext()) { this._commandType_5__18 = this.__7__wrap21.Current; this._shouldExportCommand_5__19 = true; if ((this.context.InitialSessionState != null) && (this.commandOrigin == CommandOrigin.Runspace)) { foreach (SessionStateCommandEntry entry in this.context.InitialSessionState.Commands[this._exportedCommand_5__17]) { string b = null; if (entry.Module != null) { b = entry.Module.Name; } else if (entry.PSSnapIn != null) { b = entry.PSSnapIn.Name; } if (string.Equals(this._moduleShortName_5__15, b, StringComparison.OrdinalIgnoreCase) && (entry.Visibility == SessionStateEntryVisibility.Private)) { this._shouldExportCommand_5__19 = false; } } } if (!this._shouldExportCommand_5__19) { continue; } this._current_5__1a = null; switch (this._commandType_5__18) { case CommandTypes.Alias: this._current_5__1a = new AliasInfo(this._exportedCommand_5__17, null, this.context); break; case CommandTypes.Function: this._current_5__1a = new FunctionInfo(this._exportedCommand_5__17, ScriptBlock.Create(""), this.context); break; case CommandTypes.Cmdlet: this._current_5__1a = new CmdletInfo(this._exportedCommand_5__17, null, null, null, this.context); break; case CommandTypes.Workflow: this._current_5__1a = new WorkflowInfo(this._exportedCommand_5__17, ScriptBlock.Create(""), this.context); break; } if (this._current_5__1a != null) { this._current_5__1a.SetModule(this._tempModuleInfo_5__11); } this.__2__current = this._current_5__1a; this.__1__state = 7; return(true); Label_060F: this.__1__state = 5; } this.__m__Finally22(); } } this.__m__Finally20(); } } this.__m__Finally1c(); } } return(false); } finally { (this as IDisposable).Dispose(); } }
/// <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 }; } } } } } } }
private static PSObject ConvertToPSObject(GetAWSServiceCmdlet.ServiceInfo service, CmdletInfo cmdlet) { var result = new PSObject(); result.Properties.Add(new PSNoteProperty("CmdletName", cmdlet.Name)); result.Properties.Add(new PSNoteProperty("ServiceOperation", string.Join(";", cmdlet.Operations))); result.Properties.Add(new PSNoteProperty("ServiceName", service.Description)); #if MODULAR result.Properties.Add(new PSNoteProperty("ModuleName", service.ModuleName)); #endif return(result); }
internal override IEnumerable <PSTypeName> GetInferredType(CompletionContext context) { PseudoBindingInfo iteratorVariable0 = new PseudoParameterBinder().DoPseudoParameterBinding(this, null, null, false); if (iteratorVariable0.CommandInfo != null) { AstParameterArgumentPair iteratorVariable1; string key = "Path"; if (!iteratorVariable0.BoundArguments.TryGetValue(key, out iteratorVariable1)) { key = "LiteralPath"; iteratorVariable0.BoundArguments.TryGetValue(key, out iteratorVariable1); } CommandInfo commandInfo = iteratorVariable0.CommandInfo; AstPair iteratorVariable4 = iteratorVariable1 as AstPair; if ((iteratorVariable4 != null) && (iteratorVariable4.Argument is StringConstantExpressionAst)) { string str = ((StringConstantExpressionAst)iteratorVariable4.Argument).Value; try { commandInfo = commandInfo.CreateGetCommandCopy(new string[] { "-" + key, str }); } catch (InvalidOperationException) { } } CmdletInfo iteratorVariable5 = commandInfo as CmdletInfo; if (iteratorVariable5 != null) { if (iteratorVariable5.ImplementingType.FullName.Equals("Microsoft.PowerShell.Commands.NewObjectCommand", StringComparison.Ordinal)) { AstParameterArgumentPair iteratorVariable6; if (iteratorVariable0.BoundArguments.TryGetValue("TypeName", out iteratorVariable6)) { AstPair iteratorVariable7 = iteratorVariable6 as AstPair; if ((iteratorVariable7 != null) && (iteratorVariable7.Argument is StringConstantExpressionAst)) { yield return(new PSTypeName(((StringConstantExpressionAst)iteratorVariable7.Argument).Value)); } } goto Label_0579; } if (iteratorVariable5.ImplementingType.Equals(typeof(WhereObjectCommand)) || iteratorVariable5.ImplementingType.FullName.Equals("Microsoft.PowerShell.Commands.SortObjectCommand", StringComparison.Ordinal)) { PipelineAst parent = this.Parent as PipelineAst; if (parent != null) { int iteratorVariable9 = 0; while (iteratorVariable9 < parent.PipelineElements.Count) { if (parent.PipelineElements[iteratorVariable9] == this) { break; } iteratorVariable9++; } if (iteratorVariable9 > 0) { foreach (PSTypeName iteratorVariable10 in parent.PipelineElements[iteratorVariable9 - 1].GetInferredType(context)) { yield return(iteratorVariable10); } } } goto Label_0579; } if (iteratorVariable5.ImplementingType.Equals(typeof(ForEachObjectCommand))) { AstParameterArgumentPair iteratorVariable11; if (iteratorVariable0.BoundArguments.TryGetValue("Begin", out iteratorVariable11)) { foreach (PSTypeName iteratorVariable12 in this.GetInferredTypeFromScriptBlockParameter(iteratorVariable11, context)) { yield return(iteratorVariable12); } } if (iteratorVariable0.BoundArguments.TryGetValue("Process", out iteratorVariable11)) { foreach (PSTypeName iteratorVariable13 in this.GetInferredTypeFromScriptBlockParameter(iteratorVariable11, context)) { yield return(iteratorVariable13); } } if (iteratorVariable0.BoundArguments.TryGetValue("End", out iteratorVariable11)) { foreach (PSTypeName iteratorVariable14 in this.GetInferredTypeFromScriptBlockParameter(iteratorVariable11, context)) { yield return(iteratorVariable14); } } } } foreach (PSTypeName iteratorVariable15 in commandInfo.OutputType) { yield return(iteratorVariable15); } } Label_0579: yield break; }