SiW – Robust Sessions and PowerCLI

One of the new features that came with PowerShell v3 was the introduction of “robust” or “persistent” sessions. This is, imho, a huge improvement on the concept of remote sessions who were introduced in PowerShell v2.
In short, before robust sessions, you had to keep the the client, that created the session, open to keep the remote session alive. With robust sessions, the client side can be closed, and you can reconnect to the robust session, even from another client.
This new remote session concept is something that can be used to solve a number of known PowerCLI “issues”.

                        siw-icon

Siw stands for Server in Waiting. We selected that term since we liked the sound of it, no double entendre should be suspected :-)

Some of these issues, that most of you probably know:

  • Connect-VIServer can be slow
  • The 1st cmdlet in a session is slow
  • Keep the PowerCLI version aligned on all the stations were it is used
  • Have powerfull stations to run scripts against “big” vSphere environments

The idea is that you would have a “workhorse” station, with enough resources to cope with the bigger vSphere environments. On this workhorse station you set up a number of robust sessions, and when you need to run a PowerCLI script on a client, you would connect from the client to such a robust session, and execute your script in that robust session.

         siw-schematic

To make the creation and usage of these robust sessions in combination with PowerCLI easier, I created a number of functions.

The Functions

function New-SiwSession {

<#  
.SYNOPSIS  Creates a number of robust PowerCLI sessions   
.DESCRIPTION The function will create a number of
  robust remote sessions on a specific server. The
  remote sessions will be initialised to run PowerCLI
  scripts
.NOTES  Author:  Luc Dekens  
.PARAMETER ComputerName
  The hostname of the server where the robust PowerCLI
  sessions will be created
.PARAMETER Credential
  A PSCredential object that contains the credentials for
  the robust session.
.PARAMETER SiwType
  The name prefix for the robust PowerCLI sessions
.PARAMETER NumberOfSessions
  The number of robust PowerCLI sessions that shall be
  created. The maximum number is 99.
.PARAMETER vServer
  The name of the vSphere server to which the robust PowerCLI
  session shall connect
 .PARAMETER vCredential
  The PSCredential object that will be used to connect to the
  $vServer server. If $null, the session credentials will be
  used

.EXAMPLE
  PS> New-SiwSession -ComputerName $tgtServer -Credential $cred `
  >> -SiwType "PowerCLI" -NumberOfSessions 3 -vServer "vCenter"
#>

  param(
    [String]$ComputerName,
    [System.Management.Automation.PSCredential]$Credential,
    [String]$SiwType,
    [ValidateRange(1,99)] 
    [Int]$NumberOfSessions,
	[String]$vServer,
    [System.Management.Automation.PSCredential]$vCredential
  )

  if(!$vCredential){$vCredential = $Credential}
  $pclStartUp = {
    param($vServer,$Credential)

    Add-PSSnapin VMware.VimAutomation.Core
    Set-PowerCLIConfiguration -DisplayDeprecationWarnings $false -Confirm:$false | Out-Null
    Connect-VIServer -Server $vServer -Credential $Credential | Out-Null
    Get-Datacenter | Out-Null
  }

  $newSiwOption = @{
    IdleTimeout = -1
    NoMachineProfile = $true
    SkipCACheck = $true
    SkipCNCheck = $true
    SkipRevocationCheck = $true
  }
  $SiwOptions = New-PSSessionOption @newSiwOption 

  $newSiwSession = @{
    ComputerName = $ComputerName
    Credential = $Credential
    EnableNetworkAccess = $true
    Name = $null
    SessionOption = $SiwOptions
  }

  1..$NumberOfSessions | %{
    $newSiwSession.Name = $SiwType + ("-{0:d2}" -f $_)
    $SiwSession = New-PSSession @newSiwSession
    $pclInit = @{
      Session = $SiwSession
      ScriptBlock = $pclStartUp
      ArgumentList = $vServer,$Credential
    }
    Invoke-Command @pclInit
    Disconnect-PSSession -Session $SiwSession -Confirm:$false | Out-Null
  }
}

function Get-SiwSession {

<#  
.SYNOPSIS  Returns a robust PowerCLI session
.DESCRIPTION The function will return an available robust
  PowerCLI session. If no robust sessions are available,
  function  will return $null
.NOTES  Author:  Luc Dekens  
.PARAMETER ComputerName
  The hostname of the server where the robust PowerCLI
  sessions will be created
.PARAMETER Credential
  A PSCredential object that contains the credentials for
  the robust session.
.PARAMETER SiwType
  The name prefix for the robust PowerCLI sessions
.EXAMPLE
  PS> Get-SiwSession -ComputerName $tgtServer -Credential $cred `
  >> -SiwType "PowerCLI"
#>

  param(
    [String]$ComputerName,
    [System.Management.Automation.PSCredential]$Credential,
    [String]$SiwType 
  )

  $getSiwSession = @{
    ComputerName = $ComputerName
    Credential = $Credential
  }

  Get-PSSession @getSiwSession |
  Where {$_.Name -match "^$($SiwType)" -and $_.Availability -eq "None"} |
  Get-Random
}

