Beispiel #1
0
        /// <summary>
        /// Initialize the runspace pool.
        /// </summary>
        /// <param name="minRunspaces"></param>
        /// <param name="maxRunspaces"></param>
        public void InitializeRunspaces(int minRunspaces, int maxRunspaces, string[] modulesToLoad)
        {
            // create the default session state.
            // session state can be used to set things like execution policy, language constraints, etc.
            // optionally load any modules (by name) that were supplied.

            var defaultSessionState = InitialSessionState.CreateDefault();

            defaultSessionState.ExecutionPolicy = Microsoft.PowerShell.ExecutionPolicy.Unrestricted;

            foreach (var moduleName in modulesToLoad)
            {
                defaultSessionState.ImportPSModule(moduleName);
            }

            // use the runspace factory to create a pool of runspaces
            // with a minimum and maximum number of runspaces to maintain.

            RsPool = RunspaceFactory.CreateRunspacePool(defaultSessionState);
            RsPool.SetMinRunspaces(minRunspaces);
            RsPool.SetMaxRunspaces(maxRunspaces);

            // set the pool options for thread use.
            // we can throw away or re-use the threads depending on the usage scenario.

            RsPool.ThreadOptions = PSThreadOptions.UseNewThread;

            // open the pool.
            // this will start by initializing the minimum number of runspaces.

            RsPool.Open();
        }
Beispiel #2
0
        /// <summary>
        /// Initialize the runspace pool.
        /// </summary>
        /// <param name="runspace">Contains runspace config parameters necessary for the script</param>
        public void InitializeRunspaces(ScriptRunspace runspace)
        {
            // create the default session state.
            // session state can be used to set things like execution policy, language constraints, etc.
            var defaultSessionState = InitialSessionState.CreateDefault();

            if (!String.IsNullOrEmpty(runspace.ExecutionPolicy))
            {
                defaultSessionState.ExecutionPolicy = runspace.ExecutionPolicy.ToEnum <Microsoft.PowerShell.ExecutionPolicy>();
            }

            // optionally load any modules (by name) that were supplied.
            foreach (var moduleName in runspace.Modules)
            {
                defaultSessionState.ImportPSModule(moduleName);
            }

            // use the runspace factory to create a pool of runspaces with a minimum and maximum number of runspaces to maintain.
            RsPool = RunspaceFactory.CreateRunspacePool(defaultSessionState);
            RsPool.SetMinRunspaces(runspace.Min);
            RsPool.SetMaxRunspaces(runspace.Max);

            // set the pool options for thread use.
            // we can throw away or re-use the threads depending on the usage scenario.
            RsPool.ThreadOptions = PSThreadOptions.UseNewThread;

            // open the pool. this will start by initializing the minimum number of runspaces.
            RsPool.Open();
        }
Beispiel #3
0
        public (string, string) InMemoryPfxRunspacePool()
        {
            // IApplicationEnvironment for ASP.NET Core
            string asmPath    = System.Reflection.Assembly.GetExecutingAssembly().Location;
            string rootFolder = System.IO.Path.GetDirectoryName(asmPath);

            var timer = Stopwatch.StartNew();

            var defaultSessionState = InitialSessionState.CreateDefault();

            defaultSessionState.ExecutionPolicy          = Microsoft.PowerShell.ExecutionPolicy.Unrestricted;
            defaultSessionState.ThrowOnRunspaceOpenError = true;
            defaultSessionState.ImportPSModule(new string[] { "ExchangeOnlineManagement" });
            defaultSessionState.Variables.Add(new SessionStateVariableEntry("exoAppId", AppId, "no description"));
            defaultSessionState.Variables.Add(new SessionStateVariableEntry("exoOrganization", Organization, "no description"));
            defaultSessionState.Variables.Add(new SessionStateVariableEntry("exoCertificate", Certificate, "no description"));
            bool result = defaultSessionState.StartupScripts.Add(System.IO.Path.Combine(rootFolder, "ConnectExO.ps1"));

            using (RunspacePool RsPool = RunspaceFactory.CreateRunspacePool(defaultSessionState))
            {
                RsPool.SetMinRunspaces(1);
                RsPool.SetMaxRunspaces(3);

                RsPool.ThreadOptions = PSThreadOptions.UseNewThread;

                RsPool.Open();

                var ts1 = timer.Elapsed;

                using (var ps = PowerShell.Create())
                {
                    ps.RunspacePool = RsPool;

                    // ps.Commands.Clear();
                    ps.Commands.AddCommand("Get-EXOMailBox")
                    .AddParameter("ResultSize", "unlimited");

                    // var pipelineObjects = await ps.InvokeAsync().ConfigureAwait(false);
                    List <PSObject> results = ps.Invoke().ToList();

                    var ts2 = timer.Elapsed;
                    return(FlattenErrors(ps), ResultsToSimpleString(results));
                }
            }
        }
