从C#调用Exchange命令行管理程序#

问题描述:

我目前使用.NET 3.5/C#开发执行自动化Exchange操作的Windows服务。该服务基本上监视SQL数据库的执行操作,然后生成PowerShell并重定向输出,以便可以从驻留在别处的UI监视结果。下面是我使用的调用过程的代码...从C#调用Exchange命令行管理程序#

Action<object, DataReceivedEventArgs> DataReceived = (sender, data) => 
{ 
    // Log data in SQL 
}; 
System.Diagnostics.Process p = new System.Diagnostics.Process(); 
p.StartInfo.FileName = "powershell.exe" 
p.StartInfo.Arguments = arguments; 

// Arguments are (they're coming from SQL, didn't feel like escaping everything just for this example) 
// -command ". 'C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1'; Connect-ExchangeServer -auto; Get-Mailbox –ResultSize unlimited | Search-Mailbox -SearchQuery ... stuff ... 

p.StartInfo.LoadUserProfile = true;   
p.StartInfo.RedirectStandardOutput = true; 
p.StartInfo.RedirectStandardInput = true; 
p.StartInfo.UseShellExecute = false; 
p.StartInfo.CreateNoWindow = true; 
p.OutputDataReceived += new DataReceivedEventHandler(DataReceived); 
p.Start(); 

这个代码可以做的事情一样运行的ping,tracert命令,nslookup将,回声,目录,和所有常见的命令行的怀疑与行为与我将它键入命令提示符相同。例如,我可以将上述内容复制粘贴到“运行”框中,并且完美无瑕。每当我试图如上运行它,但是,我收到以下内容:

Get-ItemProperty : Cannot find path 'HKLM:\SOFTWARE\Microsoft\ExchangeServer\v14\Setup' because it does not exist. 
At C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1:46 char:34 
+ $global:exbin = (get-itemproperty <<<< HKLM:\SOFTWARE\Microsoft\ExchangeServer\v14\Setup).MsiInstallPath + "bin\" 
    + CategoryInfo   : ObjectNotFound: (HKLM:\SOFTWARE\...erver\v14\Setup:String) [Get-ItemProperty], ItemNotFo 
    undException 
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetItemPropertyCommand 

Get-ItemProperty : Cannot find path 'HKLM:\SOFTWARE\Microsoft\ExchangeServer\v14\Setup' because it does not exist. 
At C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1:47 char:38 
+ $global:exinstall = (get-itemproperty <<<< HKLM:\SOFTWARE\Microsoft\ExchangeServer\v14\Setup).MsiInstallPath 
    + CategoryInfo   : ObjectNotFound: (HKLM:\SOFTWARE\...erver\v14\Setup:String) [Get-ItemProperty], ItemNotFo 
    undException 
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetItemPropertyCommand 

Get-ItemProperty : Cannot find path 'HKLM:\SOFTWARE\Microsoft\ExchangeServer\v14\Setup' because it does not exist. 
At C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1:48 char:38 
+ $global:exscripts = (get-itemproperty <<<< HKLM:\SOFTWARE\Microsoft\ExchangeServer\v14\Setup).MsiInstallPath + "scri 
pts\" 
    + CategoryInfo   : ObjectNotFound: (HKLM:\SOFTWARE\...erver\v14\Setup:String) [Get-ItemProperty], ItemNotFo 
    undException 
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetItemPropertyCommand 

The term 'bin\CommonConnectFunctions.ps1' 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 C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1:52 char:2 
+ . <<<< $global:exbin"CommonConnectFunctions.ps1" 
    + CategoryInfo   : ObjectNotFound: (bin\CommonConnectFunctions.ps1:String) [], CommandNotFoundException 
    + FullyQualifiedErrorId : CommandNotFoundException 

其他错误整体转换后如下这一点,但不过去我已经决定了它所有的RemoteExchange PowerShell脚本归结到前三个错误:无法从注册表中读取。有没有人有任何想法,为什么这可能会发生?

事情我已经试图让这项工作:

  • 运行在一个控制台应用程序的代码,而不是服务上下文。
  • 每次我运行它,我做了一个域和Exchange管理员,我从来没有UAC提示,所以我怀疑这个问题是凭证之一
  • 检查的注册表键...... HKLM键它看着还授予感到沉沦
  • 完全读取权限我已经启用无符号PowerShell脚本执行服务器
  • 把命令变成一个PowerShell脚本,并调用该程序
  • 硬编码的注册表键的值代入上PowerShell脚本(这只是给我另一套注册表读取错误进一步下行)
  • 在流程中使用的ShellExecute(这不能用输出重定向来完成,这是我需要)
  • 在StartInfo的明确设置环境变量在产卵环境

的名称相符给任何人可以给我一只手...谢谢十亿!

***编辑:也许我应该澄清hardcoding位。我已经裂了开来RemoteExchange.ps1,并设置有示数到他们的正确值的变量(而不是使用的getProperty或其他),我得到稍微更远:

Exception calling "TryLoadExchangeTypes" with "2" argument(s): "Unable to determine the installed file version from the 
registry key 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ExchangeServer\v14\Setup'." 
At C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1:79 char:92 
+ $typeLoadResult = [Microsoft.Exchange.Configuration.Tasks.TaskHelper]::TryLoadExchangeTypes <<<< ($ManagementPath, $t 
ypeListToCheck) 
    + CategoryInfo   : NotSpecified: (:) [], MethodInvocationException 
    + FullyQualifiedErrorId : DotNetMethodException 

从什么我从看surmising像79这不是我可以改变的东西。它试图从库中加载类型,并且需要继续查看注册表,所以我不能修正一个变量。

您可以打开Exchange。PS1驻留在\ bin,然后编辑下

## EXCHANGE VARIABLEs ######################################################## 

更改$全球出现的变量:exbin,$全球:exinstall,和$全球:exscripts被硬编码路径

"C:\Program Files\Microsoft\Exchange Server\V14\bin\" 
"C:\Program Files\Microsoft\Exchange Server\V14\" 
"C:\Program Files\Microsoft\Exchange Server\V14\scripts\" 

这不是一个理想的解决方案,但是解决方法不应该影响调用这些变量的其他任何内容。

+0

请参阅编辑原始问题。 – 2012-07-26 16:22:03

+0

您目前正在运行什么样的SP 2010? – 2012-07-26 17:58:27

试着在x64中编译你的程序。

我知道这很奇怪,但在x86管理的PowerShell中,有些cmdlet无法从x64程序中看到注册表项。

(我接到线索:“这些事情之一是不喜欢其他|首页中的可怕DBA”:http://www.scarydba.com/2010/06/30/one-of-these-things-is-not-like-the-other/

+0

你是对的,这里是一个[更深的解释](http://msdn.microsoft.com/en-us/library/windows/desktop/aa384187%28v=vs.85%29.aspx) 提出了一个解决方案在该链接的底部。另请参阅我的答案[这里](http://stackoverflow.com/questions/13266159/how-can-i-run-command-in-microsoft-exchange-server-powershell-through-python-scr)。 – Zifik 2012-12-19 18:53:00

有同样的问题,实际上终于想通了。我以前的回答完全错误。

我正确回答了here