Пример #1
0
 public void Error_DataAdded(object sender, DataAddedEventArgs e)
 {
     try
     {
         var items = (IList)sender;
         var item  = items[e.Index];
         _log.Error("{0}", item);
     }
     catch (Exception ex)
     {
         _log.Warning("Exception logging error: {0}", ex);
     }
 }
Пример #2
0
        public void Apply(IContextManager contextManager, IUpgradeLog logger)
        {
            // IDEA: The other alternative to a custom host is simply define function Write-Host
            var host         = new ScriptHost(logger);
            var outputLogger = new OutputLogger(logger);
            var parameters   = GetScriptParameterNames().ToList();

            using (var runspace = RunspaceFactory.CreateRunspace(host))
            {
                runspace.Open();
                //runspace.SessionStateProxy.SetVariable("ErrorActionPreference", "Stop");
                runspace.SessionStateProxy.SetVariable("SPContext", contextManager.CurrentContext);
                runspace.SessionStateProxy.SetVariable("SPUrl", contextManager.CurrentContext.Url);
                runspace.SessionStateProxy.SetVariable("SPUserName", contextManager.UserName);
                runspace.SessionStateProxy.SetVariable("SPPassword", contextManager.Password);
                runspace.SessionStateProxy.SetVariable("SPSecurePassword", contextManager.SecurePassword);
                PSCredential psCredential = null;
                if (!string.IsNullOrWhiteSpace(contextManager.UserName) && contextManager.SecurePassword != null)
                {
                    psCredential = new PSCredential(contextManager.UserName, contextManager.SecurePassword);
                }
                runspace.SessionStateProxy.SetVariable("SPCredentials", psCredential);
                runspace.SessionStateProxy.SetVariable("SPVariables", _variables);

                // TODO: Allow custom parameters to be passed through (from ScriptMigrationProvider)

                // TODO: Store calculated PSCredential with ScriptHost / ScriptHostUI, so it returns from PromptForCredential

                //var initial = InitialSessionState.Create();
                //initial.ImportPSModule("OfficeDevPnP.PowerShell.Commands");

                using (var pipeline = runspace.CreatePipeline("Set-ExecutionPolicy Unrestricted -Scope Process -Confirm:$false -Force"))
                {
                    var output = pipeline.Invoke();
                }
                using (var pipeline = runspace.CreatePipeline("Import-Module OfficeDevPnP.PowerShell.Commands"))
                {
                    var output = pipeline.Invoke();
                }

                using (var shell = PowerShell.Create())
                {
                    shell.Runspace = runspace;

                    //shell.AddScript("Set-ExecutionPolicy Unrestricted -Scope CurrentUser;");
                    //shell.AddScript("Import-Module OfficeDevPnP.PowerShell.Commands");

                    shell.AddCommand(_filePath);
                    if (parameters.Any(p => string.Equals(p, "Context", StringComparison.InvariantCultureIgnoreCase)))
                    {
                        shell.AddParameter("Context", contextManager.CurrentContext);
                    }
                    if (parameters.Any(p => string.Equals(p, "Url", StringComparison.InvariantCultureIgnoreCase)))
                    {
                        shell.AddParameter("Url", contextManager.CurrentContext.Url);
                    }
                    if (parameters.Any(p => string.Equals(p, "UserName", StringComparison.InvariantCultureIgnoreCase)))
                    {
                        shell.AddParameter("UserName", contextManager.UserName);
                    }
                    if (parameters.Any(p => string.Equals(p, "Password", StringComparison.InvariantCultureIgnoreCase)))
                    {
                        shell.AddParameter("Password", contextManager.Password);
                    }
                    if (parameters.Any(p => string.Equals(p, "SecurePassword", StringComparison.InvariantCultureIgnoreCase)))
                    {
                        shell.AddParameter("SecurePassword", contextManager.SecurePassword);
                    }
                    if (parameters.Any(p => string.Equals(p, "Credentials", StringComparison.InvariantCultureIgnoreCase)))
                    {
                        shell.AddParameter("Credentials", psCredential);
                    }
                    // Custom parameters
                    foreach (var kvp in _variables)
                    {
                        if (parameters.Any(p => string.Equals(p, kvp.Key, StringComparison.InvariantCultureIgnoreCase)))
                        {
                            shell.AddParameter(kvp.Key, kvp.Value);
                        }
                    }

                    // Exit codes not supported... need to check exit within script and convert to error
                    //shell.AddScript("Write-Host \"EXIT: $LastExitCode\";");

                    PSDataCollection <PSObject> outputCollection = new PSDataCollection <PSObject>();
                    //outputCollection.DataAdded += OutputCollection_DataAdded;
                    outputCollection.DataAdded       += outputLogger.OutputCollection_DataAdded;
                    shell.Streams.Debug.DataAdded    += outputLogger.Debug_DataAdded;
                    shell.Streams.Error.DataAdded    += outputLogger.Error_DataAdded;
                    shell.Streams.Progress.DataAdded += outputLogger.Progress_DataAdded;
                    shell.Streams.Verbose.DataAdded  += outputLogger.Verbose_DataAdded;
                    shell.Streams.Warning.DataAdded  += outputLogger.Warning_DataAdded;

                    var settings = new PSInvocationSettings()
                    {
                        ErrorActionPreference = ActionPreference.Stop
                    };
                    IAsyncResult result = shell.BeginInvoke <PSObject, PSObject>(null, outputCollection, settings, null, null);

                    while (result.IsCompleted == false)
                    {
                        //Console.WriteLine("Waiting for pipeline to finish...");
                        Thread.Sleep(1000);

                        // TODO: Add timeout (configured from ScriptMigrationProvider)
                    }

                    //Console.WriteLine("** Host. ShouldExit: {0}, ExitCode: {1}, HadErrors: {0}. State: {1}, Reason: {2}",
                    //    host.ShouldExit, host.ExitCode, shell.HadErrors, shell.InvocationStateInfo.State, shell.InvocationStateInfo.Reason);

                    //Console.WriteLine("Output (after script run):");
                    //foreach (PSObject outputItem in outputCollection)
                    //{
                    //    //TODO: handle/process the output items if required
                    //    Console.WriteLine(outputItem.BaseObject.ToString());
                    //}

                    if (host.ExitCode != 0)
                    {
                        logger.Error("Script exited with code: {0}", host.ExitCode);
                        if (shell.HadErrors)
                        {
                            foreach (var error in shell.Streams.Error)
                            {
                                logger.Error("{0}", error);
                            }
                        }
                        throw new ScriptException(string.Format("Script exited with code: {0}", host.ExitCode));
                    }
                    if (shell.HadErrors)
                    {
                        if (shell.Streams.Error.Count > 0)
                        {
                            logger.Error("Script had non-terminating errors. Suppress errors to allow script to run. State: {0}", shell.InvocationStateInfo.State);
                            foreach (var error in shell.Streams.Error)
                            {
                                logger.Error("{0}", error);
                            }
                            throw new ScriptException(string.Format("{0}. {1}", shell.InvocationStateInfo.State, shell.InvocationStateInfo.Reason));
                        }
                        else
                        {
                            logger.Warning("Script had non-terminating errors that were suppressed (error stream was empty). State: {0}", shell.InvocationStateInfo.State);
                        }
                    }
                    logger.Verbose("Script '{0}' complete", _filePath);
                }
            }
        }