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