VMware Cloud Community
Brcko_94
Contributor
Contributor
Jump to solution

Terminate Idle VI Client Sessions with PowerCLI Script

Hello PowerCLI gurus

I've been looking on the net for a PowerCLI script that would terminate all VI client sessions that have been idle for x period of time.  I've found a post on VMware forums (http://communities.vmware.com/message/914858?z=zI0r8n) but had no luck with it.  I've also found a script created by A.Mikkelsen at http://www.amikkelsen.com/?p=384 but that one is not working either.

Following is the actual script by A.Mikkelsen that is based on the code by LucD in the previously mentioned forum.

START

##################################################################################
# The script terminates all idle user sessions if idle for longer that xx   #
#                             #
# Created by: Anders Mikkelsen, 2010                                #
##################################################################################
clear
# Add-PSSnapin VMware.VimAutomation.Core

# $server = "vcenter server"
# $user   = "vcenter username"
# $pwd    = "vcenter password"

# Add 1 hour extra the the time, due to timestamp difference between MSSQL and Windows time.
#  5 hours idle time = 360
# 10 hours idle time = 660
$intOlderThan = 60

# Connect-VIServer $server -User $user -Password $pwd
# Connect-VIServer $server

$svcRef = new-object VMware.Vim.ManagedObjectReference
$svcRef.Type = "ServiceInstance"
$svcRef.Value = "ServiceInstance"
$serviceInstance = get-view $svcRef

$sessMgr = get-view $serviceInstance.Content.sessionManager
$oldSessions = @()
foreach ($sess in $sessMgr.SessionList){
if (($sess.LastActiveTime).addminutes($intOlderThan) -lt (Get-Date)){
  $oldSessions += $sess.Key
  #write "$($sess.UserName)"
   }
}

# Terminale session than are idle for longer than approved ($intOlderThan)
$sessMgr.TerminateSession($oldSessions)

Disconnect-VIServer * -Confirm:$false

END

The error message I receive is:

START

Exception calling "TerminateSession" with "1" argument(s): "A specified parameter was not correct.

"

At D:\Scripts\vc_terminate_idle_sessions.ps1:36 char:26

+ $sessMgr.TerminateSession <<<< ($oldSessions)

    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException

    + FullyQualifiedErrorId : DotNetMethodException

END

I should mention that my knowledge of PowerCLI is next to nothing so any help in tweaking this script to get it working with PowerCLI 5.1 Release 2 and VC 5 U2 would be much appreciated.

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

The error is caused by the fact that you are trying to kill your own session (if it was started longer than the time interval ago).

Apparently in vSphere 5.* they included a fail-safe mechanism to avoid that.

You can catch this by adding a simple test.

## max number of idle minutes for sessions to keep
$intOlderThan = 60
$serviceInstance = Get-View 'ServiceInstance'
## get the session manager object
$sessMgr = Get-View $serviceInstance.Content.sessionManager
## array to hold info about stale sessions
$oldSessions = @()
foreach ($sess in $sessMgr.SessionList){
   
if (($sess.LastActiveTime).addminutes($intOlderThan) -lt (Get-Date) -and
         
$sess.Key -ne $sessMgr.CurrentSession.Key){
       
$oldSessions += $sess.Key
    }
## end if
} ## end foreach

## if there are any old sessions, terminate them; else, just write message to the Warning stream
if (($oldSessions | Measure-Object).Count -gt 0) {
   
## Terminate sessions than are idle for longer than approved ($intOlderThan)
    $sessMgr.TerminateSession($oldSessions)
}
## end if
else {Write-Warning "No sessions that have been idle for more than '$intOlderThan' minutes; no action taken"}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

0 Kudos
17 Replies
mattboren
Expert
Expert
Jump to solution

Hello,

I suspect that you might be running into a situation where you have no sessions that have been inactive for longer than the configured time.  To help rule that in/out, you could add a check for the number of sessions held in the $oldSessions array -- if greater than 0, then try to terminate them, else, write to the Warning stream that there are no such sessions to terminate.  Updated/consolidated a bit:

## max number of idle minutes for sessions to keep
$intOlderThan = 60
$serviceInstance = Get-View 'ServiceInstance'
## get the session manager object
$sessMgr = Get-View $serviceInstance.Content.sessionManager
## array to hold info about stale sessions
$oldSessions = @()
foreach ($sess in $sessMgr.SessionList){
   
if (($sess.LastActiveTime).addminutes($intOlderThan) -lt (Get-Date)){
       
$oldSessions += $sess.Key
    }
## end if
} ## end foreach

## if there are any old sessions, terminate them; else, just write message to the Warning stream
if (($oldSessions | Measure-Object).Count -gt 0) {
   
## Terminate sessions than are idle for longer than approved ($intOlderThan)
    $sessMgr.TerminateSession($oldSessions)
}
## end if
else {Write-Warning "No sessions that have been idle for more than '$intOlderThan' minutes; no action taken"}

How does that do for you?

lakey81
Enthusiast
Enthusiast
Jump to solution

Check out this blog about listing and disconnecting sessions.   There are cmdlets available to download and I've been using them successfully to disconnect idle sessions.

http://blogs.vmware.com/vipowershell/2011/09/list-and-disconnect-vcenter-sessions.html

0 Kudos
Brcko_94
Contributor
Contributor
Jump to solution

Thank you Matt

Unfortunately that's not the case, I've checked the VI client sessions and there were plenty of sessions that were idle for longer period of time than specified in the script.  In any case I've used your script too but to no avail.  Smiley Sad  I get pretty much identical error message:

START ERROR

Exception calling "TerminateSession" with "1" argument(s): "A specified parameter was not correct.

"

At D:\Scripts\vc_terminate_idle_sessions.ps1:17 char:30

+     $sessMgr.TerminateSession <<<< ($oldSessions)

    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException

    + FullyQualifiedErrorId : DotNetMethodException

END ERROR

Cheers

0 Kudos
LucD
Leadership
Leadership
Jump to solution

The error is caused by the fact that you are trying to kill your own session (if it was started longer than the time interval ago).

Apparently in vSphere 5.* they included a fail-safe mechanism to avoid that.

You can catch this by adding a simple test.

## max number of idle minutes for sessions to keep
$intOlderThan = 60
$serviceInstance = Get-View 'ServiceInstance'
## get the session manager object
$sessMgr = Get-View $serviceInstance.Content.sessionManager
## array to hold info about stale sessions
$oldSessions = @()
foreach ($sess in $sessMgr.SessionList){
   
if (($sess.LastActiveTime).addminutes($intOlderThan) -lt (Get-Date) -and
         
$sess.Key -ne $sessMgr.CurrentSession.Key){
       
$oldSessions += $sess.Key
    }
## end if
} ## end foreach

## if there are any old sessions, terminate them; else, just write message to the Warning stream
if (($oldSessions | Measure-Object).Count -gt 0) {
   
## Terminate sessions than are idle for longer than approved ($intOlderThan)
    $sessMgr.TerminateSession($oldSessions)
}
## end if
else {Write-Warning "No sessions that have been idle for more than '$intOlderThan' minutes; no action taken"}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Brcko_94
Contributor
Contributor
Jump to solution

Hi LucD

Much appreciate your assistance.

Prior to posting my last post I did make sure that my session was not idle, and it never was showing as idle.  Well not in VI client anyway.  However, I've tested your script and it works, kind of.  Well it actually does terminate all sessions that have been idle for specified or greater period of time but it also terminates my active session.

Not much of a biggie as I'm intending to run the script with a service account which than should get around the issue.

Cheers

0 Kudos
mattboren
Expert
Expert
Jump to solution

Thanks for the catch, Luc.

0 Kudos
nimos001
Enthusiast
Enthusiast
Jump to solution

When I run this script I get a message that no sessions have been idle for over 60 minutes. I actually have many that are well over this time. I am running this against 5.5U3 without luck. If I modify the script for something less than 60 minutes it works for those idle sessions, but once it's over the 60 minutes mark it doesn't seem to see it. Very strange...

EDIT: I was pretty sure it had worked earlier but it looks like its not working regardless of what I set the minute mark at. I always get the message of no sessions being idle for that period of time.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

It would be interesting to see the output of the following.

Get-Date

$serviceInstance = Get-View 'ServiceInstance'

$sessMgr = Get-View $serviceInstance.Content.sessionManager

$sessMgr.SessionList | Select UserName,LoginTime,LastActiveTime


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
nimos001
Enthusiast
Enthusiast
Jump to solution

Here is a sampling of the output. I currently have sessions idle for as long as 12 hours...

sessions.jpg

0 Kudos
LucD
Leadership
Leadership
Jump to solution

That long session, could that be your PowerCLI session ?

The script doesn't kill that session.

On the others, when exactly did you run the script ?

That's why I put the Get-Date at the top.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
nimos001
Enthusiast
Enthusiast
Jump to solution

No, it's not my current session. Having trouble seeing all of the output since it scrolls down and I can't go back up to view or copy.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Try adding a First parameter

$sessMgr.SessionList | Select -First 10 -Property  UserName,LoginTime,LastActiveTime


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
nimos001
Enthusiast
Enthusiast
Jump to solution

Thursday, February 4, 2016 7:45:23 AM

UserName       :

LoginTime      : 2/3/2016 11:34:29 PM

LastActiveTime : 2/4/2016 1:44:43 PM

UserName       :

LoginTime      : 2/3/2016 11:34:59 PM

LastActiveTime : 2/3/2016 11:34:59 PM

UserName       :

LoginTime      : 1/31/2016 1:58:00 AM

LastActiveTime : 2/4/2016 1:43:34 PM

UserName       :

LoginTime      : 1/29/2016 3:01:30 PM

LastActiveTime : 2/4/2016 12:46:43 PM

UserName       :

LoginTime      : 1/29/2016 5:22:02 PM

LastActiveTime : 2/4/2016 1:35:02 PM

UserName       :

LoginTime      : 2/4/2016 9:35:19 AM

LastActiveTime : 2/4/2016 9:35:19 AM

UserName       :

LoginTime      : 2/4/2016 1:39:18 PM

LastActiveTime : 2/4/2016 1:45:18 PM

UserName       :

LoginTime      : 2/3/2016 10:32:49 PM

LastActiveTime : 2/3/2016 10:33:00 PM

UserName       :

LoginTime      : 2/4/2016 1:43:03 PM

LastActiveTime : 2/4/2016 1:45:03 PM

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Could it be that you have sessions from different timezones ?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
nimos001
Enthusiast
Enthusiast
Jump to solution

I don't believe that is the issue. I will keep digging around and try to figure it out. Here are a couple more views for what it's worth. Thanks for trying to help out.

session_2.jpg

sessions_3.jpg

Apparently I am not running all of the code? I pulled the below thinking this is all I needed?

## max number of idle minutes for sessions to keep
$intOlderThan = 60
$serviceInstance = Get-View 'ServiceInstance'
## get the session manager object
$sessMgr = Get-View $serviceInstance.Content.sessionManager
## array to hold info about stale sessions
$oldSessions = @()
foreach ($sess in $sessMgr.SessionList){
   
if (($sess.LastActiveTime).addminutes($intOlderThan) -lt (Get-Date) -and
         
$sess.Key -ne $sessMgr.CurrentSession.Key){
       
$oldSessions += $sess.Key
    }
## end if
} ## end foreach

## if there are any old sessions, terminate them; else, just write message to the Warning stream
if (($oldSessions | Measure-Object).Count -gt 0) {
   
## Terminate sessions than are idle for longer than approved ($intOlderThan)
    $sessMgr.TerminateSession($oldSessions)
}
## end if
else {Write-Warning "No sessions that have been idle for more than '$intOlderThan' minutes; no action taken"}

0 Kudos
LucD
Leadership
Leadership
Jump to solution

That looks complete.

That code, kills sessions that haven't been active for a specific amount of time.

To get a complete view you might want to run the code in my Get complete vCenter session info post.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
nimos001
Enthusiast
Enthusiast
Jump to solution

The script in the link does work for me and I am able to pull the information on the sessions and source correctly. That being said when I run the script in this thread it does appear to terminate 'some' connections but not all. If I wait several hours between attempting to run the script it does remove some connections, but after that it always says there are none to remove. Even if I keep dropping the session time in the script. I still have tons of connections that are days old and are not removed unless manually done. Still scratching my head on why it's not working as expected for me here. The reason I am even looking into this script is to mask an issue we seem to be having with lots of idles sessions not closing out. It's not uncommon for us to see over 100 connections (active/idle). We are working to try and resolve this but was hoping to put the script in place to help out.

0 Kudos