명령 줄 인수를 사용하여 C #에서 PowerShell 스크립트 실행
C # 내에서 PowerShell 스크립트를 실행해야합니다. 스크립트에는 명령 줄 인수가 필요합니다.
이것이 내가 지금까지 한 일입니다.
RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
runspace.Open();
RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.Add(scriptFile);
// Execute PowerShell script
results = pipeline.Invoke();
scriptFile은 "C : \ Program Files \ MyProgram \ Whatever.ps1"과 같은 것을 포함합니다.
스크립트는 "-key Value"와 같은 명령 줄 인수를 사용하는 반면 Value는 공백도 포함 할 수있는 경로와 유사 할 수 있습니다.
이게 작동하지 않습니다. 누구든지 C # 내에서 PowerShell 스크립트에 명령 줄 인수를 전달하고 공백에 문제가 없는지 확인하는 방법을 알고 있습니까?
별도의 명령으로 스크립트 파일을 만들어보십시오.
Command myCommand = new Command(scriptfile);
그런 다음 매개 변수를 추가 할 수 있습니다.
CommandParameter testParam = new CommandParameter("key","value");
myCommand.Parameters.Add(testParam);
그리고 마지막으로
pipeline.Commands.Add(myCommand);
다음은 완전하고 편집 된 코드입니다.
RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
runspace.Open();
RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
Pipeline pipeline = runspace.CreatePipeline();
//Here's how you add a new script with arguments
Command myCommand = new Command(scriptfile);
CommandParameter testParam = new CommandParameter("key","value");
myCommand.Parameters.Add(testParam);
pipeline.Commands.Add(myCommand);
// Execute PowerShell script
results = pipeline.Invoke();
다른 해결책이 있습니다. 누군가가 정책을 변경할 수 있기 때문에 PowerShell 스크립트 실행이 성공하는지 테스트하고 싶습니다. 인수로 실행할 스크립트의 경로를 지정합니다.
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = @"powershell.exe";
startInfo.Arguments = @"& 'c:\Scripts\test.ps1'";
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
string output = process.StandardOutput.ReadToEnd();
Assert.IsTrue(output.Contains("StringToBeVerifiedInAUnitTest"));
string errors = process.StandardError.ReadToEnd();
Assert.IsTrue(string.IsNullOrEmpty(errors));
스크립트 내용은 다음과 같습니다.
$someVariable = "StringToBeVerifiedInAUnitTest"
$someVariable
Commands.AddScript 메서드에 전달하는 매개 변수에 대해 더 명확하게 알 수 있습니까?
C : \ Foo1.PS1 Hello World Hunger C : \ Foo2.PS1 Hello World
scriptFile = "C : \ Foo1.PS1"
parameters = "parm1 parm2 parm3"... 매개 변수의 가변 길이
이 문제를 해결했습니다 ... 이름으로 null을 전달하고 CommandParameters 컬렉션에 값으로 매개 변수를 전달합니다.
내 기능은 다음과 같습니다.
private static void RunPowershellScript(string scriptFile, string scriptParameters)
{
RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
runspace.Open();
RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
Pipeline pipeline = runspace.CreatePipeline();
Command scriptCommand = new Command(scriptFile);
Collection<CommandParameter> commandParameters = new Collection<CommandParameter>();
foreach (string scriptParameter in scriptParameters.Split(' '))
{
CommandParameter commandParm = new CommandParameter(null, scriptParameter);
commandParameters.Add(commandParm);
scriptCommand.Parameters.Add(commandParm);
}
pipeline.Commands.Add(scriptCommand);
Collection<PSObject> psObjects;
psObjects = pipeline.Invoke();
}
AddScript 메서드와 함께 파이프 라인을 사용할 수도 있습니다.
string cmdArg = ".\script.ps1 -foo bar"
Collection<PSObject> psresults;
using (Pipeline pipeline = _runspace.CreatePipeline())
{
pipeline.Commands.AddScript(cmdArg);
pipeline.Commands[0].MergeMyResults(PipelineResultTypes.Error, PipelineResultTypes.Output);
psresults = pipeline.Invoke();
}
return psresults;
문자열과 전달하는 매개 변수를받습니다.
다음은 스크립트에 매개 변수를 추가하는 방법입니다.
pipeline.Commands.AddScript(Script);
This is with using an HashMap as paramaters the key being the name of the variable in the script and the value is the value of the variable.
pipeline.Commands.AddScript(script));
FillVariables(pipeline, scriptParameter);
Collection<PSObject> results = pipeline.Invoke();
And the fill variable method is:
private static void FillVariables(Pipeline pipeline, Hashtable scriptParameters)
{
// Add additional variables to PowerShell
if (scriptParameters != null)
{
foreach (DictionaryEntry entry in scriptParameters)
{
CommandParameter Param = new CommandParameter(entry.Key as String, entry.Value);
pipeline.Commands[0].Parameters.Add(Param);
}
}
}
this way you can easily add multiple parameters to a script. I've also noticed that if you want to get a value from a variable in you script like so:
Object resultcollection = runspace.SessionStateProxy.GetVariable("results");
//results being the name of the v
you'll have to do it the way I showed because for some reason if you do it the way Kosi2801 suggests the script variables list doesn't get filled with your own variables.
Mine is a bit more smaller and simpler:
/// <summary>
/// Runs a PowerShell script taking it's path and parameters.
/// </summary>
/// <param name="scriptFullPath">The full file path for the .ps1 file.</param>
/// <param name="parameters">The parameters for the script, can be null.</param>
/// <returns>The output from the PowerShell execution.</returns>
public static ICollection<PSObject> RunScript(string scriptFullPath, ICollection<CommandParameter> parameters = null)
{
var runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
var pipeline = runspace.CreatePipeline();
var cmd = new Command(scriptFullPath);
if (parameters != null)
{
foreach (var p in parameters)
{
cmd.Parameters.Add(p);
}
}
pipeline.Commands.Add(cmd);
var results = pipeline.Invoke();
pipeline.Dispose();
runspace.Dispose();
return results;
}
For me, the most flexible way to run PowerShell script from C# was using PowerShell.Create().AddScript()
The snippet of the code is
string scriptDirectory = Path.GetDirectoryName(
ConfigurationManager.AppSettings["PathToTechOpsTooling"]);
var script =
"Set-Location " + scriptDirectory + Environment.NewLine +
"Import-Module .\\script.psd1" + Environment.NewLine +
"$data = Import-Csv -Path " + tempCsvFile + " -Encoding UTF8" +
Environment.NewLine +
"New-Registration -server " + dbServer + " -DBName " + dbName +
" -Username \"" + user.Username + "\" + -Users $userData";
_powershell = PowerShell.Create().AddScript(script);
_powershell.Invoke<User>();
foreach (var errorRecord in _powershell.Streams.Error)
Console.WriteLine(errorRecord);
You can check if there's any error by checking Streams.Error. It was really handy to check the collection. User is the type of object the PowerShell script returns.
'development' 카테고리의 다른 글
SQL Server 연결이 가끔 작동 함 (0) | 2020.09.05 |
---|---|
Spring의 양식 태그에서 modelAttribute와 commandName 속성의 차이점은 무엇입니까? (0) | 2020.09.05 |
C99 부울 데이터 유형? (0) | 2020.09.05 |
MVC3 Razor에서 작업 내에서 렌더링 된 뷰의 html을 어떻게 얻습니까? (0) | 2020.09.05 |
conda 또는 conda-forge를 Python 환경에 사용해야합니까? (0) | 2020.09.05 |