कमांडलाइन तर्क के साथ C # से PowerShell स्क्रिप्ट निष्पादित करें


101

मुझे 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 \ जो भी हो। कुछ भी शामिल है"।

स्क्रिप्ट कमांड-तर्क का उपयोग करता है जैसे "-की वैल्यू" जबकि वैल्यू कुछ ऐसे पथ की तरह हो सकती है जिसमें स्पेस भी हो सकता है।

मुझे यह काम नहीं आता। क्या कोई जानता है कि C # से PowerShell स्क्रिप्ट में कमांडलाइन तर्क कैसे पास करें और सुनिश्चित करें कि रिक्त स्थान कोई समस्या नहीं है?


1
भविष्य के उपयोगकर्ताओं के लिए स्पष्ट करने के लिए, स्वीकृत उत्तर उपयोग मापदंडों के बिना भी रिक्त स्थान वाले लोगों के लिए समस्या का समाधान करते हैं। का उपयोग करना: Command myCommand = new Command(scriptfile);और फिर pipeline.Commands.Add(myCommand);भागने के मुद्दे को हल करें।
scharette

जवाबों:


111

एक अलग कमांड के रूप में स्क्रिप्टफ़ाइल बनाने का प्रयास करें:

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

मुझे अभी भी समस्या है कि अगर c: \ program files \ myprogram जैसा कुछ है, तो कुंजी c: \ program पर सेट है। :(
मेप्सिजेटो

कोई बात नहीं। कभी-कभी यह मदद करता है जब आप जानते हैं कि तारों को सही ढंग से कैसे विभाजित किया जाए। ;-) धन्यवाद फिर से, आपके समाधान ने मेरी समस्या को हल करने में मेरी मदद की!
Mephisztoe

@Tronex - आपको अपनी स्क्रिप्ट के लिए पैरामीटर होने के नाते कुंजी को परिभाषित करना चाहिए। PowerShell में पथों के साथ काम करने के लिए कुछ महान बिलिन टूल हैं। शायद उस बारे में एक और सवाल पूछें। @ कोसी 2801 में मापदंडों को जोड़ने का सही उत्तर है।
स्टीवन मुरावस्की

मेरे उत्तर को टाइप करते हुए आपका ओवरलैप किया गया .. मुझे खुशी है कि आप इसे हल कर चुके हैं!
स्टीवन मुरावस्की

1
scriptInvoker वैरिएबल का उपयोग नहीं किया जा रहा है।
निहार

33

मेरे पास एक और उपाय है। मैं बस परीक्षण करना चाहता हूं कि क्या पावरस्ले स्क्रिप्ट निष्पादित करना सफल होता है, क्योंकि शायद कोई व्यक्ति नीति को बदल सकता है। तर्क के रूप में, मैं केवल निष्पादित होने वाली स्क्रिप्ट का पथ निर्दिष्ट करता हूं।

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

1
नमस्ते। क्या आपके पास ऐसा कोई विचार है कि आपके द्वारा बताई गई और सभी कमांड प्रक्रिया को निष्पादित करने के दौरान शक्तियां क्यों शुरू होती हैं (हमारे मामले में) बाहर नहीं निकलती हैं?
यूगेनीयू टोरिका

आप किस पुस्तकालय का उपयोग कर रहे हैं
SoftwareSavant

11

मुझे कमांड्स.एडस्क्रिप्ट विधि में मापदंडों को पारित करने में परेशानी हुई।

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

बस जोड़ा गया:using (Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration))...using (Pipeline pipeline = runspace.CreatePipeline())
रेड

जब मैं कई मापदंडों को पारित कर रहा हूं, तो यह त्रुटि होती है: System 'में एक अनहेल्डेड अपवाद' System.Management.Automation.ParseException 'System.Management.Automation.dll में हुई
मुहम्मद नोमान

5

आप बस AddScript Method के साथ पाइपलाइन का उपयोग कर सकते हैं:

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;

यह एक स्ट्रिंग लेगा, और जो भी पैरामीटर आप इसे पास करेंगे।


4

मेरा एक छोटा और अधिक सरल है:

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

3

यदि आप उपयोग करते हैं तो स्क्रिप्ट में पैरामीटर जोड़ने का एक तरीका है

pipeline.Commands.AddScript(Script);

यह एक हशपप का उपयोग करने के साथ होता है क्योंकि स्क्रिप्ट में चर का नाम होने के कारण पैरामेटर्स महत्वपूर्ण होता है और मूल्य चर का मूल्य होता है।

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 का नाम है

आपको इसे वैसे ही करना होगा जैसा मैंने दिखाया क्योंकि किसी कारण से अगर आप इसे करते हैं तो कोसी 2801 से पता चलता है कि स्क्रिप्ट चर सूची आपके अपने चर से भरी नहीं जाती है।


3

मेरे लिए, C # से PowerShell स्क्रिप्ट को चलाने का सबसे लचीला तरीका उपयोग कर रहा था PowerShell.Create().AddScript()

कोड का स्निपेट है

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.Error की जाँच करके कोई त्रुटि है, तो आप देख सकते हैं। संग्रह की जांच करना वास्तव में बहुत आसान था। उपयोगकर्ता ऑब्जेक्ट PowerShell स्क्रिप्ट रिटर्न का प्रकार है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.