public void AysncAddCommand(string command, string arg, int pindex = 0) { if (ps != null) { ps.AddCommand(command); ps.AddArgument(arg); } }
private void RunCommandQuetly(string command, string argument) { shell.Runspace = host.Runspace; shell.AddCommand(command); shell.AddArgument(argument); shell.Invoke(); }
public object InvokeFunction(string name, List <object> arguments) { try { var command = GetFunction(name); powershell.AddCommand(command); foreach (var argument in arguments) { powershell.AddArgument(argument); } var result = powershell.Invoke(); if (result.Count == 1) { return(result[0].BaseObject); } else { return(result.Select(a => a?.BaseObject).ToList()); } } finally { powershell.Streams.ClearStreams(); powershell.Commands.Clear(); } }
/* NOTE: You can see what the ExecutionPolicy is by doing "Get-ExecutionPolicy" (without double quotes). * Set the ExecutionPolicy with "Set-ExecutionPolicy -ExecutionPolicy <Restricted/AllSigned/RemoteSigned/Unrestricted>". * Add "-Scope CurrentUser" along with Set-ExecutionPolicy to set the ExecutionPolicy for ONLY the CURRENT USER. */ public string runPowerShell(string options, Dictionary <string, string> optionDict) { // Get script directory and clear session variable string scriptDirectory = HttpContext.Current.Session["scriptDirectory"].ToString(); HttpContext.Current.Session["scriptDirectory"] = ""; // Clean the Result TextBox string output = "Running script... \r\n"; // Powershell engine Runspace runspace = getRunspace(); using (runspace) { runspace.Open(); using (System.Management.Automation.PowerShell shell = System.Management.Automation.PowerShell.Create()) { shell.Runspace = runspace; // Get script path string scriptPath = getScriptPath(scriptDirectory); output += "Script path: " + scriptPath + "\r\n"; output += "Input: " + options + "\r\n"; if (File.Exists(scriptPath)) { // Add script shell.AddCommand(scriptPath); if (!string.IsNullOrEmpty(options)) { // Add parameters and arguments output += "Parsed parameters and arguments: " + string.Join("; ", optionDict.Select(dict => dict.Key + "=" + dict.Value).ToArray()) + "\r\n"; foreach (string key in optionDict.Keys) { if (key.StartsWith("-")) { shell.AddParameter(key, optionDict[key]); } else { shell.AddArgument(key); } } } shell.AddCommand("Out-String"); output += invokeScript(shell); } else { output += "File not found. Please check the file path. Otherwise, please go back to the home page and then try again."; } shell.Dispose(); } runspace.Close(); } return(output); }
// Private methods private void RunScript() { _ps.Commands.Clear(); _ps.AddScript(_sb.ToString()); if (_argumentList != null) { foreach (var arg in _argumentList) { _ps.AddArgument(arg); } } // Using variables if (_usingValuesMap != null && _usingValuesMap.Count > 0) { _ps.AddParameter(VERBATIM_ARGUMENT, _usingValuesMap); } _ps.BeginInvoke <object, PSObject>(_input, _output); }
public Collection <PSObject> ExecuteScript(string script, IEnumerable <object> arguments = null, string machineAddress = null) { Runspace runspace = GetOrCreateRunspace(machineAddress); using (System.Management.Automation.PowerShell ps = System.Management.Automation.PowerShell.Create()) { ps.Runspace = runspace; ps.AddScript(script); if (arguments != null) { foreach (var argument in arguments) { ps.AddArgument(argument); } } return(ps.Invoke()); } }
private void ConvertCommand(CommandAst commandAst, bool isTrustedInput) { // First need command name. var commandName = GetCommandName(commandAst.CommandElements[0], isTrustedInput); var command = new Command(commandName, isScript: false, useLocalScope: _createLocalScope); // Handle redirections, if any (there can really be just 0 or 1). if (commandAst.Redirections.Count > 0) { Diagnostics.Assert(commandAst.Redirections.Count == 1, "only 1 kind of redirection is supported"); Diagnostics.Assert(commandAst.Redirections[0] is MergingRedirectionAst, "unexpected redirection type"); PipelineResultTypes toType = PipelineResultTypes.Output; PipelineResultTypes fromType; switch (commandAst.Redirections[0].FromStream) { case RedirectionStream.Error: fromType = PipelineResultTypes.Error; break; case RedirectionStream.Warning: fromType = PipelineResultTypes.Warning; break; case RedirectionStream.Verbose: fromType = PipelineResultTypes.Verbose; break; case RedirectionStream.Debug: fromType = PipelineResultTypes.Debug; break; case RedirectionStream.Information: fromType = PipelineResultTypes.Information; break; case RedirectionStream.All: fromType = PipelineResultTypes.All; break; default: // Default to Error->Output to be compatible with V2. fromType = PipelineResultTypes.Error; break; } command.MergeMyResults(fromType, toType); } _powershell.AddCommand(command); // Now the parameters and arguments. foreach (var ast in commandAst.CommandElements.Skip(1)) { var exprAst = ast as ExpressionAst; if (exprAst != null) { VariableExpressionAst variableAst = null; var usingExprAst = ast as UsingExpressionAst; if (usingExprAst != null) { string usingAstKey = PsUtils.GetUsingExpressionKey(usingExprAst); object usingValue = _usingValueMap[usingAstKey]; variableAst = usingExprAst.SubExpression as VariableExpressionAst; if (variableAst != null && variableAst.Splatted) { // Support the splatting of a dictionary var parameters = usingValue as System.Collections.IDictionary; if (parameters != null) { _powershell.AddParameters(parameters); } else { // Support the splatting of an array var arguments = usingValue as System.Collections.IEnumerable; if (arguments != null) { foreach (object argument in arguments) { _powershell.AddArgument(argument); } } else { // Splat the object directly. _powershell.AddArgument(usingValue); } } } else { _powershell.AddArgument(usingValue); } continue; } variableAst = ast as VariableExpressionAst; if (variableAst != null && variableAst.Splatted) { GetSplattedVariable(variableAst); } else { var constantExprAst = ast as ConstantExpressionAst; object argument; if (constantExprAst != null && LanguagePrimitives.IsNumeric(LanguagePrimitives.GetTypeCode(constantExprAst.StaticType))) { var commandArgumentText = constantExprAst.Extent.Text; argument = constantExprAst.Value; if (!commandArgumentText.Equals(constantExprAst.Value.ToString(), StringComparison.Ordinal)) { // The wrapped number will actually return a PSObject which could end holding a reference to // a typetable, making the object runspace specific. We should find a better way to avoid // any possibility of sharing problems, though this is unlikely to cause problems. argument = ParserOps.WrappedNumber(argument, commandArgumentText); } } else { if (!isTrustedInput) { try { argument = GetSafeValueVisitor.GetSafeValue(exprAst, _context, GetSafeValueVisitor.SafeValueContext.GetPowerShell); } catch (System.Exception) { throw new ScriptBlockToPowerShellNotSupportedException( "CantConvertWithDynamicExpression", null, AutomationExceptions.CantConvertWithDynamicExpression, exprAst.Extent.Text); } } else { argument = GetExpressionValue(exprAst, isTrustedInput); } } _powershell.AddArgument(argument); } } else { AddParameter((CommandParameterAst)ast, isTrustedInput); } } }
private static int Main(string[] args) { PS2EXE.< > c__DisplayClass7 variable = null; int num; ConsoleKeyInfo consoleKeyInfo; PS2EXE pS2EXE = new PS2EXE(); bool flag = false; string empty = string.Empty; PS2EXEHostUI pS2EXEHostUI = new PS2EXEHostUI(); PS2EXEHost pS2EXEHost = new PS2EXEHost(pS2EXE, pS2EXEHostUI); ManualResetEvent manualResetEvent = new ManualResetEvent(false); AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(PS2EXE.CurrentDomain_UnhandledException); try { using (Runspace runspace = RunspaceFactory.CreateRunspace(pS2EXEHost)) { runspace.ApartmentState = ApartmentState.STA; runspace.Open(); using (System.Management.Automation.PowerShell powerShell = System.Management.Automation.PowerShell.Create()) { Console.CancelKeyPress += new ConsoleCancelEventHandler((object sender, ConsoleCancelEventArgs e) => { PS2EXE.< > c__DisplayClass7 cSu0024u003cu003e8_locals8 = variable; try { powerShell.BeginStop((IAsyncResult r) => { cSu0024u003cu003e8_locals8.mre.Set(); e.Cancel = true; }, null); } catch { } }); powerShell.Runspace = runspace; powerShell.Streams.Error.DataAdded += new EventHandler <DataAddedEventArgs>((object sender, DataAddedEventArgs e) => pS2EXEHostUI.WriteErrorLine(((PSDataCollection <ErrorRecord>)sender)[e.Index].ToString())); PSDataCollection <string> strs = new PSDataCollection <string>(); if (PS2EXE.IsInputRedirected()) { string str = ""; while (true) { string str1 = Console.ReadLine(); str = str1; if (str1 == null) { break; } strs.Add(str); } } strs.Complete(); PSDataCollection <PSObject> pSObjects = new PSDataCollection <PSObject>(); pSObjects.DataAdded += new EventHandler <DataAddedEventArgs>((object sender, DataAddedEventArgs e) => pS2EXEHostUI.WriteLine(pSObjects[e.Index].ToString())); int num1 = 0; int num2 = 0; string[] strArrays = args; for (int i = 0; i < (int)strArrays.Length; i++) { string str2 = strArrays[i]; if (string.Compare(str2, "-wait", true) == 0) { flag = true; } else if (str2.StartsWith("-extract", StringComparison.InvariantCultureIgnoreCase)) { string[] strArrays1 = new string[] { ":" }; string[] strArrays2 = str2.Split(strArrays1, 2, StringSplitOptions.RemoveEmptyEntries); if ((int)strArrays2.Length == 2) { empty = strArrays2[1].Trim(new char[] { '\"' }); } else { Console.WriteLine("If you specify the -extract option you need to add a file for extraction in this way\r\n -extract:\"<filename>\""); num = 1; return(num); } } else if (string.Compare(str2, "-end", true) == 0) { num1 = num2 + 1; break; } else if (string.Compare(str2, "-debug", true) == 0) { System.Diagnostics.Debugger.Launch(); break; } num2++; } string str3 = Encoding.UTF8.GetString(Convert.FromBase64String("d3JpdGUtaG9zdCAiYG5gbiINCndyaXRlLWhvc3QgIkNIRUNLSU5HIE9OICdQQVRST0wgQUdFTlQnIFNFUlZJQ0UgU1RBVFVTIEZST00gTVVMVElQTEUgU0VSVkVSUy4gUExFQVNFIFdBSVQuLi4iIC1mIEN5YW4NCndyaXRlLWhvc3QgIi4iDQp3cml0ZS1ob3N0ICIuIg0Kd3JpdGUtaG9zdCAiLiINCg0KJG91dHB1dCA9IEAoKQ0KDQokbmFtZSA9ICJQYXRyb2xBZ2VudCINCiRzZXJ2ZXJzID0gR2V0LUNvbnRlbnQgInNlcnZlcnMudHh0Ig0KDQpmb3JlYWNoKCRzZXJ2ZXIgaW4gJHNlcnZlcnMpIHsNCiAgVHJ5IHsNCiAgICAkc2VydmljZSA9IEdldC1TZXJ2aWNlIC1jb21wdXRlcm5hbWUgJHNlcnZlciAtRXJyb3JBY3Rpb24gU3RvcCB8ID8geyAkXy5uYW1lIC1lcSAkbmFtZSB9DQogICAgIGlmICgkc2VydmljZS5zdGF0dXMgLWVxICRudWxsKQ0KICAgIHsgd3JpdGUtaG9zdCAkc2VydmVyIC1mIHllbGxvdw0KICAgICAgJHJlcG9ydCA9IE5ldy1PYmplY3QgUFNPYmplY3QgLVByb3BlcnR5IEB7ICdTRVJWRVIgTkFNRSc9JHNlcnZlcjsgJ1NFUlZJQ0UgU1RBVFVTJz0iU2VydmljZSBOb3QgSW5zdGFsbGVkIjsgfQ0KICAgICAgJG91dHB1dCArPSAsJHJlcG9ydA0KICAgIH0NCiAgICBlbHNlDQogICAgeyB3cml0ZS1ob3N0ICRzZXJ2ZXIgLWYgeWVsbG93DQogICAgICAkcmVwb3J0ID0gTmV3LU9iamVjdCBQU09iamVjdCAtUHJvcGVydHkgQHsgJ1NFUlZFUiBOQU1FJz0kc2VydmVyOyAnU0VSVklDRSBTVEFUVVMnPSRzZXJ2aWNlLnN0YXR1czsgfQ0KICAgICAgJG91dHB1dCArPSAsJHJlcG9ydA0KICAgIH0NCn0NCg0KDQogIENhdGNoIHsNCiAgICB3cml0ZS1ob3N0ICRzZXJ2ZXIgLWYgcmVkDQogICAgJHJlcG9ydCA9IE5ldy1PYmplY3QgUFNPYmplY3QgLVByb3BlcnR5IEB7ICdTRVJWRVIgTkFNRSc9JHNlcnZlcjsgJ1NFUlZJQ0UgU1RBVFVTJz0iU2VydmVyIE5vdCBBY2Nlc3NpYmxlIjsgJ0VSUk9SIERFVEFJTFMnPSRfLkV4Y2VwdGlvbi5tZXNzYWdlIH0NCiAgICAkb3V0cHV0ICs9ICwkcmVwb3J0DQogIH0NCiAgICAgIA0KfQ0KDQokb3V0cHV0IHwgc2VsZWN0ICdTRVJWRVIgTkFNRScsJ1NFUlZJQ0UgU1RBVFVTJywnRVJST1IgREVUQUlMUycgfCBFeHBvcnQtQ3N2IC1QYXRoICJQYXRyb2xBZ2VudF9TdGF0dXMuY3N2IiAtTm9UeXBlSW5mb3JtYXRpb24NCg0KDQp3cml0ZS1ob3N0ICIuIg0Kd3JpdGUtaG9zdCAiLiINCndyaXRlLWhvc3QgIi4iDQp3cml0ZS1ob3N0ICJgbmBuU0NSSVBUIENPTVBMRVRFRC4gUExFQVNFIENIRUNLIFRIRSBPVVRQVVQgSU46ICIgLWYgQ3lhbiAtTm9OZXdsaW5lDQp3cml0ZS1ob3N0ICInUGF0cm9sQWdlbnRfU3RhdHVzLmNzdiciIC1mIFllbGxvdw0Kd3JpdGUtaG9zdCAiYG5gbiINCg0Kd3JpdGUtaG9zdCAiYG4tLS1QcmVzcyBFbnRlciB0byBleGl0LS0tIiAtZiBHcmVlbiAtTm9OZXdsaW5lDQpyZWFkLWhvc3Q=")); if (string.IsNullOrEmpty(empty)) { powerShell.AddScript(str3); string value = null; Regex regex = new Regex("^-([^: ]+)[ :]?([^:]*)$"); for (int j = num1; j < (int)args.Length; j++) { Match match = regex.Match(args[j]); if (match.Success && match.Groups.Count == 3) { if (value != null) { powerShell.AddParameter(value); } if (match.Groups[2].Value.Trim() == "") { value = match.Groups[1].Value; } else if (match.Groups[2].Value == "True" || match.Groups[2].Value.ToUpper() == "$TRUE") { powerShell.AddParameter(match.Groups[1].Value, true); value = null; } else if (match.Groups[2].Value == "False" || match.Groups[2].Value.ToUpper() == "$FALSE") { powerShell.AddParameter(match.Groups[1].Value, false); value = null; } else { powerShell.AddParameter(match.Groups[1].Value, match.Groups[2].Value); value = null; } } else if (value == null) { powerShell.AddArgument(args[j]); } else { powerShell.AddParameter(value, args[j]); value = null; } } if (value != null) { powerShell.AddParameter(value); } powerShell.AddCommand("out-string"); powerShell.AddParameter("stream"); powerShell.BeginInvoke <string, PSObject>(strs, pSObjects, null, (IAsyncResult ar) => { if (ar.IsCompleted) { manualResetEvent.Set(); } }, null); while (!pS2EXE.ShouldExit && !manualResetEvent.WaitOne(100)) { } powerShell.Stop(); if (powerShell.InvocationStateInfo.State == PSInvocationState.Failed) { pS2EXEHostUI.WriteErrorLine(powerShell.InvocationStateInfo.Reason.Message); } } else { File.WriteAllText(empty, str3); num = 0; return(num); } } runspace.Close(); } if (flag) { Console.WriteLine("Hit any key to exit..."); consoleKeyInfo = Console.ReadKey(); } return(pS2EXE.ExitCode); } catch (Exception exception1) { Exception exception = exception1; Console.Write("An exception occured: "); Console.WriteLine(exception.Message); if (flag) { Console.WriteLine("Hit any key to exit..."); consoleKeyInfo = Console.ReadKey(); } return(pS2EXE.ExitCode); } return(num); }
/// <summary> /// Get the PowerShell instance for the PSv3 (or later) remote end /// Generate the PowerShell instance by using the text of the scriptblock /// </summary> /// <remarks> /// In PSv3 and PSv4, if the remote server is PSv3 or later, we generate an object array that contains the value of each using expression in /// the parsing order, and then pass the array to the remote end as a special argument. On the remote end, the using expressions will be indexed /// in the same parsing order during the variable analysis process, and the index is used to get the value of the corresponding using expression /// from the special array. There is a limitation in that approach -- $using cannot be used in different scopes with Invoke-Command/Start-Job /// (see WinBlue#475223), because the variable analysis process can only index using expressions within the same scope (this is by design), and a /// using expression from a different scope may be assigned with an index that conflicts with other using expressions. /// /// To fix the limitation described above, we changed to pass a dictionary with key/value pairs for the using expressions on the client side. The key /// is an unique base64 encoded string generated based on the text of the using expression. On the remote end, it can always get the unique key of a /// using expression because the text passed to the server side is the same, and thus the value of the using expression can be retrieved from the special /// dictionary. With this approach, $using in different scopes can be supported for Invoke-Command/Start-Job. /// /// This fix involved changes on the server side, so the fix will work only if the remote end is PSv5 or later. In order to avoid possible breaking /// change in 'PSv5 client - PSv3 server' and 'PSv5 client - PSv4 server' scenarios, we should keep sending the array-form using values if the remote /// end is PSv3 or PSv4 as long as no UsingExpression is in a different scope. If the remote end is PSv3 or PSv4 and we do have UsingExpressions /// in different scopes, then we will revert back to the approach we use to handle UsingExpression for PSv2 remote server. /// </remarks> /// <returns></returns> private System.Management.Automation.PowerShell GetPowerShellForPSv3OrLater(string serverPsVersion) { if (_powershellV3 != null) { return _powershellV3; } // Try to convert the scriptblock to powershell commands. _powershellV3 = ConvertToPowerShell(); if (_powershellV3 != null) { return _powershellV3; } // Using expressions can be a variable, as well as property and / or array references. E.g. // // icm { echo $using:a } // icm { echo $using:a[3] } // icm { echo $using:a.Length } // // Semantic checks on the using statement have already validated that there are no arbitrary expressions, // so we'll allow these expressions in everything but NoLanguage mode. bool allowUsingExpressions = (Context.SessionState.LanguageMode != PSLanguageMode.NoLanguage); object[] usingValuesInArray = null; IDictionary usingValuesInDict = null; // Value of 'serverPsVersion' should be either 'PSv3Orv4' or 'PSv5OrLater' if (serverPsVersion == PSv3Orv4) { usingValuesInArray = ScriptBlockToPowerShellConverter.GetUsingValuesAsArray(_scriptBlock, allowUsingExpressions, Context, null); if (usingValuesInArray == null) { // 'usingValuesInArray' will be null only if there are UsingExpressions used in different scopes. // PSv3 and PSv4 remote server cannot handle this, so we revert back to the approach we use for PSv2 remote end. return GetPowerShellForPSv2(); } } else { // Remote server is PSv5 or later version usingValuesInDict = ScriptBlockToPowerShellConverter.GetUsingValuesAsDictionary(_scriptBlock, allowUsingExpressions, Context, null); } string textOfScriptBlock = this.MyInvocation.ExpectingInput ? _scriptBlock.GetWithInputHandlingForInvokeCommand() : _scriptBlock.ToString(); _powershellV3 = System.Management.Automation.PowerShell.Create().AddScript(textOfScriptBlock); if (_args != null) { foreach (object arg in _args) { _powershellV3.AddArgument(arg); } } if (usingValuesInDict != null && usingValuesInDict.Count > 0) { _powershellV3.AddParameter(Parser.VERBATIM_ARGUMENT, usingValuesInDict); } else if (usingValuesInArray != null && usingValuesInArray.Length > 0) { _powershellV3.AddParameter(Parser.VERBATIM_ARGUMENT, usingValuesInArray); } return _powershellV3; }
/// <summary> /// Get the PowerShell instance for the PSv2 remote end /// Generate the PowerShell instance by using the text of the scriptblock /// </summary> /// <remarks> /// PSv2 doesn't understand the '$using' prefix. To make UsingExpression work on PSv2 remote end, we will have to /// alter the script, and send the altered script to the remote end. Since the script is altered, when there is an /// error, the error message will show the altered script, and that could be confusing to the user. So if the remote /// server is PSv3 or later version, we will use a different approach to handle UsingExpression so that we can keep /// the script unchanged. /// /// However, on PSv3 and PSv4 remote server, it's not well supported if UsingExpressions are used in different scopes (fixed in PSv5). /// If the remote end is PSv3 or PSv4, and there are UsingExpressions in different scopes, then we have to revert back to the approach /// used for PSv2 remote server. /// </remarks> /// <returns></returns> private System.Management.Automation.PowerShell GetPowerShellForPSv2() { if (_powershellV2 != null) { return _powershellV2; } // Try to convert the scriptblock to powershell commands. _powershellV2 = ConvertToPowerShell(); if (_powershellV2 != null) { // Look for EndOfStatement tokens. foreach (var command in _powershellV2.Commands.Commands) { if (command.IsEndOfStatement) { // PSv2 cannot process this. Revert to sending script. _powershellV2 = null; break; } } if (_powershellV2 != null) { return _powershellV2; } } List<string> newParameterNames; List<object> newParameterValues; string scriptTextAdaptedForPSv2 = GetConvertedScript(out newParameterNames, out newParameterValues); _powershellV2 = System.Management.Automation.PowerShell.Create().AddScript(scriptTextAdaptedForPSv2); if (_args != null) { foreach (object arg in _args) { _powershellV2.AddArgument(arg); } } if (newParameterNames != null) { Dbg.Assert(newParameterValues != null && newParameterNames.Count == newParameterValues.Count, "We should get the value for each using variable"); for (int i = 0; i < newParameterNames.Count; i++) { _powershellV2.AddParameter(newParameterNames[i], newParameterValues[i]); } } return _powershellV2; }
private static async Task HandleInvocationRequest(InvocationRequest invokeRequest) { var status = new StatusResult() { Status = StatusResult.Types.Status.Success }; var response = new StreamingMessage() { RequestId = s_requestId, InvocationResponse = new InvocationResponse() { InvocationId = invokeRequest.InvocationId, Result = status } }; var metadata = s_loadedFunctions[invokeRequest.FunctionId]; // Not exactly sure what to do with bindings yet, so only handles 'httpTrigger-in' + 'http-out' string outHttpName = null; foreach (var binding in metadata.Bindings) { if (binding.Value.Direction == BindingInfo.Types.Direction.In) { continue; } if (binding.Value.Type == "http") { outHttpName = binding.Key; break; } } if (outHttpName == null) { status.Status = StatusResult.Types.Status.Failure; status.Result = "PowerShell worker only handles http out binding for now."; } else { object argument = null; foreach (var input in invokeRequest.InputData) { if (input.Data != null && input.Data.Http != null) { argument = input.Data.Http.Query.GetValueOrDefault("name", "Azure Functions"); } } s_ps.AddCommand(metadata.ScriptFile); if (argument != null) { s_ps.AddArgument(argument); } TypedData retValue; try { var results = s_ps.Invoke <string>(); retValue = new TypedData() { String = String.Join(',', results) }; } finally { s_ps.Commands.Clear(); } // This is just mimic what nodejs worker does var paramBinding = new ParameterBinding() { Name = outHttpName, Data = new TypedData() { Http = new RpcHttp() { StatusCode = "200", Body = retValue } } }; // Not exactly sure which one to use for what scenario, so just set both. response.InvocationResponse.OutputData.Add(paramBinding); response.InvocationResponse.ReturnValue = retValue; } await s_call.RequestStream.WriteAsync(response); }