Powershell to Exchange 2013 - Restricted language mode error

11,298

I ended up getting support from Microsoft and they provided the following solution which works. Instead of connection via a remote powershell session, it is possible to connect to the local powershell and then import the remote session. Doing this fixes the issue.

Error handling not included in example below

var runspace = RunspaceFactory.CreateRunspace();
runspace.Open();

object psSessionConnection;

// Create a powershell session for remote exchange server
using (var powershell = PowerShell.Create())
{
    var command = new PSCommand();
    command.AddCommand("New-PSSession");
    command.AddParameter("ConfigurationName", "Microsoft.Exchange");
    command.AddParameter("ConnectionUri", new Uri(_exchangeConnectionUri));
    command.AddParameter("Authentication", "Kerberos");
    powershell.Commands = command;
    powershell.Runspace = runspace;

    // TODO: Handle errors
    var result = powershell.Invoke();
    psSessionConnection = result[0];
}

// Set ExecutionPolicy on the process to unrestricted
using (var powershell = PowerShell.Create())
{
    var command = new PSCommand();
    command.AddCommand("Set-ExecutionPolicy");
    command.AddParameter("Scope", "Process");
    command.AddParameter("ExecutionPolicy", "Unrestricted");
    powershell.Commands = command;
    powershell.Runspace = runspace;

    powershell.Invoke()
}

// Import remote exchange session into runspace
using (var powershell = PowerShell.Create())
{
    var command = new PSCommand();
    command.AddCommand("Import-PSSession");
    command.AddParameter("Session", psSessionConnection);
    powershell.Commands = command;
    powershell.Runspace = runspace;

    powershell.Invoke();
}
Share:
11,298

Related videos on Youtube

andreas
Author by

andreas

Updated on September 14, 2022

Comments

  • andreas
    andreas over 1 year

    I'm working on a C# web service that will be deployed on an Exchange 2013 server. This service will be responsible for running powershell commands to configure Exchange.

    I connect via a runspace created like this

    const string shellUri = "http://schemas.microsoft.com/powershell/microsoft.exchange";
    var uri = new Uri(_exchangeConnectionUri);
    var credentials = (PSCredential)null; // Windows authentication
    var connectionInfo = new WSManConnectionInfo(uri, shellUri, credentials);
    connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Kerberos;
    var runspace = RunspaceFactory.CreateRunspace(connectionInfo);
    

    Using this runspace I am able to run basic powershell commands on the server.

    get-mailbox -ResultSize unlimited
    

    But running more complicated commands gives me errors (this does work if run directly through powershell)

    get-mailbox -ResultSize unlimited | where {$_.emailaddresses -like "*test.com"}
    
    At line:1 char:43
    + get-mailbox -ResultSize unlimited | where {$_.emailaddresses -like "*test.com ...
    +                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Script block literals are not allowed in restricted language mode or a Data section.
    
    At line:1 char:44
    + get-mailbox -ResultSize unlimited | where {$_.emailaddresses -like "*test.com ...
    +                                            ~~~~~~~~~~~~~~~~~
    Property references are not allowed in restricted language mode or a Data section.
    
    At line:1 char:44
    + get-mailbox -ResultSize unlimited | where {$_.emailaddresses -like "*test.com ...
    +                                            ~~
    A variable that cannot be referenced in restricted language mode or a Data section is being referenced. Variables that can be referenced include the following: $PSCulture, $PSUICulture, $true, $false, and  $null.
    

    After searching I found that I might have to register a new PSSessionConfiguration and make sure the scripts are running under PSLanguageMode = FullLanguage. See this post

    I tried to do this, but as soon as I change the shellUri to http://schemas.microsoft.com/powershell/MyConfigName I get the following error.

    The WS-Management service cannot process the request.
    Cannot find the MyConfigName session configuration in the WSMan: drive on the ComputerName computer.
    

    Using the following shelllUri gave me the same error http://schemas.microsoft.com/powershell/Microsoft.Powershell

    This led me to try the following directly through powershell on the exchange server

    > Get-PSSessionConfiguration | format-list -property name
    result:
    Name : MyConfigName
    Name : microsoft.powershell
    Name : microsoft.powershell.workflow
    Name : microsoft.powershell32
    Name : microsoft.windows.servermanagerworkflows
    
    > $session = New-PSSession -ConfigurationName MyConfigName -ConnectionUri $uri -Authentication Kerberos
    result:
    error "Cannot find the MyConfigName session configuration in the WSMan: drive on the ComputerName computer."
    
    > $session = New-PSSession -ConfigurationName Microsoft.Powershell -ConnectionUri $uri -Authentication Kerberos
    result:
    error "Cannot find the Microsoft.Powershell session configuration in the WSMan: drive on the ComputerName."
    
    > $session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $uri -Authentication Kerberos
    result:
    nothing, meaning $session variable set correctly
    

    Like from the C# code, I can only use the Microsoft.Exchange configuration, but this configuration doesn't exist according to Get-PSSessionConfiguration, and the configurations that do exist in that list won't work.

    I am now wondering how to add a configuration with FullLanguage that I can use when calling powershell from code. I might also be completely wrong, and my issue is not related to PSSessionConfigurations at all, but then I still wonder why I can't see the Microsoft.Exchange configuration anywhere.

  • Zakos
    Zakos almost 10 years
    thanks , had same problem. Do I need to run those 3 [usings] for each script I wanna use ?
  • andreas
    andreas almost 10 years
    Running these 3 usings will prepare the runspace for other commands. The first one takes quite a while (around 5 seconds for us) so it is not feasible to run it for every command. We ended up saving the runspace in a static variable and reusing it for new commands.
  • Zakos
    Zakos almost 10 years
    Suddenly , I get 0 result on the first using-Invoke , therefore psSessionConnection = result[0]; throw outOfRange expcetions , do you know why ?
  • andreas
    andreas almost 10 years
    I don't know much more about this sadly. It could be something with the server setup or authentication. Sorry I can't be of more help.
  • Lareau
    Lareau over 6 years
    Btw, the code is missing semi-colon after the powershell.Invoke() (I can't edit the post as it's below the limit of characters for edits).
  • james
    james over 3 years
    Thanks @andreas, it really help me. First get a powershell session and import that session to execute cmd.