public void PowerShellTest() { string command = "Get-Process -Name explorer"; Task task = new Task("powershell", command, "1"); Job job = new Job(task, null); PowerShellManager.Execute(job, new Agent(default));
/// <summary> /// Implementation method to actual invoke the corresponding function. /// InvocationRequest messages are processed in parallel when there are multiple PowerShellManager instances in the pool. /// </summary> private void ProcessInvocationRequestImpl( StreamingMessage request, AzFunctionInfo functionInfo, PowerShellManager psManager, FunctionInvocationPerformanceStopwatch stopwatch) { InvocationRequest invocationRequest = request.InvocationRequest; StreamingMessage response = NewStreamingMessageTemplate( request.RequestId, StreamingMessage.ContentOneofCase.InvocationResponse, out StatusResult status); response.InvocationResponse.InvocationId = invocationRequest.InvocationId; try { // Invoke the function and return a hashtable of out binding data Hashtable results = InvokeFunction(functionInfo, psManager, stopwatch, invocationRequest); BindOutputFromResult(response.InvocationResponse, functionInfo, results); } catch (Exception e) { status.Status = StatusResult.Types.Status.Failure; status.Exception = e.ToRpcException(); } finally { _powershellPool.ReclaimUsedWorker(psManager); } _msgStream.Write(response); }
public async Task <List <ActionResult> > Execute(DeploymentTaskExecutionParams execParams) { var validation = await Validate(execParams); if (validation.Any()) { return(validation); } var script = Helpers.ReadStringResource(SCRIPT_NAME); var certRequest = execParams.Subject as CertificateRequestResult; execParams.Log?.Information("Executing command via PowerShell"); var services = execParams.Settings.Parameters.FirstOrDefault(p => p.Key == "services")?.Value; var doNotRequireSsl = execParams.Settings.Parameters.FirstOrDefault(p => p.Key == "donotrequiressl")?.Value; var parameters = new Dictionary <string, object> { { "services", services }, { "addDoNotRequireSslFlag", doNotRequireSsl } }; var scriptResult = await PowerShellManager.RunScript(execParams.Context.PowershellExecutionPolicy, certRequest, parameters : parameters, scriptContent : script, credentials : execParams.Credentials); return(new List <ActionResult> { scriptResult }); }
/// <summary> /// Ejecuta un script de powershell /// </summary> private async Task ExecuteContentAsync(BlockLogModel block, string content, NormalizedDictionary <object> parameters, ExecuteScriptSentence sentence) { PowerShellManager manager = new PowerShellManager(); // Carga el script en memoria manager.LoadScript(content); // Asigna los parámetros if (!AddParameters(manager, parameters, sentence, out string error)) { Errors.Add(error); } else { // Ejecuta await manager.ExecuteAsync(); // Comprueba los errores if (manager.Errors.Count > 0) { Errors.AddRange(manager.Errors); } else if (manager.OutputItems.Count > 0) { foreach (object output in manager.OutputItems) { block.Info($"{manager.OutputItems.IndexOf(output).ToString()}: {output?.ToString()}"); } } } }
private async void TestScript_Click(object sender, EventArgs e) { var button = (Button)sender; string scriptFile = null; var result = new CertificateRequestResult { ManagedItem = MainViewModel.SelectedItem, IsSuccess = true, Message = "Script Testing Message" }; if (button.Name == "Button_TestPreRequest") { scriptFile = MainViewModel.SelectedItem.RequestConfig.PreRequestPowerShellScript; result.IsSuccess = false; // pre-request messages will always have IsSuccess = false } else if (button.Name == "Button_TestPostRequest") { scriptFile = MainViewModel.SelectedItem.RequestConfig.PostRequestPowerShellScript; } if (string.IsNullOrEmpty(scriptFile)) { return; // don't try to run empty script } try { string scriptOutput = await PowerShellManager.RunScript(result, scriptFile); MessageBox.Show(scriptOutput, "Powershell Output", MessageBoxButton.OK, MessageBoxImage.Information); } catch (ArgumentException ex) { MessageBox.Show(ex.Message, "Script Error", MessageBoxButton.OK, MessageBoxImage.Error); } }
public async Task <List <ActionResult> > Execute(DeploymentTaskExecutionParams execParams) { var validation = await Validate(execParams); if (validation.Any()) { return(validation); } var script = Helpers.ReadStringResource(SCRIPT_NAME); var definition = execParams.Definition; definition = GetDefinition(definition); var certRequest = execParams.Subject as CertificateRequestResult; execParams.Log?.Information("Executing command via PowerShell"); var performRestart = execParams.Settings.Parameters.FirstOrDefault(p => p.Key == "performServiceRestart")?.Value ?? "false"; var alternateTlsBinding = execParams.Settings.Parameters.FirstOrDefault(p => p.Key == "alternateTlsBinding")?.Value ?? "false"; var parameters = new Dictionary <string, object> { { "performServiceRestart", performRestart }, { "alternateTlsBinding", alternateTlsBinding } }; var scriptResult = await PowerShellManager.RunScript(execParams.Context.PowershellExecutionPolicy, certRequest, parameters : parameters, scriptContent : script, credentials : execParams.Credentials); return(new List <ActionResult> { scriptResult }); }
/// <summary> /// Method to process a InvocationRequest. /// This method checks out a worker from the pool, and then starts the actual invocation in a threadpool thread. /// </summary> internal StreamingMessage ProcessInvocationRequest(StreamingMessage request) { AzFunctionInfo functionInfo = null; PowerShellManager psManager = null; try { functionInfo = _functionLoader.GetFunctionInfo(request.InvocationRequest.FunctionId); psManager = _powershellPool.CheckoutIdleWorker(request, functionInfo); Task.Run(() => ProcessInvocationRequestImpl(request, functionInfo, psManager)); } catch (Exception e) { _powershellPool.ReclaimUsedWorker(psManager); StreamingMessage response = NewStreamingMessageTemplate( request.RequestId, StreamingMessage.ContentOneofCase.InvocationResponse, out StatusResult status); response.InvocationResponse.InvocationId = request.InvocationRequest.InvocationId; status.Status = StatusResult.Types.Status.Failure; status.Exception = e.ToRpcException(); return(response); } return(null); }
/// <summary> /// Set the 'ReturnValue' and 'OutputData' based on the invocation results appropriately. /// </summary> private void BindOutputFromResult(PowerShellManager psManager, InvocationResponse response, AzFunctionInfo functionInfo, Hashtable results) { switch (functionInfo.Type) { case AzFunctionType.RegularFunction: // Set out binding data and return response to be sent back to host foreach (KeyValuePair <string, ReadOnlyBindingInfo> binding in functionInfo.OutputBindings) { // if one of the bindings is '$return' we need to set the ReturnValue string outBindingName = binding.Key; if (string.Equals(outBindingName, AzFunctionInfo.DollarReturn, StringComparison.OrdinalIgnoreCase)) { response.ReturnValue = results[outBindingName].ToTypedData(psManager); continue; } ParameterBinding paramBinding = new ParameterBinding() { Name = outBindingName, Data = results[outBindingName].ToTypedData(psManager) }; response.OutputData.Add(paramBinding); } break; case AzFunctionType.OrchestrationFunction: case AzFunctionType.ActivityFunction: response.ReturnValue = results[AzFunctionInfo.DollarReturn].ToTypedData(psManager); break; default: throw new InvalidOperationException("Unreachable code."); } }
internal RequestProcessor(MessagingStream msgStream) { _msgStream = msgStream; _logger = new RpcLogger(msgStream); _powerShellManager = new PowerShellManager(_logger); _functionLoader = new FunctionLoader(); }
/// <summary> /// Method to process a InvocationRequest. /// This method checks out a worker from the pool, and then starts the actual invocation in a threadpool thread. /// </summary> internal StreamingMessage ProcessInvocationRequest(StreamingMessage request) { Exception error = null; try { if (_dependencyManager.DependencyDownloadTask != null && !_dependencyManager.DependencyDownloadTask.IsCompleted) { var rpcLogger = new RpcLogger(_msgStream); rpcLogger.SetContext(request.RequestId, request.InvocationRequest?.InvocationId); rpcLogger.Log(LogLevel.Information, PowerShellWorkerStrings.DependencyDownloadInProgress, isUserLog: true); _dependencyManager.WaitOnDependencyDownload(); } if (_dependencyManager.DependencyError != null) { error = _dependencyManager.DependencyError; } else { AzFunctionInfo functionInfo = FunctionLoader.GetFunctionInfo(request.InvocationRequest.FunctionId); PowerShellManager psManager = _powershellPool.CheckoutIdleWorker(request, functionInfo); if (_powershellPool.UpperBound == 1) { // When the concurrency upper bound is 1, we can handle only one invocation at a time anyways, // so it's better to just do it on the current thread to reduce the required synchronization. ProcessInvocationRequestImpl(request, functionInfo, psManager); } else { // When the concurrency upper bound is more than 1, we have to handle the invocation in a worker // thread, so multiple invocations can make progress at the same time, even though by time-sharing. Task.Run(() => ProcessInvocationRequestImpl(request, functionInfo, psManager)); } } } catch (Exception e) { error = e; } if (error != null) { StreamingMessage response = NewStreamingMessageTemplate( request.RequestId, StreamingMessage.ContentOneofCase.InvocationResponse, out StatusResult status); response.InvocationResponse.InvocationId = request.InvocationRequest.InvocationId; status.Status = StatusResult.Types.Status.Failure; status.Exception = error.ToRpcException(); return(response); } return(null); }
private static Hashtable InvokeFunction( PowerShellManager powerShellManager, AzFunctionInfo functionInfo, Hashtable triggerMetadata = null, RetryContext retryContext = null) { return(powerShellManager.InvokeFunction(functionInfo, triggerMetadata, null, retryContext, s_testInputData, new FunctionInvocationPerformanceStopwatch())); }
public async Task <ActionResult> DeleteRecord(DnsRecord request) { var scriptContent = PrepareScript("Remove-DnsTxt", request.RecordName, request.RecordValue); var objParams = _parameters.ToDictionary(p => p.Key, p => p.Value as object); return(await PowerShellManager.RunScript(null, null, objParams, scriptContent, null, _scriptExecutionPolicy)); }
public object GetRequestModel() { string diskCfreeSpace = PowerShellManager.Execute(DOM.PowerShellScript.GetFreeSpaceOfDiscC); string computerName = PowerShellManager.Execute(DOM.PowerShellScript.GetComputerName); string updateTimestamp = string.Format("{0:O}", DateTime.UtcNow); return(new { Id = 1, updateTimestamp, computerName, diskCfreeSpace }); }
public void InitializeRunspaceSuccess() { var logger = new ConsoleLogger(); var manager = new PowerShellManager(logger); manager.InitializeRunspace(); Assert.Single(logger.FullLog); Assert.Equal("Warning: Required environment variables to authenticate to Azure were not present", logger.FullLog[0]); }
/// <summary> /// Execute a local powershell script /// </summary> /// <param name="log"></param> /// <param name="managedCert"></param> /// <param name="settings"></param> /// <param name="credentials"></param> /// <param name="isPreviewOnly"></param> /// <returns></returns> public async Task <List <ActionResult> > Execute(DeploymentTaskExecutionParams execParams) { var results = new List <ActionResult>(); var certRequest = execParams.Subject as CertificateRequestResult; var command = execParams.Settings.Parameters.FirstOrDefault(c => c.Key == "scriptpath")?.Value; var args = execParams.Settings.Parameters.FirstOrDefault(c => c.Key == "args")?.Value; var inputResultAsArgument = execParams.Settings.Parameters.FirstOrDefault(c => c.Key == "inputresult")?.Value; var parameters = new Dictionary <string, object>(); if (inputResultAsArgument?.Trim().ToLower() == "true") { parameters.Add("result", certRequest); } ; if (!string.IsNullOrEmpty(args)) { foreach (var o in args.Split(';')) { if (!string.IsNullOrEmpty(o)) { var keyValuePair = o.Split('='); if (keyValuePair.Length == 1) { // item has a key only parameters.Add(keyValuePair[0].Trim(), ""); } else { // item has a key and value parameters.Add(keyValuePair[0].Trim(), keyValuePair[1].Trim()); } } } } execParams.Log?.Information("Executing command via PowerShell"); string logonType = execParams.Settings.Parameters.FirstOrDefault(c => c.Key == "logontype")?.Value ?? null; // if running as local/default service user no credentials are provided for user impersonation var credentials = execParams.Settings.ChallengeProvider == StandardAuthTypes.STANDARD_AUTH_LOCAL ? null : execParams.Credentials; var result = await PowerShellManager.RunScript(execParams.Context.PowershellExecutionPolicy, null, command, parameters, null, credentials : credentials, logonType : logonType); results.Add(result); return(results); }
private Hashtable InvokeFunction( AzFunctionInfo functionInfo, PowerShellManager psManager, FunctionInvocationPerformanceStopwatch stopwatch, InvocationRequest invocationRequest) { var triggerMetadata = GetTriggerMetadata(functionInfo, invocationRequest); var traceContext = GetTraceContext(functionInfo, invocationRequest); stopwatch.OnCheckpoint(FunctionInvocationPerformanceStopwatch.Checkpoint.MetadataAndTraceContextReady); return(psManager.InvokeFunction(functionInfo, triggerMetadata, traceContext, invocationRequest.InputData, stopwatch)); }
public void TestObjectToTypedData_PSObjectToString() { var logger = new ConsoleLogger(); var manager = new PowerShellManager(logger); manager.InitializeRunspace(); object input = PSObject.AsPSObject("Hello World"); TypedData output = input.ToTypedData(manager); Assert.Equal(TypedData.DataOneofCase.String, output.DataCase); Assert.Equal("Hello World", output.String); }
/// <summary> /// Invoke a regular function or an activity function. /// </summary> private Hashtable InvokeSingleActivityFunction( PowerShellManager psManager, AzFunctionInfo functionInfo, InvocationRequest invocationRequest, FunctionInvocationPerformanceStopwatch stopwatch) { const string InvocationId = "InvocationId"; const string FunctionDirectory = "FunctionDirectory"; const string FunctionName = "FunctionName"; // Bundle all TriggerMetadata into Hashtable to send down to PowerShell Hashtable triggerMetadata = null; TraceContext traceContext = null; if (functionInfo.HasTriggerMetadataParam) { triggerMetadata = new Hashtable(StringComparer.OrdinalIgnoreCase); foreach (var dataItem in invocationRequest.TriggerMetadata) { // MapField<K, V> is case-sensitive, but powershell is case-insensitive, // so for keys differ only in casing, the first wins. if (!triggerMetadata.ContainsKey(dataItem.Key)) { triggerMetadata.Add(dataItem.Key, dataItem.Value.ToObject()); } } if (!triggerMetadata.ContainsKey(InvocationId)) { triggerMetadata.Add(InvocationId, invocationRequest.InvocationId); } if (!triggerMetadata.ContainsKey(FunctionDirectory)) { triggerMetadata.Add(FunctionDirectory, functionInfo.FuncDirectory); } if (!triggerMetadata.ContainsKey(FunctionName)) { triggerMetadata.Add(FunctionName, functionInfo.FuncName); } } if (functionInfo.HasTraceContextParam) { traceContext = new TraceContext(invocationRequest.TraceContext.TraceParent, invocationRequest.TraceContext.TraceState, invocationRequest.TraceContext.Attributes); } stopwatch.OnCheckpoint(FunctionInvocationPerformanceStopwatch.Checkpoint.MetadataAndTraceContextReady); return(psManager.InvokeFunction(functionInfo, triggerMetadata, traceContext, invocationRequest.InputData, stopwatch)); }
public void TestObjectToTypedData_PSObjectToBytes() { var logger = new ConsoleLogger(); var manager = new PowerShellManager(logger); manager.InitializeRunspace(); var data = new byte[] { 12, 23, 34 }; object input = PSObject.AsPSObject(data); TypedData output = input.ToTypedData(manager); Assert.Equal(TypedData.DataOneofCase.Bytes, output.DataCase); Assert.Equal(3, output.Bytes.Length); }
/// <summary> /// Method to process a InvocationRequest. /// This method checks out a worker from the pool, and then starts the actual invocation in a threadpool thread. /// </summary> internal StreamingMessage ProcessInvocationRequest(StreamingMessage request) { try { var stopwatch = new FunctionInvocationPerformanceStopwatch(); stopwatch.OnStart(); // Will block if installing dependencies is required _dependencyManager.WaitForDependenciesAvailability( () => { var rpcLogger = new RpcLogger(_msgStream); rpcLogger.SetContext(request.RequestId, request.InvocationRequest?.InvocationId); return(rpcLogger); }); stopwatch.OnCheckpoint(FunctionInvocationPerformanceStopwatch.Checkpoint.DependenciesAvailable); AzFunctionInfo functionInfo = FunctionLoader.GetFunctionInfo(request.InvocationRequest.FunctionId); PowerShellManager psManager = _powershellPool.CheckoutIdleWorker( request.RequestId, request.InvocationRequest?.InvocationId, functionInfo.FuncName, functionInfo.OutputBindings); stopwatch.OnCheckpoint(FunctionInvocationPerformanceStopwatch.Checkpoint.RunspaceAvailable); // When the concurrency upper bound is more than 1, we have to handle the invocation in a worker // thread, so multiple invocations can make progress at the same time, even though by time-sharing. Task.Run(() => ProcessInvocationRequestImpl(request, functionInfo, psManager, stopwatch)); } catch (Exception e) { StreamingMessage response = NewStreamingMessageTemplate( request.RequestId, StreamingMessage.ContentOneofCase.InvocationResponse, out StatusResult status); response.InvocationResponse.InvocationId = request.InvocationRequest.InvocationId; status.Status = StatusResult.Types.Status.Failure; status.Exception = e.ToRpcException(); return(response); } return(null); }
public void InvokeFunctionWithEntryPointWorks() { var logger = new ConsoleLogger(); var manager = new PowerShellManager(logger); manager.InitializeRunspace(); string path = System.IO.Path.Join( AppDomain.CurrentDomain.BaseDirectory, "Unit/PowerShell/TestScripts/testFunctionWithEntryPoint.ps1"); var functionInfo = GetAzFunctionInfo(path, "Run"); Hashtable result = manager.InvokeFunction(functionInfo, null, TestInputData); Assert.Equal(TestStringData, result[TestOutputBindingName]); }
public void TestObjectToTypedData_PSObjectToStream() { var logger = new ConsoleLogger(); var manager = new PowerShellManager(logger); manager.InitializeRunspace(); using (var data = new MemoryStream(new byte[] { 12, 23, 34 })) { object input = PSObject.AsPSObject(data); TypedData output = input.ToTypedData(manager); Assert.Equal(TypedData.DataOneofCase.Stream, output.DataCase); Assert.Equal(3, output.Stream.Length); } }
public async Task TestLoadManagedCertificates() { var path = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); await PowerShellManager.RunScript(new CertificateRequestResult {}, path + "\\Assets\\Powershell\\Simple.ps1"); var transcriptLogExists = System.IO.File.Exists(@"C:\Temp\Certify\TestOutput\TestTranscript.txt"); var outputExists = System.IO.File.Exists(@"C:\Temp\Certify\TestOutput\TestPSOutput.txt"); Assert.IsTrue(outputExists, "Powershell output file should exist"); Assert.IsTrue(transcriptLogExists, "Powershell transcript log file should exist"); System.IO.File.Delete(@"C:\Temp\Certify\TestOutput\TestPSOutput.txt"); System.IO.File.Delete(@"C:\Temp\Certify\TestOutput\TestTranscript.txt"); }
public PowerShellManagerTests() { _testLogger = new ConsoleLogger(); _testManager = TestUtils.NewTestPowerShellManager(_testLogger); _testInputData = new List <ParameterBinding> { new ParameterBinding { Name = TestUtils.TestInputBindingName, Data = new TypedData { String = TestStringData } } }; }
/// <summary> /// Invoke a regular function or an activity function. /// </summary> private Hashtable InvokeSingleActivityFunction(PowerShellManager psManager, AzFunctionInfo functionInfo, InvocationRequest invocationRequest) { // Bundle all TriggerMetadata into Hashtable to send down to PowerShell var triggerMetadata = new Hashtable(StringComparer.OrdinalIgnoreCase); foreach (var dataItem in invocationRequest.TriggerMetadata) { // MapField<K, V> is case-sensitive, but powershell is case-insensitive, // so for keys differ only in casing, the first wins. if (!triggerMetadata.ContainsKey(dataItem.Key)) { triggerMetadata.Add(dataItem.Key, dataItem.Value.ToObject()); } } return(psManager.InvokeFunction(functionInfo, triggerMetadata, invocationRequest.InputData)); }
/// <summary> /// Method to process a InvocationRequest. /// This method checks out a worker from the pool, and then starts the actual invocation in a threadpool thread. /// </summary> internal StreamingMessage ProcessInvocationRequest(StreamingMessage request) { try { // Will block if installing dependencies is required _dependencyManager.WaitForDependenciesAvailability( () => { var rpcLogger = new RpcLogger(_msgStream); rpcLogger.SetContext(request.RequestId, request.InvocationRequest?.InvocationId); return(rpcLogger); }); AzFunctionInfo functionInfo = FunctionLoader.GetFunctionInfo(request.InvocationRequest.FunctionId); PowerShellManager psManager = _powershellPool.CheckoutIdleWorker(request, functionInfo); if (_powershellPool.UpperBound == 1) { // When the concurrency upper bound is 1, we can handle only one invocation at a time anyways, // so it's better to just do it on the current thread to reduce the required synchronization. ProcessInvocationRequestImpl(request, functionInfo, psManager); } else { // When the concurrency upper bound is more than 1, we have to handle the invocation in a worker // thread, so multiple invocations can make progress at the same time, even though by time-sharing. Task.Run(() => ProcessInvocationRequestImpl(request, functionInfo, psManager)); } } catch (Exception e) { StreamingMessage response = NewStreamingMessageTemplate( request.RequestId, StreamingMessage.ContentOneofCase.InvocationResponse, out StatusResult status); response.InvocationResponse.InvocationId = request.InvocationRequest.InvocationId; status.Status = StatusResult.Types.Status.Failure; status.Exception = e.ToRpcException(); return(response); } return(null); }
public void TestObjectToTypedData_PSObjectToJson_1() { var logger = new ConsoleLogger(); var manager = new PowerShellManager(logger); manager.InitializeRunspace(); var data = new Hashtable { { "foo", "bar" } }; object input = PSObject.AsPSObject(data); var expected = new TypedData { Json = "{\"foo\":\"bar\"}" }; Assert.Equal(expected, input.ToTypedData(manager)); }
public void TestObjectToTypedData_PSObjectToJson_2() { var logger = new ConsoleLogger(); var manager = new PowerShellManager(logger); manager.InitializeRunspace(); using (var ps = System.Management.Automation.PowerShell.Create()) { object input = ps.AddScript("[pscustomobject]@{foo = 'bar'}").Invoke()[0]; var expected = new TypedData { Json = "{\"foo\":\"bar\"}" }; Assert.Equal(expected, input.ToTypedData(manager)); } }
public void PrependingToPSModulePathShouldWork() { var logger = new ConsoleLogger(); var manager = new PowerShellManager(logger); var data = "/some/unknown/directory"; string modulePathBefore = Environment.GetEnvironmentVariable("PSModulePath"); manager.PrependToPSModulePath(data); try { // the data path should be ahead of anything else Assert.Equal($"{data}{System.IO.Path.PathSeparator}{modulePathBefore}", Environment.GetEnvironmentVariable("PSModulePath")); } finally { // Set the PSModulePath back to what it was before Environment.SetEnvironmentVariable("PSModulePath", modulePathBefore); } }
public async Task TestLoadManagedCertificates() { var path = AppContext.BaseDirectory; await PowerShellManager.RunScript("Unrestricted", new CertificateRequestResult { }, System.IO.Path.Combine(path, "Assets\\Powershell\\Simple.ps1")); var transcriptLogExists = System.IO.File.Exists(@"C:\Temp\Certify\TestOutput\TestTranscript.txt"); var outputExists = System.IO.File.Exists(@"C:\Temp\Certify\TestOutput\TestPSOutput.txt"); Assert.IsTrue(outputExists, "Powershell output file should exist"); Assert.IsTrue(transcriptLogExists, "Powershell transcript log file should exist"); try { System.IO.File.Delete(@"C:\Temp\Certify\TestOutput\TestPSOutput.txt"); System.IO.File.Delete(@"C:\Temp\Certify\TestOutput\TestTranscript.txt"); } catch { } }