使用C#调用Powershell命令

时间:2014-12-01 19:35:26

标签: powershell c#-4.0 process

我尝试使用C#执行此PowerShell命令,并等待输出,这是我的域名上的SharePoint网站列表! PowerShell本身工作正常,但使用C#进程调用它,不等待输出! 任何想法或建议都表示赞赏。

//命令

string cmd = @"[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SharePoint') >        $null  
$farm = [Microsoft.SharePoint.Administration.SPFarm]::Local 
$websvcs = $farm.Services | where -FilterScript {$_.GetType() -eq [Microsoft.SharePoint.Administration.SPWebService]} 
$webapps = @() 
foreach ($websvc in $websvcs) {  
        foreach ($webapp in $websvc.WebApplications) {  
                foreach ($site in $webapp.Sites) { 
                $site.URL  
                } 
        } 
} "; 

// C#Process!

        Process proc = new Process();
        proc.StartInfo = new ProcessStartInfo("powershell.exe", cmd);
        proc.Start();
        proc.StartInfo.RedirectStandardOutput = true;
        proc.StartInfo.UseShellExecute = false;
        proc.WaitForExit();
        string output = "";
        while (!proc.HasExited)
        {
            output += proc.StandardOutput.ReadToEnd();
        }

3 个答案:

答案 0 :(得分:0)

我会使用PowerShell自动化引擎。在您的C#项目中,引用System.Management.Automation.dll中的程序集C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\3.0。然后在你的代码中试试这个:

string cmd = "your commands";
string output = "";
using (var ps = PowerShell.Create())
{
    ps.AddScript(cmd);
    var results = ps.Invoke();
    foreach (var result in results) 
    {
        output += result.ToString();
    }
}

如果您只在输出中输入类型名称,请更改此行:

$site.URL  

为:

$site.URL | Out-String

答案 1 :(得分:0)

完成process.HasExited

true始终为proc.WaitForExit(),因此永远不会输入while循环,output将具有初始值。您不需要循环,只需在进程退出后读取输出:

proc.WaitForExit();
string output = proc.StandardOutput.ReadToEnd();

我假设您有一个特定的原因想要在子进程中执行PowerShell代码。否则,更好的方法是@Keith Hill的答案,或者只是将您的PowerShell代码转换为C#并直接从您的应用程序查询数据。在添加System.Management.Automation程序集的引用和usingSystem.Collections.Generic命名空间的一些System.Linq语句后,直接翻译就像......

var farm = Microsoft.SharePoint.Administration.SPFarm.Local;
var websvcs = farm.Services.OfType<Microsoft.SharePoint.Administration.SPWebService>();
var siteUrls = new List<string>();

foreach (var websvc in websvcs)
    foreach (var webapp in websvc.WebApplications)
        foreach (var site in webapp.Sites)
            siteUrls.Add(site.Url);

......更多LINQified方法可能......

var farm = Microsoft.SharePoint.Administration.SPFarm.Local;
var websvcs = farm.Services.OfType<Microsoft.SharePoint.Administration.SPWebService>();
var siteUrls = websvcs
    .SelectMany(websvc => websvc.WebApplications)
    .SelectMany(webapp => webapp.Sites)
    .Select(site => site.Url);

答案 2 :(得分:0)

var farm = Microsoft.SharePoint.Administration.SPFarm.Local;
        var websvcs = farm.Services.OfType<Microsoft.SharePoint.Administration.SPWebService>();
        var siteUrls = websvcs
            .SelectMany(websvc => websvc.WebApplications)
            .SelectMany(webapp => webapp.Sites)
            .Select(site => site.Url);

        foreach (var i in siteUrls)
        {
            Console.WriteLine(i.ToString());
        }