programing

명령줄 인수를 사용하여 C#에서 PowerShell 스크립트 실행

closeapi 2023. 4. 16. 15:09
반응형

명령줄 인수를 사용하여 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();

스크립트 파일에는 "C:\Program Files\MyProgram\"과 같은 것이 포함되어 있습니다.뭐든지요.ps1"

스크립트는 "-key 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();

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

명령어에 매개 변수를 전달하는 데 문제가 있었습니다.AddScript 메서드

C:\Foo1.PS1 Hello World Hunger
C:\Foo2.PS1 Hello World

scriptFile = "C:\Foo1.PS1"

parameters = "parm1 parm2 parm3" ... variable length of params

는 이 했습니다.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;

문자열이 필요합니다. 전달되는 파라미터가 무엇이든 상관없습니다.

저는 조금 더 작고 심플합니다.

/// <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;
}

은 C# PowerShell을 사용하는 이었습니다.PowerShell.Create().AddScript()

우선, Microsoft 를 인스톨 할 필요가 있습니다.PowerShell.SDK nuget 패키지.또, .net 프레임워크를 타겟으로 하고 있는 경우는, Microsoft 필요합니다.PowerShell.5.참조 조립품

코드 조각은

using System.Management.Automation;

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);

Streams를 체크하면 오류가 없는지 확인할 수 있습니다.오류. 소장품 확인은 정말 쉬웠어요.사용자는 PowerShell 스크립트가 반환하는 개체 유형입니다.

다음은 를 사용하는 경우 스크립트에 파라미터를 추가하는 방법입니다.

pipeline.Commands.AddScript(Script);

이는 HashMap을 파라미터로 사용하는 경우로, 키는 스크립트의 변수 이름이고 값은 변수의 값입니다.

pipeline.Commands.AddScript(script));
FillVariables(pipeline, scriptParameter);
Collection<PSObject> results = pipeline.Invoke();

채우기 변수 방법은 다음과 같습니다.

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);
    }
  }
}

이렇게 하면 여러 파라미터를 스크립트에 쉽게 추가할 수 있습니다.스크립트에 포함된 변수에서 값을 가져오려면 다음과 같이 하십시오.

Object resultcollection = runspace.SessionStateProxy.GetVariable("results");

//v의 이름이 됩니다.

어떤 이유로든 Kosi2801이 제안하는 대로 하면 스크립트 변수 목록이 사용자 자신의 변수로 채워지지 않기 때문입니다.

인수에 공백이 포함된 경우를 포함하여 다음과 같은 작업을 수행할 수 있습니다.

using (PowerShell PowerShellInst = PowerShell.Create())
        {

            PowerShell ps = PowerShell.Create();
            
            string param1= "my param";
            string param2= "another param";
            string scriptPath = <path to script>;

            ps.AddScript(File.ReadAllText(scriptPath));

            ps.AddArgument(param1);
            ps.AddArgument(param2);

            ps.Invoke();
         
        }

이 접근방식은 매우 이해하기 쉽고 명확합니다.

코드로 검출할 수 없는 경우System.Management.Automation.Runspaces종속성을 추가해야 하는 네임스페이스System.Management.Automation.dll이 DLL은 PowerShell과 함께 제공되며 기본적으로 다음 디렉토리에 있습니다.C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\3.0

참조를 추가하려면 프로젝트를 열고 "References" > "Add reference" 를 오른쪽 클릭하여 "Browse" 버튼을 선택하고 위의 위치로 이동하여 필요한 .dll 파일을 선택합니다."추가"를 클릭하면 참조가 찾아보기 탭에 표시되고 옆에 체크박스가 켜집니다.

참조 추가 후System.Management.Automation.Runspaces언급된 다른 코드에서 를 실행하여 매개 변수를 추가하고 PowerShell 스크립트를 실행할 수 있습니다.나는 "키"와 "값" 쌍을 저장하기 위해 태플을 사용하는 것이 매우 편리하다고 생각한다.

/// <summary>
/// Run a powershell script with a list of arguments
/// </summary>
/// <param name="commandFile">The .ps1 script to execute</param>
/// <param name="arguments">The arguments you want to pass to the script as parameters</param>
private void ExecutePowerShellCommand(string commandFile, List<Tuple<string, string>> arguments)
{
    RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
    Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
    runspace.Open();

    Pipeline pipeline = runspace.CreatePipeline();

    //commandFile is the PowerShell script you want to execute, e.g. "FooBar.ps1"
    Command cmd = new Command(commandFile);

    // Loop through all the tuples containing the "key", "value" pairs and add them as a command parameter
    foreach (var parameter in arguments)
        cmd.Parameters.Add(new CommandParameter(parameter.Item1, parameter.Item2));

    pipeline.Commands.Add(cmd);

    // Execute the PowerShell script
    var result = pipeline.Invoke();

}

발신자 코드:

string commandFile = @"C:\data\test.ps1";

List<Tuple<string, string>> arguments = new List<Tuple<string, string>>();
arguments.Add(new Tuple<string, string>("filePath", @"C:\path\to\some\file"));
arguments.Add(new Tuple<string, string>("fileName", "FooBar.txt"));

ExecutePowerShellCommand(commandFile, arguments);

언급URL : https://stackoverflow.com/questions/527513/execute-powershell-script-from-c-sharp-with-commandline-arguments

반응형