Office Communications Server's Access Edge Servers and MediaRelay roles have a list of hosts they allow to connect on the internal interface.  This is managed by the an administrative GUI accessed under ComputerManagement.   GUIs are great for discoverability (if they're well-written, which this one isn't), but horrible for automation.  This a problem when we talk scaling out.  On an AES or MR server, we can dump the list via the following WMI query:

Get-WmiObject -query 'select InternalServer from MSFT_SIPFederationInternalServerData';

This is great, but for some reason -computer remote.host will return an RPC error on the remote host.  PSExec to the rescue, sort of.  PSExec isn't object-oriented, so it won't return that wonderful list of objects we're used to with PowerShell.  Given that we need only one chunk of data, we can cudgel it out of the query with a combination of Select-String and -replace (with the magic of regular expressions.)

$internal = (& $psExecPath "\\$computer" cmd.exe "/c echo . | powerShell.exe -noprofile -nologo -command Get-WmiObject -query 'select InternalServer from MSFT_SIPFederationInternalServerData'" | Select-String "InternalServer\s+:") -replace ".*:\s*" | % { $_.ToLower(); }

There are a few hacks in that pipeline.  Let's go through them:

For some reason PSExec PowerShell.exe will hang.  I think it has something to do with the grey magic that PSH plays with filehandles.  In the past, we discussed someone else's discovery that PSExec \\remote.host cmd.exe "/c echo . | powershell.exe -command ..." does the needful, albeing in a messy fashion.

Next, PSExec returns the output of PowerShell.exe -command Get-WmiObject as text, or, more specifically, an array of strings.  The Select-String gets the the data we're seeking.

The -replace operator works on not just a single string, but an array of strings, returning an array of post-replaced strings.  The ".*:\s*" alphabet soup means "everything before the colon, and all whitespace after it."  This returns only the value.

Lastly, because I'm storing this in an array, I'll be using the [Array]::IndexOf() method, which is case-sensitive.  Hostnames are case-insensitive, so my canonicalizing it ToLower() has no effect the data.  I just have to remember to also canonicalize ToLower() the hostnames I am testing are present in the trusted list.

Another way to do this is to stuff it all in [HashTable] object because their keys are case-insensitive.