Announcement

Collapse
No announcement yet.

List Process by User - Alphabetical

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • List Process by User - Alphabetical

    Hi,

    i currently use a script periodically to see how many users are using a certain application (terminal server). I just get a read out of the number of apps.

    Sometimes the same user may be using the same app 3 times..which consumes licences.

    Is there a way of printing out to screen or file the users in alphabetical order and process?

    the script i currently use is below:

    this is for a prompt to tell me how many processes are running:

    sProcessName = "app.exe"

    sComputer = "." ' use "." for local computer
    Set oWmi = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & sComputer & "\root\cimv2")

    Set colProcessList = oWmi.ExecQuery _
    ("Select * from Win32_Process Where Name = '" & sProcessName & "'")

    iCount = colProcessList.Count

    If iCount > 0 Then
    wscript.echo "There are currently " & iCount & " instances of Application running. This means that the remote users are currently occupying " & iCount & " database licences"
    Else
    wscript.echo "The process [" & sProcessName & "] is not running."
    End If

  • #2
    Re: List Process by User - Alphabetical

    1. Use a For ... Next loop, for each "objprocess" in colProcessList:
    a. ".GetOwner" (get the sUsername & sUserdomain ).
    b. "Append" to a temp outputfile: domain\user, date/time, processname

    2. After all objprocess are past,
    a. read the tempfile,
    b. sort the content by_line (now it will be sorted automatically by username because every line starts with domain\user ).

    If you create a csv-file as outputfile, you can use Excel to show quantities.



    Something else...
    Just a thought, maybe you can create a processmonitor using "Win32_ProcessStartTrace" to monitor all new instances of "app.exe".
    Every time a new process starts with that name, get: the Domain\Username of the owner, the processname and the processID of that process.
    Then use Win32_Process to query all instances of "app.exe" that are currently running.
    - For each instance of "app.exe" compare the owner with that of the new process.
    - Terminate each instance of "app.exe" started by that domain\Username if the processID is not the same as the new process.
    - Write a log file of each processes terminated by the script.


    \Rems

    This posting is provided "AS IS" with no warranties, and confers no rights.

    __________________

    ** Remember to give credit where credit's due **
    and leave Reputation Points for meaningful posts

    Comment


    • #3
      Re: List Process by User - Alphabetical

      are you able to show me that in the script?

      i didn't do the script myself. thanks

      Comment


      • #4
        Re: List Process by User - Alphabetical

        Code:
        ' ListProcessByUser.vbs
        '
        'Remco Simons [NL] 2007
        '(http://forums.petri.com/showthread.php?t=15777)
        '----------------------------------------------------------------
        
        sProcessName = "app.exe"
        
        sComputer = "."   'executed on the terminalserver
        
        
        
         Const ForAppending = 8
         Const ForReading   = 1
         Const ForWriting   = 2
        
         Set objFSO = CreateObject("Scripting.FileSystemObject")
        
         Set objShell = CreateObject("Wscript.Shell")
         sOutTmp = objShell.ExpandEnvironmentStrings("%temp%\" & objFSO.GetTempName)
        
         On Error Resume Next
        
        
        
        'Query for all instances of the process, write to temp outputfile
        '----------------------------------------------------------------
        
         Set oWmi = GetObject("winmgmts:" _
             & "{impersonationLevel=impersonate}!\\" & sComputer & "\root\cimv2")
        
         Set colProcessList = oWmi.ExecQuery _
              ("Select * from Win32_Process Where Name = '" & sProcessName & "'")
        
         n = 0
        
        
         With objFSO.OpenTextFile(sOutTmp, ForAppending, True)
        
           for each colprocess in colProcessList
              Return = colprocess.GetOwner(strUserName, strDomain)
              If Return = 0 Then  'And Not IsNull(colprocess.CreationDate) Then
                 n = Right(100000 + (n+1), Len(colProcessList.Count))
                 .WriteLine """" & strDomain & "\" & strUserName & """," & _
                         colprocess.CreationDate &","""& colprocess.Name & _
                         """," & chr(35) & n &"/"& colProcessList.Count
              End If
           next
        
         .Close 
         End With
         Set oWmi = Nothing
        
        
        
        'Read the temp file, and run 'SortIt'-function
        '----------------------------------------------------------------
         with objFSO.GetFile(sOutTmp).OpenAsTextStream(1, -2)
            strArray = .ReadAll
         .Close 
         End With
         strArray = SortIt(strArray)
         'strArray = Replace(strArray, "," ,vbTab)  '(optional:) replace the comma with a Tab
        
        
        
        'overwrite the temp outputfile with the sorted lines
        '----------------------------------------------------------------
         With objFSO.OpenTextFile(sOutTmp, ForWriting)
            .WriteLine "ProcessOwner,StartTime,ProcessName,FoundSeq"
            .WriteLine strArray
         .Close
         End With
         Erase strArray
        
        
        
        'Show results (comma seperated value), cleanup and end script
        '----------------------------------------------------------------
         objShell.Run "wordpad.exe " & sOutTmp, , false
        
         wscript.sleep 600
         objFSO.DeleteFile(sOutTmp) 'deletes the temp-file from disk
        
         Set objShell = Nothing
         Set objFSO = Nothing
          Wscript.quit(0)
        
        
        
        '******************************************************************************
        
        Function SortIt(ByVal strValue)
        '(by: "MyndPhlyp" http://groups.google.com/groups/search?ie=UTF-8&oe=UTF-8&q=%22Function+SortIt%28ByVal+strValue%29%22+MyndPhlyp )
          Dim arrUnsorted
          Dim arrSorted
          Dim bolSorted
          Dim strSorted
        
          arrUnsorted = Split(strValue, vbCrLf)
        
          bolSorted = False
        
          Do Until bolSorted
            bolSorted = True
            For I = 0 to UBound(arrUnsorted)
              ' Compare this entry to the next entry
              If I < UBound(arrUnsorted) Then
                If arrUnsorted(I+1) < arrUnsorted(i) Then
                  strTemp = arrUnsorted(I+1)
                  arrUnsorted(I+1) = arrUnsorted(I)
                  arrUnsorted(I) = strTemp
                  bolSorted = False
                End If
              End If
            Next
          Loop
        
          strSorted = ""
        
          For I = 1 to UBound(arrUnsorted)
            strSorted = strSorted & arrUnsorted(I) & vbCrLf
          Next
        
          SortIt = strSorted
        End Function
        Last edited by Rems; 16th May 2007, 23:12.

        This posting is provided "AS IS" with no warranties, and confers no rights.

        __________________

        ** Remember to give credit where credit's due **
        and leave Reputation Points for meaningful posts

        Comment


        • #5
          Re: List Process by User - Alphabetical

          fantastic ..thanks very much.

          Comment


          • #6
            Re: List Process by User - Alphabetical

            Originally posted by Rems View Post

            Something else...
            Just a thought, maybe you can create a processmonitor using "Win32_ProcessStartTrace" to monitor all new instances of "app.exe".
            Every time a new process starts with that name, get: the Domain\Username of the owner, the processname and the processID of that process.
            Then use Win32_Process to query all instances of "app.exe" that are currently running.
            - For each instance of "app.exe" compare the owner with that of the new process.
            - Terminate each instance of "app.exe" started by that domain\Username if the processID is not the same as the new process.
            - Write a log file of each processes terminated by the script.


            \Rems
            i tell you what, thats one super script you helped me with....its unreal.

            i've been thinking about the quotes you have above........i think i may want something like that.......

            what i would like to have also, why not, is filter the users and write a log for certain users............eg many times i get 50 users using a process...............

            i would like to monitor when users: user1, user2, user3, user4 are using the apps....so perhaps i can make an extra script and filter the output for the users i want to monitor............

            this is possible yeah? if so, i'd appreciate your help. thanks very much

            Comment


            • #7
              Re: List Process by User - Alphabetical

              You have to test the next script your self.

              It must be executed during startup of the terminal serverl. The script must stay in memory.


              This is an example how only one instance of a processName is allowed to run by a user. The older instance(s) of the application from the same owner will be terminated when a new one is executed.
              Code:
              'Only-1-Instance-PerUser.vbs
              
              sMembersOf = "securitygroupname"
              arrTargetProcs = Array("app1.exe", "app2.exe")  '<--multiple applications separated with a comma
              
              TerminateLogFile = "c:\TLF.csv"
              
              
              strComputer = "."
              
              On Error Resume Next
              Set SINK = WScript.CreateObject("WbemScripting.SWbemSink","SINK_")
              
              Set objWMIService = GetObject("winmgmts:" _
                & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
              
              objWMIService.ExecNotificationQueryAsync SINK, _
                "SELECT * FROM Win32_ProcessStartTrace"
              
              'Wscript.Echo "Waiting for target processes ..."
              
              
              Do
                 WScript.Sleep 10000
              Loop
              
              
              
              '******************************************************************************
              
              Sub SINK_OnObjectReady(objLatestEvent, objAsyncContext)
              'Trap asynchronous events.
              'http://www.microsoft.com/technet/scriptcenter/resources/scriptshop/shop0805.mspx
              
              For Each strTargetProc In arrTargetProcs
                If LCase(objLatestEvent.ProcessName) = LCase(strTargetProc) Then
              
                  strProcName = objLatestEvent.ProcessName
                  strHandle = CStr(objLatestEvent.ProcessID)
              
                  On Error Resume Next
                  Set objProcess = objWMIService.Get _
                             ("Win32_Process.Handle='" & strHandle & "'")
                  objProcess.GetOwner strNameOfUser, strUserDomain
                  strNwOwner = UCase(strUserDomain & "\" & strNameOfUser)
              
                  If IsMember(strUserDomain, strNameOfUser, sMembersOf) then
                      ProcSearch strProcName, strHandle, strNwOwner
                  End If
              
                End If
              
              Next
              
              End Sub
              
              
              
              Sub ProcSearch(nwProcName, nwHandle, nwOwner)
              'Remco Simons [NL] 2007
              
               On Error Resume Next
               Set objFSO = CreateObject("Scripting.FileSystemObject")
              
               Set colProcess = objWMIService.ExecQuery _
                  ("Select * from Win32_Process Where Name = '" & nwProcName & "'" )
              
               With objFSO.OpenTextFile(TerminateLogFile, 8, True)
                For Each oProcess in colProcess
                   If nwHandle <> oProcess.Handle Then
                      oProcess.GetOwner strUser,strDomain
                      strOwner = UCase(strDomain) & "\" & UCase(strUser)
                      If nwOwner = strOwner Then
                         intReturn = oProcess.Terminate()
                         strLine = strOwner & "," & now & "," & oProcess.Name
                         If intReturn = 0 Then
                            .WriteLine strLine & "," & "TERMINATED"
                         Else
                            .WriteLine strLine & "," & "UNABLE to terminate!"
                         End If
               
                      End If
                   End If
                Next
               .Close
               End With
               Set objFSO = Nothing
               Set colProcess = Nothing
              End Sub
              
              
              Function IsMember(sDomain, sUser, sGroup)
               Set objUser = GetObject("WinNT://" & sDomain & "/" & _
                 sUser & ",user")
                 check = False
                For Each objGroup in objUser.Groups
                  If objGroup.Name = sGroup Then
                    check = True
                    Exit For
                  End If
                Next
                IsMember = check
              End Function

              This script also, why not, filter the users.
              There where several options. Here in this example you must create a special Group in the Active Directory for these users. Then the script check the membership before take action:

              \Rems



              -EDIT-

              If you don't want to terminate the processes (yet), but only monitoring and write to the logfile,
              then change the line:
              intReturn = oProcess.Terminate()
              To:
              intReturn = 1 'oProcess.Terminate()
              Last edited by Rems; 18th May 2007, 20:04.

              This posting is provided "AS IS" with no warranties, and confers no rights.

              __________________

              ** Remember to give credit where credit's due **
              and leave Reputation Points for meaningful posts

              Comment


              • #8
                Re: List Process by User - Alphabetical

                thanks very much.

                i do not want to terminate the processes. just run the same script as the first one and just have the output filtered....

                if i edit the script you added and the following:

                If you don't want to terminate the processes (yet), but only monitoring and write to the logfile,
                then change the line:
                intReturn = oProcess.Terminate()
                To:
                intReturn = 1 'oProcess.Terminate()

                will i be able to run this as per normal, eg run the .vbs file when i need to? or do i need to add it to a start up script?

                thanks heaps.

                Comment


                • #9
                  Re: List Process by User - Alphabetical

                  i do not want to terminate the processes.
                  In that case you could even modify the ProcSearch subroutine a bit more, so it write only one line per event -> log only when a user start an extra instance of the application:

                  line per event:
                  User: username,started: appname,at: date/time, while already: 3 instance(s) running.

                  The log can only be written in order the events took place. The logfile has comma seperated values, so you can sort by username afterwards with excel.


                  filter the users and write a log for certain users
                  A user-filter can be added to both scripts. In the second script, group membership is used for filtering, but you could also create a filter that checks an OU or you can use a userlist textfile as inputfile.


                  will i be able to run this as per normal, eg run the .vbs file when i need to? or do i need to add it to a start up script?
                  The results you get from the first script is just a current moment, a snapshot. Someone can open several instances of the same applications before or after you runned that script, and you never know about that.

                  The second script starts monitoring the 'starting of a certain application' per user. If you want the results over a complete day, for a thoroughly result the script can best be loaded automaticly and as early as posible, to accomplish that execute it with the Startup of the server. But, if you only want to load the script for a period of the day you can manualy execute the script. To end monitoring, open Taskmanager and end the "wscript.exe" tree.


                  \Rems

                  This posting is provided "AS IS" with no warranties, and confers no rights.

                  __________________

                  ** Remember to give credit where credit's due **
                  and leave Reputation Points for meaningful posts

                  Comment


                  • #10
                    Re: List Process by User - Alphabetical

                    what i have done with some similar scripts is have them append to a log file....and they are scheduled to run , eg every 30 mins............so i have a log file with the appended output.

                    that is what i'd like to do with this, eg i would like to log every 30 mins how many of app.exe that eg user1,user2, user3, user4 have running.....

                    so from this perspective, i would need the .vbs modified so that it saves and appends to a file, and also, the hard one, is that it only outputs for the users: user1, user2, user3, user4.

                    all of this is to monitor these users for licensing reason.

                    thanks

                    Comment

                    Working...
                    X