3
votes

I'm trying to run next script remotely from client computer:

Get-Mailbox | foreach { Get-InboxRule -Mailbox $_.Name | Remove-InboxRule }

There is my code:

private const string SHELL_URI = "http://schemas.microsoft.com/powershell/Microsoft.Exchange";

    static public void RunPowerShellScript(string scriptfile, List<CommandParameter> cmdList, string runasUsername, string runasPassword, string serverIP)
    {
        // Prepare the credentials that will be used when connecting
        // to the server. More info on the user to use on the notes
        // below this code snippet.

        System.Uri serverUri = new Uri(String.Format("http://{0}/POWERSHELL?serializationLevel=Full", serverIP));
        System.Security.SecureString securePassword = new System.Security.SecureString();

        foreach (char c in runasPassword.ToCharArray())
        {
            securePassword.AppendChar(c);
        }

        System.Management.Automation.PSCredential creds = new System.Management.Automation.PSCredential(runasUsername, securePassword);

        RunspaceConfiguration rc = RunspaceConfiguration.Create();
        WSManConnectionInfo wsManInfo = new WSManConnectionInfo(serverUri, SHELL_URI, creds);
        wsManInfo.AuthenticationMechanism = AuthenticationMechanism.Basic;
        RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();

        Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
        runspace.Open();

        RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);

        Pipeline pipeline = runspace.CreatePipeline();

        //Here's how you add a new script with arguments
        Command myCommand = new Command(scriptfile, true);

        if(cmdList != null)
        {
            foreach (var cmd in cmdList)
                myCommand.Parameters.Add(cmd);
        }

        pipeline.Commands.Add(myCommand);

        // Execute PowerShell script
        var results = pipeline.Invoke();
    }

As a result, the last line throws exception:

The term 'Get-Mailbox' 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.

I know, that i'm using PowerShell there, not ExchangeManagedShell. I`ve tried to add snapin like this:

RunspaceConfiguration rsConfig = RunspaceConfiguration.Create();
PSSnapInException snapInException = null;
PSSnapInInfo info = rsConfig.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.Admin", out snapInException);
Runspace myRunSpace = RunspaceFactory.CreateRunspace(rsConfig);
myRunSpace.Open(rsConfig);

but there is no ExchangeManagedShell on client computer.

P.S. I'm trying to connect to Exchange2013.

What im doing wrong?

[EDITION #1]

Oh, I've found out, what i'm doing wrong:

WSManConnectionInfo wsManInfo = new WSManConnectionInfo(serverUri, SHELL_URI, creds);
wsManInfo.AuthenticationMechanism = AuthenticationMechanism.Basic;
RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();

Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
runspace.Open();

I even don't connect to remote computer. Creating wsManInfo, but don't use it in RunspaceFactory.CreateRunspace();.

But i still don't know how to solve the problem...

2
Do you get an error message from the AddPSSnapIn method call or does it work fine? On Exchange 2010 the snapin name is Microsoft.Exchange.Management.PowerShell.E2010. Could you use PowerShell and run Get-PSSnapin -Registered on the machine to find the name of the PSSnapin? - Robert Westerlund
When i'm trying to add snapin, i receive next exception: "The Windows PowerShell snap-in 'Microsoft.Exchange.Management.PowerShell.Admin' is not installed on this machine." I`ve tried .E2010 and .E2013 - the same. - IStar
Could you try using PowerShell (without the C# application) to Enter-PSSession to the remote computer and then run the Add-PSSnapin in that session? Does that work or do you get an error message there as well? - Robert Westerlund
Hmm. It seems to me that I don't understand how to do this. I've tried like this: Enter-PSSession -Computer 192.168.0.60. As a result get this: Enter-PSSession : Connecting to remote server failed with the following error message : The WinRM client cannot process the request. Default authentication may be used with an IP address under the following conditions:... - IStar
If the computers are in the same domain, do use the computer name instead of IP-address. If they are not, or if you have to use the IP-address, I think you'll have to add the address to the TrustedHosts-list. You'll have to ensure you can connect to the remote computer using PSSessions before you try running commands through a PSSessions. - Robert Westerlund

2 Answers

0
votes

Have you checked whether the credentials that you are using have the right to invoke the "Get-Mailbox" command? If not,account has to be given the privilege to execute the command via RBAC.

0
votes

Thw solution is simple. Just needed to write this

System.Uri serverUri = new Uri(String.Format("https://{0}/POWERSHELL/Microsoft.Exchange", serverIP));  

instead of that

System.Uri serverUri = new Uri(String.Format("http://{0}/POWERSHELL?serializationLevel=Full", serverIP));

Just added "Microsoft.Exchange"