function Abort-SiwSession {

<#  
.SYNOPSIS  Aborts robust PowerCLI sessions   
.DESCRIPTION The function abort all robust PowerCLI
  sessions on a server.
.NOTES  Author:  Luc Dekens  
.PARAMETER Session
  The handle of the session that needs to be aborted.
.EXAMPLE
  PS> Abort-SiwSession -Session $pcliSession
#>

  param( 
    [CmdletBinding()]
    [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
    [System.Management.Automation.Runspaces.PSSession]$Session
  )

  $session | %{
    $cimInstance = @{
      ComputerName = $_.ComputerName
            ClassName = "Win32_Process"
      Filter = "Name Like 'wsmprovhost.exe'"
    }
    Get-CimInstance @cimInstance |
    Invoke-CimMethod -MethodName Terminate -Confirm:$false
  }
}

Annotations

Line 38: The function allows a request to create up to99 robust PowerCLI sessions. But keep in mind that PowerShell itself has a throttle limit of 32 sessions. In other words PowerShell handle the instructions in the first 32 sessions and place the other remote sessions in wait.

Line 45-52: These are the lines that set up the robust session as a PowerCLI session.Line 49: The robust session can’t handle PowerCLI warning messages correctly, so we suppress those.

Line 51: This random PowerCLI cmdlet avoids the delay you normally see on the 1st PowerCLI cmdlet that is executed in a new session.

Line 54-60: The session options.

Line 63-69: The parameters used to create the remote session.

Line 71-81: The loop and code block that create the requested number of robust PowerCLI sessions

Line 46,77,79: Notice how the values for the PowerCLI code block are passed to the remote session.

Line 80: The remote session is immediately disconnected.

Line 107: Since you can only connect to a robust session with the same credentials as the ones which created the session, the function requires these as a parameter as well.

Line 118: To avoid over-using the 1st robust session that is returned, the function will return a “random” available session.

Line 146: Since this function is/was primarily used to “kill” unresponsive functions, it uses the Win32_Process instance that corresponds with a robust session on that target remote server.

Sample Usage

Since the hard work for setting up and using robust PowerCLI sessions is done in the functions, the use of these robust PowerCLI sessions is quite simple.

First you create a number of sessions.

$tgtServer = "SRV1"
$vCenter = "VCENTER"

$pswdSecure = ConvertTo-SecureString -String $pswd -AsPlainText -Force
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username,$pswdSecure

# Create 3 Siw sessions
New-SiwSession -ComputerName $tgtServer -Credential $cred -SiwType "PowerCLI" -NumberOfSessions 3 -vServer $vCenter

Once the sessions are created, you connect to one of the available ones to run your PowerCLI code.

# Use one of the sessions to run PowerCLI code on SRV1
$session = Get-SiwSession -ComputerName $tgtServer -Credential $cred -SiwType "PowerCLI"

Connect-PSSession -Session $session | Out-Null
Invoke-Command -Session $session -ScriptBlock {Get-VMHost}
Disconnect-PSSession -Session $session | Out-Null

# Drop the sessions
Get-PSSession -ComputerName $tgtServer -Credential $cred | Remove-PSSession

Should something go wrong and the robust PowerCLI session is stuck, you can try the abort function to kill the session.

# Abort the sessions
Get-PSSession -ComputerName SRV1 -Credential $cred | Abort-SiwSession

Enjoy!

11 thoughts on “SiW – Robust Sessions and PowerCLI

  1. Pingback: VMworld 2013 | vmdude

  2. Pingback: VMworld 2013 | vmdude

  3. Impressed by the readability of your code and the completeness of yuor functions. Great handling of credentials.
    Just a dumb question, what does SiW means? And why not to limits the number of sessions to 32 out-of-the-box?

    • Thanks Carlo.

      SiW was kind of a joke, it stands for “Server in Waiting”, derived from “Lady in Waiting” :-)
      There should be an explanatory text for the acronym under the first image.

      Yes, I could limit the maximum number of sessions to 32, but than again I can imagine a server that is used for multiple types of work (PowerCLI, PowerCLI View, SharePoint…). We have in fact set up a kind of Team script server where all the team members can execute their scripts.
      As I explained in the post, the 32-session limit is just a throttle limit. If you create more than 32 sessions, the ones after the first 32 will have to wait.
      In practice we rarely see more than 32 active sessions.

  4. Luc, I was in the PowerCLI deep dive sessions. Great session!
    you have talked abou Event-O-Matic. Where can i find this utility?
    Best regards
    Robert

  5. Luc, I was in the PowerCLI deep dive yesterday when you were discussing robust sessions. Great session!

    Am I correct in assuming any variables or custom objects created in the session remain intact as long as the session is active, regardless what you do on the client side?

    • Hi Robbie, thanks for attending the session.

      Yes, you are correct, the variables will remain in the session, unless you explicitely remove them.
      I intend to do a follow-up with some more practical examples on hoe the SiW can be used. There are a couple of other best practices one should be aware of.

      • hi Luc
        i would love to know these best practices; i have experienced this issue many times when value in variables remain in the session gives incorrect output.

        Thanks for Event-O-Matic, it is awesome and its so useful.
        just a request.
        i couldn’t find much about “StorageResourceManager” if you write a post on this, will be grateful. I was trying to use “ApplyStorageDrsRecommendation_Task” for ‘clonevm_task’, but my concern was how i will aline “RecommendDatastores” for that.

        • Thanks.
          During VMworld EMEA I will present a follow up session on the use of the SiW concept. That session will be posted after the Barcelona presentation.

          I’ll see what I can come up with for using the RecommendDatastores method in combination with the CloneVM_Task method.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>