diff --git a/src/Microsoft.PowerShell.Activities/Activities/ActivityGenerator.cs b/src/Microsoft.PowerShell.Activities/Activities/ActivityGenerator.cs
new file mode 100644
index 0000000000..745ad6032b
--- /dev/null
+++ b/src/Microsoft.PowerShell.Activities/Activities/ActivityGenerator.cs
@@ -0,0 +1,795 @@
+//
+// Copyright (C) Microsoft. All rights reserved.
+//
+using System;
+using System.Management.Automation;
+using System.Management.Automation.Runspaces;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.CSharp;
+using System.Diagnostics.CodeAnalysis;
+using System.IO;
+using Microsoft.PowerShell.Cmdletization;
+using Microsoft.PowerShell.Cmdletization.Xml;
+using System.Xml;
+using System.Xml.Serialization;
+using System.Xml.Schema;
+using System.CodeDom.Compiler;
+using System.CodeDom;
+
+namespace Microsoft.PowerShell.Activities
+{
+ ///
+ /// Generates an activity that corresponds to a PowerShell command
+ ///
+ public static class ActivityGenerator
+ {
+ private static readonly Lazy xmlSerializer = new Lazy(ConstructXmlSerializer);
+ private static readonly Lazy xmlReaderSettings = new Lazy(ConstructXmlReaderSettings);
+
+ static XmlSerializer ConstructXmlSerializer()
+ {
+ XmlSerializer xmlSerializer = new Microsoft.PowerShell.Cmdletization.Xml.PowerShellMetadataSerializer();
+ return xmlSerializer;
+ }
+
+ static XmlReaderSettings ConstructXmlReaderSettings()
+ {
+ //
+ // XmlReaderSettings
+ //
+ XmlReaderSettings result = new XmlReaderSettings();
+ // general settings
+ result.CheckCharacters = true;
+ result.CloseInput = false;
+ result.ConformanceLevel = ConformanceLevel.Document;
+ result.IgnoreComments = true;
+ result.IgnoreProcessingInstructions = true;
+ result.IgnoreWhitespace = false;
+ result.MaxCharactersFromEntities = 16384; // generous guess for the upper bound
+ result.MaxCharactersInDocument = 128 * 1024 * 1024; // generous guess for the upper bound
+ result.DtdProcessing = DtdProcessing.Parse; // Allowing DTD parsing with limits of MaxCharactersFromEntities/MaxCharactersInDocument
+ result.XmlResolver = null; // do not fetch external documents
+ // xsd schema related settings
+ result.ValidationFlags = XmlSchemaValidationFlags.ProcessIdentityConstraints |
+ XmlSchemaValidationFlags.ReportValidationWarnings;
+ result.ValidationType = ValidationType.Schema;
+ string cmdletizationXsd = ActivityResources.Xml_cmdletsOverObjectsXsd;
+ XmlReader cmdletizationSchemaReader = XmlReader.Create(new StringReader(cmdletizationXsd), result);
+ result.Schemas = new XmlSchemaSet();
+ result.Schemas.Add(null, cmdletizationSchemaReader);
+ result.Schemas.XmlResolver = null; // do not fetch external documents
+
+ return result;
+ }
+
+ static string templateCommand = @"
+using Microsoft.PowerShell.Activities;
+using System.Management.Automation;
+using System.Activities;
+using System.Collections.Generic;
+using System.ComponentModel;
+
+
+namespace {0}
+{{
+ ///
+ /// Activity to invoke the {1} command in a Workflow.
+ ///
+ [System.CodeDom.Compiler.GeneratedCode(""Microsoft.PowerShell.Activities.ActivityGenerator.GenerateFromName"", ""3.0"")]
+ public sealed class {2} : {6}
+ {{
+ ///
+ /// Gets the display name of the command invoked by this activity.
+ ///
+ public {2}()
+ {{
+ this.DisplayName = ""{8}"";
+ }}
+
+ ///
+ /// Gets the fully qualified name of the command invoked by this activity.
+ ///
+ public override string PSCommandName {{ get {{ return ""{4}""; }} }}
+
+ // Arguments
+ {3}
+
+ // Module defining this command
+ {7}
+
+ // Optional custom code for this activity
+ {9}
+
+ ///
+ /// Returns a configured instance of System.Management.Automation.PowerShell, pre-populated with the command to run.
+ ///
+ /// The NativeActivityContext for the currently running activity.
+ /// A populated instance of Sytem.Management.Automation.PowerShell
+ /// The infrastructure takes responsibility for closing and disposing the PowerShell instance returned.
+ protected override ActivityImplementationContext GetPowerShell(NativeActivityContext context)
+ {{
+ System.Management.Automation.PowerShell invoker = global::System.Management.Automation.PowerShell.Create();
+ System.Management.Automation.PowerShell targetCommand = invoker.AddCommand(PSCommandName);
+
+ // Initialize the arguments
+ {5}
+
+ return new ActivityImplementationContext() {{ PowerShellInstance = invoker }};
+ }}
+ }}
+}}";
+
+ const string templateParameter = @"
+ ///
+ /// Provides access to the {1} parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument<{0}> {1} {{ get; set; }}";
+
+ const string templateParameterSetter = @"
+ if({0}.Expression != null)
+ {{
+ targetCommand.AddParameter(""{1}"", {0}.Get(context));
+ }}";
+
+ const string customRemotingMapping = @"
+ if(GetIsComputerNameSpecified(context) && (PSRemotingBehavior.Get(context) == RemotingBehavior.Custom))
+ {
+ targetCommand.AddParameter(""ComputerName"", PSComputerName.Get(context));
+ }";
+
+ const string supportsCustomRemoting = @"
+ ///
+ /// Declares that this activity supports its own remoting.
+ ///
+ protected override bool SupportsCustomRemoting { get { return true; } }";
+
+ ///
+ /// Generate an activity for the named command.
+ ///
+ /// The command name to generate.
+ /// The namespace that will contain the command - for example,
+ /// Microsoft.PowerShell.Activities.
+ ///
+ /// A string representing the C# source code of the generated activity.
+ public static string GenerateFromName(string command, string activityNamespace)
+ {
+ return GenerateFromName(command, activityNamespace, false);
+ }
+
+ ///
+ /// Generate an activity for the named command.
+ ///
+ /// The command name to generate.
+ /// The namespace that will contain the command - for example,
+ /// Microsoft.PowerShell.Activities.
+ ///
+ /// True if remoting-related parameters should be suppressed. This
+ /// should only be specified for commands that offer no value when run on a remote computer.
+ ///
+ /// A string representing the C# source code of the generated activity.
+ public static string GenerateFromName(string command, string activityNamespace, bool shouldRunLocally)
+ {
+ StringBuilder output = new StringBuilder();
+
+ // Get the command from the runspace
+ using (System.Management.Automation.PowerShell invoker = System.Management.Automation.PowerShell.Create())
+ {
+ invoker.AddCommand("Get-Command").AddParameter("Name", command);
+ Collection result = invoker.Invoke();
+
+ if (result.Count == 0)
+ {
+ string message = String.Format(CultureInfo.InvariantCulture, ActivityResources.ActivityNameNotFound, command);
+ throw new ArgumentException(message, "command");
+ }
+
+ foreach (CommandInfo commandToGenerate in result)
+ {
+ output.AppendLine(GenerateFromCommandInfo(commandToGenerate, activityNamespace, shouldRunLocally));
+ }
+ }
+
+ return output.ToString().Trim();
+ }
+
+
+ ///
+ /// By default, the activity wrapper uses the remoting command base.
+ ///
+ /// The command name to generate.
+ /// The namespace that will contain the command - for example,
+ /// Microsoft.PowerShell.Activities.
+ ///
+ ///
+ public static string GenerateFromCommandInfo(CommandInfo command, string activityNamespace)
+ {
+ return GenerateFromCommandInfo(command, activityNamespace, false);
+ }
+
+ ///
+ /// By default, the activity wrapper uses the remoting command base.
+ ///
+ /// The command name to generate.
+ /// The namespace that will contain the command - for example,
+ /// Microsoft.PowerShell.Activities.
+ ///
+ /// True if remoting-related parameters should be suppressed. This
+ /// should only be specified for commands that offer no value when run on a remote computer.
+ ///
+ ///
+ public static string GenerateFromCommandInfo(CommandInfo command, string activityNamespace, bool shouldRunLocally)
+ {
+ string activityBaseClass = "PSRemotingActivity";
+ if (shouldRunLocally || (command.RemotingCapability == RemotingCapability.None))
+ {
+ activityBaseClass = "PSActivity";
+ }
+
+ return GenerateFromCommandInfo(command, activityNamespace, activityBaseClass, null, null, String.Empty);
+ }
+
+ ///
+ /// Generate an activity for the given command.
+ ///
+ /// The command to use as the basis of the generated activity.
+ /// The namespace that will contain the command - for example,
+ /// Microsoft.PowerShell.Activities.
+ ///
+ /// The class to use as the base class for this activity
+ ///
+ /// A list of parameters on the command being wrapped that should not
+ /// be copied to the activity.
+ ///
+ /// The module that contains the wrapped command
+ /// Addition text to inset in the class definition
+ /// A string representing the C# source code of the generated activity.
+ public static string GenerateFromCommandInfo(
+ CommandInfo command,
+ string activityNamespace,
+ string activityBaseClass,
+ string[] parametersToExclude,
+ string moduleToLoad,
+ string moduleDefinitionText
+ )
+ {
+ if (command == null)
+ {
+ throw new ArgumentNullException("command");
+ }
+
+ if (String.IsNullOrEmpty(activityNamespace))
+ {
+ throw new ArgumentNullException("activityNamespace");
+ }
+
+
+ if (String.IsNullOrEmpty(activityBaseClass))
+ {
+ throw new ArgumentNullException("activityBaseClass");
+ }
+
+ StringBuilder parameterBlock = new StringBuilder();
+ StringBuilder parameterInitialization = new StringBuilder();
+ string commandName = command.Name;
+ commandName = commandName.Substring(0, 1).ToUpper(CultureInfo.CurrentCulture) + commandName.Substring(1);
+ string activityName = command.Name.Replace("-", "");
+ activityName = activityName.Substring(0, 1).ToUpper(CultureInfo.CurrentCulture) + activityName.Substring(1);
+
+ String displayName = commandName;
+
+ // Verify that the activity name doesn't conflict with anything in the inheritance hierarchy
+ Type testType = typeof(PSRemotingActivity);
+ while (testType != null)
+ {
+ if (String.Equals(testType.Name, activityName, StringComparison.OrdinalIgnoreCase))
+ {
+ string message = String.Format(CultureInfo.InvariantCulture, ActivityResources.ActivityNameConflict, activityName);
+ throw new ArgumentException(message, "command");
+ }
+
+ testType = testType.BaseType;
+ }
+
+ // The default list of parameters that need to be ignored.
+ List ignoredParameters = new List(Cmdlet.CommonParameters.Concat(Cmdlet.OptionalCommonParameters));
+
+ // Add in any additional parameters the caller requested to ignore
+ if (parametersToExclude != null && parametersToExclude.Length > 0)
+ {
+ ignoredParameters.AddRange(parametersToExclude);
+ }
+
+ // If this activity supports its own remoting, ignore the ComputerName
+ // parameter (we will add special handling for that later)
+ if (command.RemotingCapability == RemotingCapability.SupportedByCommand)
+ {
+ ignoredParameters.Add("ComputerName");
+ }
+
+ // Avoid properties in parent classes.
+ List parentProperties = new List();
+ testType = typeof(PSRemotingActivity);
+ while (testType != typeof(PSActivity).BaseType)
+ {
+ parentProperties.AddRange(
+ from property in testType.GetProperties() select property.Name
+ );
+
+ testType = testType.BaseType;
+ }
+
+ foreach(KeyValuePair parameter in command.Parameters)
+ {
+ // Get the name (with capitalized first letter)
+ string name = parameter.Key;
+ name = name.Substring(0, 1).ToUpper(CultureInfo.CurrentCulture) + name.Substring(1);
+
+ // Ignore the common parameters
+ if(ignoredParameters.Contains(name, StringComparer.OrdinalIgnoreCase))
+ {
+ continue;
+ }
+
+ // Avoid parameters used by the parent activity, currently "Id" and
+ // "DisplayName". If the command has a noun, we name it:
+ // NounId and NounDisplayName - for example, ProcessId, and
+ // ServiceDisplayName.
+ string originalName = name;
+ if (parentProperties.Contains(name, StringComparer.OrdinalIgnoreCase))
+ {
+ if (commandName.Contains('-'))
+ {
+ string[] commandParts = commandName.Split('-');
+ string noun = commandParts[1];
+ noun = noun.Substring(0, 1).ToUpper(CultureInfo.CurrentCulture) + noun.Substring(1);
+ name = noun + name;
+ }
+ else
+ {
+ name = commandName + name;
+ }
+ }
+
+ // If the parameter name is the same as the command name, add "Activity"
+ // to the command name. Otherwise, we run afoul of the error:
+ // "Member names cannot be the same as their enclosing type".
+ if (String.Equals(name, activityName, StringComparison.OrdinalIgnoreCase))
+ {
+ activityName += "Activity";
+ }
+
+ // And the type
+ string type = parameter.Value.ParameterType.ToString();
+
+ // Fix generic types
+ if(type.Contains('`'))
+ {
+ type = System.Text.RegularExpressions.Regex.Replace(type, "`[\\d]+", "");
+ type = System.Text.RegularExpressions.Regex.Replace(type, "\\[", "<");
+ type = System.Text.RegularExpressions.Regex.Replace(type, "\\]", ">");
+ }
+
+ // Fix nested classes...
+ if (type.Contains('+'))
+ {
+ type = System.Text.RegularExpressions.Regex.Replace(type, "\\+", ".");
+ }
+
+ // Append the parameter ( InArgument Name { get; set } ... )
+ parameterBlock.AppendLine(
+ String.Format(CultureInfo.InvariantCulture,
+ templateParameter,
+ type,
+ name));
+
+ // Append the parameter initializer (... Parameters.Add(...) )
+ // This may have to be mapped from name to originalName when the
+ // parameter has a conflict with the parent activity.
+ parameterInitialization.AppendLine(
+ String.Format(CultureInfo.InvariantCulture,
+ templateParameterSetter,
+ name,
+ originalName));
+ }
+
+ // Append the remoting support to parameter initialization
+ if (command.RemotingCapability == RemotingCapability.SupportedByCommand)
+ {
+ parameterBlock.AppendLine(supportsCustomRemoting);
+ parameterInitialization.AppendLine(customRemotingMapping);
+ }
+
+
+ // If no module definition string has been included then add the defining module
+ // to the list of modules and make use a module-qualified name
+ string psDefiningModule = "";
+ if (string.IsNullOrEmpty(moduleDefinitionText))
+ {
+ // Prefer the module to load that was passed in over the module that
+ // eventually defined the cmdlet...
+ if (!string.IsNullOrEmpty(moduleToLoad))
+ {
+ commandName = moduleToLoad + "\\" + commandName;
+ }
+ else if (!String.IsNullOrEmpty(command.ModuleName))
+ {
+ commandName = command.ModuleName + "\\" + commandName;
+ }
+
+ if (!String.IsNullOrEmpty(moduleToLoad))
+ {
+ psDefiningModule = " /// \n/// Script module contents for this activity`n/// \n" +
+ @"protected override string PSDefiningModule { get { return """ + moduleToLoad + @"""; } }";
+ }
+ }
+
+ return String.Format(CultureInfo.InvariantCulture,
+ templateCommand,
+ activityNamespace,
+ commandName,
+ activityName,
+ parameterBlock.ToString(),
+ commandName.Replace("\\", "\\\\"),
+ parameterInitialization.ToString(),
+ activityBaseClass,
+ psDefiningModule,
+ displayName,
+ moduleDefinitionText);
+ }
+
+ ///
+ /// Generates a complete activity source file from a module.
+ ///
+ ///
+ /// The namesspace to use for the target classes
+ /// An array of code elements to compile into an assembly
+ static public string[] GenerateFromModuleInfo(PSModuleInfo moduleToProcess, string activityNamespace)
+ {
+ if (moduleToProcess == null)
+ throw new ArgumentNullException("moduleToProcess");
+
+ List codeToCompile = new List();
+
+ // Cmdlets and function need to exist in separate namespaces...
+ if (moduleToProcess.ExportedCmdlets != null)
+ {
+ string namespaceToUse = ! string.IsNullOrEmpty(activityNamespace) ? activityNamespace : moduleToProcess.Name + "_Cmdlet_Activities";
+ foreach (CmdletInfo ci in moduleToProcess.ExportedCmdlets.Values)
+ {
+ string code = Microsoft.PowerShell.Activities.ActivityGenerator.GenerateFromCommandInfo(ci, namespaceToUse, "PSRemotingActivity", null, null, "");
+ codeToCompile.Add(code);
+ }
+ }
+
+ Dictionary modules = new Dictionary();
+ PSModuleInfo cimModule = moduleToProcess;
+
+ if (moduleToProcess.ExportedFunctions != null)
+ {
+ string namespaceToUse = !string.IsNullOrEmpty(activityNamespace) ? activityNamespace : moduleToProcess.Name + "_Function_Activities";
+ foreach (FunctionInfo fi in moduleToProcess.ExportedFunctions.Values)
+ {
+ string moduleName = null;
+ string moduleDefinition = null;
+
+ // Save the module defining this function - we may need to extract
+ // embedded types further on
+ if (fi.ScriptBlock.Module != null && !string.IsNullOrEmpty(fi.ScriptBlock.Module.Definition))
+ {
+ moduleName = fi.ScriptBlock.Module.Name;
+ moduleDefinition = fi.ScriptBlock.Module.Definition;
+ }
+
+ string code;
+ if (fi.ScriptBlock.Module.ModuleType == ModuleType.Cim)
+ {
+ // Special-case CIM activities
+ string embeddedDefinition = "";
+
+ // Embed the module definition in the activity...
+ if (moduleDefinition != null)
+ {
+ // Remove all of the calls to Export-ModuleMember and getcommand
+ string editedDefinition = System.Text.RegularExpressions.Regex.Replace(moduleDefinition, @"Microsoft.PowerShell.Core\\Export-ModuleMember[^\n]*\n", "");
+ editedDefinition = System.Text.RegularExpressions.Regex.Replace(editedDefinition,
+ @"if \(\$\(Microsoft.PowerShell.Core\\Get-Command Set-StrictMode[^\n]*\n", "");
+
+ embeddedDefinition = "protected override string ModuleDefinition { get { return _moduleDefinition; } }\r\n const string _moduleDefinition = @\""
+ + editedDefinition.Replace("\"", "\"\"") + "\";";
+ }
+ code = Microsoft.PowerShell.Activities.ActivityGenerator.GenerateFromCommandInfo(
+ fi, namespaceToUse, "PSGeneratedCIMActivity", new string[] { "Computer", "AsJob", "CimSession" }, null, embeddedDefinition);
+
+ cimModule = fi.ScriptBlock.Module;
+ }
+ else
+ {
+ code = Microsoft.PowerShell.Activities.ActivityGenerator.GenerateFromCommandInfo(
+ fi, namespaceToUse, "PSRemotingActivity", new string[] { "Computer", "AsJob" }, moduleToProcess.Name, "");
+ }
+ codeToCompile.Add(code);
+
+ if (moduleName != null && !modules.ContainsKey(fi.ScriptBlock.Module.Name))
+ {
+ modules.Add(moduleName, moduleDefinition);
+ }
+
+
+ }
+ }
+
+ string fileName = cimModule.Path;
+
+ // See if there are any embedded types to extract
+ if (Path.GetExtension(fileName).Equals(".cdxml", StringComparison.OrdinalIgnoreCase))
+ {
+ // generate cmdletization proxies
+ using (FileStream file = new FileStream(fileName, FileMode.Open, FileAccess.Read))
+ {
+ XmlReader xmlReader = XmlReader.Create(file, xmlReaderSettings.Value);
+
+ PowerShellMetadata cmdletizationMetadata = (PowerShellMetadata)xmlSerializer.Value.Deserialize(xmlReader);
+
+ if (cmdletizationMetadata != null && cmdletizationMetadata.Enums != null)
+ {
+ foreach (EnumMetadataEnum enumMetadata in cmdletizationMetadata.Enums)
+ {
+ codeToCompile.Add(GetCSharpCode(enumMetadata));
+ }
+ }
+ }
+ }
+
+ return codeToCompile.ToArray();
+ }
+
+ internal static string GetCSharpCode(EnumMetadataEnum enumMetadata)
+ {
+ var codeCompileUnit = CreateCodeCompileUnit(enumMetadata);
+
+ var stringWriter = new StringWriter(CultureInfo.InvariantCulture);
+ CodeDomProvider.CreateProvider("C#").GenerateCodeFromCompileUnit(
+ codeCompileUnit,
+ stringWriter,
+ new CodeGeneratorOptions());
+ return stringWriter.ToString();
+ }
+
+ private const string namespacePrefix = "Microsoft.PowerShell.Cmdletization.GeneratedTypes";
+
+ private static CodeCompileUnit CreateCodeCompileUnit(EnumMetadataEnum enumMetadata)
+ {
+ var codeDomProvider = CodeDomProvider.CreateProvider("C#");
+
+ string subnamespaceText = string.Empty;
+ string enumNameText;
+ int indexOfLastDot = enumMetadata.EnumName.LastIndexOf('.');
+ if (indexOfLastDot < 0)
+ {
+ enumNameText = enumMetadata.EnumName;
+ }
+ else
+ {
+ subnamespaceText = "." + enumMetadata.EnumName.Substring(0, indexOfLastDot);
+ enumNameText = enumMetadata.EnumName.Substring(
+ indexOfLastDot + 1, enumMetadata.EnumName.Length - indexOfLastDot - 1);
+ }
+
+ // defense in depth (in case xsd is allowing some invalid identifiers)
+ // + xsd allows reserved keywords (i.e. "namespace" passes the regex test, but is not a valid identifier)
+ if (!codeDomProvider.IsValidIdentifier(enumNameText))
+ {
+ var errorMessage = string.Format(
+ CultureInfo.InvariantCulture,
+ ActivityResources.EnumWriter_InvalidEnumName,
+ enumMetadata.EnumName);
+ throw new XmlException(errorMessage);
+ }
+ var newEnum = new CodeTypeDeclaration(codeDomProvider.CreateValidIdentifier(enumNameText)) { IsEnum = true, Attributes = MemberAttributes.Public };
+
+ if (enumMetadata.BitwiseFlagsSpecified && enumMetadata.BitwiseFlags)
+ {
+ newEnum.CustomAttributes.Add(
+ new CodeAttributeDeclaration(new CodeTypeReference(typeof(FlagsAttribute))));
+ }
+
+ Type underlyingType = null;
+ if (enumMetadata.UnderlyingType != null)
+ {
+ underlyingType = Type.GetType(enumMetadata.UnderlyingType, false, true);
+
+ if (underlyingType != null)
+ {
+ newEnum.BaseTypes.Add(underlyingType);
+ }
+ else
+ {
+ underlyingType = typeof(Int32);
+ }
+ }
+ else
+ {
+ underlyingType = typeof(Int32);
+ }
+
+ foreach (var value in enumMetadata.Value)
+ {
+ // defense in depth (in case xsd is allowing some invalid identifiers)
+ // + xsd allows reserved keywords (i.e. "namespace" passes the regex test, but is not a valid identifier)
+ if (!codeDomProvider.IsValidIdentifier(value.Name)) // defense in depth (in case xsd is allowing some invalid identifiers)
+ {
+ var errorMessage = string.Format(
+ CultureInfo.InvariantCulture,
+ ActivityResources.EnumWriter_InvalidValueName,
+ value.Name);
+ throw new XmlException(errorMessage);
+ }
+
+ var nameValuePair = new CodeMemberField(underlyingType, codeDomProvider.CreateValidIdentifier(value.Name));
+
+ object integerValue = LanguagePrimitives.ConvertTo(
+ value.Value, underlyingType, CultureInfo.InvariantCulture);
+ nameValuePair.InitExpression = new CodePrimitiveExpression(integerValue);
+
+ newEnum.Members.Add(nameValuePair);
+ }
+
+ var topLevelNamespace = new CodeNamespace(namespacePrefix + subnamespaceText);
+ topLevelNamespace.Types.Add(newEnum);
+
+ var codeCompileUnit = new CodeCompileUnit();
+ codeCompileUnit.Namespaces.Add(topLevelNamespace);
+ codeCompileUnit.ReferencedAssemblies.Add("System.dll");
+
+ return codeCompileUnit;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static Assembly GenerateAssemblyFromModuleInfo(
+ PSModuleInfo moduleToProcess,
+ string activityNamespace,
+ string outputAssemblyPath,
+ string[] referenceAssemblies,
+ out string errors
+ )
+ {
+ string[] src = GenerateFromModuleInfo(moduleToProcess, activityNamespace);
+
+ bool toAssembly = ! string.IsNullOrEmpty(outputAssemblyPath);
+
+ return CompileStrings(src, referenceAssemblies, toAssembly, outputAssemblyPath, out errors);
+ }
+
+ private static Assembly CompileStrings(
+ string[] src,
+ string[] referenceAssemblies,
+ bool toAssembly,
+ string outputAssemblyPath,
+ out string errors
+ )
+ {
+ var cpar = new System.CodeDom.Compiler.CompilerParameters()
+ {
+ GenerateInMemory = ! toAssembly,
+ OutputAssembly = outputAssemblyPath,
+ };
+
+ // Add default references...
+ cpar.ReferencedAssemblies.Add(typeof(System.Activities.Activity).Assembly.Location);
+ cpar.ReferencedAssemblies.Add(typeof(System.CodeDom.Compiler.CodeCompiler).Assembly.Location);
+ cpar.ReferencedAssemblies.Add(typeof(PSObject).Assembly.Location);
+ cpar.ReferencedAssemblies.Add(typeof(Microsoft.PowerShell.Activities.PSActivity).Assembly.Location);
+ cpar.ReferencedAssemblies.Add(ResolveReferencedAssembly("Microsoft.Management.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"));
+ cpar.ReferencedAssemblies.Add(ResolveReferencedAssembly("Microsoft.PowerShell.Commands.Management, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"));
+
+ // Add user supplied references...
+ if (referenceAssemblies != null)
+ {
+ foreach (string asm in referenceAssemblies)
+ {
+ cpar.ReferencedAssemblies.Add(ResolveReferencedAssembly(asm));
+ }
+ }
+
+ var compiler = new Microsoft.CSharp.CSharpCodeProvider();
+ var cr = compiler.CompileAssemblyFromSource(cpar, src);
+ if (cr.Errors == null || cr.Errors.Count == 0)
+ {
+ errors = string.Empty;
+ }
+ else
+ {
+ StringBuilder errorBuilder = new StringBuilder();
+ foreach (var err in cr.Errors)
+ {
+ errorBuilder.Append(err.ToString());
+ errorBuilder.Append('\n');
+ }
+
+ errors = errorBuilder.ToString();
+ }
+
+ if (errors.Length > 0)
+ {
+ return null;
+ }
+
+ // If the assembly was written to disk, return null
+ // since we don't want to load the assembly we've just created.
+ if (toAssembly)
+ {
+ return null;
+ }
+ else
+ {
+ return cr.CompiledAssembly;
+ }
+ }
+
+ [SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Reflection.Assembly.LoadWithPartialName")]
+ [SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Reflection.Assembly.LoadFrom")]
+ private static string ResolveReferencedAssembly(string assembly)
+ {
+ Assembly asm = null;
+
+ if (assembly == null)
+ {
+ throw new ArgumentNullException("assembly");
+ }
+
+ if (System.IO.Path.IsPathRooted(assembly))
+ {
+ return assembly;
+ }
+
+ if (assembly.Contains(','))
+ {
+ try
+ {
+ asm = Assembly.Load(assembly);
+ return asm.Location;
+ }
+ catch (Exception)
+ {
+ ;
+ }
+ }
+
+
+ if (asm == null)
+ {
+ try
+ {
+#pragma warning disable 0618
+ asm = Assembly.LoadWithPartialName(assembly);
+ return asm.Location;
+ }
+ catch (Exception)
+ {
+ ;
+ }
+ }
+
+ if (asm == null)
+ {
+ throw new InvalidOperationException(assembly);
+ }
+ return null;
+ }
+ }
+}
diff --git a/src/Microsoft.PowerShell.Activities/Activities/GetCimAssociatedInstanceActivity.cs b/src/Microsoft.PowerShell.Activities/Activities/GetCimAssociatedInstanceActivity.cs
new file mode 100644
index 0000000000..8a052183fc
--- /dev/null
+++ b/src/Microsoft.PowerShell.Activities/Activities/GetCimAssociatedInstanceActivity.cs
@@ -0,0 +1,135 @@
+
+using Microsoft.PowerShell.Activities;
+using System.Activities;
+using System.Collections.Generic;
+using System.ComponentModel;
+
+
+namespace Microsoft.PowerShell.Activities
+{
+ ///
+ /// Activity to invoke the CimCmdlets\Get-CimAssociatedInstance command in a Workflow.
+ ///
+ [System.CodeDom.Compiler.GeneratedCode("Microsoft.PowerShell.Activities.ActivityGenerator.GenerateFromName", "3.0")]
+ public sealed class GetCimAssociatedInstance : GenericCimCmdletActivity
+ {
+ ///
+ /// Gets the display name of the command invoked by this activity.
+ ///
+ public GetCimAssociatedInstance()
+ {
+ this.DisplayName = "Get-CimAssociatedInstance";
+ }
+
+ ///
+ /// Gets the fully qualified name of the command invoked by this activity.
+ ///
+ public override string PSCommandName { get { return "CimCmdlets\\Get-CimAssociatedInstance"; } }
+
+ ///
+ /// The .NET type implementing the cmdlet to invoke.
+ ///
+ public override System.Type TypeImplementingCmdlet { get { return typeof(Microsoft.Management.Infrastructure.CimCmdlets.GetCimAssociatedInstanceCommand); } }
+
+ // Arguments
+
+ ///
+ /// Provides access to the Association parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument Association { get; set; }
+
+ ///
+ /// Provides access to the ResultClassName parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument ResultClassName { get; set; }
+
+ ///
+ /// Provides access to the InputObject parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument InputObject { get; set; }
+
+ ///
+ /// Provides access to the Namespace parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument Namespace { get; set; }
+
+ ///
+ /// Provides access to the OperationTimeoutSec parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument OperationTimeoutSec { get; set; }
+
+ ///
+ /// Provides access to the KeyOnly parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument KeyOnly { get; set; }
+
+ ///
+ /// No module needed for this activity
+ ///
+ protected override string PSDefiningModule { get { return null; } }
+
+ ///
+ /// Returns a configured instance of System.Management.Automation.PowerShell, pre-populated with the command to run.
+ ///
+ /// The NativeActivityContext for the currently running activity.
+ /// A populated instance of Sytem.Management.Automation.PowerShell
+ /// The infrastructure takes responsibility for closing and disposing the PowerShell instance returned.
+ protected override ActivityImplementationContext GetPowerShell(NativeActivityContext context)
+ {
+ System.Management.Automation.PowerShell invoker = global::System.Management.Automation.PowerShell.Create();
+ System.Management.Automation.PowerShell targetCommand = invoker.AddCommand(PSCommandName);
+
+ // Initialize the arguments
+
+ if(Association.Expression != null)
+ {
+ targetCommand.AddParameter("Association", Association.Get(context));
+ }
+
+ if (ResultClassName.Expression != null)
+ {
+ targetCommand.AddParameter("ResultClassName", ResultClassName.Get(context));
+ }
+
+ if (InputObject.Expression != null)
+ {
+ targetCommand.AddParameter("InputObject", InputObject.Get(context));
+ }
+
+ if(Namespace.Expression != null)
+ {
+ targetCommand.AddParameter("Namespace", Namespace.Get(context));
+ }
+
+ if(OperationTimeoutSec.Expression != null)
+ {
+ targetCommand.AddParameter("OperationTimeoutSec", OperationTimeoutSec.Get(context));
+ }
+
+ if(KeyOnly.Expression != null)
+ {
+ targetCommand.AddParameter("KeyOnly", KeyOnly.Get(context));
+ }
+
+ if (ResourceUri != null)
+ {
+ targetCommand.AddParameter("ResourceUri", ResourceUri.Get(context));
+ }
+
+
+ return new ActivityImplementationContext() { PowerShellInstance = invoker };
+ }
+ }
+}
diff --git a/src/Microsoft.PowerShell.Activities/Activities/GetCimClassActivity.cs b/src/Microsoft.PowerShell.Activities/Activities/GetCimClassActivity.cs
new file mode 100644
index 0000000000..7176899885
--- /dev/null
+++ b/src/Microsoft.PowerShell.Activities/Activities/GetCimClassActivity.cs
@@ -0,0 +1,131 @@
+
+using Microsoft.PowerShell.Activities;
+using System.Activities;
+using System.Collections.Generic;
+using System.ComponentModel;
+
+
+namespace Microsoft.PowerShell.Activities
+{
+ ///
+ /// Activity to invoke the CimCmdlets\Get-CimClass command in a Workflow.
+ ///
+ [System.CodeDom.Compiler.GeneratedCode("Microsoft.PowerShell.Activities.ActivityGenerator.GenerateFromName", "3.0")]
+ public sealed class GetCimClass : GenericCimCmdletActivity
+ {
+ ///
+ /// Gets the display name of the command invoked by this activity.
+ ///
+ public GetCimClass()
+ {
+ this.DisplayName = "Get-CimClass";
+ }
+
+ ///
+ /// Gets the fully qualified name of the command invoked by this activity.
+ ///
+ public override string PSCommandName { get { return "CimCmdlets\\Get-CimClass"; } }
+
+ ///
+ /// The .NET type implementing the cmdlet to invoke.
+ ///
+ public override System.Type TypeImplementingCmdlet { get { return typeof(Microsoft.Management.Infrastructure.CimCmdlets.GetCimClassCommand); } }
+
+ // Arguments
+
+ ///
+ /// Provides access to the ClassName parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument ClassName { get; set; }
+
+ ///
+ /// Provides access to the Namespace parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument Namespace { get; set; }
+
+ ///
+ /// Provides access to the OperationTimeoutSec parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument OperationTimeoutSec { get; set; }
+
+ ///
+ /// Provides access to the MethodName parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument MethodName { get; set; }
+
+ ///
+ /// Provides access to the PropertyName parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument PropertyName { get; set; }
+
+ ///
+ /// Provides access to the QualifierName parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument QualifierName { get; set; }
+
+ ///
+ /// No module needed for this activity
+ ///
+ protected override string PSDefiningModule { get { return null; } }
+
+ ///
+ /// Returns a configured instance of System.Management.Automation.PowerShell, pre-populated with the command to run.
+ ///
+ /// The NativeActivityContext for the currently running activity.
+ /// A populated instance of Sytem.Management.Automation.PowerShell
+ /// The infrastructure takes responsibility for closing and disposing the PowerShell instance returned.
+ protected override ActivityImplementationContext GetPowerShell(NativeActivityContext context)
+ {
+ System.Management.Automation.PowerShell invoker = global::System.Management.Automation.PowerShell.Create();
+ System.Management.Automation.PowerShell targetCommand = invoker.AddCommand(PSCommandName);
+
+ // Initialize the arguments
+ // Specified ClassName cannot be WhiteSpace or NULL
+ //
+ if (ClassName.Expression != null && !string.IsNullOrWhiteSpace(ClassName.Get(context)))
+ {
+ targetCommand.AddParameter("ClassName", ClassName.Get(context));
+ }
+
+ if(Namespace.Expression != null)
+ {
+ targetCommand.AddParameter("Namespace", Namespace.Get(context));
+ }
+
+ if(OperationTimeoutSec.Expression != null)
+ {
+ targetCommand.AddParameter("OperationTimeoutSec", OperationTimeoutSec.Get(context));
+ }
+
+ if(MethodName.Expression != null)
+ {
+ targetCommand.AddParameter("MethodName", MethodName.Get(context));
+ }
+
+ if(PropertyName.Expression != null)
+ {
+ targetCommand.AddParameter("PropertyName", PropertyName.Get(context));
+ }
+
+ if(QualifierName.Expression != null)
+ {
+ targetCommand.AddParameter("QualifierName", QualifierName.Get(context));
+ }
+
+
+ return new ActivityImplementationContext() { PowerShellInstance = invoker };
+ }
+ }
+}
diff --git a/src/Microsoft.PowerShell.Activities/Activities/GetCimInstanceActivity.cs b/src/Microsoft.PowerShell.Activities/Activities/GetCimInstanceActivity.cs
new file mode 100644
index 0000000000..8821a95245
--- /dev/null
+++ b/src/Microsoft.PowerShell.Activities/Activities/GetCimInstanceActivity.cs
@@ -0,0 +1,177 @@
+
+using Microsoft.PowerShell.Activities;
+using System.Activities;
+using System.Collections.Generic;
+using System.ComponentModel;
+
+
+namespace Microsoft.PowerShell.Activities
+{
+ ///
+ /// Activity to invoke the CimCmdlets\Get-CimInstance command in a Workflow.
+ ///
+ [System.CodeDom.Compiler.GeneratedCode("Microsoft.PowerShell.Activities.ActivityGenerator.GenerateFromName", "3.0")]
+ public sealed class GetCimInstance : GenericCimCmdletActivity
+ {
+ ///
+ /// Gets the display name of the command invoked by this activity.
+ ///
+ public GetCimInstance()
+ {
+ this.DisplayName = "Get-CimInstance";
+ }
+
+ ///
+ /// Gets the fully qualified name of the command invoked by this activity.
+ ///
+ public override string PSCommandName { get { return "CimCmdlets\\Get-CimInstance"; } }
+
+ ///
+ /// The .NET type implementing the cmdlet to invoke.
+ ///
+ public override System.Type TypeImplementingCmdlet { get { return typeof(Microsoft.Management.Infrastructure.CimCmdlets.GetCimInstanceCommand); } }
+
+ // Arguments
+
+ ///
+ /// Provides access to the ClassName parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument ClassName { get; set; }
+
+ ///
+ /// Provides access to the Filter parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument Filter { get; set; }
+
+ ///
+ /// Provides access to the KeyOnly parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument KeyOnly { get; set; }
+
+ ///
+ /// Provides access to the Namespace parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument Namespace { get; set; }
+
+ ///
+ /// Provides access to the OperationTimeoutSec parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument OperationTimeoutSec { get; set; }
+
+ ///
+ /// Provides access to the InputObject parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument InputObject { get; set; }
+
+ ///
+ /// Provides access to the Query parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument Query { get; set; }
+
+ ///
+ /// Provides access to the QueryDialect parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument QueryDialect { get; set; }
+
+ ///
+ /// Provides access to the Shallow parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument Shallow { get; set; }
+
+ ///
+ /// Provides access to the Property parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument Property { get; set; }
+
+ ///
+ /// Returns a configured instance of System.Management.Automation.PowerShell, pre-populated with the command to run.
+ ///
+ /// The NativeActivityContext for the currently running activity.
+ /// A populated instance of Sytem.Management.Automation.PowerShell
+ /// The infrastructure takes responsibility for closing and disposing the PowerShell instance returned.
+ protected override ActivityImplementationContext GetPowerShell(NativeActivityContext context)
+ {
+ System.Management.Automation.PowerShell invoker = global::System.Management.Automation.PowerShell.Create();
+ System.Management.Automation.PowerShell targetCommand = invoker.AddCommand(PSCommandName);
+
+ // Initialize the arguments
+
+ if(ClassName.Expression != null)
+ {
+ targetCommand.AddParameter("ClassName", ClassName.Get(context));
+ }
+
+ if (Filter.Expression != null)
+ {
+ targetCommand.AddParameter("Filter", Filter.Get(context));
+ }
+
+ if(KeyOnly.Expression != null)
+ {
+ targetCommand.AddParameter("KeyOnly", KeyOnly.Get(context));
+ }
+
+ if(Namespace.Expression != null)
+ {
+ targetCommand.AddParameter("Namespace", Namespace.Get(context));
+ }
+
+ if(OperationTimeoutSec.Expression != null)
+ {
+ targetCommand.AddParameter("OperationTimeoutSec", OperationTimeoutSec.Get(context));
+ }
+
+ if (InputObject.Expression != null)
+ {
+ targetCommand.AddParameter("InputObject", InputObject.Get(context));
+ }
+
+ if(Query.Expression != null)
+ {
+ targetCommand.AddParameter("Query", Query.Get(context));
+ }
+
+ if(QueryDialect.Expression != null)
+ {
+ targetCommand.AddParameter("QueryDialect", QueryDialect.Get(context));
+ }
+
+ if(Shallow.Expression != null)
+ {
+ targetCommand.AddParameter("Shallow", Shallow.Get(context));
+ }
+
+ if (Property.Expression != null)
+ {
+ targetCommand.AddParameter("Property", Property.Get(context));
+ }
+
+ if (ResourceUri != null)
+ {
+ targetCommand.AddParameter("ResourceUri", ResourceUri.Get(context));
+ }
+
+ return new ActivityImplementationContext() { PowerShellInstance = invoker };
+ }
+ }
+}
diff --git a/src/Microsoft.PowerShell.Activities/Activities/GetPSWorkflowData.cs b/src/Microsoft.PowerShell.Activities/Activities/GetPSWorkflowData.cs
new file mode 100644
index 0000000000..8fbc788d79
--- /dev/null
+++ b/src/Microsoft.PowerShell.Activities/Activities/GetPSWorkflowData.cs
@@ -0,0 +1,338 @@
+using System;
+using System.Activities;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Globalization;
+using System.Diagnostics.CodeAnalysis;
+using System.Management.Automation;
+using System.Management.Automation.Tracing;
+using System.ComponentModel;
+
+namespace Microsoft.PowerShell.Activities
+{
+
+ ///
+ ///
+ ///
+ public enum PSWorkflowRuntimeVariable
+ {
+ // Command Parameters
+ ///
+ ///
+ ///
+ PSComputerName = 0,
+ ///
+ ///
+ ///
+ PSCredential = 1,
+ ///
+ ///
+ ///
+ PSPort = 2,
+ ///
+ ///
+ ///
+ PSUseSsl = 3,
+ ///
+ ///
+ ///
+ PSConfigurationName = 4,
+ ///
+ ///
+ ///
+ PSApplicationName = 5,
+ ///
+ ///
+ ///
+ PSConnectionUri = 6,
+ ///
+ ///
+ ///
+ PSAllowRedirection = 7,
+ ///
+ ///
+ ///
+ PSSessionOption = 8,
+ ///
+ ///
+ ///
+ PSAuthentication = 9,
+ ///
+ ///
+ ///
+ PSAuthenticationLevel = 10,
+ ///
+ ///
+ ///
+ PSCertificateThumbprint = 11,
+ ///
+ ///
+ ///
+ Input = 13,
+ ///
+ ///
+ ///
+ Verbose = 15,
+
+ // Retry policy constants
+ ///
+ ///
+ ///
+ PSConnectionRetryCount = 19,
+ ///
+ ///
+ ///
+ PSConnectionRetryIntervalSec = 21,
+
+ ///
+ ///
+ ///
+ PSPrivateMetadata = 24,
+
+ // Timers
+ ///
+ ///
+ ///
+ PSRunningTimeoutSec = 27,
+ ///
+ ///
+ ///
+ PSElapsedTimeoutSec = 28,
+
+ ///
+ ///
+ ///
+ PSWorkflowRoot = 31,
+
+ ///
+ ///
+ ///
+ JobName = 32,
+ ///
+ ///
+ ///
+ JobInstanceId = 33,
+ ///
+ ///
+ ///
+ JobId = 34,
+
+ ///
+ ///
+ ///
+ JobCommandName = 36,
+
+ ///
+ ///
+ ///
+ ParentJobInstanceId = 40,
+
+ ///
+ ///
+ ///
+ ParentJobName = 41,
+
+ ///
+ ///
+ ///
+ ParentJobId = 42,
+
+ ///
+ ///
+ ///
+ ParentCommandName = 43,
+
+ ///
+ ///
+ ///
+ WorkflowInstanceId = 48,
+
+ ///
+ ///
+ ///
+ PSSenderInfo = 49,
+
+ ///
+ ///
+ ///
+ PSCulture = 50,
+
+ ///
+ ///
+ ///
+ [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly")]
+ PSUICulture = 51,
+
+ ///
+ ///
+ ///
+ PSVersionTable = 52,
+
+ ///
+ /// PSPersist
+ ///
+ PSPersist = 53,
+
+ ///
+ /// ErrorAction
+ ///
+ ErrorAction = 54,
+
+ ///
+ /// WarningAction
+ ///
+ WarningAction = 55,
+
+ ///
+ /// InformationAction
+ ///
+ InformationAction = 56,
+
+ ///
+ /// Tell the activity to look for a custom string
+ ///
+ Other = 1000,
+
+ ///
+ /// Return all values as a hashtable
+ ///
+ All = 1001,
+ }
+
+ ///
+ /// Activity to retrieve the value of a workflow runtime variable.
+ ///
+ public sealed class GetPSWorkflowData : NativeActivity
+ {
+ ///
+ /// The variable to retrieve.
+ ///
+ [RequiredArgument]
+ public PSWorkflowRuntimeVariable VariableToRetrieve
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// The variable to retrieve, if not included in the PSWorkflowRuntimeVariable enum.
+ ///
+ [DefaultValue(null)]
+ public InArgument OtherVariableName
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// Execute the logic for this activity...
+ ///
+ ///
+ protected override void Execute(NativeActivityContext context)
+ {
+ // Retrieve our host overrides
+ HostParameterDefaults hostValues = context.GetExtension();
+
+ PropertyDescriptorCollection col = context.DataContext.GetProperties();
+ string variableName = null;
+
+ if (VariableToRetrieve != PSWorkflowRuntimeVariable.Other)
+ {
+ // Get the symbolic name for the enum
+ variableName = LanguagePrimitives.ConvertTo(VariableToRetrieve);
+ }
+ else
+ {
+ if (OtherVariableName.Expression != null)
+ {
+ string value = OtherVariableName.Get(context);
+
+ if (!string.IsNullOrWhiteSpace(value))
+ {
+ variableName = value;
+ }
+ }
+ }
+
+ //BUGBUG need a better exception here, could also do this as a custom validator
+ // Make sure we have a variable here...
+ if (string.IsNullOrWhiteSpace(variableName))
+ {
+ throw new InvalidOperationException("OtherVariable");
+ }
+
+ object valueToReturn = null;
+ PSDataCollection outputStream = null;
+ foreach (System.ComponentModel.PropertyDescriptor property in context.DataContext.GetProperties())
+ {
+ if (string.Equals(property.Name, "ParameterDefaults", StringComparison.OrdinalIgnoreCase))
+ {
+ foreach (var parameter in ((Microsoft.PowerShell.Activities.HostParameterDefaults)property.GetValue(context.DataContext)).Parameters)
+ {
+ if (parameter.Key.Equals(variableName, StringComparison.OrdinalIgnoreCase))
+ {
+ valueToReturn = parameter.Value;
+ }
+ else if (parameter.Key.Equals("Result"))
+ {
+ outputStream = parameter.Value as PSDataCollection;
+ }
+ }
+
+ //
+ // If the property to return was all, then just return the entire collection as a hashtable.
+ // (We still needed to loop to find the output stream to write into.)
+ //
+ if (VariableToRetrieve == PSWorkflowRuntimeVariable.All)
+ {
+ System.Collections.Hashtable workflowRuntimeVariables = new System.Collections.Hashtable(StringComparer.OrdinalIgnoreCase);
+
+ string[] enumNames = VariableToRetrieve.GetType().GetEnumNames();
+
+ // Skipping last two enum names, Other and All, as they are not actual variable names
+ //
+ for (int i=0; i < (enumNames.Length - 2); i++)
+ {
+ workflowRuntimeVariables.Add(enumNames[i], null);
+ }
+
+ Dictionary dictionaryParam = ((Microsoft.PowerShell.Activities.HostParameterDefaults)property.GetValue(context.DataContext)).Parameters;
+
+ foreach(string varKey in dictionaryParam.Keys)
+ {
+ // We need to get the values of required runtime variables only, not evrything from DataContext parameters
+ //
+ if (workflowRuntimeVariables.ContainsKey(varKey))
+ {
+ Object value = null;
+ dictionaryParam.TryGetValue(varKey, out value);
+ workflowRuntimeVariables[varKey] = value;
+ }
+ }
+
+ valueToReturn = workflowRuntimeVariables;
+ }
+ break;
+ }
+ }
+
+ if (this.Result.Expression != null)
+ {
+ this.Result.Set(context, valueToReturn);
+ }
+ else if (outputStream != null)
+ {
+ if (valueToReturn != null)
+ {
+ outputStream.Add(PSObject.AsPSObject(valueToReturn));
+ }
+ }
+ else
+ {
+ //BUGBUG need a better exception here...
+ throw new InvalidOperationException("Result");
+ }
+ }
+ }
+}
diff --git a/src/Microsoft.PowerShell.Activities/Activities/InlineScript.cs b/src/Microsoft.PowerShell.Activities/Activities/InlineScript.cs
new file mode 100644
index 0000000000..767bf7b63b
--- /dev/null
+++ b/src/Microsoft.PowerShell.Activities/Activities/InlineScript.cs
@@ -0,0 +1,812 @@
+//
+// Copyright (C) Microsoft. All rights reserved.
+//
+using System;
+using System.Activities;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using System.Management.Automation;
+using System.Management.Automation.Language;
+using System.ComponentModel;
+using System.Text;
+using System.Reflection;
+
+namespace Microsoft.PowerShell.Activities
+{
+ ///
+ /// Activity to support the invocation of PowerShell script content in a Workflow.
+ ///
+#if _NOTARMBUILD_
+ [Designer(typeof(InlineScriptDesigner))]
+#endif
+ public sealed class InlineScript : PSRemotingActivity
+ {
+ ///
+ /// The script text to invoke.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public string Command
+ {
+ get { return _command; }
+ set
+ {
+ _command = value;
+ _commandSpecified = true;
+ }
+ }
+ private string _command;
+ private bool _commandSpecified;
+
+ ///
+ /// Name of the command to invoke
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument CommandName { get; set; }
+
+ ///
+ /// Parameters to invoke the command with.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument Parameters { get; set; }
+
+ ///
+ /// Declares that this activity supports its own remoting.
+ ///
+ protected override bool SupportsCustomRemoting { get { return true; } }
+
+ private ScriptBlock _compiledScriptForInProc;
+ private ScriptBlock _compiledScriptForOutProc;
+ private string _scriptWithoutUsing;
+ private HashSet _usingVariables;
+ // Remember the names of the variables/arguments that statically exist in the
+ // workflow context and potentially can be referenced by a using variable in
+ // an InlineScript. Those static variables/arguments include:
+ // 1. the default arguments of InlineScript and its parents
+ // 2. the workflow runtime variables
+ //
+ // This static set is used to decide whether to add the special prefix
+ // to a variable or not, when replacing a using variable.
+ private static readonly HashSet StaticPotentialUsingVariableSet = new HashSet(StringComparer.OrdinalIgnoreCase);
+ private const string VariablePrefix = "__PSUsingVariable_";
+
+
+ static InlineScript()
+ {
+ PopulatePotentialUsingVariableStaticSet();
+ }
+
+ private static void PopulatePotentialUsingVariableStaticSet()
+ {
+ var namesToExclude = new HashSet(StringComparer.OrdinalIgnoreCase)
+ {
+ // from inlinescript common arguments
+ "Result", "PSError", "PSWarning", "PSVerbose", "PSDebug", "PSProgress", "PSInformation",
+
+ // from workflow runtime variables
+ "Other", "All",
+
+ // some workflow variables/arguments conflict with the built-in powershell variables, including:
+ // Input, PSSessionOption, PSCulture, PSUICulture, PSVersionTable
+ //
+ // per discussion with Hemant and Rahim, we want to:
+ // 1. treat $using:input, $using:PSSessionOption, $using:PSCulture, and $using:PSUICulture as workflow
+ // variable; add the special prefix when replacing 'using'.
+ // 2. treat PSVersionTable as powershell variable, so never add special prefix to it.
+ "PSVersionTable"
+ };
+
+ // Handle InlineScript activity common arguments
+ foreach (string argumentName in GetInlineScriptActivityArguments())
+ {
+ if (namesToExclude.Contains(argumentName)) { continue; }
+ if (!StaticPotentialUsingVariableSet.Contains(argumentName))
+ {
+ StaticPotentialUsingVariableSet.Add(argumentName);
+ }
+ }
+
+ // Handle workflow runtime variables
+ var wfRuntimeVariables = typeof(PSWorkflowRuntimeVariable).GetEnumNames();
+ foreach (string variableName in wfRuntimeVariables)
+ {
+ if (namesToExclude.Contains(variableName)) { continue; }
+ if (!StaticPotentialUsingVariableSet.Contains(variableName))
+ {
+ StaticPotentialUsingVariableSet.Add(variableName);
+ }
+ }
+ }
+
+ // Use the same logic as the PSActivity.GetActivityArguments to retrieve the names of all default
+ // arguments from the InlineScript and its parents
+ internal static IEnumerable GetInlineScriptActivityArguments()
+ {
+ Type activityType = typeof(InlineScript);
+
+ while (activityType != null)
+ {
+ // We don't want to support parameter defaults for arguments on
+ // concrete types (as they almost guaranteed to collide with other types),
+ // but base classes make sense.
+ if (activityType.IsAbstract)
+ {
+ // Populate any parameter defaults. We only look at fields that are defined on this
+ // specific type (as opposed to derived types) so that we don't make assumptions about
+ // other activities and their defaults.
+ foreach (PropertyInfo field in activityType.GetProperties())
+ {
+ // See if it's an argument
+ if (typeof(Argument).IsAssignableFrom(field.PropertyType))
+ {
+ // Get the argument name
+ yield return field.Name;
+ }
+ }
+ }
+
+ // Go to our base type, but stop when we go above PSActivity
+ activityType = activityType.BaseType;
+ if (!typeof(PSActivity).IsAssignableFrom(activityType))
+ activityType = null;
+ }
+ }
+
+ ///
+ /// Validates the contents of the script block for this command.
+ ///
+ /// Metatdata for this activity
+ protected override void CacheMetadata(NativeActivityMetadata metadata)
+ {
+ base.CacheMetadata(metadata);
+
+ if (! string.IsNullOrWhiteSpace(Command))
+ {
+ Token[] tokens;
+ ParseError[] errors;
+ Parser.ParseInput(Command, out tokens, out errors);
+ if (errors != null && errors.Length > 0)
+ {
+ string compositeErrorString = "";
+ foreach (var e in errors)
+ {
+ // Format and add each error message...
+ compositeErrorString += string.Format(CultureInfo.InvariantCulture,
+ "[{0}, {1}]: {2}\n", e.Extent.StartLineNumber, e.Extent.StartColumnNumber, e.Message);
+ }
+ metadata.AddValidationError(compositeErrorString);
+ }
+ }
+ }
+
+ ///
+ /// Indicates if preference variables need to be updated
+ ///
+ protected override bool UpdatePreferenceVariable
+ {
+ get { return false; }
+ }
+
+ ///
+ /// Returns a configured instance of System.Management.Automation.PowerShell, pre-populated with the script to run.
+ ///
+ /// The NativeActivityContext for the currently running activity.
+ /// A populated instance of Sytem.Management.Automation.PowerShell
+ /// The infrastructure takes responsibility for closing and disposing the PowerShell instance returned.
+ [System.Diagnostics.CodeAnalysis.SuppressMessage(
+ "Microsoft.Reliability",
+ "CA2000:Dispose objects before losing scope",
+ Justification = "Disposed by the infrastructure.")]
+ protected override ActivityImplementationContext GetPowerShell(NativeActivityContext context)
+ {
+ ValidateParameters();
+ System.Management.Automation.PowerShell invoker = null;
+ HashSet allWorkflowVarNames = new HashSet(StaticPotentialUsingVariableSet, StringComparer.OrdinalIgnoreCase);
+ Dictionary defaults = this.ParameterDefaults.Get(context);
+ Dictionary activityVariables = new Dictionary(StringComparer.OrdinalIgnoreCase);
+ Dictionary activityUsingVariables = new Dictionary(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 collectionObject = value as PSDataCollection;
+
+ 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;
+ }
+
+ private void SetAvailableUsingVariables(Dictionary allActivityVariables, Dictionary activityUsingVariables)
+ {
+ if (_usingVariables == null) { return; }
+
+ foreach (string varName in _usingVariables)
+ {
+ object value;
+ string varNameToUse = VariablePrefix + varName;
+ if (allActivityVariables.TryGetValue(varName, out value) && !activityUsingVariables.ContainsKey(varNameToUse))
+ {
+ activityUsingVariables.Add(varNameToUse, value);
+ }
+ }
+ }
+
+ private void ValidateParameters()
+ {
+ if (_commandSpecified)
+ {
+ if (CommandName.Expression != null || Parameters.Expression != null)
+ {
+ throw new ArgumentException(ActivityResources.CannotSpecifyBothCommandAndCommandName);
+ }
+ }
+ else
+ {
+ if (CommandName.Expression == null)
+ {
+ throw new ArgumentException(ActivityResources.CannotSpecifyBothCommandAndCommandName);
+ }
+ }
+ }
+
+ ///
+ /// Checks if the script is blocked
+ ///
+ ///
+ private bool IsBlocked(string script)
+ {
+ string[] psUnsupportedConsoleApplications = new string[]
+ {
+ "cmd",
+ "cmd.exe",
+ "diskpart",
+ "diskpart.exe",
+ "edit.com",
+ "netsh",
+ "netsh.exe",
+ "nslookup",
+ "nslookup.exe",
+ "powershell",
+ "powershell.exe",
+ };
+
+ foreach (string app in psUnsupportedConsoleApplications)
+ {
+ if (script.Equals(app, StringComparison.OrdinalIgnoreCase))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ #region "Using variable utility"
+
+ ///
+ /// Remove the "Using" prefix for all UsingExpressionAsts that appear in the given script
+ ///
+ /// script text
+ /// all workflow variables/arguments that potentially can be referred by a using variable
+ /// names of the variables in the script that have the "Using" prefix
+ ///
+ /// Return script if the script text is empty string or null
+ /// Return script if there are errors when parsing the script text
+ /// Return script if there is no UsingExpressionAst in the given script
+ /// Return a new script text that has all the "Using" prefixes removed
+ ///
+ private static string RemoveUsingPrefix(string script, HashSet allWorkflowVariables, out HashSet usingVariables)
+ {
+ usingVariables = new HashSet(StringComparer.OrdinalIgnoreCase);
+ var usingAsts = GetUsingExpressionAsts(script);
+ if (usingAsts == null || !usingAsts.Any()) { return script; }
+
+ StringBuilder newScript = null;
+ int startOffset = 0;
+ foreach (Ast ast in usingAsts)
+ {
+ var usingAst = ast as UsingExpressionAst;
+ if (usingAst == null) { continue; }
+
+ VariableExpressionAst variableAst = UsingExpressionAst.ExtractUsingVariable(usingAst);
+ if (variableAst == null) { continue; }
+
+ if (newScript == null)
+ {
+ newScript = new StringBuilder();
+ }
+
+ string varName = variableAst.VariablePath.UserPath;
+ string varSign = variableAst.Splatted ? "@" : "$";
+ bool needPrefix = allWorkflowVariables.Contains(varName);
+ string newVar = needPrefix ? (varSign + VariablePrefix + varName) : (varSign + varName);
+
+ // Add those variable names that potentially refer to workflow variables/arguments
+ if (needPrefix && !usingVariables.Contains(varName))
+ {
+ usingVariables.Add(varName);
+ }
+
+ newScript.Append(script.Substring(startOffset, variableAst.Extent.StartOffset - startOffset));
+ newScript.Append(newVar);
+ startOffset = variableAst.Extent.EndOffset;
+ }
+
+ if (newScript != null)
+ {
+ newScript.Append(script.Substring(startOffset));
+ return newScript.ToString();
+ }
+
+ return script;
+ }
+
+ ///
+ /// Get the UsingExpressionAsts out of a script
+ ///
+ ///
+ /// a list of UsingExpressionAsts ordered by the StartOffset
+ private static IEnumerable GetUsingExpressionAsts(string script)
+ {
+ if (String.IsNullOrEmpty(script))
+ {
+ return null;
+ }
+
+ ParseError[] errors;
+ Token[] tokens;
+ ScriptBlockAst scriptAst = Parser.ParseInput(script, out tokens, out errors);
+ if (errors.Length != 0)
+ {
+ return null;
+ }
+
+ var list = scriptAst.FindAll(ast => ast is UsingExpressionAst, searchNestedScriptBlocks: true).ToList();
+ if (list.Count > 1)
+ {
+ return list.OrderBy(a => a.Extent.StartOffset);
+ }
+ return list;
+ }
+
+ #endregion "Using variable utility"
+
+ ///
+ /// Adds the PSActivity variable to the active runspace, which is of type InlineScriptContext.
+ ///
+ /// The ActivityImplementationContext returned by the call to GetCommand.
+ protected override void PrepareSession(ActivityImplementationContext implementationContext)
+ {
+ if (implementationContext.PSActivityEnvironment == null)
+ {
+ implementationContext.PSActivityEnvironment = new PSActivityEnvironment();
+ }
+
+ // Update the preference variables
+ UpdatePreferenceVariables(implementationContext);
+ System.Management.Automation.PowerShell session = implementationContext.PowerShellInstance;
+
+ implementationContext.PSActivityEnvironment.Variables["UserName"] = System.Environment.UserName;
+
+ string computerName = null;
+ if (implementationContext.ConnectionInfo != null)
+ {
+ computerName = implementationContext.ConnectionInfo.ComputerName;
+ }
+ if (string.IsNullOrEmpty(computerName))
+ {
+ computerName = "localhost";
+ }
+
+ implementationContext.PSActivityEnvironment.Variables["ComputerName"] = computerName;
+ implementationContext.PSActivityEnvironment.Variables["PSComputerName"] = computerName;
+
+ string workflowCommandName = null;
+
+ Dictionary activityVariables = (Dictionary)implementationContext.WorkflowContext;
+ if (activityVariables != null && activityVariables.ContainsKey("ParameterDefaults"))
+ {
+ HostParameterDefaults defaults = activityVariables["ParameterDefaults"] as HostParameterDefaults;
+ if (defaults != null)
+ {
+ workflowCommandName = defaults.Parameters["WorkflowCommandName"] as string;
+ }
+ }
+
+ if (string.IsNullOrEmpty(workflowCommandName))
+ {
+ workflowCommandName = "unknown";
+ }
+
+ implementationContext.PSActivityEnvironment.Variables["CommandName"] = workflowCommandName;
+
+ // Populate the default variables
+ InlineScriptContext inlineScriptContext = new InlineScriptContext(this);
+
+ // Populate the activity variables
+ foreach (KeyValuePair entry in activityVariables)
+ {
+ if (String.Equals(entry.Key, "ParameterDefaults", StringComparison.OrdinalIgnoreCase))
+ {
+ System.Diagnostics.Debug.Assert(entry.Value is HostParameterDefaults, "ParameterDefaults does not contain a HostParameterDefaults object");
+ inlineScriptContext.Variables[entry.Key] = ((HostParameterDefaults)entry.Value).Parameters;
+ continue;
+ }
+ inlineScriptContext.Variables[entry.Key] = entry.Value;
+ }
+
+ // Set the PowerShell session variables...
+ foreach (KeyValuePair entry in activityVariables)
+ {
+ var value = entry.Value;
+
+ if (String.Equals(entry.Key, "ParameterDefaults", StringComparison.OrdinalIgnoreCase))
+ continue;
+ implementationContext.PSActivityEnvironment.Variables[entry.Key] = value;
+ }
+ }
+
+ // InlineScript needs to handle these specially, since it might go through the PowerShell AddScript() API.
+ // If the parameter "CommandName" is in use, we add the preference configuration to the command parameters,
+ // otherwise, we add the preference configuration to the preference variable.
+ // All other activities have this set automatically by the infrastructure via parameters.
+ private void UpdatePreferenceVariables(ActivityImplementationContext implementationContext)
+ {
+ System.Management.Automation.PowerShell session = implementationContext.PowerShellInstance;
+ System.Management.Automation.Runspaces.Command command = null;
+
+ if (!_commandSpecified)
+ {
+ // "CommandName" and "Parameters" are in use
+ command = session.Commands.Commands[0];
+ }
+
+ if (implementationContext.Verbose != null)
+ {
+ if (command != null)
+ {
+ command.Parameters.Add("Verbose", implementationContext.Verbose);
+ }
+ else
+ {
+ // Map the boolean / switch to an actual action preference
+ ActionPreference preference = ActionPreference.SilentlyContinue;
+
+ if (implementationContext.Verbose.Value)
+ preference = ActionPreference.Continue;
+
+ implementationContext.PSActivityEnvironment.Variables["VerbosePreference"] = preference;
+ }
+ }
+
+ if (implementationContext.Debug != null)
+ {
+ if (command != null)
+ {
+ command.Parameters.Add("Debug", implementationContext.Debug);
+ }
+ else
+ {
+ // Map the boolean / switch to an actual action preference
+ ActionPreference preference = ActionPreference.SilentlyContinue;
+
+ if (implementationContext.Debug.Value)
+ preference = ActionPreference.Continue;
+
+ implementationContext.PSActivityEnvironment.Variables["DebugPreference"] = preference;
+ }
+ }
+
+ if (implementationContext.WhatIf != null && command != null)
+ {
+ command.Parameters.Add("WhatIf", implementationContext.WhatIf);
+ }
+
+ if (implementationContext.ErrorAction != null)
+ {
+ if (command != null)
+ {
+ command.Parameters.Add("ErrorAction", implementationContext.ErrorAction);
+ }
+ else
+ {
+ implementationContext.PSActivityEnvironment.Variables["ErrorActionPreference"] = implementationContext.ErrorAction;
+ }
+ }
+
+ if (implementationContext.WarningAction != null)
+ {
+ if (command != null)
+ {
+ command.Parameters.Add("WarningAction", implementationContext.WarningAction);
+ }
+ else
+ {
+ implementationContext.PSActivityEnvironment.Variables["WarningPreference"] = implementationContext.WarningAction;
+ }
+ }
+
+ if (implementationContext.InformationAction != null)
+ {
+ if (command != null)
+ {
+ command.Parameters.Add("InformationAction", implementationContext.InformationAction);
+ }
+ else
+ {
+ implementationContext.PSActivityEnvironment.Variables["InformationPreference"] = implementationContext.InformationAction;
+ }
+ }
+
+ }
+
+ static CommandInfo _ci;
+ static readonly object Syncroot = new object();
+ }
+
+ ///
+ /// Defines the context information available to scripts running within the
+ /// InlineScript activity. These are exposed through the $PSActivity automatic
+ /// variable.
+ ///
+ public class InlineScriptContext
+ {
+ ///
+ /// Creates a new InlineScriptContext
+ ///
+ /// The InlineScript activity being invoked
+ public InlineScriptContext(InlineScript current)
+ {
+ this.current = current;
+ this.variables = new Dictionary(StringComparer.OrdinalIgnoreCase);
+ this.current = null;
+ }
+
+ ///
+ /// Gets the current InlineScript activity being invoked.
+ ///
+ //public InlineScript Current
+ //{
+ // get { return current; }
+ //}
+ private InlineScript current;
+
+ ///
+ /// Gets the current variables and arguments that are in-scope for
+ /// the current activity within its context in the workflow.
+ ///
+ public Dictionary Variables
+ {
+ get { return variables; }
+ }
+ private Dictionary variables;
+ }
+
+ ///
+ /// Suspends the current workflow.
+ ///
+ public class Suspend : NativeActivity
+ {
+ ///
+ /// Optional field used for resuming the worklfow for a specific label.
+ ///
+ public string Label { get; set; }
+
+ ///
+ /// Returns true if the activity can induce an idle.
+ ///
+ protected override bool CanInduceIdle { get { return true; } }
+
+ ///
+ /// Invokes the activity
+ ///
+ /// The activity context.
+ /// True if the given argument is set.
+ protected override void Execute(NativeActivityContext context)
+ {
+ string bookmarkname = string.IsNullOrEmpty(this.Label) ?
+ PSActivity.PSSuspendBookmarkPrefix :
+ PSActivity.PSSuspendBookmarkPrefix + this.Label + "_";
+
+ bookmarkname += Guid.NewGuid().ToString().Replace("-", "_");
+
+ context.CreateBookmark(bookmarkname, BookmarkResumed);
+ }
+
+ private void BookmarkResumed(NativeActivityContext context, Bookmark bookmark, object value)
+ {
+ }
+ }
+}
diff --git a/src/Microsoft.PowerShell.Activities/Activities/InlineScriptDesigner.xaml.cs b/src/Microsoft.PowerShell.Activities/Activities/InlineScriptDesigner.xaml.cs
new file mode 100644
index 0000000000..a8580782e1
--- /dev/null
+++ b/src/Microsoft.PowerShell.Activities/Activities/InlineScriptDesigner.xaml.cs
@@ -0,0 +1,35 @@
+//
+// Copyright (C) Microsoft. All rights reserved.
+//
+#if _NOTARMBUILD_
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace Microsoft.PowerShell.Activities
+{
+ ///
+ /// Interaction logic for InlineScriptDesigner.xaml
+ ///
+ public partial class InlineScriptDesigner
+ {
+ ///
+ /// Create the designer instance
+ ///
+ public InlineScriptDesigner()
+ {
+ InitializeComponent();
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/Microsoft.PowerShell.Activities/Activities/InvokeCimMethodActivity.cs b/src/Microsoft.PowerShell.Activities/Activities/InvokeCimMethodActivity.cs
new file mode 100644
index 0000000000..b818ffba9c
--- /dev/null
+++ b/src/Microsoft.PowerShell.Activities/Activities/InvokeCimMethodActivity.cs
@@ -0,0 +1,170 @@
+
+using Microsoft.PowerShell.Activities;
+using System.Activities;
+using System.Collections.Generic;
+using System.ComponentModel;
+
+
+namespace Microsoft.PowerShell.Activities
+{
+ ///
+ /// Activity to invoke the CimCmdlets\Invoke-CimMethod command in a Workflow.
+ ///
+ [System.CodeDom.Compiler.GeneratedCode("Microsoft.PowerShell.Activities.ActivityGenerator.GenerateFromName", "3.0")]
+ public sealed class InvokeCimMethod : GenericCimCmdletActivity
+ {
+ ///
+ /// Gets the display name of the command invoked by this activity.
+ ///
+ public InvokeCimMethod()
+ {
+ this.DisplayName = "Invoke-CimMethod";
+ }
+
+ ///
+ /// Gets the fully qualified name of the command invoked by this activity.
+ ///
+ public override string PSCommandName { get { return "CimCmdlets\\Invoke-CimMethod"; } }
+
+ ///
+ /// The .NET type implementing the cmdlet to invoke.
+ ///
+ public override System.Type TypeImplementingCmdlet { get { return typeof(Microsoft.Management.Infrastructure.CimCmdlets.InvokeCimMethodCommand); } }
+
+ // Arguments
+
+ ///
+ /// Provides access to the ClassName parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument ClassName { get; set; }
+
+ ///
+ /// Provides access to the CimClass parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument CimClass { get; set; }
+
+ ///
+ /// Provides access to the Query parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument Query { get; set; }
+
+ ///
+ /// Provides access to the QueryDialect parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument QueryDialect { get; set; }
+
+ ///
+ /// Provides access to the InputObject parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument InputObject { get; set; }
+
+ ///
+ /// Provides access to the Arguments parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument Arguments { get; set; }
+
+ ///
+ /// Provides access to the MethodName parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument MethodName { get; set; }
+
+ ///
+ /// Provides access to the Namespace parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument Namespace { get; set; }
+
+ ///
+ /// Provides access to the OperationTimeoutSec parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument OperationTimeoutSec { get; set; }
+
+ ///
+ /// Script module contents for this activity
+ ///
+ protected override string PSDefiningModule { get { return null; } }
+
+ ///
+ /// Returns a configured instance of System.Management.Automation.PowerShell, pre-populated with the command to run.
+ ///
+ /// The NativeActivityContext for the currently running activity.
+ /// A populated instance of Sytem.Management.Automation.PowerShell
+ /// The infrastructure takes responsibility for closing and disposing the PowerShell instance returned.
+ protected override ActivityImplementationContext GetPowerShell(NativeActivityContext context)
+ {
+ System.Management.Automation.PowerShell invoker = global::System.Management.Automation.PowerShell.Create();
+ System.Management.Automation.PowerShell targetCommand = invoker.AddCommand(PSCommandName);
+
+ // Initialize the arguments
+
+ if(ClassName.Expression != null)
+ {
+ targetCommand.AddParameter("ClassName", ClassName.Get(context));
+ }
+
+ if(CimClass.Expression != null)
+ {
+ targetCommand.AddParameter("CimClass", CimClass.Get(context));
+ }
+
+ if(Query.Expression != null)
+ {
+ targetCommand.AddParameter("Query", Query.Get(context));
+ }
+
+ if(QueryDialect.Expression != null)
+ {
+ targetCommand.AddParameter("QueryDialect", QueryDialect.Get(context));
+ }
+
+ if (InputObject.Expression != null)
+ {
+ targetCommand.AddParameter("InputObject", InputObject.Get(context));
+ }
+
+ if(Arguments.Expression != null)
+ {
+ targetCommand.AddParameter("Arguments", Arguments.Get(context));
+ }
+
+ if(MethodName.Expression != null)
+ {
+ targetCommand.AddParameter("MethodName", MethodName.Get(context));
+ }
+
+ if(Namespace.Expression != null)
+ {
+ targetCommand.AddParameter("Namespace", Namespace.Get(context));
+ }
+
+ if(OperationTimeoutSec.Expression != null)
+ {
+ targetCommand.AddParameter("OperationTimeoutSec", OperationTimeoutSec.Get(context));
+ }
+
+ if (ResourceUri != null)
+ {
+ targetCommand.AddParameter("ResourceUri", ResourceUri.Get(context));
+ }
+
+ return new ActivityImplementationContext() { PowerShellInstance = invoker };
+ }
+ }
+}
diff --git a/src/Microsoft.PowerShell.Activities/Activities/IsArgumentSet.cs b/src/Microsoft.PowerShell.Activities/Activities/IsArgumentSet.cs
new file mode 100644
index 0000000000..f1e1365589
--- /dev/null
+++ b/src/Microsoft.PowerShell.Activities/Activities/IsArgumentSet.cs
@@ -0,0 +1,41 @@
+//
+// Copyright (C) Microsoft. All rights reserved.
+//
+using System;
+using System.Activities;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using System.Management.Automation;
+using System.Management.Automation.Language;
+using System.ComponentModel;
+using System.Text;
+using System.Reflection;
+
+namespace Microsoft.PowerShell.Activities.Internal
+{
+ ///
+ /// Determines whether an argument to a PSActivity activity
+ /// has been set.
+ ///
+ [SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes", Justification = "Needed Internal use only")]
+ public class IsArgumentSet : CodeActivity
+ {
+ ///
+ /// The argument to investigate.
+ ///
+ [DefaultValue(null)]
+ public Argument Argument { get; set; }
+
+ ///
+ /// Invokes the activity
+ ///
+ /// The activity context.
+ /// True if the given argument is set.
+ protected override bool Execute(CodeActivityContext context)
+ {
+ return Argument != null && Argument.Expression != null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.PowerShell.Activities/Activities/NewCimInstanceActivity.cs b/src/Microsoft.PowerShell.Activities/Activities/NewCimInstanceActivity.cs
new file mode 100644
index 0000000000..04745a5b06
--- /dev/null
+++ b/src/Microsoft.PowerShell.Activities/Activities/NewCimInstanceActivity.cs
@@ -0,0 +1,163 @@
+
+using Microsoft.PowerShell.Activities;
+using System.Activities;
+using System.Collections.Generic;
+using System.ComponentModel;
+
+
+namespace Microsoft.PowerShell.Activities
+{
+ ///
+ /// Activity to invoke the CimCmdlets\New-CimInstance command in a Workflow.
+ ///
+ [System.CodeDom.Compiler.GeneratedCode("Microsoft.PowerShell.Activities.ActivityGenerator.GenerateFromName", "3.0")]
+ public sealed class NewCimInstance : GenericCimCmdletActivity
+ {
+ ///
+ /// Gets the display name of the command invoked by this activity.
+ ///
+ public NewCimInstance()
+ {
+ this.DisplayName = "New-CimInstance";
+ }
+
+ ///
+ /// Gets the fully qualified name of the command invoked by this activity.
+ ///
+ public override string PSCommandName { get { return "CimCmdlets\\New-CimInstance"; } }
+
+ ///
+ /// The .NET type implementing the cmdlet to invoke.
+ ///
+ public override System.Type TypeImplementingCmdlet { get { return typeof(Microsoft.Management.Infrastructure.CimCmdlets.NewCimInstanceCommand); } }
+
+ // Arguments
+
+ ///
+ /// Provides access to the ClassName parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument ClassName { get; set; }
+
+ ///
+ /// Provides access to the Key parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument Key { get; set; }
+
+ ///
+ /// Provides access to the CimClass parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument CimClass { get; set; }
+
+ ///
+ /// Provides access to the Property parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument Property { get; set; }
+
+ ///
+ /// Provides access to the Namespace parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument Namespace { get; set; }
+
+ ///
+ /// Provides access to the OperationTimeoutSec parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument OperationTimeoutSec { get; set; }
+
+
+ ///
+ /// Provides access to the ClientOnly parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument ClientOnly { get; set; }
+
+ ///
+ /// Script module contents for this activity`n///
+ protected override string PSDefiningModule { get { return null; } }
+
+ ///
+ /// Returns a configured instance of System.Management.Automation.PowerShell, pre-populated with the command to run.
+ ///
+ /// The NativeActivityContext for the currently running activity.
+ /// A populated instance of Sytem.Management.Automation.PowerShell
+ /// The infrastructure takes responsibility for closing and disposing the PowerShell instance returned.
+ protected override ActivityImplementationContext GetPowerShell(NativeActivityContext context)
+ {
+ System.Management.Automation.PowerShell invoker = global::System.Management.Automation.PowerShell.Create();
+ System.Management.Automation.PowerShell targetCommand = invoker.AddCommand(PSCommandName);
+
+ // Initialize the arguments
+
+ if(ClassName.Expression != null)
+ {
+ targetCommand.AddParameter("ClassName", ClassName.Get(context));
+ }
+
+ if(Key.Expression != null)
+ {
+ targetCommand.AddParameter("Key", Key.Get(context));
+ }
+
+ if(CimClass.Expression != null)
+ {
+ targetCommand.AddParameter("CimClass", CimClass.Get(context));
+ }
+
+ if(Property.Expression != null)
+ {
+ targetCommand.AddParameter("Property", Property.Get(context));
+ }
+
+ if(Namespace.Expression != null)
+ {
+ targetCommand.AddParameter("Namespace", Namespace.Get(context));
+ }
+
+ if(OperationTimeoutSec.Expression != null)
+ {
+ targetCommand.AddParameter("OperationTimeoutSec", OperationTimeoutSec.Get(context));
+ }
+
+ if (ResourceUri != null)
+ {
+ targetCommand.AddParameter("ResourceUri", ResourceUri.Get(context));
+ }
+
+ if (ClientOnly.Expression != null)
+ {
+ // Retrieve our host overrides
+ var hostValues = context.GetExtension();
+ string[] computerName = null;
+
+ if (hostValues != null)
+ {
+ Dictionary incomingArguments = hostValues.Parameters;
+ if (incomingArguments.ContainsKey("PSComputerName"))
+ {
+ computerName = incomingArguments["PSComputerName"] as string[];
+ }
+ }
+
+ if (computerName == null)
+ {
+ targetCommand.AddParameter("ClientOnly", ClientOnly.Get(context));
+ }
+ }
+
+
+ return new ActivityImplementationContext() { PowerShellInstance = invoker };
+ }
+ }
+}
diff --git a/src/Microsoft.PowerShell.Activities/Activities/NewCimSessionActivity.cs b/src/Microsoft.PowerShell.Activities/Activities/NewCimSessionActivity.cs
new file mode 100644
index 0000000000..59bf6502ce
--- /dev/null
+++ b/src/Microsoft.PowerShell.Activities/Activities/NewCimSessionActivity.cs
@@ -0,0 +1,148 @@
+
+using Microsoft.PowerShell.Activities;
+using System.Activities;
+using System.Collections.Generic;
+using System.ComponentModel;
+
+
+namespace Microsoft.PowerShell.Activities
+{
+ ///
+ /// Activity to invoke the CimCmdlets\New-CimSession command in a Workflow.
+ ///
+ [System.CodeDom.Compiler.GeneratedCode("Microsoft.PowerShell.Activities.ActivityGenerator.GenerateFromName", "3.0")]
+ public sealed class NewCimSession : GenericCimCmdletActivity
+ {
+ ///
+ /// Gets the display name of the command invoked by this activity.
+ ///
+ public NewCimSession()
+ {
+ this.DisplayName = "New-CimSession";
+ }
+
+ ///
+ /// Gets the fully qualified name of the command invoked by this activity.
+ ///
+ public override string PSCommandName { get { return "CimCmdlets\\New-CimSession"; } }
+
+ ///
+ /// The .NET type implementing the cmdlet to invoke.
+ ///
+ public override System.Type TypeImplementingCmdlet { get { return typeof(Microsoft.Management.Infrastructure.CimCmdlets.NewCimSessionCommand); } }
+
+ // Arguments
+
+ ///
+ /// Provides access to the Authentication parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument Authentication { get; set; }
+
+ ///
+ /// Provides access to the Credential parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument Credential { get; set; }
+
+ ///
+ /// Provides access to the CertificateThumbprint parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument CertificateThumbprint { get; set; }
+
+ ///
+ /// Provides access to the Name parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument Name { get; set; }
+
+ ///
+ /// Provides access to the OperationTimeoutSec parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument OperationTimeoutSec { get; set; }
+
+ ///
+ /// Provides access to the Port parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument Port { get; set; }
+
+ ///
+ /// Provides access to the SessionOption parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument SessionOption { get; set; }
+
+
+
+ ///
+ /// Script module contents for this activity`n///
+ protected override string PSDefiningModule { get { return "CimCmdlets"; } }
+
+ ///
+ /// Returns a configured instance of System.Management.Automation.PowerShell, pre-populated with the command to run.
+ ///
+ /// The NativeActivityContext for the currently running activity.
+ /// A populated instance of Sytem.Management.Automation.PowerShell
+ /// The infrastructure takes responsibility for closing and disposing the PowerShell instance returned.
+ protected override ActivityImplementationContext GetPowerShell(NativeActivityContext context)
+ {
+ System.Management.Automation.PowerShell invoker = global::System.Management.Automation.PowerShell.Create();
+ System.Management.Automation.PowerShell targetCommand = invoker.AddCommand(PSCommandName);
+
+ // Initialize the arguments
+
+ if (GetIsComputerNameSpecified(context))
+ {
+ targetCommand.AddParameter("ComputerName", PSComputerName.Get(context));
+ }
+
+ if(Authentication.Expression != null)
+ {
+ targetCommand.AddParameter("Authentication", Authentication.Get(context));
+ }
+
+ if(Credential.Expression != null)
+ {
+ targetCommand.AddParameter("Credential", Credential.Get(context));
+ }
+
+ if(CertificateThumbprint.Expression != null)
+ {
+ targetCommand.AddParameter("CertificateThumbprint", CertificateThumbprint.Get(context));
+ }
+
+ if(Name.Expression != null)
+ {
+ targetCommand.AddParameter("Name", Name.Get(context));
+ }
+
+ if(OperationTimeoutSec.Expression != null)
+ {
+ targetCommand.AddParameter("OperationTimeoutSec", OperationTimeoutSec.Get(context));
+ }
+
+ if(Port.Expression != null)
+ {
+ targetCommand.AddParameter("Port", Port.Get(context));
+ }
+
+ if(SessionOption.Expression != null)
+ {
+ targetCommand.AddParameter("SessionOption", SessionOption.Get(context));
+ }
+
+
+ return new ActivityImplementationContext() { PowerShellInstance = invoker };
+ }
+ }
+}
diff --git a/src/Microsoft.PowerShell.Activities/Activities/NewCimSessionOptionActivity.cs b/src/Microsoft.PowerShell.Activities/Activities/NewCimSessionOptionActivity.cs
new file mode 100644
index 0000000000..6eca4892c9
--- /dev/null
+++ b/src/Microsoft.PowerShell.Activities/Activities/NewCimSessionOptionActivity.cs
@@ -0,0 +1,286 @@
+
+using Microsoft.PowerShell.Activities;
+using System.Activities;
+using System.Collections.Generic;
+using System.ComponentModel;
+
+
+namespace Microsoft.PowerShell.Activities
+{
+ ///
+ /// Activity to invoke the CimCmdlets\New-CimSessionOption command in a Workflow.
+ ///
+ [System.CodeDom.Compiler.GeneratedCode("Microsoft.PowerShell.Activities.ActivityGenerator.GenerateFromName", "3.0")]
+ public sealed class NewCimSessionOption : GenericCimCmdletActivity
+ {
+ ///
+ /// Gets the display name of the command invoked by this activity.
+ ///
+ public NewCimSessionOption()
+ {
+ this.DisplayName = "New-CimSessionOption";
+ }
+
+ ///
+ /// Gets the fully qualified name of the command invoked by this activity.
+ ///
+ public override string PSCommandName { get { return "CimCmdlets\\New-CimSessionOption"; } }
+
+ ///
+ /// The .NET type implementing the cmdlet to invoke.
+ ///
+ public override System.Type TypeImplementingCmdlet { get { return typeof(Microsoft.Management.Infrastructure.CimCmdlets.NewCimSessionOptionCommand); } }
+
+ // Arguments
+
+ ///
+ /// Provides access to the NoEncryption parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument NoEncryption { get; set; }
+
+ ///
+ /// Provides access to the CertificateCACheck parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument CertificateCACheck { get; set; }
+
+ ///
+ /// Provides access to the CertificateCNCheck parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument CertificateCNCheck { get; set; }
+
+ ///
+ /// Provides access to the CertRevocationCheck parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument CertRevocationCheck { get; set; }
+
+ ///
+ /// Provides access to the EncodePortInServicePrincipalName parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument EncodePortInServicePrincipalName { get; set; }
+
+ ///
+ /// Provides access to the Encoding parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument Encoding { get; set; }
+
+ ///
+ /// Provides access to the HttpPrefix parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument HttpPrefix { get; set; }
+
+ ///
+ /// Provides access to the MaxEnvelopeSizeKB parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument MaxEnvelopeSizeKB { get; set; }
+
+ ///
+ /// Provides access to the ProxyAuthentication parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument ProxyAuthentication { get; set; }
+
+ ///
+ /// Provides access to the ProxyCertificateThumbprint parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument ProxyCertificateThumbprint { get; set; }
+
+ ///
+ /// Provides access to the ProxyCredential parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument ProxyCredential { get; set; }
+
+ ///
+ /// Provides access to the ProxyType parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument ProxyType { get; set; }
+
+ ///
+ /// Provides access to the UseSsl parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument UseSsl { get; set; }
+
+ ///
+ /// Provides access to the Impersonation parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument Impersonation { get; set; }
+
+ ///
+ /// Provides access to the PacketIntegrity parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument PacketIntegrity { get; set; }
+
+ ///
+ /// Provides access to the PacketPrivacy parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument PacketPrivacy { get; set; }
+
+ ///
+ /// Provides access to the Protocol parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument Protocol { get; set; }
+
+ ///
+ /// Provides access to the UICulture parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument UICulture { get; set; }
+
+ ///
+ /// Provides access to the Culture parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument Culture { get; set; }
+
+
+ ///
+ /// Script module contents for this activity`n///
+ protected override string PSDefiningModule { get { return null; } }
+
+ ///
+ /// Returns a configured instance of System.Management.Automation.PowerShell, pre-populated with the command to run.
+ ///
+ /// The NativeActivityContext for the currently running activity.
+ /// A populated instance of Sytem.Management.Automation.PowerShell
+ /// The infrastructure takes responsibility for closing and disposing the PowerShell instance returned.
+ protected override ActivityImplementationContext GetPowerShell(NativeActivityContext context)
+ {
+ System.Management.Automation.PowerShell invoker = global::System.Management.Automation.PowerShell.Create();
+ System.Management.Automation.PowerShell targetCommand = invoker.AddCommand(PSCommandName);
+
+ // Initialize the arguments
+
+ if(NoEncryption.Expression != null)
+ {
+ targetCommand.AddParameter("NoEncryption", NoEncryption.Get(context));
+ }
+
+ if(CertificateCACheck.Expression != null)
+ {
+ targetCommand.AddParameter("CertificateCACheck", CertificateCACheck.Get(context));
+ }
+
+ if(CertificateCNCheck.Expression != null)
+ {
+ targetCommand.AddParameter("CertificateCNCheck", CertificateCNCheck.Get(context));
+ }
+
+ if(CertRevocationCheck.Expression != null)
+ {
+ targetCommand.AddParameter("CertRevocationCheck", CertRevocationCheck.Get(context));
+ }
+
+ if(EncodePortInServicePrincipalName.Expression != null)
+ {
+ targetCommand.AddParameter("EncodePortInServicePrincipalName", EncodePortInServicePrincipalName.Get(context));
+ }
+
+ if(Encoding.Expression != null)
+ {
+ targetCommand.AddParameter("Encoding", Encoding.Get(context));
+ }
+
+ if(HttpPrefix.Expression != null)
+ {
+ targetCommand.AddParameter("HttpPrefix", HttpPrefix.Get(context));
+ }
+
+ if(MaxEnvelopeSizeKB.Expression != null)
+ {
+ targetCommand.AddParameter("MaxEnvelopeSizeKB", MaxEnvelopeSizeKB.Get(context));
+ }
+
+ if(ProxyAuthentication.Expression != null)
+ {
+ targetCommand.AddParameter("ProxyAuthentication", ProxyAuthentication.Get(context));
+ }
+
+ if(ProxyCertificateThumbprint.Expression != null)
+ {
+ targetCommand.AddParameter("ProxyCertificateThumbprint", ProxyCertificateThumbprint.Get(context));
+ }
+
+ if(ProxyCredential.Expression != null)
+ {
+ targetCommand.AddParameter("ProxyCredential", ProxyCredential.Get(context));
+ }
+
+ if(ProxyType.Expression != null)
+ {
+ targetCommand.AddParameter("ProxyType", ProxyType.Get(context));
+ }
+
+ if(UseSsl.Expression != null)
+ {
+ targetCommand.AddParameter("UseSsl", UseSsl.Get(context));
+ }
+
+ if(Impersonation.Expression != null)
+ {
+ targetCommand.AddParameter("Impersonation", Impersonation.Get(context));
+ }
+
+ if(PacketIntegrity.Expression != null)
+ {
+ targetCommand.AddParameter("PacketIntegrity", PacketIntegrity.Get(context));
+ }
+
+ if(PacketPrivacy.Expression != null)
+ {
+ targetCommand.AddParameter("PacketPrivacy", PacketPrivacy.Get(context));
+ }
+
+ if(Protocol.Expression != null)
+ {
+ targetCommand.AddParameter("Protocol", Protocol.Get(context));
+ }
+
+ if(UICulture.Expression != null)
+ {
+ targetCommand.AddParameter("UICulture", UICulture.Get(context));
+ }
+
+ if(Culture.Expression != null)
+ {
+ targetCommand.AddParameter("Culture", Culture.Get(context));
+ }
+
+
+ return new ActivityImplementationContext() { PowerShellInstance = invoker };
+ }
+ }
+}
diff --git a/src/Microsoft.PowerShell.Activities/Activities/PSPersist.cs b/src/Microsoft.PowerShell.Activities/Activities/PSPersist.cs
new file mode 100644
index 0000000000..266c5056d1
--- /dev/null
+++ b/src/Microsoft.PowerShell.Activities/Activities/PSPersist.cs
@@ -0,0 +1,43 @@
+//
+// Copyright (C) Microsoft. All rights reserved.
+//
+using System;
+using System.Activities;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using System.Management.Automation;
+using System.Management.Automation.Language;
+using System.ComponentModel;
+using System.Text;
+using System.Reflection;
+
+namespace Microsoft.PowerShell.Activities
+{
+ ///
+ /// Persist the current workflow. Also defines the persistence point where suspend-job is getting suspended.
+ ///
+ public class PSPersist : NativeActivity
+ {
+ ///
+ /// Returns true if the activity can induce an idle.
+ ///
+ protected override bool CanInduceIdle { get { return true; } }
+
+ ///
+ /// Invokes the activity
+ ///
+ /// The activity context.
+ protected override void Execute(NativeActivityContext context)
+ {
+ string bookmarkname = PSActivity.PSPersistBookmarkPrefix + Guid.NewGuid().ToString().Replace("-", "_");
+ context.CreateBookmark(bookmarkname, BookmarkResumed);
+
+ }
+
+ private void BookmarkResumed(NativeActivityContext context, Bookmark bookmark, object value)
+ {
+ }
+ }
+}
diff --git a/src/Microsoft.PowerShell.Activities/Activities/Pipeline.cs b/src/Microsoft.PowerShell.Activities/Activities/Pipeline.cs
new file mode 100644
index 0000000000..cac9c7058e
--- /dev/null
+++ b/src/Microsoft.PowerShell.Activities/Activities/Pipeline.cs
@@ -0,0 +1,296 @@
+//
+// Copyright (C) Microsoft. All rights reserved.
+//
+using System;
+using System.Activities;
+using System.Activities.Validation;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Runtime;
+using System.Activities.Statements;
+using System.Management.Automation;
+using System.ComponentModel;
+
+namespace Microsoft.PowerShell.Activities
+{
+ ///
+ /// The implementation of pipeline activity.
+ /// This similar concept which we have in PowerShell today like Get-Process | Stop-Process.
+ /// Pipline activity will make sure the piped execution of its child acitities.
+ ///
+#if _NOTARMBUILD_
+ [Designer (typeof (PipelineDesigner))]
+#endif
+ public sealed class Pipeline : PipelineEnabledActivity
+ {
+ ///
+ /// Tracks the number of current child activity in the collection.
+ ///
+ private Variable lastIndexHint;
+
+ private bool inputValidationFailed;
+ private bool resultValidationFailed;
+
+ ///
+ /// Maintain intermediate outflow of data from child activity.
+ ///
+ private Variable> OutputStream;
+
+ ///
+ /// Maintain intermediate inflow of data into child activity.
+ ///
+ private Variable> InputStream;
+
+ ///
+ /// Get activities.
+ ///
+ [RequiredArgument]
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage",
+ "CA2227:CollectionPropertiesShouldBeReadOnly",
+ Justification = "This is needs to support assignment via workflow.")]
+ public Collection Activities { get; set; }
+
+ ///
+ /// Default constructor
+ ///
+ public Pipeline()
+ : base()
+ {
+ this.lastIndexHint = new Variable();
+ this.Activities = new Collection();
+
+ this.inputValidationFailed = false;
+ this.resultValidationFailed = false;
+ }
+
+ ///
+ /// Validate the required number of activities of pipeline activity.
+ /// Setup the cachemetata with variables and activities.
+ ///
+ ///
+ protected override void CacheMetadata(NativeActivityMetadata metadata)
+ {
+ int count = 0;
+
+ if (this.Activities != null)
+ {
+ count = this.Activities.Count;
+ }
+
+ if (count == 0)
+ {
+ metadata.AddValidationError(new ValidationError(ActivityResources.NoChildPipeline, true));
+ return;
+ }
+
+ //BUGBUG: As written, the following checks cause error in scenarios where they should not.
+ // They are left in for the time being but disabled until we verify that there are no
+ // scenarios where we need to check for two variables being assigned.
+#if false
+ if (Input != null && Input.Expression != null && this.Activities[0].Input != null && this.Activities[0].Input.Expression != null)
+ {
+ metadata.AddValidationError(new ValidationError(ActivityResources.DuplicateInputDefinedInPipeline, true));
+ this.inputValidationFailed = true;
+ return;
+ }
+
+ if (Result != null && Result.Expression != null && this.Activities[count - 1].Result != null && this.Activities[count - 1].Result.Expression != null)
+ {
+ metadata.AddValidationError(new ValidationError(ActivityResources.DuplicateResultDefinedInPipeline, true));
+ this.resultValidationFailed = true;
+ return;
+ }
+#endif
+ // Adding variables into the CacheMetatdata of pipeline activity.
+ metadata.AddImplementationVariable(this.lastIndexHint);
+
+ // We use a GUID here to make this name hard to guess. It's not a security issue,
+ // it just prevents code from accidentally taking a dependency on it.
+ this.OutputStream = new Variable>(Guid.NewGuid().ToString().Replace("-","_"));
+ this.InputStream = new Variable>(Guid.NewGuid().ToString().Replace("-","_"));
+
+ metadata.AddVariable(this.OutputStream);
+ metadata.AddVariable(this.InputStream);
+
+ bool appendOutput = false;
+ if ((this.AppendOutput != null) && (this.AppendOutput.Value))
+ {
+ appendOutput = true;
+ }
+
+ // Adding activities into the CacheMetatdata of pipeline activity.
+ if (count == 1)
+ {
+
+ if (Input != null && Input.Expression != null)
+ {
+ this.Activities[0].Input = this.Input;
+ }
+
+ if (Result != null && Result.Expression != null)
+ {
+ this.Activities[0].Result = this.Result;
+ }
+
+ if (appendOutput)
+ {
+ this.Activities[0].AppendOutput = true;
+ }
+
+ metadata.AddChild(this.Activities[0]);
+ }
+ else
+ {
+
+ if (Input != null && Input.Expression != null)
+ {
+ this.Activities[0].Input = this.Input;
+ }
+
+ // Connecting child activities with temporary input and out streams.
+ this.Activities[0].Result = this.OutputStream;
+ metadata.AddChild(this.Activities[0]);
+
+ for (int i = 1; i < (count - 1); i++)
+ {
+ this.Activities[i].Input = this.InputStream;
+ this.Activities[i].Result = this.OutputStream;
+
+ metadata.AddChild(this.Activities[i]);
+ }
+
+ if (Result != null && Result.Expression != null)
+ {
+ this.Activities[count - 1].Result = this.Result;
+ }
+
+ if (appendOutput)
+ {
+ this.Activities[count - 1].AppendOutput = true;
+ }
+
+ this.Activities[count - 1].Input = this.InputStream;
+ metadata.AddChild(this.Activities[count - 1]);
+ }
+ }
+
+ ///
+ /// Executes the first child activity
+ ///
+ /// The execution context of pipeline activity.
+ protected override void Execute(NativeActivityContext executionContext)
+ {
+ int count = 0;
+
+ if (this.Activities != null)
+ {
+ count = this.Activities.Count;
+ }
+
+ if (count == 0)
+ {
+ throw new ArgumentException(ActivityResources.NoChildPipeline);
+ }
+
+ if (this.inputValidationFailed && Input != null && Input.Expression != null && this.Activities[0].Input != null && this.Activities[0].Input.Expression != null)
+ {
+ throw new ArgumentException(ActivityResources.DuplicateInputDefinedInPipeline);
+ }
+
+ if (this.resultValidationFailed && Result != null && Result.Expression != null && this.Activities[count - 1].Result != null && this.Activities[count - 1].Result.Expression != null)
+ {
+ throw new ArgumentException(ActivityResources.DuplicateResultDefinedInPipeline);
+ }
+
+ //Executing the first child activity.
+ PipelineEnabledActivity firstChild = this.Activities[0];
+ executionContext.ScheduleActivity(firstChild, new CompletionCallback(InternalExecute));
+ }
+
+ ///
+ /// Get results from previous activity and schedule the execution of next activity.
+ ///
+ /// The execution context of pipeline activity.
+ /// The activity instance of completed child activity.
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
+ private void InternalExecute(NativeActivityContext executionContext, ActivityInstance completedInstance)
+ {
+ int completedInstanceIndex;
+
+ // Reading the value of pipeline activity variables from the context.
+ completedInstanceIndex = this.lastIndexHint.Get(executionContext);
+
+ PSDataCollection outValue = this.GetData(executionContext, this.OutputStream);
+ PSDataCollection inValue = this.GetData(executionContext, this.InputStream);
+
+ // Re-checking the index of the the child activity, which has just completed its execution.
+ if (completedInstanceIndex >= this.Activities.Count || this.Activities[completedInstanceIndex] != completedInstance.Activity)
+ {
+ completedInstanceIndex = this.Activities.IndexOf((PSActivity) completedInstance.Activity);
+ }
+
+ // Calculating next child activity.
+ int nextChildIndex = completedInstanceIndex + 1;
+
+ // Checking for pipeline activity completion.
+ if (nextChildIndex == this.Activities.Count)
+ {
+ if (inValue != null) inValue.Dispose();
+ if (outValue != null) outValue.Dispose();
+ return;
+ }
+
+ // Setting up the environment for next child activity to run.
+ if (outValue != null) outValue.Complete();
+ if (inValue != null) inValue.Dispose();
+
+ inValue = outValue;
+ outValue = new PSDataCollection();
+
+ // The pipeline is complete if there is no input
+ // PS > function foo { $input | Write-Output "Hello" }
+ // PS > foo
+ // PS >
+ if ((inValue == null) || (inValue.Count == 0))
+ {
+ if (outValue != null) outValue.Dispose();
+ return;
+ }
+
+ this.SetData(executionContext, this.OutputStream, outValue);
+ this.SetData(executionContext, this.InputStream, inValue);
+
+ // Executing the next child activity.
+ PipelineEnabledActivity nextChild = this.Activities[nextChildIndex];
+
+ executionContext.ScheduleActivity(nextChild, new CompletionCallback(InternalExecute));
+
+ this.lastIndexHint.Set(executionContext, nextChildIndex);
+ }
+
+ ///
+ /// Get the data from the pipeline variable.
+ ///
+ /// The activity context.
+ /// The variable which value to get.
+ /// Returns the value of the variable.
+ private PSDataCollection GetData(ActivityContext context, Variable> variable)
+ {
+ PropertyDescriptor prop = context.DataContext.GetProperties()[variable.Name];
+ return (PSDataCollection)prop.GetValue(context.DataContext);
+ }
+
+ ///
+ /// Set the data to the pipeline variable.
+ ///
+ /// The activity context.
+ /// The variable which needs to set.
+ /// The value for the vriable.
+ private void SetData(ActivityContext context, Variable> variable, PSDataCollection value)
+ {
+ PropertyDescriptor prop = context.DataContext.GetProperties()[variable.Name];
+ prop.SetValue(context.DataContext, value);
+ }
+
+ }
+}
diff --git a/src/Microsoft.PowerShell.Activities/Activities/PipelineDesigner.xaml.cs b/src/Microsoft.PowerShell.Activities/Activities/PipelineDesigner.xaml.cs
new file mode 100644
index 0000000000..713ef39e89
--- /dev/null
+++ b/src/Microsoft.PowerShell.Activities/Activities/PipelineDesigner.xaml.cs
@@ -0,0 +1,23 @@
+//
+// Copyright (C) Microsoft. All rights reserved.
+//
+
+#if _NOTARMBUILD_
+namespace Microsoft.PowerShell.Activities
+{
+ ///
+ /// Interaction logic for PipelineDesigner.xaml
+ ///
+ public partial class PipelineDesigner
+ {
+ ///
+ /// Default Constructor.
+ ///
+ public PipelineDesigner()
+ {
+ InitializeComponent();
+ }
+
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/Microsoft.PowerShell.Activities/Activities/PowerShellValue.cs b/src/Microsoft.PowerShell.Activities/Activities/PowerShellValue.cs
new file mode 100644
index 0000000000..49d2e43f71
--- /dev/null
+++ b/src/Microsoft.PowerShell.Activities/Activities/PowerShellValue.cs
@@ -0,0 +1,564 @@
+/********************************************************************++
+Copyright (c) Microsoft Corporation. All rights reserved.
+--********************************************************************/
+
+using System;
+using System.Collections.Concurrent;
+using System.ComponentModel;
+using System.Globalization;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Activities;
+using System.Diagnostics;
+using System.Management.Automation;
+using System.Management.Automation.Language;
+using System.Management.Automation.Runspaces;
+
+namespace Microsoft.PowerShell.Activities
+{
+ ///
+ /// Evaluate the Powershell expression and return the value of type T.
+ ///
+ public sealed class PowerShellValue : NativeActivity
+ {
+ ///
+ /// The PowerShell expression, which will be evaluated and retuned a type of T value.
+ ///
+ [RequiredArgument]
+ public string Expression { get; set; }
+
+ ///
+ /// Determines whether to connect the input stream for this activity.
+ ///
+ [DefaultValue(false)]
+ public bool UseDefaultInput
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// Validates the syntax of the script text for this activity.
+ ///
+ /// Activity metatdata for this activity
+ protected override void CacheMetadata(NativeActivityMetadata metadata)
+ {
+ base.CacheMetadata(metadata);
+
+ if (!string.IsNullOrWhiteSpace(Expression))
+ {
+ var errors = new Collection();
+ PSParser.Tokenize(Expression, out errors);
+ if (errors != null && errors.Count > 0)
+ {
+ string compositeErrorString = "";
+ foreach (var e in errors)
+ {
+ // Format and add each error message...
+ compositeErrorString += string.Format(CultureInfo.InvariantCulture,
+ "[{0}, {1}]: {2}\n", e.Token.StartLine, e.Token.StartColumn, e.Message);
+ }
+ metadata.AddValidationError(compositeErrorString);
+ }
+ }
+ }
+
+ ///
+ /// Get the scriptblock for this activity, caching it once it's compiled.
+ ///
+ private ScriptBlock ExpressionScriptBlock
+ {
+ get
+ {
+ if (_expressionScriptBlock == null)
+ {
+ lock (syncroot)
+ {
+ if (_expressionScriptBlock == null)
+ {
+ // The guard check for a null expression string is done in Execute() instead
+ // of in this property. It's also done in the validation check for CacheMetadata
+ string updatedExpression = Expression;
+
+ // Hack to make sure the $input *does* get unrolled...
+ if (string.Equals("$input", Expression.Trim(), StringComparison.OrdinalIgnoreCase))
+ {
+ updatedExpression = "$(" + updatedExpression + "\n)";
+ }
+ else
+ {
+ Token[] tokens;
+ ParseError[] errors;
+ ScriptBlockAst exprAst = Parser.ParseInput(updatedExpression, out tokens, out errors);
+ if (errors.Length > 0)
+ {
+ throw new ParseException(errors);
+ }
+
+ if (exprAst.BeginBlock == null && exprAst.ProcessBlock == null && exprAst.EndBlock != null)
+ {
+ var statements = exprAst.EndBlock.Statements;
+ if (statements != null && statements.Count == 1)
+ {
+ PipelineAst pipeline = statements[0] as PipelineAst;
+ if (pipeline != null && pipeline.GetPureExpression() != null)
+ {
+ // It is very difficult to get equivalent expression semantics in workflow because the engine
+ // APIs get in the way necessitating a lot of fiddling with the actual expression as well as post-processing
+ // the result of the expression.
+ // We wrap a pure expression in an array so that PowerShell's loop unrolling doesn't impact our
+ // ability to return collections. We also add a trap/break so that terminating errors in expressions
+ // are turned into exceptions for the PowerShell object. The trap and closing ')' go on their own line
+ // for the XAML designer case where the expression might have a trailing '#' making the rest of the
+ // line into a comment.
+ updatedExpression = ",(" + updatedExpression + "\n); trap { break }";
+ }
+ }
+ }
+ }
+
+ _expressionScriptBlock = ScriptBlock.Create(updatedExpression);
+ }
+ }
+ }
+ return _expressionScriptBlock;
+ }
+ }
+ ScriptBlock _expressionScriptBlock;
+
+ ///
+ /// Check to see if the expression only uses elements of the restricted language
+ /// as well as only using the allowed commands and variables.
+ ///
+ ///
+ /// List of command names to allow in the expression
+ ///
+ ///
+ /// List of variable names to allow in the expression. If the collection contains a single
+ /// element "*", all variables will be allowed including environment variables
+ /// functions, etc.
+ ///
+ ///
+ /// If true, environment variables are allowed even if the allowedVariables list is empty.
+ ///
+ public void ValidateExpressionConstraints(IEnumerable allowedCommands, IEnumerable allowedVariables, bool allowEnvironmentVariables)
+ {
+ ExpressionScriptBlock.CheckRestrictedLanguage(allowedCommands, allowedVariables, allowEnvironmentVariables);
+ }
+
+ ///
+ /// Execution of PowerShell value activity.
+ /// PowerShell expression will be evaluated using PowerShell runspace and the value of Type T will be returned.
+ ///
+ ///
+ 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 collectionObject = value as PSDataCollection;
+ 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 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();
+
+ // 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 collectionObject = value as PSDataCollection;
+
+ 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 inputStream = null;
+ if (UseDefaultInput)
+ {
+ // Retrieve our host overrides
+ hostValues = context.GetExtension();
+
+ if (hostValues != null)
+ {
+ Dictionary incomingArguments = hostValues.Parameters;
+ if (incomingArguments.ContainsKey("Input"))
+ {
+ inputStream = incomingArguments["Input"] as PSDataCollection;
+ }
+ }
+ }
+
+ // 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 errorStream = null;
+
+ // Retrieve our host overrides
+ hostValues = context.GetExtension();
+
+ if (hostValues != null)
+ {
+ Dictionary incomingArguments = hostValues.Parameters;
+ if (incomingArguments.ContainsKey("PSError"))
+ {
+ errorStream = incomingArguments["PSError"] as PSDataCollection;
+ }
+ }
+
+ 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( result );
+ }
+ }
+ else
+ {
+ valueToReturn = LanguagePrimitives.ConvertTo(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
+ if (typeof(T) == typeof(PSDataCollection))
+ {
+ Object tempValueToReturn = new PSDataCollection(
+ new List { LanguagePrimitives.ConvertTo(returnedvalue[0]) });
+ valueToReturn = (T)tempValueToReturn;
+ }
+ else
+ {
+ throw;
+ }
+ }
+
+ Result.Set(context, valueToReturn);
+ }
+ }
+ }
+
+ private static void HandleErrorDataAdding(object sender, DataAddingEventArgs e)
+ {
+ HostSettingCommandMetadata commandMetadata;
+ CommandMetadataTable.TryGetValue(e.PowerShellInstanceId, out commandMetadata);
+
+ if (commandMetadata != null)
+ {
+ PowerShellInvocation_ErrorAdding(sender, e, commandMetadata);
+ }
+ }
+
+ private static readonly ConcurrentDictionary CommandMetadataTable =
+ new ConcurrentDictionary();
+
+ private static void PowerShellInvocation_ErrorAdding(object sender, DataAddingEventArgs e, HostSettingCommandMetadata commandMetadata)
+ {
+ ErrorRecord errorRecord = e.ItemAdded as ErrorRecord;
+
+ if (errorRecord != null)
+ {
+ if (commandMetadata != null)
+ {
+ ScriptPosition scriptStart = new ScriptPosition(
+ commandMetadata.CommandName,
+ commandMetadata.StartLineNumber,
+ commandMetadata.StartColumnNumber,
+ null);
+ ScriptPosition scriptEnd = new ScriptPosition(
+ commandMetadata.CommandName,
+ commandMetadata.EndLineNumber,
+ commandMetadata.EndColumnNumber,
+ null);
+ ScriptExtent extent = new ScriptExtent(scriptStart, scriptEnd);
+
+ if (errorRecord.InvocationInfo != null)
+ {
+ errorRecord.InvocationInfo.DisplayScriptPosition = extent;
+ }
+ }
+ }
+ }
+
+ static CommandInfo _ci;
+ static object syncroot = new object();
+ }
+}
diff --git a/src/Microsoft.PowerShell.Activities/Activities/RemoveCimInstanceActivity.cs b/src/Microsoft.PowerShell.Activities/Activities/RemoveCimInstanceActivity.cs
new file mode 100644
index 0000000000..77e9dcc90a
--- /dev/null
+++ b/src/Microsoft.PowerShell.Activities/Activities/RemoveCimInstanceActivity.cs
@@ -0,0 +1,120 @@
+
+using Microsoft.PowerShell.Activities;
+using System.Activities;
+using System.Collections.Generic;
+using System.ComponentModel;
+
+
+namespace Microsoft.PowerShell.Activities
+{
+ ///
+ /// Activity to invoke the CimCmdlets\Remove-CimInstance command in a Workflow.
+ ///
+ [System.CodeDom.Compiler.GeneratedCode("Microsoft.PowerShell.Activities.ActivityGenerator.GenerateFromName", "3.0")]
+ public sealed class RemoveCimInstance : GenericCimCmdletActivity
+ {
+ ///
+ /// Gets the display name of the command invoked by this activity.
+ ///
+ public RemoveCimInstance()
+ {
+ this.DisplayName = "Remove-CimInstance";
+ }
+
+ ///
+ /// Gets the fully qualified name of the command invoked by this activity.
+ ///
+ public override string PSCommandName { get { return "CimCmdlets\\Remove-CimInstance"; } }
+
+ ///
+ /// The .NET type implementing the cmdlet to invoke.
+ ///
+ public override System.Type TypeImplementingCmdlet { get { return typeof(Microsoft.Management.Infrastructure.CimCmdlets.RemoveCimInstanceCommand); } }
+
+ ///
+ /// Provides access to the Namespace parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument Namespace { get; set; }
+
+ ///
+ /// Provides access to the OperationTimeoutSec parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument OperationTimeoutSec { get; set; }
+
+ ///
+ /// Provides access to the InputObject parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument InputObject { get; set; }
+
+ ///
+ /// Provides access to the Query parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument Query { get; set; }
+
+ ///
+ /// Provides access to the QueryDialect parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument QueryDialect { get; set; }
+
+
+ ///
+ /// Script module contents for this activity`n///
+ protected override string PSDefiningModule { get { return null; } }
+
+ ///
+ /// Returns a configured instance of System.Management.Automation.PowerShell, pre-populated with the command to run.
+ ///
+ /// The NativeActivityContext for the currently running activity.
+ /// A populated instance of Sytem.Management.Automation.PowerShell
+ /// The infrastructure takes responsibility for closing and disposing the PowerShell instance returned.
+ protected override ActivityImplementationContext GetPowerShell(NativeActivityContext context)
+ {
+ System.Management.Automation.PowerShell invoker = global::System.Management.Automation.PowerShell.Create();
+ System.Management.Automation.PowerShell targetCommand = invoker.AddCommand(PSCommandName);
+
+ // Initialize the arguments
+
+ if(Namespace.Expression != null)
+ {
+ targetCommand.AddParameter("Namespace", Namespace.Get(context));
+ }
+
+ if(OperationTimeoutSec.Expression != null)
+ {
+ targetCommand.AddParameter("OperationTimeoutSec", OperationTimeoutSec.Get(context));
+ }
+
+ if (InputObject.Expression != null)
+ {
+ targetCommand.AddParameter("InputObject", InputObject.Get(context));
+ }
+
+ if(Query.Expression != null)
+ {
+ targetCommand.AddParameter("Query", Query.Get(context));
+ }
+
+ if(QueryDialect.Expression != null)
+ {
+ targetCommand.AddParameter("QueryDialect", QueryDialect.Get(context));
+ }
+
+ if (ResourceUri != null)
+ {
+ targetCommand.AddParameter("ResourceUri", ResourceUri.Get(context));
+ }
+
+ return new ActivityImplementationContext() { PowerShellInstance = invoker };
+ }
+ }
+}
diff --git a/src/Microsoft.PowerShell.Activities/Activities/SetCimInstanceActivity.cs b/src/Microsoft.PowerShell.Activities/Activities/SetCimInstanceActivity.cs
new file mode 100644
index 0000000000..a393131281
--- /dev/null
+++ b/src/Microsoft.PowerShell.Activities/Activities/SetCimInstanceActivity.cs
@@ -0,0 +1,148 @@
+
+using Microsoft.PowerShell.Activities;
+using System.Activities;
+using System.Collections.Generic;
+using System.ComponentModel;
+
+
+namespace cimcmdlets.Activities
+{
+ ///
+ /// Activity to invoke the CimCmdlets\Set-CimInstance command in a Workflow.
+ ///
+ [System.CodeDom.Compiler.GeneratedCode("Microsoft.PowerShell.Activities.ActivityGenerator.GenerateFromName", "3.0")]
+ public sealed class SetCimInstance : GenericCimCmdletActivity
+ {
+ ///
+ /// Gets the display name of the command invoked by this activity.
+ ///
+ public SetCimInstance()
+ {
+ this.DisplayName = "Set-CimInstance";
+ }
+
+ ///
+ /// Gets the fully qualified name of the command invoked by this activity.
+ ///
+ public override string PSCommandName { get { return "CimCmdlets\\Set-CimInstance"; } }
+
+ ///
+ /// The .NET type implementing the cmdlet to invoke.
+ ///
+ public override System.Type TypeImplementingCmdlet { get { return typeof(Microsoft.Management.Infrastructure.CimCmdlets.SetCimInstanceCommand); } }
+
+ ///
+ /// Provides access to the Namespace parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument Namespace { get; set; }
+
+ ///
+ /// Provides access to the OperationTimeoutSec parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument OperationTimeoutSec { get; set; }
+
+ ///
+ /// Provides access to the InputObject parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument InputObject { get; set; }
+
+ ///
+ /// Provides access to the Query parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument Query { get; set; }
+
+ ///
+ /// Provides access to the QueryDialect parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument QueryDialect { get; set; }
+
+ ///
+ /// Provides access to the Property parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument Property { get; set; }
+
+ ///
+ /// Provides access to the PassThru parameter.
+ ///
+ [ParameterSpecificCategory]
+ [DefaultValue(null)]
+ public InArgument PassThru { get; set; }
+
+ ///
+ /// Module defining this command
+ /// Script module contents for this activity
+ ///
+ protected override string PSDefiningModule { get { return "CimCmdlets"; } }
+
+ // Additional custom code for this activity
+
+
+ ///
+ /// Returns a configured instance of System.Management.Automation.PowerShell, pre-populated with the command to run.
+ ///
+ /// The NativeActivityContext for the currently running activity.
+ /// A populated instance of Sytem.Management.Automation.PowerShell
+ /// The infrastructure takes responsibility for closing and disposing the PowerShell instance returned.
+ protected override ActivityImplementationContext GetPowerShell(NativeActivityContext context)
+ {
+ System.Management.Automation.PowerShell invoker = global::System.Management.Automation.PowerShell.Create();
+ System.Management.Automation.PowerShell targetCommand = invoker.AddCommand(PSCommandName);
+
+ // Initialize the arguments
+
+ if(Namespace.Expression != null)
+ {
+ targetCommand.AddParameter("Namespace", Namespace.Get(context));
+ }
+
+ if(OperationTimeoutSec.Expression != null)
+ {
+ targetCommand.AddParameter("OperationTimeoutSec", OperationTimeoutSec.Get(context));
+ }
+
+ if (InputObject.Expression != null)
+ {
+ targetCommand.AddParameter("InputObject", InputObject.Get(context));
+ }
+
+ if(Query.Expression != null)
+ {
+ targetCommand.AddParameter("Query", Query.Get(context));
+ }
+
+ if(QueryDialect.Expression != null)
+ {
+ targetCommand.AddParameter("QueryDialect", QueryDialect.Get(context));
+ }
+
+ if(Property.Expression != null)
+ {
+ targetCommand.AddParameter("Property", Property.Get(context));
+ }
+
+ if(PassThru.Expression != null)
+ {
+ targetCommand.AddParameter("PassThru", PassThru.Get(context));
+ }
+
+ if (ResourceUri != null)
+ {
+ targetCommand.AddParameter("ResourceUri", ResourceUri.Get(context));
+ }
+
+ return new ActivityImplementationContext() { PowerShellInstance = invoker };
+ }
+ }
+}
diff --git a/src/Microsoft.PowerShell.Activities/Activities/SetHostValue.cs b/src/Microsoft.PowerShell.Activities/Activities/SetHostValue.cs
new file mode 100644
index 0000000000..eb06b2da64
--- /dev/null
+++ b/src/Microsoft.PowerShell.Activities/Activities/SetHostValue.cs
@@ -0,0 +1,602 @@
+using System;
+using System.Reflection;
+using System.Activities;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Globalization;
+using System.Diagnostics.CodeAnalysis;
+using System.Management.Automation;
+using System.Management.Automation.Remoting;
+using System.Management.Automation.Runspaces;
+using System.Management.Automation.Tracing;
+using System.ComponentModel;
+
+namespace Microsoft.PowerShell.Activities
+{
+ ///
+ /// Activity to set a host value in a Workflow.
+ ///
+ public sealed class SetPSWorkflowData : NativeActivity
+ {
+ ///
+ /// The variable to set, if not included in the PSWorkflowRuntimeVariable enum.
+ ///
+ [DefaultValue(null)]
+ public InArgument OtherVariableName
+ {
+ get;
+ set;
+ }
+
+ ///
+ ///
+ ///
+ [DefaultValue(null)]
+ public InArgument