Powershell to Exchange 2013 - Restricted language mode error
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();
}
Related videos on Youtube
andreas
Updated on September 14, 2022Comments
-
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 almost 10 yearsthanks , had same problem. Do I need to run those 3 [usings] for each script I wanna use ?
-
andreas almost 10 yearsRunning 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 almost 10 yearsSuddenly , I get 0 result on the first using-Invoke , therefore psSessionConnection = result[0]; throw outOfRange expcetions , do you know why ?
-
andreas almost 10 yearsI 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 over 6 yearsBtw, 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 over 3 yearsThanks @andreas, it really help me. First get a powershell session and import that session to execute cmd.