0

我有代码可以从包含大量 PowerShell cmdlet 的 .ps1 文件中运行 PowerShell cmdlet ......当我执行它时,我得到了这个异常:

术语“New-BuildCVFromSql”未被识别为 cmdlet、函数、脚本文件或可运行程序的名称。检查名称的拼写,或者如果包含路径,请验证路径是否正确并重试。

private void RunPowerShellCommandToBuildCV()
{
    string BigWindow = "";
    string FileNamePopup = "";

    TestPopup(ref BigWindow, ref FileNamePopup);

    string psScriptPath = @"D:\Project Files\CIS3G\Webapp\_Powershell\JcdcCv.psm1";
    string psScript = string.Empty;

    if(File.Exists(psScriptPath))
        psScript = File.ReadAllText(psScriptPath);
    else
        throw new FileNotFoundException("Wrong path for the script file");

    // Init the PowerShell runspace and pipeline - EWB
    Runspace runSpace = RunspaceFactory.CreateRunspace();
    runSpace.Open();

    // Set execution policy - EWB
    RunspaceInvoke runSpaceInvoker = new RunspaceInvoke(runSpace);
    runSpaceInvoker.Invoke("Set-ExecutionPolicy Unrestricted");

    Pipeline pipeline = runSpace.CreatePipeline();

    // I tried loading it both of the ways below and had no joy load the script from the string - EWB
    //pipeline.Commands.AddScript(psScript);

    // Load as file - EWB
    pipeline.Commands.AddScript(psScriptPath, false);

    // Add the outstring command to the pipeline.
    pipeline.Commands.Add("Out-String");

    Command myCommand = new System.Management.Automation.Runspaces.Command("New-BuildCVFromSql");

    CommandParameter SqlOrExcelFile                          = new CommandParameter("SqlOrExcelFile", @"C:\Documents and Settings\Brown.Ericw\My Documents\tempeval.sql");
    CommandParameter Js                                      = new CommandParameter("Js", "JCDC");
    CommandParameter FileName                                = new CommandParameter("FileName", @"Evaluation\EvaluationFormPartialListVM");

    myCommand.Parameters.Add(SqlOrExcelFile);
    myCommand.Parameters.Add(Js);
    myCommand.Parameters.Add(FileName);

    pipeline.Commands.Add(myCommand);

    Collection<PSObject> output = pipeline.Invoke();
    //foreach (PSObject psObject in output)
    //{

    //System.Diagnostics.Debug.WriteLine ("Object name: " + psObject.);
    //}
}

所以显然我没有正确加载这个脚本文件。在 PowerShell ISE/IDE 中,我必须先运行脚本,然后才能执行任何命令。那是我做错了吗?

我只是想将一个界面放在其他人编写的一堆 PowerShell 脚本之上,所以我不能真正更改他/她的脚本文件,因为它们正在其他地方被其他人使用......

在 .ps1 文件中,我试图调用的 cmdlet 是这样定义的:

# Create CV Method #

function New-BuildCVFromSql {
  param([Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true)]$SqlFile,
        [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true)]$js,
        [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true)]$FileName)

 ...

附录:根据这篇文章,我还尝试使用 PowerShell 而不是管道:

从 c# 调用 powershell 函数的问题

像这样,但我得到了同样的例外:

private void RunPowerShellCommandToBuildCV()
{
    string BigWindow = "";
    string FileNamePopup = "";

    TestPopup(ref BigWindow, ref FileNamePopup);

    string psScriptPath = @"D:\Project Files\CIS3G\Webapp\_Powershell\JcdcCv.psm1";
    string psScript = string.Empty;

    if (File.Exists(psScriptPath))
        psScript = File.ReadAllText(psScriptPath);
    else
        throw new FileNotFoundException("Wrong path for the script file");

    // Init the PowerShell runspace and pipeline - EWB
    using (Runspace runSpace = RunspaceFactory.CreateRunspace())
    {
        runSpace.Open();

        // Set execution policy - EWB
        RunspaceInvoke runSpaceInvoker = new RunspaceInvoke(runSpace);
        runSpaceInvoker.Invoke("Set-ExecutionPolicy Unrestricted");

        //Pipeline pipeline = runSpace.CreatePipeline();

        PowerShell ps = PowerShell.Create();
        ps.Runspace = runSpace;

        // Load as file - EWB
        ps.AddScript(psScriptPath);

        ps.AddCommand("New-BuildCVFromSql").AddParameters(new Dictionary<string, string>()
         {
             {"SqlOrExcelFile", @"C:\tempeval.sql"},
             {"Js", "JCDC"},
             {"FileName", @"Evaluation\EvaluationFormPartialListCV"}
         });

        foreach (PSObject result in ps.Invoke())
        {
            Debug.WriteLine ("Object : " + result);
        }
    }

附录 2:

删除所有命令内容(因为它们仅适用于内置 CmdLets,而不适用于用户定义的函数)并这样做似乎是在调用代码,尽管在运行时没有加载任何依赖项......我仍在调查。

ps.AddScript( @"New-BuildCVFromSql 'C:\Documents and Settings\Brown.Ericw\My Documents\tempeval.sql' JCDC 'Evaluation\EvaluationFormPartialListCV'" );

尽管在运行时没有加载任何依赖项,但它似乎正在调用代码......我仍在调查。但如果它是从 ISE 运行的,它就可以工作......

4

2 回答 2

2

在您的第二个版本中RunPowerShellCommandToBuildCV()缺少ps.invoke()添加后的脚本:

    //load as file - EWB
    ps.AddScript( psScriptPath );
    ps.Invoke(); //<--------- !!!!
    ps.AddCommand( "New-BuildCVFromSql" ).AddParameters(new Dictionary<string, string>()
     {
         { "SqlOrExcelFile", @"C:\tempeval.sql" },
         { "Js", "JCDC" },
         { "FileName", @"Evaluation\EvaluationFormPartialListCV" }
     });

在知道有一个函数调用Invoke()之后runspaceNew-BuildCVFromSql

于 2012-06-06T19:16:01.153 回答
0

我就是这样做的,它很有效:

private static void Test()
{
    dynamic parameters = new ExpandoObject();
    parameters.test= "myImage";
    parameters.arg2= 2;

    var results = RunPowerShellFunction("My-Function", parameters);
    var obj = results[0];
    var str = results[1];
}

private static dynamic RunPowerShellFunction(string functionName, dynamic parameters)
{
    dynamic rv = null;

    try
    {
        InitialSessionState iss = InitialSessionState.CreateDefault();

        using (Runspace runspace = RunspaceFactory.CreateRunspace(iss))
        {
            runspace.Name = typeof(DockerManager).Name;
            runspace.Open();

            RunspaceInvoke runSpaceInvoker = new RunspaceInvoke(runspace);
            runSpaceInvoker.Invoke("Set-ExecutionPolicy Unrestricted");

            using (var mainPowerShell = System.Management.Automation.PowerShell.Create())
            {
                mainPowerShell.Runspace = runspace;

                mainPowerShell.AddScript(LoadedScriptText, false);
                mainPowerShell.Invoke();

                var cmd = mainPowerShell.AddCommand(functionName);

                if (parameters != null)
                {
                    foreach (var parameter in parameters)
                    {
                        cmd.AddParameter(parameter.Key, parameter.Value);
                    }
                }

                rv = cmd.Invoke();
            }
        }
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex.Message);
    }

    return rv;
}
于 2017-04-22T10:09:15.187 回答