[英]how to invoke the powershell command with “format-list” and “out-file” pipeline from c#?
嗨,我正在開發一個 C# 程序來調用遠程運行空間中的交換 2010 powershell cmdlet。 ps 命令是:
“Get-MailboxDatabase -Server EX2010SVR1 -Status | Format-List Identity,Guid,mounted,CircularLoggingEnabled,Recovery | Out-File 'C:\db.txt' -Encoding UTF8 -Width 8192”。
我的代碼類似於:
static int Main(string[] args)
{
const string SHELL_URI = "http://schemas.microsoft.com/powershell/Microsoft.Exchange";
const string COMMAND = "Get-MailboxDatabase -Server EX2010SVR1 -Status | Format-List Identity,Guid,mounted,CircularLoggingEnabled,Recovery | Out-File 'C:\db.txt' -Encoding UTF8 -Width 8192";
System.Uri serverUri = new Uri("http://EX2010SVR1/powershell?serializationLevel=Full");
PSCredential creds = (PSCredential)null; // Use Windows Authentication
WSManConnectionInfo connectionInfo = new WSManConnectionInfo(serverUri, SHELL_URI, creds);
try
{
using (Runspace rs = RunspaceFactory.CreateRunspace(connectionInfo))
{
rs.Open();
PowerShell psh = PowerShell.Create();
psh.Runspace = rs;
psh.AddCommand(COMMAND);
Collection results = psh.Invoke();
rs.Close();
}
}
catch (Exception ex)
{
System.Console.WriteLine("exception: {0}", ex.ToString());
}
return 0;
}
當我在托管 Exchange 2010 服務器的 Win2008 R2 上運行 c# 程序時,我總是遇到異常:
System.Management.Automation.RemoteException: The term 'Format-List' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
at System.Management.Automation.PowerShell.CoreInvoke[TOutput](IEnumerable input, PSDataCollection`1 output, PSInvocationSettings settings)
at System.Management.Automation.PowerShell.Invoke(IEnumerable input, PSInvocationSettings settings)
at System.Management.Automation.PowerShell.Invoke()
at RemotePS.Program.Main(String[] args)
該程序在沒有“格式列表”和“輸出文件”管道的情況下運行良好。 整個命令也可以正常工作,以換取 2010 管理 shell。 我還確認它是系統上的 powershell 2.0。
任何人都可以幫助弄清楚發生了什么嗎? 任何幫助深表感謝。
湯姆
我寫的第一個嵌入式 PowerShell 遇到了同樣的問題。 我尋找蹤跡,但我再也找不到了。
這是對我有用的東西,我適應了您的代碼:
static void Main(string[] args)
{
const string SHELL_URI = "http://schemas.microsoft.com/powershell/Microsoft.PowerShell";
const string COMMAND = @"get-process | format-List | Out-File -file c:\temp\jpb.txt";
System.Uri serverUri = new Uri("http://WM2008R2ENT/powershell?serializationLevel=Full");
PSCredential creds = (PSCredential)null; // Use Windows Authentication
WSManConnectionInfo connectionInfo = new WSManConnectionInfo(false,
"WM2008R2ENT",
5985,
"/wsman",
SHELL_URI,
creds);
try
{
using (Runspace rs = RunspaceFactory.CreateRunspace(connectionInfo))
{
rs.Open();
Pipeline pipeline = rs.CreatePipeline();
string cmdLine;
cmdLine = string.Format("&{{{0}}}", COMMAND);
pipeline.Commands.AddScript(cmdLine);
Collection<PSObject> results = pipeline.Invoke();
rs.Close();
}
}
catch (Exception ex)
{
System.Console.WriteLine("exception: {0}", ex.ToString());
}
return;
}
小心,我沒有使用 Exchange PowerShell
在我使用管道的示例中,您的問題可能來自您傳遞命令的方式。
您可以嘗試使用“命令”對象。
Runspace rs = RunspaceFactory.CreateRunspace();
PowerShell ps = PowerShell.Create();
Pipeline pipeline = rs.CreatePipeline();
Command cmd1 = new Command("Get-MailboxDatabase");
cmd1.Parameters.Add("Server", "EX2010SVR1");
cmd1.Parameters.Add("Status");
pipeline.Commands.Add(cmd1);
Command cmd2 = new Command("Format-List");
cmd2.Parameters.Add("Property", "Identity, Guid, mounted, CircularLoggingEnabled, Recovery");
pipeline.Commands.Add(cmd2);
Command cmd3 = new Command("Format-List");
cmd3.Parameters.Add("FilePath", "C:\db.txt");
cmd3.Parameters.Add("Encoding", "UTF8");
cmd3.Parameters.Add("Width", "8192");
pipeline.Commands.Add(cmd3);
Collection<PSObject> output = pipeline.Invoke();
我意識到這是一個老話題,但我想展示我的發現,不管它們有多短。
我最近和我的一位同事遇到了同樣的問題。 我們設法將問題追溯到丟失的運行空間。 我們還必須連接到Microsoft.Exchange
運行空間,當我們這樣做時, Format-List
commandlet 變得不可用。 如果我們不使用運行空間,命令行開關就可以正常工作。
我們還沒有解決它,但我打算探索使用RunspacePool
而不僅僅是Runspace
的可能性,從而允許在管道中執行兩個命令行開關。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.