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 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.
To make the creation and usage of these robust sessions in combination with PowerCLI easier, I created a number of functions.
The Functions
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
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.
1 2 3 4 5 6 7 8 |
$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.
1 2 3 4 5 6 7 8 9 |
# 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.
1 2 |
# Abort the sessions Get-PSSession -ComputerName SRV1 -Credential $cred | Abort-SiwSession |
Enjoy!
Carlo
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?
admin
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.
Robert
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
LucD
Hi Robert, thanks for attending the session.
The Event-O-Matic post should go up this weekend.
LucD
@Robert, the Event-O-Matic post is up.
Robbie Holloman
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?
admin
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.
Sanshis
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.
admin
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.