//This function allows use to use await - see http://blogs.msdn.com/b/pfxteam/archive/2012/04/12/10293335.aspx private static async Task<ExecutionResult> RunScriptfileAsync(PSScriptRunner Runner, string Scriptfile) { ExecutionResult result; result = await Runner.RunScriptFileAsync(Scriptfile); Console.WriteLine("Async finished!"); return result; }
internal async Task <List <AssetRecord> > Run(PSScriptRunner scriptRunner, string assetScriptPath, IProgress <RunnerProgressDetail> progress = null) { _results = new List <AssetRecord>(); await RunInternalAsync(scriptRunner, assetScriptPath, progress); return(_results); }
internal async Task<List<TestRecord>> RunAsync(PSScriptRunner scriptRunner, string testScriptsPath, IProgress<RunnerProgressDetail> progress = null) { _results = new List<TestRecord>(); await RunInternalAsync(scriptRunner, testScriptsPath, progress); return _results; }
//This function allows use to use await - see http://blogs.msdn.com/b/pfxteam/archive/2012/04/12/10293335.aspx private static async Task <ExecutionResult> RunScriptfileAsync(PSScriptRunner Runner, string Scriptfile) { ExecutionResult result; result = await Runner.RunScriptFileAsync(Scriptfile); Console.WriteLine("Async finished!"); return(result); }
static void Main(string[] args) { string basefolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); string testscript; //testscript = "TestScript_LongRunningOutput.ps1"; //testscript = "TestScript_LongRunningOutputWithErrors.ps1"; //testscript = "TestScript_FatalError.ps1"; //testscript = "TestScript_IncorrectCmdletParameter.ps1"; //testscript = "TestScript_DataInAllStreams.ps1"; //testscript = "TestScript_Using out-null.ps1"; //testscript = "TestScript_ReturnHashtable1.ps1"; //testscript = "TestScript_ReturnHashtable2.ps1"; testscript = "TestScript_Using Variables 1.ps1"; string scriptfilename = Path.Combine(basefolder, testscript); Version testVersion = new Version(1, 2, 3, 4); HashSet <VariablePlain> vars = new HashSet <VariablePlain>(); vars.Add(new VariablePlain("MyTestVarVersion", testVersion)); vars.Add(new VariablePlain("MyTestVarWrite", "Write Var Set by C#", false)); vars.Add(new VariablePlain("MyTestVarReadOnly", "ReadOnly Var set by C#", true)); PSScriptRunnerPreferences prefs = new PSScriptRunnerPreferences(); prefs.RequiredPSVersion = 4; prefs.Variables = vars; PSScriptRunner runner = new PSScriptRunner(prefs); runner.TestPowerShellEnvironment(); Task <ExecutionResult> task = RunScriptfileAsync(runner, scriptfilename); bool finished = false; while (finished == false) { Console.WriteLine("Waiting for runner to finish..."); finished = task.Wait(333); } ExecutionResult execResult = task.Result; Console.WriteLine("Finished!"); Console.WriteLine(execResult.ToString()); runner.Dispose(); Console.WriteLine("Press return to exit..."); Console.ReadLine(); }
static void Main(string[] args) { string basefolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); string testscript; //testscript = "TestScript_LongRunningOutput.ps1"; //testscript = "TestScript_LongRunningOutputWithErrors.ps1"; //testscript = "TestScript_FatalError.ps1"; //testscript = "TestScript_IncorrectCmdletParameter.ps1"; //testscript = "TestScript_DataInAllStreams.ps1"; //testscript = "TestScript_Using out-null.ps1"; //testscript = "TestScript_ReturnHashtable1.ps1"; //testscript = "TestScript_ReturnHashtable2.ps1"; testscript = "TestScript_Using Variables 1.ps1"; string scriptfilename = Path.Combine(basefolder, testscript); Version testVersion = new Version(1, 2, 3, 4); HashSet<VariablePlain> vars = new HashSet<VariablePlain>(); vars.Add(new VariablePlain("MyTestVarVersion", testVersion)); vars.Add(new VariablePlain("MyTestVarWrite","Write Var Set by C#",false)); vars.Add(new VariablePlain("MyTestVarReadOnly","ReadOnly Var set by C#",true)); PSScriptRunnerPreferences prefs = new PSScriptRunnerPreferences(); prefs.RequiredPSVersion = 4; prefs.Variables = vars; PSScriptRunner runner = new PSScriptRunner(prefs); runner.TestPowerShellEnvironment(); Task<ExecutionResult> task = RunScriptfileAsync(runner, scriptfilename); bool finished = false; while (finished == false) { Console.WriteLine("Waiting for runner to finish..."); finished = task.Wait(333); } ExecutionResult execResult = task.Result; Console.WriteLine("Finished!"); Console.WriteLine(execResult.ToString()); runner.Dispose(); Console.WriteLine("Press return to exit..."); Console.ReadLine(); }
/// <summary> /// Executes all assets and tests found in CompilationPath asynchronously /// </summary> /// <param name="compilationPath">Directory to read data from. Must contain the required subfolders ASSETS, TESTS and MODULES.</param> /// <param name="progress">An IProgress implementation to report status to</param> public async Task<Report> RunAsync(string compilationPath, IProgress<RunnerProgressDetail> progress = null) { if (string.IsNullOrWhiteSpace(compilationPath)) throw new ArgumentException("Compilation path is not set"); //Check if all folders are present string rootfolder = PathExtension.FullPath(compilationPath); if (PathExtension.DirectoryExists(rootfolder) == false) throw new CompilationFolderException(rootfolder); //Check subfolders string assetScriptsPath = PathExtension.Combine(rootfolder, Xteq5EngineConstant.DirectoryNameAssets); CheckCompilationSubfolder(assetScriptsPath); string testScriptsPath = PathExtension.Combine(rootfolder, Xteq5EngineConstant.DirectoryNameTests); CheckCompilationSubfolder(testScriptsPath); string modulePath = PathExtension.Combine(rootfolder, Xteq5EngineConstant.DirectoryNameModules); CheckCompilationSubfolder(modulePath); //Perform a WMI test to make sure the script are able to access WMI data WMITest wmiTest = new WMITest(); wmiTest.Test(); //Create the result object Report report = new Report(); //Set source folder report.CompilationFolder = compilationPath; //Everything looks fine so far. Let's go. PSScriptRunnerPreferences prefs = new PSScriptRunnerPreferences(); //We require at least version 4 of PowerShell prefs.RequiredPSVersion = 4; //Load modules from this path prefs.ModulePath = modulePath; //Add Xteq5EngineVersion read-only variable prefs.Variables.Add(new VariablePlain(Xteq5EngineConstant.VariableNameEngineVersion, Xteq5EngineConstant.Version, true)); //Add Xteq5Running read-only variable prefs.Variables.Add(new VariablePlain(Xteq5EngineConstant.VariableNameIsActive, true, true)); //Execute all assets List<AssetRecord> assets; using (PSScriptRunner psScriptRunnerAssets = new PSScriptRunner(prefs)) { //Check that the PowerShell environment is ready. If not, we'll error out from here. psScriptRunnerAssets.TestPowerShellEnvironment(); //Now execute all assets AssetScriptRunner assetRunner = new AssetScriptRunner(); assets = await assetRunner.Run(psScriptRunnerAssets, assetScriptsPath, progress); } //Add Xteq5Assets read-only variable Hashtable hashtableAssets = CreateHashtableFromAssetRecords(assets); prefs.Variables.Add(new VariablePlain(Xteq5EngineConstant.VariableNameAssets, hashtableAssets, true)); //Execute all tests List<TestRecord> tests; using (PSScriptRunner psScriptRunnerTests = new PSScriptRunner(prefs)) { //No TestPowerShellEnvironment() here, we should be OK if the first test worked TestScriptRunner testsRunner = new TestScriptRunner(); tests = await testsRunner.RunAsync(psScriptRunnerTests, testScriptsPath, progress); } //Contstruct the final result report.UserName = Environment.UserName; report.ComputerName = Environment.MachineName; report.EngineVersion = Xteq5EngineConstant.Version; report.Assets = assets; report.Tests = tests; CalculateRecordStatistics(report, assets, tests); //Set IssuesFound report.IssuesFound = false; report.TestIssuesFound = false; report.AssetIssuesFound = false; if ((report.AssetStatiscs.FatalCount + report.AssetStatiscs.MajorCount + report.AssetStatiscs.MinorCount) > 0) report.AssetIssuesFound = true; if ((report.TestStatiscs.FatalCount + report.TestStatiscs.MajorCount + report.TestStatiscs.MinorCount) > 0) report.TestIssuesFound = true; if (report.AssetIssuesFound || report.TestIssuesFound) report.IssuesFound = true; report.Finish(); return report; }
/// <summary> /// Executes all assets and tests found in CompilationPath asynchronously /// </summary> /// <param name="compilationPath">Directory to read data from. Must contain the required subfolders ASSETS, TESTS and MODULES.</param> /// <param name="progress">An IProgress implementation to report status to</param> public async Task <Report> RunAsync(string compilationPath, IProgress <RunnerProgressDetail> progress = null) { if (string.IsNullOrWhiteSpace(compilationPath)) { throw new ArgumentException("Compilation path is not set"); } //Check if all folders are present string rootfolder = PathExtension.FullPath(compilationPath); if (PathExtension.DirectoryExists(rootfolder) == false) { throw new CompilationFolderException(rootfolder); } //Check subfolders string assetScriptsPath = PathExtension.Combine(rootfolder, Xteq5EngineConstant.DirectoryNameAssets); CheckCompilationSubfolder(assetScriptsPath); string testScriptsPath = PathExtension.Combine(rootfolder, Xteq5EngineConstant.DirectoryNameTests); CheckCompilationSubfolder(testScriptsPath); string modulePath = PathExtension.Combine(rootfolder, Xteq5EngineConstant.DirectoryNameModules); CheckCompilationSubfolder(modulePath); //Perform a WMI test to make sure the script are able to access WMI data WMITest wmiTest = new WMITest(); wmiTest.Test(); //Create the result object Report report = new Report(); //Set source folder report.CompilationFolder = compilationPath; //Everything looks fine so far. Let's go. PSScriptRunnerPreferences prefs = new PSScriptRunnerPreferences(); //We require at least version 4 of PowerShell prefs.RequiredPSVersion = 4; //Load modules from this path prefs.ModulePath = modulePath; //Add Xteq5EngineVersion read-only variable prefs.Variables.Add(new VariablePlain(Xteq5EngineConstant.VariableNameEngineVersion, Xteq5EngineConstant.Version, true)); //Add Xteq5Running read-only variable prefs.Variables.Add(new VariablePlain(Xteq5EngineConstant.VariableNameIsActive, true, true)); //Execute all assets List <AssetRecord> assets; using (PSScriptRunner psScriptRunnerAssets = new PSScriptRunner(prefs)) { //Check that the PowerShell environment is ready. If not, we'll error out from here. psScriptRunnerAssets.TestPowerShellEnvironment(); //Now execute all assets AssetScriptRunner assetRunner = new AssetScriptRunner(); assets = await assetRunner.Run(psScriptRunnerAssets, assetScriptsPath, progress); } //Add Xteq5Assets read-only variable Hashtable hashtableAssets = CreateHashtableFromAssetRecords(assets); prefs.Variables.Add(new VariablePlain(Xteq5EngineConstant.VariableNameAssets, hashtableAssets, true)); //Execute all tests List <TestRecord> tests; using (PSScriptRunner psScriptRunnerTests = new PSScriptRunner(prefs)) { //No TestPowerShellEnvironment() here, we should be OK if the first test worked TestScriptRunner testsRunner = new TestScriptRunner(); tests = await testsRunner.RunAsync(psScriptRunnerTests, testScriptsPath, progress); } //Contstruct the final result report.UserName = Environment.UserName; report.ComputerName = Environment.MachineName; report.EngineVersion = Xteq5EngineConstant.Version; report.Assets = assets; report.Tests = tests; CalculateRecordStatistics(report, assets, tests); //Set IssuesFound report.IssuesFound = false; report.TestIssuesFound = false; report.AssetIssuesFound = false; if ((report.AssetStatiscs.FatalCount + report.AssetStatiscs.MajorCount + report.AssetStatiscs.MinorCount) > 0) { report.AssetIssuesFound = true; } if ((report.TestStatiscs.FatalCount + report.TestStatiscs.MajorCount + report.TestStatiscs.MinorCount) > 0) { report.TestIssuesFound = true; } if (report.AssetIssuesFound || report.TestIssuesFound) { report.IssuesFound = true; } report.Finish(); return(report); }
protected async Task RunInternalAsync(PSScriptRunner scriptRunner, string scriptDirectory, IProgress <RunnerProgressDetail> progress = null) { //Assign progress reporter and set it that it can be used after calling Report() _reporter = new ProgressReporter <RunnerProgressDetail>(progress, createNewInstanceAfterReport: true); //Report that we are about to start _reporter.Content.Action = RunnerAction.Starting; _reporter.Report(); string[] allScripts = Directory.GetFiles(scriptDirectory, Xteq5EngineConstant.ScriptFilePattern); NaturalSort.Sort(allScripts); foreach (string scriptFilename in allScripts) { //Set the values we already have BaseRecord record = new BaseRecord(); record.ScriptFilePath = scriptFilename; record.Name = Path.GetFileNameWithoutExtension(scriptFilename); try { //Report back status ReportProgressScript(scriptFilename); using (ExecutionResult execResult = await scriptRunner.RunScriptFileAsync(scriptFilename)) { record.ProcessMessages = execResult.ToString(); if (execResult.Successful == false) { ProcessFailure(record); } else { //The script was run OK record.ScriptSuccessful = true; //Search the output Hashtable table = new Hashtable(); //new() is required or the compiler will complain about an unassigned local variable bool foundHashtable = false; //Search the output collection for a hashtable foreach (PSObject psobj in execResult.StreamOutput) { if (psobj.BaseObject != null && psobj.BaseObject is Hashtable) { foundHashtable = true; table = psobj.BaseObject as Hashtable; break; } } if (foundHashtable == false) { //No hashtable was found within output stream. Add this to messages record.AddLineToProcessMessages("No Hashtable was returned"); ProcessFailure(record); } else { ProcessHashtableOutputInternal(record, table); } } } } catch (Exception exc) { //That didn't go well record.ProcessMessages = exc.ToString(); //Let the actual implementation decide what to do next ProcessFailure(record); } //MTH: End of processing with this file. Next one please! } //Report status that this entire run has finished _reporter.Content.Action = RunnerAction.Ended; _reporter.Report(); }