Beispiel #4
0
        /// <summary>
        /// GetExternalRecord: Get external rules in parallel using RunspacePool and run each rule in its own runspace.
        /// </summary>
        /// <param name="ast"></param>
        /// <param name="token"></param>
        /// <param name="rules"></param>
        /// <param name="command"></param>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public IEnumerable <DiagnosticRecord> GetExternalRecord(Ast ast, Token[] token, ExternalRule[] rules, InvokeScriptAnalyzerCommand command, string filePath)
        {
            // Defines InitialSessionState.
            InitialSessionState state = InitialSessionState.CreateDefault2();

            // Groups rules by module paths and imports them.
            Dictionary <string, List <ExternalRule> > modules = rules
                                                                .GroupBy <ExternalRule, string>(item => item.GetFullModulePath())
                                                                .ToDictionary(item => item.Key, item => item.ToList());

            state.ImportPSModule(modules.Keys.ToArray <string>());

            // Creates and opens RunspacePool
            RunspacePool rsp = RunspaceFactory.CreateRunspacePool(state);

            rsp.SetMinRunspaces(1);
            rsp.SetMaxRunspaces(5);
            rsp.Open();

            // Groups rules by AstType and Tokens.
            Dictionary <string, List <ExternalRule> > astRuleGroups = rules
                                                                      .Where <ExternalRule>(item => item.GetParameter().EndsWith("ast", StringComparison.OrdinalIgnoreCase))
                                                                      .GroupBy <ExternalRule, string>(item => item.GetParameterType())
                                                                      .ToDictionary(item => item.Key, item => item.ToList());

            Dictionary <string, List <ExternalRule> > tokenRuleGroups = rules
                                                                        .Where <ExternalRule>(item => item.GetParameter().EndsWith("token", StringComparison.OrdinalIgnoreCase))
                                                                        .GroupBy <ExternalRule, string>(item => item.GetParameterType())
                                                                        .ToDictionary(item => item.Key, item => item.ToList());

            using (rsp)
            {
                // Defines the commands to be run.
                List <System.Management.Automation.PowerShell> powerShellCommands
                    = new List <System.Management.Automation.PowerShell>();

                // Defines the command results.
                List <IAsyncResult> powerShellCommandResults = new List <IAsyncResult>();

                #region Builds and invokes commands list

                foreach (KeyValuePair <string, List <ExternalRule> > tokenRuleGroup in tokenRuleGroups)
                {
                    foreach (IExternalRule rule in tokenRuleGroup.Value)
                    {
                        System.Management.Automation.PowerShell posh =
                            System.Management.Automation.PowerShell.Create();
                        posh.RunspacePool = rsp;

                        // Adds command to run external analyzer rule, like
                        // Measure-CurlyBracket -ScriptBlockAst $ScriptBlockAst
                        // Adds module name (source name) to handle ducplicate function names in different modules.
                        string ruleName = string.Format("{0}\\{1}", rule.GetSourceName(), rule.GetName());
                        posh.Commands.AddCommand(ruleName);
                        posh.Commands.AddParameter(rule.GetParameter(), token);

                        // Merges results because external analyzer rules may throw exceptions.
                        posh.Commands.Commands[0].MergeMyResults(PipelineResultTypes.Error,
                                                                 PipelineResultTypes.Output);

                        powerShellCommands.Add(posh);
                        powerShellCommandResults.Add(posh.BeginInvoke());
                    }
                }

                foreach (KeyValuePair <string, List <ExternalRule> > astRuleGroup in astRuleGroups)
                {
                    // Find all AstTypes that appeared in rule groups.
                    IEnumerable <Ast> childAsts = ast.FindAll(new Func <Ast, bool>((testAst) =>
                                                                                   (astRuleGroup.Key.IndexOf(testAst.GetType().FullName, StringComparison.OrdinalIgnoreCase) != -1)), false);

                    foreach (Ast childAst in childAsts)
                    {
                        foreach (IExternalRule rule in astRuleGroup.Value)
                        {
                            System.Management.Automation.PowerShell posh =
                                System.Management.Automation.PowerShell.Create();
                            posh.RunspacePool = rsp;

                            // Adds command to run external analyzer rule, like
                            // Measure-CurlyBracket -ScriptBlockAst $ScriptBlockAst
                            // Adds module name (source name) to handle ducplicate function names in different modules.
                            string ruleName = string.Format("{0}\\{1}", rule.GetSourceName(), rule.GetName());
                            posh.Commands.AddCommand(ruleName);
                            posh.Commands.AddParameter(rule.GetParameter(), childAst);

                            // Merges results because external analyzer rules may throw exceptions.
                            posh.Commands.Commands[0].MergeMyResults(PipelineResultTypes.Error,
                                                                     PipelineResultTypes.Output);

                            powerShellCommands.Add(posh);
                            powerShellCommandResults.Add(posh.BeginInvoke());
                        }
                    }
                }

                #endregion
                #region Collects the results from commands.
                List <DiagnosticRecord> diagnostics = new List <DiagnosticRecord>();
                try
                {
                    for (int i = 0; i < powerShellCommands.Count; i++)
                    {
                        // EndInvoke will wait for each command to finish, so we will be getting the commands
                        // in the same order that they have been invoked withy BeginInvoke.
                        PSDataCollection <PSObject> psobjects = powerShellCommands[i].EndInvoke(powerShellCommandResults[i]);

                        foreach (var psobject in psobjects)
                        {
                            DiagnosticSeverity severity;
                            IScriptExtent      extent;
                            string             message  = string.Empty;
                            string             ruleName = string.Empty;

                            if (psobject != null && psobject.ImmediateBaseObject != null)
                            {
                                // Because error stream is merged to output stream,
                                // we need to handle the error records.
                                if (psobject.ImmediateBaseObject is ErrorRecord)
                                {
                                    ErrorRecord record = (ErrorRecord)psobject.ImmediateBaseObject;
                                    command.WriteError(record);
                                    continue;
                                }

                                // DiagnosticRecord may not be correctly returned from external rule.
                                try
                                {
                                    Enum.TryParse <DiagnosticSeverity>(psobject.Properties["Severity"].Value.ToString().ToUpper(), out severity);
                                    message  = psobject.Properties["Message"].Value.ToString();
                                    extent   = (IScriptExtent)psobject.Properties["Extent"].Value;
                                    ruleName = psobject.Properties["RuleName"].Value.ToString();
                                }
                                catch (Exception ex)
                                {
                                    command.WriteError(new ErrorRecord(ex, ex.HResult.ToString("X"), ErrorCategory.NotSpecified, this));
                                    continue;
                                }

                                if (!string.IsNullOrEmpty(message))
                                {
                                    diagnostics.Add(new DiagnosticRecord(message, extent, ruleName, severity, null));
                                }
                            }
                        }
                    }
                }
                //Catch exception where customized defined rules have exceptins when doing invoke
                catch (Exception ex)
                {
                    command.WriteError(new ErrorRecord(ex, ex.HResult.ToString("X"), ErrorCategory.NotSpecified, this));
                }

                return(diagnostics);

                #endregion
            }
        }
