locked
Problem invoking Exchange Management Shell from C#... RRS feed

  • Question

  • I'm currently using .NET 3.5 / C# to develop a Windows service that performs automated Exchange operations. This service basically watches a SQL database for operations to perform then spawns PowerShell and redirects the output so that results can be monitored from a UI residing elsewhere. Below is the code I'm using to invoke the process...

    	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();

    This code can do things like run ping, tracert, nslookup, echo, dir, and all of the usual command-line suspects with behavior identical to as if I typed it into a command prompt. For instance, I could copy-paste the above into the Run box and it would work flawlessly. Whenever I try to run it as above, however, I receive the following:

    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

    A whole slew of other errors follows after this, but from going over the RemoteExchange PowerShell script I've determined that it all comes down to those first three errors: not being able to read from the registry. Does anyone have any idea as to why this might be happening?

    Things I've tried to get this to work:

    • Running this code in a console app as opposed to a service context.
    • Every time I've run it I've done so as a domain and Exchange admin and I never got an UAC prompts, so I doubt the issue is one of credentials
    • Checked registry keys... The HKLM key it's looking at also has full read permissions granted to everbody
    • I've enabled unsigned PowerShell script execution on the server
    • Putting the command into a PowerShell script and invoking that programmatically
    • Hardcoding the registry keys' values into the PowerShell script (which just gives me another set of registry read errors further down the line)
    • Using ShellExecute on the process (this can't be done with output redirection, which I require)
    • Explicitly setting environment variables on the StartInfo to match the ones in the spawning environment

    To anyone that can give me a hand... thanks a billion!

    • Moved by Bob Shen Monday, July 30, 2012 10:02 AM (From:Visual C# General)
    Thursday, July 26, 2012 1:43 PM

Answers

All replies