Technical description of how to connectg to Exchange in order to run Powershell cmdlets

Overview

Connections between Cerebrum and Exchange

We need to execute PowerShell commandlets on a Client Access Server, in order to provision mailboxes, etc. in Exchange.

This can be done by using the winrm-client developed for the new AD-sync, with some extensions. An alternative is to use SSH as a transport from the Cerebrum production environment to the springboard.

The overall flow in the connection looks like this (as of 08.08.2013):

+------------+     +--------------------------+     +-------------------+
| cere-prodX | --> | springboard.exutv.uio.no | --> | mgmt.exutv.uio.no |
+------------+ 1.  +--------------------------+ 2.  +-------------------+
  • Connection 1:

    The connection between the Cerebrum production machine and the springboard used to establish a connection between Cerebrum and Exchange own client, and we connect as a local user.

  • Connection 2:

    The connection between the springboard and the machine used for managing Exchange is created by the New-PSSession commandlet, as a user with Administrative rights in Exchange (i.e. uio\jsama_loc).

    Inside this session, we load Exchange specific commandlets (i.e. New-Mailbox) that we need in order to provision mailboxes and the like. These sessions can and must be reused between calls, since it takes a lot of time to load the Exchange-management environment.

We need to reuse these PSSessions, since it takes a lot of time to set up the Exchange-management environment. A more through description of this is available in Technical reference.

In other words, the machines described above has the following roles:

  • cere-prodX This is the machine where Cerebrum lives. Cerebrums purpose in this case, is to:

    • Provide a management interface to the Postmasters.
    • Provide automatic population of users and groups at regular intervals.
  • springboard.exutv.uio.no This is the machine used for connecting Cerebrum to Exchange.

    • Provide a winrm service that is available over HTTPS for Cerebrum.
    • Provide the opportunity to connect to the Exchange management machine
  • mgmt.exutv.uio.no This is the machine that has Exchange management tools installed.

    • Provide the Exchange-commands used for provisioning users and groups. I.e. New-Mailbox

Workflow of provisioning users in Exchange

When users are to be provisioned in Exchange, Cerebrum starts an export (via job_runner). This export then performs the following steps:

  • Collect all changes in Cerebrum since the last run
  • Resolve the accounts/persons these changes applies to
  • For each of the afflicted persons/accounts
    • Connect to the springboard
    • Connect from the springboard, to the Exchange management server
    • Run the appropriate commands on the management server (i.e. New-Mailbox)

A graphical representation of this is available in the following figure:

Overview of the elements in the workflow

System requirements for the springboard

Since we start a new instance of PowerShell each time we execute a command, the springboard machine used by Cerebrum for interacting with Exchange must have at least:

  • 2x8 2ghz (totalt of 16 cores)
  • 24gb ram (more is preferred)

This will allow us to run 15 simultaneous connections against Exchange, without saturating the CPU. At CPU saturation, we experience a loss of performance.

Technical reference

Detailed description of the communication flow between Cerebrum and Exchange

The following sequence diagram describes the flow in communications between Cerebrum and Exchange on a detailed level:

Sequence diagram, Cerebrum -> Exchange interaction

For each call made, we recieve the output from the Exchange-commands run, and parse it in the WinRM/SSH client used by the sync.

Configuration of Windows

We need to configure Windows to accept connections from the Cerebrum production machines, and to run commands on the management server. The following is a step-by-step list of what needs to be done:

  1. Start lusrmgr, and create a local user. Needs privileges to connect

    via winrm (admin or member of WindowsRemoteWMIUsers__ (or whatever it's called)). #TODO: Find a definite answer.

  2. Define a winrm-listener on the machine we will connect to from the Cerebrum

    production servers: winrm create winrm/config/Listener?Address=*+Transport=HTTPS @{Hostname="HOST";CertificateThumbprint="XXXXXXXXXX"}

  3. Set-Item wsman:\localhost\client\trustedhosts casXX.exutv.uio.no -Force

    should be run on the machine we use as a "springboard" # TODO: No need for this? Check it out.

  4. Enable Basic-auth for winrm. This must probably be done through the GPO.

  5. If you plan on using many simoultanious sessions, do something like this on the management machine:

    New-ThrottlingPolicy -Name cereync_concurrency_limit -PowershellMaxConcurrency Unlimited -PswsMaxConcurrency Unlimited -ThrottlingPolicyScope Regular
    Set-ThrottlingPolicyAssociation -Identity exadm_js -ThrottlingPolicy cerecyn_concurrency_limit
    

Loading Exchange-specific stuff in Powershell

After we connect to the "springboard" as a local user, we need to create a new PSSession as a user that has access to Exchange. This can be done like this:

# Create credentials for the new-PSSession
$pass = ConvertTo-SecureString -Force -AsPlainText %(ad_pasw)s
$cred = New-Object System.Management.Automation.PSCredential(%(ad_domain_user)s, $pass)

# We collect any existing sessions, and connect to the first one.
# TODO: Filter them based on availability and state
$sessions = Get-PSSession -ComputerName %(management_server)s -Credential $cred -Name cerechange
if ( $sessions ) {
    $ses = $sessions[0]
    Connect-PSSession -Session $ses 2> $null > $null
}

# If Get-PSSession or Connect-PSSession fails, make a new one!
if (($? -and ! $ses) -or ! $?) {
    $ses = New-PSSession -ComputerName %(management_server)s -Credential $cred -Name cerechange

    # We need to access Active-directory in order to find out if a
    # user is in AD:
    Import-Module ActiveDirectory 2> $null > $null

    # Import Exchange stuff or everything else:
    Invoke-Command { . RemoteExchange.ps1 } -Session $ses

    Invoke-Command { $pass = ConvertTo-SecureString -Force -AsPlainText %(ad_pasw)s } -Session $ses
    Invoke-Command { $cred = New-Object System.Management.Automation.PSCredential(%(ad_user)s, $pass) } -Session $ses

    Invoke-Command { Connect-ExchangeServer -ServerFqdn %(management_server)s -UserName %(ad_user)s } -Session $ses
}
# We want to have something to search for when removing all the crap
# we can't redirect.
write-output EOB"""

The above code will create a new, or resume an existing PSSession against the management-server as a privileged user, and connect to Exchange.

Connect-ExchangeServer needs to be maintained, although it is a commandlet supplied by Microsoft. The reason behind this, is that it does not accept a credential-parameter out of the box. Via a small hack, this script will accept the credentials supplied by the session, instead of credentials acquired via Black Magic in Windows, or the Get-Credentials dialog.

When a command has been run and the client disconnects, Disconnect-PSSession -Session $ses should be run in order to allow reconnection to the session.

After the sync. is done, Remove-PSSession should be called, in order to remove the PSSession (cleanup).

Publisert 25. okt. 2013 11:38 - Sist endret 10. mai 2019 15:59