public void AysncAddCommand(string command, string arg, int pindex = 0)
 {
     if (ps != null)
     {
         ps.AddCommand(command);
         ps.AddArgument(arg);
     }
 }
Esempio n. 2
0
 private void RunCommandQuetly(string command, string argument)
 {
     shell.Runspace = host.Runspace;
     shell.AddCommand(command);
     shell.AddArgument(argument);
     shell.Invoke();
 }
Esempio n. 3
0
        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();
            }
        }
Esempio n. 4
0
            /* 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);
            }
Esempio n. 5
0
        // 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());
            }
        }
Esempio n. 7
0
        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);
                }
            }
        }
Esempio n. 8
0
        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);
        }
Esempio n. 9
0
        /// <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;
        }
Esempio n. 10
0
        /// <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;
        }
Esempio n. 11
0
        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);
        }