2

現在、.NET 3.5 / C# を使用して、自動化された Exchange 操作を実行する Windows サービスを開発しています。このサービスは基本的に、SQL データベースで実行する操作を監視し、PowerShell を生成して出力をリダイレクトし、別の場所にある UI から結果を監視できるようにします。以下は、プロセスを呼び出すために使用しているコードです...

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、echo、dir の実行など、コマンド プロンプトに入力した場合と同じ動作で、通常のコマンド ラインで疑わしいすべてのことを実行できます。たとえば、上記をコピーして [実行] ボックスに貼り付けると、問題なく動作します。ただし、上記のように実行しようとすると、次のメッセージが表示されます。

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 スクリプトを調べた結果、最初の 3 つのエラー (レジストリから読み取れない) が原因であることがわかりました。なぜこれが起こっているのか、誰にも分かりますか?

これを機能させるために私が試みたこと:

  • サービス コンテキストではなく、コンソール アプリでこのコードを実行します。
  • 実行するたびに、ドメインおよびExchange管理者として実行しましたが、UACプロンプトが表示されなかったので、問題は資格情報の1つであるとは思えません
  • レジストリキーをチェックしました... 見ているHKLMキーには、誰にでも完全な読み取り権限が付与されています
  • サーバーで未署名の PowerShell スクリプトの実行を有効にしました
  • コマンドを PowerShell スクリプトに入れ、プログラムで呼び出す
  • レジストリ キーの値を PowerShell スクリプトにハードコーディングします (これにより、別の一連のレジストリ読み取りエラーが発生します)。
  • プロセスで ShellExecute を使用する (これは、私が必要とする出力リダイレクトでは実行できません)
  • StartInfo に環境変数を明示的に設定して、スポーン環境のものと一致させます。

私に手を差し伸べてくれる人は誰にでも... 10 億人に感謝します!

***編集: おそらく、ハードコーディング ビットを明確にする必要があります。私はすでに 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

79のように見て推測していることから、これは私が変更できるものではありません. ライブラリから型をロードしようとしていますが、そのためにはまだレジストリを調べる必要があるため、変数を修正することはできません。

4

3 に答える 3

1

プログラムをx64でコンパイルしてみてください。

私はそれが奇妙であることを知っていますが、x86管理のPowerShellでは、一部のコマンドレットはx64プログラムからのレジストリキーを見ることができません。

(私は次のことから手がかりを得ました:「これらのものの1つは他のものとは異なります|怖いDBAの家」:http ://www.scarydba.com/2010/06/30/one-of-these-things-is -他に似ていない/

于 2012-08-16T19:42:52.177 に答える
0

\bin にある Exchange.ps1 を開いて、下に表示される変数を編集できます。

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

$global:exbin、$global:exinstall、および $global:exscripts をハード コードされたパスに変更します。

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

これは理想的な解決策ではありませんが、回避策はこれらの変数を呼び出す他のものに影響を与えるべきではありません。

于 2012-07-26T14:42:44.347 に答える
0

同じ問題があり、実際に最終的にそれを理解しました。私の以前の答えは完全に間違っていました。

ここで正解しました。

于 2012-12-18T20:57:52.937 に答える