Beispiel #5
0
        public PSScriptExecutor(string pathToScripts, string[] modulesToLoad, string psExecutionPolicy, string psOutputDelimiter)
        {
            this.pathToScripts     = pathToScripts;
            this.modulesToLoad     = modulesToLoad;
            this.psExecutionPolicy = psExecutionPolicy;
            this.psOutputDelimiter = psOutputDelimiter;

            // Initialise PowerShell Runspace and preload necessary modules.
            // See here: http://stackoverflow.com/a/17071164
            // See here: http://nivot.org/blog/post/2010/05/03/PowerShell20DeveloperEssentials1InitializingARunspaceWithAModule
            InitialSessionState initialSession = InitialSessionState.CreateDefault2();

            if (modulesToLoad != null && modulesToLoad.Length > 0)
            {
                initialSession.ImportPSModule(modulesToLoad);
            }

            if (psExecutionPolicy != "None")
            {
                PSScriptInvoker.logInfo("Setting custom PowerShell Execution Policy: " + psExecutionPolicy);
                switch (psExecutionPolicy)
                {
                case "AllSigned":
                    initialSession.ExecutionPolicy = ExecutionPolicy.AllSigned;
                    break;

                case "Bypass":
                    initialSession.ExecutionPolicy = ExecutionPolicy.Bypass;
                    break;

                case "RemoteSigned":
                    initialSession.ExecutionPolicy = ExecutionPolicy.RemoteSigned;
                    break;

                case "Restricted":
                    initialSession.ExecutionPolicy = ExecutionPolicy.Restricted;
                    break;

                case "Undefined":
                    initialSession.ExecutionPolicy = ExecutionPolicy.Undefined;
                    break;

                case "Unrestricted":
                    initialSession.ExecutionPolicy = ExecutionPolicy.Unrestricted;
                    break;

                default:
                    PSScriptInvoker.logWarning("Given custom PowerShell Execution Policy is unknown: " + psExecutionPolicy + ". Only one of the following custom policies is allowed: AllSigned, Bypass, RemoteSigned, Restricted, Undefined, Unrestricted. Set to policy 'Default'.");
                    initialSession.ExecutionPolicy = ExecutionPolicy.Default;
                    break;
                }
            }

            // This loads the InitialStateSession for all instances
            // Note you can set the minimum and maximum number of runspaces as well
            // Note that without setting the minimum and maximum number of runspaces, it will use 1 as default for both:
            // https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.runspaces.runspacefactory.createrunspacepool?view=powershellsdk-1.1.0
            // See here: https://stackoverflow.com/a/24358855
            runspacePool = RunspaceFactory.CreateRunspacePool(initialSession);
            runspacePool.SetMinRunspaces(MIN_RUNSPACES);
            runspacePool.SetMaxRunspaces(int.MaxValue);
            runspacePool.ThreadOptions = PSThreadOptions.UseNewThread;
            runspacePool.Open();
        }