11 Replies Latest reply on Jun 19, 2011 8:47 PM by bradley4681

    Disconnect vi client as specified intervals

    techie11 Novice

      Is there a way to disconnect a user from the viconsole, or disconnect all idle users after x hours with powershell.

        • 1. Re: Disconnect vi client as specified intervals
          LucD Guru
          vExpertUser ModeratorsCommunity Warriors

          Unfortunately you can't manage client sessions with cmdlets (afaik).

           

          The SDK contains a method called TerminateSession that does what you want.

          You provide to this method an array of Session IDs and the method will terminate each of these session.

           

          In the sample script I test if there has been no activity for 60 minutes for each session.

           

          # Force load
          [http://Reflection.Assembly|http://Reflection.Assembly]::LoadWithPartialName("vmware.vim")
          
          $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(60)) -lt (Get-Date)){
              $oldSessions += $sess.Key
            }
          }
          $sessMgr.TerminateSession($oldSessions)

           

          Since the forum SW seems to change some code I have included the same script as a PS1 file

          • 2. Re: Disconnect vi client as specified intervals
            bradley4681 Expert

            so building on that script is there a way to disconnect all sessions idle for more then 4hrs and exclude a list of users, say service accounts listed in a file?

            • 3. Re: Disconnect vi client as specified intervals
              LucD Guru
              vExpertCommunity WarriorsUser Moderators

              Yes, that is possible.

              Note that the previous script was written for an older version of PowerCLI (VI Toolkit) and that a lot can be done much simpler.

               

              $excluded = "domain\user1","domain\user2" 
              $sessMgr
              = Get-View SessionManager
              $oldSessions = @()
              foreach ($sess in $sessMgr.SessionList){   if ((($sess.LastActiveTime).AddHours(4)) -lt (Get-Date) -and $excluded -notcontains $sess.UserName){     $oldSessions += $sess.Key   } } $sessMgr.TerminateSession($oldSessions)
              • 4. Re: Disconnect vi client as specified intervals
                bradley4681 Expert

                so could i do this to read from a file, easier to list the users and add or remove this way..

                 

                 

                 

                $excluded = Get-Content "./exclude-users.txt"
                $sessMgr = Get-View SessionManager
                $oldSessions = @()
                foreach ($sess in $sessMgr.SessionList){
                  if ((($sess.LastActiveTime).AddHours(4)) -lt (Get-Date) -and $excluded -notcontains $sess.UserName){
                    $oldSessions += $sess.Key
                  }
                }
                $sessMgr.TerminateSession($oldSessions)

                 

                 

                and then in the text file

                 

                "domain\user1"
                 "domain\user2"
                "helpdesk"
                "someguy"
                "domain\anotherguy"

                • 5. Re: Disconnect vi client as specified intervals
                  LucD Guru
                  User ModeratorsvExpertCommunity Warriors

                  Sure, the Get-Content cmdlet will create an array, just like it was with my inline version.

                  • 6. Re: Disconnect vi client as specified intervals
                    bradley4681 Expert

                    so i ran the script aginst one of my VCs and it seemed to work fine against most idle users that had been connected for more then 8hrs but one user had been idled for 6hrs and it did not disconnect them.

                     

                     

                     

                    $viservers = "VCserver1" $excluded = Get-Content "./exclude-users.txt" foreach ($singleViserver in $viservers){
                    
                        Connect-VIServer $singleViserver -user USERNAME -password 'PASSWORD' $sessMgr = Get-View SessionManager
                    $oldSessions = @()
                    foreach ($sess in $sessMgr.SessionList){
                      if ((($sess.LastActiveTime).AddHours(4)) -lt (Get-Date) -and $excluded -notcontains $sess.UserName){
                        $oldSessions += $sess.Key
                      }
                    }
                    $sessMgr.TerminateSession($oldSessions)
                    }


                    So i ran the script one more time and got the following error message:


                    Exception calling "TerminateSession" with "1" argument(s): "sessionId"At C:\Scripts\DisconSessions\DisconSessions.ps1:19 char:26 + $sessMgr.TerminateSession <<<< ($oldSessions)
                        + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
                        + FullyQualifiedErrorId : DotNetMethodException
                    



                     

                    The user that was idle for 6hrs was stil connected, i'm one hour ahead of the VCs location but i don't think that matters.
                    • 7. Re: Disconnect vi client as specified intervals
                      LucD Guru
                      User ModeratorsCommunity WarriorsvExpert

                      I don't know why that user's session that was idle for 6 hours wasn't terminated.

                      I would have to look at the content of the $sess varaible for that specific user.

                       

                      The error you got on the 2nd run is most probably because the $oldSessions array was empty.

                      The following version tests for that

                       

                      $viservers = "VCserver1" 
                      $excluded = Get-Content "./exclude-users.txt" 
                      foreach ($singleViserver in $viservers){
                          Connect-VIServer $singleViserver -user USERNAME -password 'PASSWORD' 
                              $sessMgr = Get-View SessionManager
                              $oldSessions = @()
                              foreach ($sess in $sessMgr.SessionList){
                                if ((($sess.LastActiveTime).AddHours(4)) -lt (Get-Date) -and $excluded -notcontains $sess.UserName){
                                  $oldSessions += $sess.Key
                                }
                              }
                              if($oldSessions.Count -gt 0){
                                  $sessMgr.TerminateSession($oldSessions)
                              }
                      }
                      
                      • 8. Re: Disconnect vi client as specified intervals
                        bradley4681 Expert

                        anyway to keep a running log of who get's disconnected and when?

                        • 9. Re: Disconnect vi client as specified intervals
                          LucD Guru
                          User ModeratorsCommunity WarriorsvExpert

                          Sure, you can do something like this

                           

                          $report = @()
                          $viservers = "VCserver1" 
                          $excluded = Get-Content "./exclude-users.txt" 
                          foreach ($singleViserver in $viservers){
                              Connect-VIServer $singleViserver -user USERNAME -password 'PASSWORD' 
                                  $sessMgr = Get-View SessionManager
                                  $oldSessions = @()
                                  foreach ($sess in $sessMgr.SessionList){
                                    if ((($sess.LastActiveTime).AddHours(4)) -lt (Get-Date) -and $excluded -notcontains $sess.UserName){
                                      $oldSessions += $sess.Key
                                      $row = "" | Select UserName,FullName,Timestamp,Server,LoginTime,LastActiveTime
                                      $row.UserName = $see.userName
                                      $row.FullName = $sess.fullName
                                      $row.Timestamp = Get-Date
                                     
                          $row.Server = $singleVIServer
                                      $row.LoginTime = $sess.loginTime             $row.LastACtiveTime = $sess.lastActiveTime             $report += $row          }         }         if($oldSessions.Count -gt 0){             $sessMgr.TerminateSession($oldSessions)         } } $report
                          • 10. Re: Disconnect vi client as specified intervals
                            bradley4681 Expert

                            finally got around to playing with this again and noticed that powershell will peg the cpu while running this script. any particular reason?

                            • 11. Re: Disconnect vi client as specified intervals
                              LucD Guru
                              vExpertCommunity WarriorsUser Moderators

                              There are no CPU-intensive parts in the script afaik.

                              Was the CPU high on the PC where you run the script or on the vCenter ?