2011-09-16 23 views
0

我在嘗試從C#調用Powershell函數時遇到了問題。具體來說,我試圖將一個通用的Project列表傳遞給一個PowerShell模塊函數。代碼如下:從C#調用PowerShell(ASP.NET) - 傳遞自定義對象?

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

在你的腳本中,你點源'Runspace.ps1'然後調用你的函數Get-MyCommand,沒有參數你不會讓$ args? – JPBlanc

+0

當我構建Runspace和Powershell對象時,參數被傳入。 'posh.AddArgument(allProjects);' – drohm

+0

好的,但我在想你必須寫這樣的'var script = @「。\\ server01 \ Modules \ Runspace.ps1; Get-MyCommand $ args」;'for該參數傳遞給你的函數'Get-MyCommand' – JPBlanc

回答

1

好吧我把它作爲答案,因爲我認爲你可以測試它。據我瞭解你的代碼的參數傳遞給你的腳本:

posh.AddArgument(allProjects); 

但是你的腳本中不使用這個參數傳遞給你的函數。對我來說,你可以測試:

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

在腳本中,你點源「Runspace.ps1」,然後調用函數獲取-mycommand的不帶參數。 PowerShell進入foreach循環,$ project等於null。只要$ Projects爲空就發出嘟嘟聲。

+0

我明白你的意思了。我的印象是AddArgument方法將該參數傳遞給函數,而不是我要求它在Runspace中運行的腳本。我得到了進一步,但我沒有得到這個錯誤: '不能處理參數'項目'的參數轉換。無法將類型爲「Company.Project.Entities.Project []」的「Company.Project.Entities.Project []」值轉換爲鍵入「Company.Project.Entities.Project」。 – drohm

+0

另外,還定義了powershell函數參數像這樣'[Parameter(ValueFromPipeline = $ true)] [Company.Project.Entities.Project []] $ Projects' – drohm

+0

它看起來像'_pmRepository.GetAllProjects()'只返回一個項目。你可以在沒有類型的情況下聲明'$ Projects'並使用'$ Projects.gettype'來查看類型。 – JPBlanc

相關問題