从C#调用Powershell(ASP.NET) - 传递自定义对象?

时间:2011-09-16 03:49:03

标签: powershell powershell-v2.0

我在尝试从C#调用Powershell函数时遇到了麻烦。具体来说,我试图将一个通用的Project列表传递给一个powershell模块函数。这是代码:

var script = @". \\server01\Modules\Runspace.ps1; Get-MyCommand";
var allProjects = _pmRepository.GetAllProjects();
using (Runspace runSpace = RunspaceFactory.CreateRunspace())
{
    runSpace.Open();
    PowerShell posh = PowerShell.Create();
    posh.Runspace = runSpace;
    posh.AddScript(script);
    posh.AddArgument(allProjects);

    Collection<PSObject> results = posh.Invoke();
}

GetAllProjects()方法返回Project的通用列表,Project是一个自定义类。我的模块函数签名如下所示:

function Get-MyCommand
{
    [CmdletBinding()]
    Param
    (
        [Parameter(ValueFromPipeline = $true)]
        [PSCustomObject[]] $Projects
    )
    Begin
    {}
    Process
    {
        $consumables = New-GenericList "Company.Project.Entities.Project"
        foreach($project in $projects)
        {
            if ($project.State -eq $ProjectStates.Development)
            {
                $consumables.Add($project)
            }
        }
    }
}

当我尝试遍历数组时,我收到此错误:

{“在此对象上找不到属性'状态'。请确保它存在。”}

有可能做我想做的事吗?

修改 我使用了下面的代码一段时间,但最终消耗了这个Web应用程序的后端C#代码。创建PowerShell会话的加载时间对我们的情况来说太大了。希望这会有所帮助。

    private void LoadConsumableProjects()
    {
        var results = new Collection<PSObject>();
        InitialSessionState iss = InitialSessionState.CreateDefault();
        iss.ImportPSModule(_modules);

        using (Runspace runSpace = RunspaceFactory.CreateRunspace(iss))
        {
            runSpace.Open();
            using (var ps = PowerShell.Create())
            {
                ps.Runspace = runSpace;
                ps.AddScript("Get-LatestConsumableProjects $args[0]");
                ps.AddArgument(Repository.GetAllProjects().ToArray());

                results = ps.Invoke();
                if (ps.Streams.Error.Count > 0)
                {
                    var errors = "Errors";
                }
            }
        }

        _projects = new List<Project>();
        foreach (var psObj in results)
        {
            _projects.Add((Project)psObj.BaseObject);
        }
    }

1 个答案:

答案 0 :(得分:1)

好的,我把它作为答案,因为,我认为你可以测试它。据我了解你的代码,你将一个参数传递给你的脚本:

posh.AddArgument(allProjects);

但是在你的脚本中你不会使用这个参数传递给你的函数。对我来说,你可以测试:

var script = @". \\server01\Modules\Runspace.ps1; Get-MyCommand $args[0]";

在你的脚本中,你点源'Runspace.ps1',然后调用你的函数Get-MyCommand不带参数。 PowerShell进入foreach循环,$ project等于null。如果$ Projects为空,请发出哔哔声。