Created
March 8, 2016 09:20
-
-
Save patriksvensson/2123d6f5dd7a090c5da8 to your computer and use it in GitHub Desktop.
Run PowerShell scripts from Cake
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Tools and addins | |
#addin "nuget:?package=System.Management.Automation&version=6.1.7601.17515" | |
using System.Collections; | |
using System.Management.Automation; | |
using System.Management.Automation.Internal; | |
using System.Management.Automation.Runspaces; | |
using System.Threading; | |
/////////////////////////////////////////////////////////////////////////////// | |
// NOTE: One might think that the following lines could be generalized... | |
/////////////////////////////////////////////////////////////////////////////// | |
private void OnOutputDataAdded(object sender, DataAddedEventArgs e) | |
{ | |
var data = sender as PSDataCollection<PSObject>; | |
if(data != null) { | |
var results = data.ReadAll(); | |
foreach (var item in results) { | |
Information(item.ToString()); | |
} | |
} | |
} | |
private void OnWarningDataAdded(object sender, DataAddedEventArgs e) | |
{ | |
var data = sender as PSDataCollection<WarningRecord>; | |
if(data != null) { | |
var results = data.ReadAll(); | |
foreach (var item in results) { | |
Warning(item.Message); | |
} | |
} | |
} | |
private void OnErrorDataAdded(object sender, DataAddedEventArgs e) | |
{ | |
var data = sender as PSDataCollection<ErrorRecord>; | |
if(data != null) { | |
var results = data.ReadAll(); | |
foreach (var item in results) { | |
Error(item.ErrorDetails.Message); | |
} | |
} | |
} | |
private void OnVerboseDataAdded(object sender, DataAddedEventArgs e) | |
{ | |
var data = sender as PSDataCollection<VerboseRecord>; | |
if(data != null) { | |
var results = data.ReadAll(); | |
foreach (var item in results) { | |
Verbose(item.Message); | |
} | |
} | |
} | |
private void OnDebugDataAdded(object sender, DataAddedEventArgs e) | |
{ | |
var data = sender as PSDataCollection<DebugRecord>; | |
if(data != null) { | |
var results = data.ReadAll(); | |
foreach (var item in results) { | |
Debug(item.Message); | |
} | |
} | |
} | |
/////////////////////////////////////////////////////////////////////////////// | |
public void RunPowerShellScript(FilePath script, IDictionary<string, string> arguments) | |
{ | |
using(var powershell = PowerShell.Create()) | |
{ | |
// Set the execution policy and location for the script. | |
var runspaceInvoker = new RunspaceInvoke(powershell.Runspace); | |
runspaceInvoker.Invoke("Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned -Force"); | |
runspaceInvoker.Invoke("Set-Location -Path " + script.GetDirectory().FullPath); | |
// Script command. | |
Command command = new Command(script.FullPath); | |
foreach (var argument in arguments) { | |
var parameter = new CommandParameter(argument.Key, argument.Value); | |
command.Parameters.Add(parameter); | |
} | |
command.Parameters.Add(new CommandParameter("Verbose")); | |
command.Parameters.Add(new CommandParameter("Debug")); | |
powershell.Commands.AddCommand(command); | |
// Handle non output data. | |
powershell.Streams.Verbose.DataAdded += OnVerboseDataAdded; | |
powershell.Streams.Warning.DataAdded += OnWarningDataAdded; | |
powershell.Streams.Debug.DataAdded += OnDebugDataAdded; | |
powershell.Streams.Error.DataAdded += OnErrorDataAdded; | |
// Setup output collection. | |
var output = new PSDataCollection<PSObject>(); | |
output.DataAdded += OnOutputDataAdded; | |
// Subscribe to changes in invocation state. | |
var handle = new ManualResetEvent(false); | |
powershell.InvocationStateChanged += (s, e) => { | |
if (e.InvocationStateInfo.State == PSInvocationState.Completed || | |
e.InvocationStateInfo.State == PSInvocationState.Failed) | |
{ | |
handle.Set(); | |
} | |
}; | |
try | |
{ | |
// Execute PowerShell script and wait for it to finish. | |
var result = powershell.BeginInvoke<PSObject, PSObject>(null, output); | |
handle.WaitOne(); | |
powershell.EndInvoke(result); | |
} | |
catch(RuntimeException ex) | |
{ | |
Error("The PowerShell script '{0}' exited with an error.", script.FullPath); | |
throw new CakeException(ex.Message, ex); | |
} | |
catch(Exception ex) | |
{ | |
Error("An error occured when executing PowerShell script '{0}'.", script.FullPath); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment