One of the first cmdlets people learn when starting out in PowerCLI is Connect-VIServer, this as you probably know allows you to connect to a vCenter server or a ESX/ESXi Host directly, this creates a session on the vCenter server until it has been disconnected using the Disconnect-VIServer cmdlet.

But who uses the Disconnect-VIServer cmdlet ? Come on truthfully, do you use it at the end of each script or PowerCLI session you use ?

This is obviously best practice but in my travels and from the code examples I have seen on the internet people seam to miss this out, on the face of it this is not an issue, it has “no impact” that you can see, but wait……

If you are in vCenter and go to the Sessions screen you will see that our sessions which were opened are now in an idle state:


So why do we care ?

Did you know there is actually a limit on the amount of sessions which can connect to vCenter, this is set at 100 concurrent session, both Idle and active sessions count.

You would be surprised how quickly this can fill up in a corporate environment, especially if you have multiple scripts which run as scheduled tasks and do not disconnect correctly.

This was the case at a recent customer site, they needed a quick way out of this situation to enable them the time to go back and adjust the multiple scripts they had connecting and not disconnecting and the multiple staff they had who would RDP to a server and leave the vCenter client running and connected.

The following two PowerShell Advanced Functions were written to help with this situation:

List all sessions with PowerCLI

Function Get-ViSession {
Lists vCenter Sessions.

Lists all connected vCenter Sessions.

PS C:\> Get-VISession

PS C:\> Get-VISession | Where { $_.IdleMinutes -gt 5 }
$SessionMgr = Get-View $DefaultViserver.ExtensionData.Client.ServiceContent.SessionManager
$AllSessions = @()
$SessionMgr.SessionList | Foreach {
$Session = New-Object -TypeName PSObject -Property @{
Key = $_.Key
UserName = $_.UserName
FullName = $_.FullName
LoginTime = ($_.LoginTime).ToLocalTime()
LastActiveTime = ($_.LastActiveTime).ToLocalTime()

If ($_.Key -eq $SessionMgr.CurrentSession.Key) {
$Session | Add-Member -MemberType NoteProperty -Name Status -Value “Current Session”
} Else {
$Session | Add-Member -MemberType NoteProperty -Name Status -Value “Idle”
$Session | Add-Member -MemberType NoteProperty -Name IdleMinutes -Value ([Math]::Round(((Get-Date) – ($_.LastActiveTime).ToLocalTime()).TotalMinutes))
$AllSessions += $Session


When this function is run it will give you a list of the connected sessions and various useful properties:


This can obviously be filtered using the standard PowerShell cmdlets to list any sessions which have been idle for over 30 minutes:


A further function can be used to take the input from Get-VISession and disconnect these sessions where needed:

Disconnect sessions with PowerCLI

Function Disconnect-ViSession {
Disconnects a connected vCenter Session.

Disconnects a open connected vCenter Session.

.PARAMETER  SessionList
A session or a list of sessions to disconnect.

PS C:\> Get-VISession | Where { $_.IdleMinutes -gt 5 } | Disconnect-ViSession

PS C:\> Get-VISession | Where { $_.Username -eq “User19” } | Disconnect-ViSession
Param (
Process {
$SessionMgr = Get-View $DefaultViserver.ExtensionData.Client.ServiceContent.SessionManager
$SessionList | Foreach {
Write “Disconnecting Session for $($_.Username) which has been active since $($_.LoginTime)”

The following example shows how to use these functions to disconnect any sessions with over 30 minutes of idle time:


Both of these functions show that even if there is not a built in cmdlet for a certain feature in PowerCLI there is always an easy way to create your own cmdlet like functions to work the way you need them.

Alan Renouf

Technical Marketing

Post updated: 3/6/2015 to correct number of supported sessions to 100.