Wanted to make something clear – this is an issue with Windows and PowerShell, Exchange 2016 is not the root cause of this issue. Now on to the article!
A few weeks ago I ran a poll on this and it seems that a fair number of you depend on Get-Help for finding information on PowerShell cmdlets in Exchange 2016. Now, if you are an active user of PowerShell and Exchange 2016, you may have noticed that it is broken. Yes. Broken. But it isn’t broken everywhere. If you have Exchange Server 2016 AND Windows Server 2012 R2 then Get-Help works for you. If you have Exchange 2016 AND Windows Server 2016 then your Get-Help experience isn’t good. For this article, we will cover what is wrong and ways to get around this broken experience.
Background
Like other versions of Exchange, 2016 has gone from RTM all the way now to CU7. In this time its existence on Windows 2016 has been a contentious one. Quick punch list of issues:
- Windows 2016 RTM – Issues with Exchange 2016 DAG, which would be discovered after a node was joined and rebooted
- Exchange Edge – supported, but NOT recommended on Windows 2016
- Since CU3, Exchange 2016’s Get-Help cmdlets has failed to function
Of this list, we will cover the last item. For those who have not see the issue, if we were to run Get-Help about any cmdlets in Exchange from the ‘Exchange Management Shell’ a blur of red is displayed. This red is basically Get-Help failed to execute the Get-Help cmdlets:
There is no escaping this. In Exchange 2016, if it is installed on Windows 2016 and is CU3, CU4, CU5, CU6 or even the latest of CU7, this is your experience.
Workarounds
** NOTE ** I have this in my Exchange Server 2016 PowerShell book. It is such a problem, that I decided to share it here as well):
(1) Windows Server 2012 R2
Yes. Windows Server 2012. If you have an Exchange 2016 server in the Windows 2012 R2 OS, then you are in luck. You can run Get-Help. Unlike the poor schleps that keep up to date with their OS, am engineer who has access to an Exchange 2016 server on Windows 2012 R2, will be able to run Get-Help without error or special connection needs.
(2) Special Exchange 2016 PowerShell shortcut in BIN directory
** THIS IS UNSUPPORTED **
The shortcut for this particular version is unsupported and in fact not an option I recommend. However, if you need to just use it for Get-Help, this option will work for this need. The one reason I would not use this method for anything other than Get-Help is that is bypasses RBAC. This means that you are bypassing Microsoft’s security in PowerShell.
This brings up a PowerShell shell that look like a cross between the Windows PowerShell shell and Exchange’s shell:
(3) Use a remote PowerShell connection
Now, not any remote PowerShell connection will do, we need to set a parameter in the connection called ‘SerializationLevel’. We need to set this to None in order for this connection to do what we need. What commands are needed to make this connection? If you’ve connected to an Exchange Online PowerShell session, then these cmdlets will be more familiar. To those who have not, then the gist of the cmdlets is that we need to create a new PowerShell session with ‘NewPsSession’ cmdlet. The cmdlet needs to have a ConnectionURI specified and in our case, we need to FQDN of the server name as well as the Powershell vDir specified, remember that this is a web link (HTTPS). Here is a typical connection URI for an Exchange server:
https://mail.domain.com/PowerShell
Building upon that, we need a set of credentials. This can be gathers a couple of ways. We can ask for it in the New-PsSession cmdlet, or store it in a variable for later use. Here are both methods:
$Credentials = Get-Credential
OR
-Credential (Get-Credential)
We need to give the connection a name and typically something like this is normally configured:
-ConfigurationName Microsoft.Exchange
Lastly, we need an authentication method, for a local Exchange server connecting with Domain credentials we will choose ‘Kerberos’ as our method of authentication. Putting all of this together, we get this:
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://mail.domain.com/PowerShell -Credential (Get-Credential) -Authentication Kerberos
The problem is that when we connect with the ‘Invoke-Command’ cmdlet, we’ll still experience the errors noted above. To make this work without errors, we need to configure the Serialization Level. We can do so like this:
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://mail.domain.com/PowerShell/?SerializationLevel=None -Credential (Get-Credential) -Authentication Kerberos
Once connected, we can now get help on any Exchange Powershell cmdlet. Below are some examples of this:
Invoke-Command –Session $Session –ScriptBlock {Get-Help Get-Mailbox}
Invoke-Command –Session $Session –ScriptBlock {Get-Help Set-TransportService -Full}
Invoke-Command –Session $Session –ScriptBlock {Get-Help Set-Mailbox -Full}
Conclusion
As you can see, even though Get-Help is broken, we can still get what we need from alternate connection methods with PowerShell. If you find this to be an issue and something that the Exchange Team should work to resolve, then I would have you leave feedback on their blog articles for each CU to see if they will fix the issue:
Cumulative Update 7 (CU7)
Cumulative Update 6 (CU6)
your command does not work.
it throws an error
New-PSSession : A positional parameter cannot be found that accepts argument ‘/?SerializationLevel=None’.
At line:1 char:12
+ $Session = New-PSSession -ConfigurationName Microsoft.Exchange -Conne …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [New-PSSession], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.NewPSSessionCommand
This is way better to get to help if you only need to use Get-Help
Load a regular powershell (as admin) and run the Add-PSSnapin command
Add-PSSnapin -Name Microsoft.Exchange.Management.PowerShell.SnapIn
thanks
sorry forgot to ask what is this new Get-DatabaseAvailabilityGroupConfiguration command??? Can;t get any info on it
thanks
Not a lot to this cmdlet. The Get-Help is not detailed at all. Will do some digging later today.
Looks like there is a space in the code. Just fixed it. As for the ‘Add-PSSnapin’ that is not supported by Microsoft and I would not do that.
thanks for the quick reply. how about the other question i had regarding dag command?
Rob, Looks like this cmdlets reveals a particular configuration put in place for a DAG in Exchange. The cmdlets exists in Exchange 2013 as well. By default, there is no special configuration. In order for this cmdlets to reveal anything, you need to run New-DatabaseAvailabilityGroupConfiguration to create the actual configuration referenced by the Get-DatabaseAvailabilityGroupConfiguration cmdlets. I don’t have any other information on it at the moment. Going to fire up one of my Exchange 2016 labs to see what I can find on it.
thanks for the info
on another note, do you know why the -verbose switch no longer works in Exchange 2013/2016? as long as you use windows 2008R2 the switch works, as soon as you use Exchange with Windows 2012 or higher that is no longer the case. i;ve asked around for last 2 years and MS just keeps ignoring me. At least i would like to know if this is an OS issues or Exchange issue.
thanks