/// <summary> /// Logs on the user. /// </summary> /// <param name="credential">The credential.</param> /// <returns>The LogOnUser object.</returns> private LogOnUser LogOnUser(PSCredential credential) { LogOnUser logOnUser = null; if (this.ImpersonatePowerShellUser) { LogOnType logonType = this.ImpersonatePowerShellUserLogOnType; bool loadUserProfile = this.ImpersonatePowerShellUserLoadUserProfile; WindowsIdentity windowsIdentity = WindowsIdentity.GetCurrent(); if (windowsIdentity != null) { string currentUserLogonName = windowsIdentity.Name; if (!this.PowerShellUser.Equals(currentUserLogonName, StringComparison.OrdinalIgnoreCase)) { logOnUser = new LogOnUser( credential.GetNetworkCredential().UserName, credential.GetNetworkCredential().Domain, credential.GetNetworkCredential().Password, logonType, LogOnProvider.ProviderWinNT50, loadUserProfile); } } else { logOnUser = new LogOnUser( credential.GetNetworkCredential().Domain, credential.GetNetworkCredential().UserName, credential.GetNetworkCredential().Password, logonType, LogOnProvider.ProviderWinNT50, loadUserProfile); } } return(logOnUser); }
/// <summary> /// Runs the PowerShell script. /// </summary> /// <param name="script">The script.</param> /// <param name="scriptArguments">The PowerShell script arguments.</param> /// <param name="scriptParameters">The PowerShell script parameters.</param> /// <returns>The output of the script.</returns> private object RunScript(string script, IEnumerable scriptArguments, Dictionary <string, object> scriptParameters) { Logger.Instance.WriteMethodEntry(EventIdentifier.RunPowerShellScriptRunScript); WindowsImpersonationContext context = null; LogOnUser logOnUser = null; try { PSCredential credential = this.GetPowerShellCredential(); logOnUser = this.LogOnUser(credential); if (logOnUser != null) { context = logOnUser.Impersonate(); } // Establish a new runspace for the Powershell script InitialSessionState initialSessionState = InitialSessionState.CreateDefault(); bool progressPreference = Logger.Instance.ShouldTrace(TraceEventType.Information); bool debugPreference = Logger.Instance.ShouldTrace(TraceEventType.Information); bool verbosePreference = Logger.Instance.ShouldTrace(TraceEventType.Verbose); initialSessionState.Variables.Add(new SessionStateVariableEntry("ProgressPreference", progressPreference ? "Continue" : "SilentlyContinue", string.Empty)); initialSessionState.Variables.Add(new SessionStateVariableEntry("DebugPreference", debugPreference ? "Continue" : "SilentlyContinue", string.Empty)); initialSessionState.Variables.Add(new SessionStateVariableEntry("VerbosePreference", verbosePreference ? "Continue" : "SilentlyContinue", string.Empty)); initialSessionState.Variables.Add(new SessionStateVariableEntry("AECWorkflowInstanceId", Logger.GetContextItem("WorkflowInstanceId"), string.Empty)); initialSessionState.Variables.Add(new SessionStateVariableEntry("AECRequestId", Logger.GetContextItem("RequestId"), string.Empty)); initialSessionState.Variables.Add(new SessionStateVariableEntry("AECActorId", Logger.GetContextItem("ActorId"), string.Empty)); initialSessionState.Variables.Add(new SessionStateVariableEntry("AECTargetId", Logger.GetContextItem("TargetId"), string.Empty)); initialSessionState.Variables.Add(new SessionStateVariableEntry("AECWorkflowDefinitionId", Logger.GetContextItem("WorkflowDefinitionId"), string.Empty)); initialSessionState.Variables.Add(new SessionStateVariableEntry("Credential", credential, null)); using (Runspace runspace = RunspaceFactory.CreateRunspace(initialSessionState)) { runspace.Open(); using (PowerShell shell = PowerShell.Create()) { shell.Runspace = runspace; SetupStreamEventHandlers(shell); // Add the script to the PowerShell instance to prepare for execution shell.AddScript(script); StringBuilder scriptParams = new StringBuilder(); if (scriptParameters != null) { foreach (string s in scriptParameters.Keys) { shell.AddParameter(s, scriptParameters[s]); scriptParams.AppendFormat(CultureInfo.InvariantCulture, "-{0} '{1}' ", s, scriptParameters[s]); } } else if (scriptArguments != null) { foreach (object o in scriptArguments) { shell.AddArgument(o); scriptParams.AppendFormat(CultureInfo.InvariantCulture, "'{0}' ", o); } } if (this.InputType != PowerShellInputType.None) { Logger.Instance.WriteVerbose(EventIdentifier.RunPowerShellScriptRunScript, "The PowerShell script parameters are: '{0}'.", scriptParams); } // Execute the script and identify if any errors occurred // In most circumstances, errors will not be raised as exceptions but will instead // be presented in the Error collection for the PowerShell instance Collection <PSObject> results; try { results = shell.Invoke(); } catch (Exception ex) { throw Logger.Instance.ReportError(EventIdentifier.RunPowerShellScriptRunScriptInvocationError, new WorkflowActivityLibraryException(Messages.RunPowerShellScript_ScriptInvocationError, ex, ex.Message)); } if (shell.Streams.Error.Count == 0) { if (this.ReturnType == PowerShellReturnType.None) { return(null); } if (results != null && results.Count == 1) { return(results[0].BaseObject); } if (results == null || results.Count < 1) { return(null); } // If multiple values were found for the lookup, verify that they are of a consistent type Type type = null; bool consistentType = true; foreach (PSObject pso in results) { if (type == null) { type = pso.BaseObject.GetType(); Logger.Instance.WriteVerbose(EventIdentifier.RunPowerShellScriptRunScript, "The PowerShell script returned type: '{0}'.", type); } else if (pso.BaseObject.GetType() != type) { consistentType = false; Logger.Instance.WriteError(EventIdentifier.RunPowerShellScriptRunScriptInconsistentScriptReturnTypeError, Messages.RunPowerShellScript_InconsistentScriptReturnTypeError, pso.BaseObject.GetType(), type); } } // If we have multiple values of an inconsistent type, there is a problem // which needs to be addressed by the administrator if (!consistentType) { throw Logger.Instance.ReportError(EventIdentifier.RunPowerShellScriptRunScriptInconsistentScriptReturnTypeError, new WorkflowActivityLibraryException(Messages.RunPowerShellScript_InvalidReturnTypeError)); } // Because we have multiple values returned for the PowerShell script, // we want to return them in the form of a strongly-typed list // For example: List<string> instead of List<object> // Use reflection to create a new strongly-typed list Type listType = typeof(List <>).MakeGenericType(new Type[] { type }); var typedList = Activator.CreateInstance(listType); // Using reflection, fetch the add method for the new list // and invoke it to add each value from the original PSobject collection to the new collection // Return the strongly-typed list MethodInfo add = listType.GetMethod("Add"); foreach (PSObject pso in results) { add.Invoke(typedList, new object[] { pso.BaseObject }); } return(typedList); } StringBuilder message = new StringBuilder(); message.AppendFormat(Messages.RunPowerShellScript_ScriptExecutionFailedError, shell.Streams.Error.Count); foreach (ErrorRecord error in shell.Streams.Error) { message.AppendFormat("{0}\n", error); } throw Logger.Instance.ReportError(EventIdentifier.RunPowerShellScriptRunScriptExecutionFailedError, new WorkflowActivityLibraryException(message.ToString())); } } } catch (Exception ex) { throw Logger.Instance.ReportError(EventIdentifier.RunPowerShellScriptRunScriptExecutionFailedError, ex); } finally { if (context != null) { context.Undo(); } if (logOnUser != null) { logOnUser.Dispose(); } Logger.Instance.WriteMethodExit(EventIdentifier.RunPowerShellScriptRunScript); } }