요즘 Terminal Server 관리 자동화를 위해 VBS를 이용하고 있다. 거의 완전 초보 수준이라 몇개 Script를 이용해서 만들기는 하지만 Output에 대해서는 나름 만족하고 있다. 더 나은 로직으로 관리를 하신 분들도 분명히 계실것이라 생각된다.^^ (저의 블로그를 방문해 주시는 고수 분들의 많은 지적도 부탁드립니다)

 

참고 : http://www.microsoft.com/technet/scriptcenter/default.mspx

 

=======================

CPU & MEM 과점유 프로세스 Kill

=======================

 

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Const ForAppending = 8
Const CONVERT_TO_LOCAL_TIME = True

Set dtmStart = CreateObject("WbemScripting.SWbemDateTime")
dtmStart.SetVarDate Now, CONVERT_TO_LOCAL_TIME

dtmRegular = dtmStart.GetVarDate(CONVERT_TO_LOCAL_TIME)

 

'Kill 하려는 프로세스 Name

Set colProcessList = objWMIService.ExecQuery _
    ("Select * from Win32_Process Where Name = '프로세스이름'")

For Each objProcess in colProcessList
    Wscript.Echo "Process: " & objProcess.Name & " ProcessID : " & objProcess.ProcessID
    dtmStartTime = objProcess.CreationDate
    strReturn = WMIDateStringToDate(dtmStartTime)
    Wscript.Echo strReturn
    Wscript.Echo "Working Set Size: " & objProcess.WorkingSetSize /1024 / 1024
    Wscript.Echo  "CPU Usage : " & CPUUSage(objProcess.ProcessID)


'CPU 사용시간 확인, 단위 : Second
    sngProcessTime = ( CSng(objProcess.KernelModeTime) + _
            CSng(objProcess.UserModeTime)) / 10000000

    timeFlag = DateDiff("h", strReturn, dtmRegular)
    Wscript.Echo "======================================================"

'CPU Time과 CPU사용률을 비교 – CPU 수행시간이 4시간이상 프로세스 중 사용률이 20% 이상, 메모리 사용률 2G 이상
    If   ((sngProcessTime > 18000 And CPUUSage(objProcess.ProcessId) > 20) Or objProcess.WorkingSetSize /1024/1024 > 2000  ) then
        Set objFSO = CreateObject("Scripting.FileSystemObject")
            Set objFile = objFSO.OpenTextFile("파일경로", ForAppending)

 

'Application 에서 teminate function을 사용할 경우 적용가능           
        'objProcess.Terminate()

 

'그렇지 않을 경우 CMD 명령어로 해당 프로세스 Kill
        Rem------------------------------------------------
          Set wshShell = WScript.CreateObject ("WSCript.shell")
          wshshell.run "cmd /c taskkill /f /pid " & objProcess.ProcessID      
       Set wshshell = nothing
          Rem -------------------------------------------------------------
        objFile.WriteLine now & " " & objProcess.Name & " ProcessTime:" & sngProcessTime  & " memory:" & objProcess.WorkingSetSize  /1024 /1024 & " ProcessID : " & objProcess.ProcessID & " CPU Usage : " & CPUUSage(objProcess.ProcessID)
        'objFile.WriteLine "cmd /c taskkill /f /pid " & objProcess.ProcessID
        objFile.Close
    End if

Next

 

'날짜 형식을 Date로 변경하는 Function

Function WMIDateStringToDate(dtmStart)
    WMIDateStringToDate = CDate(Mid(dtmStart, 5, 2) & "/" & _
        Mid(dtmStart, 7, 2) & "/" & Left(dtmStart, 4) _
            & " " & Mid (dtmStart, 9, 2) & ":" & _
                Mid(dtmStart, 11, 2) & ":" & Mid(dtmStart, _
                    13, 2))
End Function

 

'프로세스 사용량을 가져오는 Function

Function CPUUSage( ProcID )
        On Error Resume Next
            Set objService = GetObject("Winmgmts:{impersonationlevel=impersonate}!\Root\Cimv2")
      For Each objInstance1 in objService.ExecQuery("Select * from Win32_PerfRawData_PerfProc_Process where IDProcess = '" & ProcID & "'")
          N1 = objInstance1.PercentProcessorTime
          D1 = objInstance1.TimeStamp_Sys100NS
           Exit For
       Next
        WScript.Sleep(2000)

       For Each perf_instance2 in objService.ExecQuery("Select * from Win32_PerfRawData_PerfProc_Process where IDProcess = '" & ProcID & "'")
           N2 = perf_instance2.PercentProcessorTime
           D2 = perf_instance2.TimeStamp_Sys100NS
           Exit For
       Next

       ' CounterType - PERF_100NSEC_TIMER_INV
       ' Formula - (1- ((N2 - N1) / (D2 - D1))) x 100
        Nd = (N2 - N1)
        Dd = (D2-D1)
         PercentProcessorTime = ( (Nd/Dd))  * 100
      CPUUSage = Round(PercentProcessorTime ,0)
End Function

 

지금 위와 같은 Script를 실행할 경우 결과 파일은 TXT 파일 형태로 떨어지게 된다. 만약 해당 내용을 Event Log에 뿌리고 싶다면 Event Log를 뿌리는 것을 Function으로 작성하여 Script 내에 넣으면 된다.

 

=======================

Citrix 환경에서 특정 User Logoff

=======================

 

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Const ForAppending = 8
Const CONVERT_TO_LOCAL_TIME = True

Set dtmStart = CreateObject("WbemScripting.SWbemDateTime")
dtmStart.SetVarDate Now, CONVERT_TO_LOCAL_TIME

dtmRegular = dtmStart.GetVarDate(CONVERT_TO_LOCAL_TIME)

Set colProcessList = objWMIService.ExecQuery _
    ("Select * from Win32_Process Where Name = '프로세스이름'")

For Each objProcess in colProcessList
    Wscript.Echo "Process: " & objProcess.Name & " ProcessID : " & objProcess.ProcessID & " SessionID : " & objProcess.SessionID
    dtmStartTime = objProcess.CreationDate
    Wscript.Echo "User List : " & UserList(objProcess.CSName, objProcess.SessionID) & " Session ID : " & objProcess.SessionID
    Wscript.Echo "CPU Usage :  " & CPUUSage(objProcess.ProcessId)
    Wscript.Echo "======================================================"
If   (CPUUSage(objProcess.ProcessId) >= 4) then
        Set objFSO = CreateObject("Scripting.FileSystemObject")
        Set objFile = objFSO.OpenTextFile("파일경로", ForAppending)

          Rem------------------------------------------------
          Set wshShell = WScript.CreateObject ("WSCript.shell")
          wshshell.run "cmd /c logoff " & objProcess.SessionID
          Set wshshell = Nothing
          Rem -------------------------------------------------------------
          Critical()
        objFile.WriteLine Now & " "  & "Process: " & objProcess.Name & " ProcessID : " & objProcess.ProcessID & " User List : " & UserList(objProcess.CSName, objProcess.SessionID) & " Session ID : " & objProcess.SessionID
        objFile.Close
    End if

Next

 

'날짜 형식을 Date로 변경하는 Function

Function WMIDateStringToDate(dtmStart)
    WMIDateStringToDate = CDate(Mid(dtmStart, 5, 2) & "/" & _
        Mid(dtmStart, 7, 2) & "/" & Left(dtmStart, 4) _
            & " " & Mid (dtmStart, 9, 2) & ":" & _
                Mid(dtmStart, 11, 2) & ":" & Mid(dtmStart, _
                    13, 2))
End Function

 

'프로세스 사용량을 가져오는 Function

Function CPUUSage( ProcID )
        On Error Resume Next
            Set objService = GetObject("Winmgmts:{impersonationlevel=impersonate}!\Root\Cimv2")
      For Each objInstance1 in objService.ExecQuery("Select * from Win32_PerfRawData_PerfProc_Process where IDProcess = '" & ProcID & "'")
          N1 = objInstance1.PercentProcessorTime
          D1 = objInstance1.TimeStamp_Sys100NS
           Exit For
       Next
        WScript.Sleep(20)

       For Each perf_instance2 in objService.ExecQuery("Select * from Win32_PerfRawData_PerfProc_Process where IDProcess = '" & ProcID & "'")
           N2 = perf_instance2.PercentProcessorTime
           D2 = perf_instance2.TimeStamp_Sys100NS
           Exit For
       Next

       ' CounterType - PERF_100NSEC_TIMER_INV
       ' Formula - (1- ((N2 - N1) / (D2 - D1))) x 100
        Nd = (N2 - N1)
        Dd = (D2-D1)
         PercentProcessorTime = ( (Nd/Dd))  * 100
      CPUUSage = Round(PercentProcessorTime ,0)
End Function

 

' User Name을 불러오는 Function

Function UserList(aServer, aSession)

On Error Resume Next
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\Citrix")
Set colItems = objWMIService.ExecQuery( "SELECT * FROM MetaFrame_Process where ServerName = '" & aServer & "' and SessionID = '" & aSession & "' and ProcessName = '프로세스이름'")

For Each objItem in colItems  
    username = objItem.UserName
Next

    UserList = username

End Function

 

' 수행결과를 Event Log로 뿌리는 Function

Function Critical()

    Const EVENT_SUCCESS = 2
    Set objShell = Wscript.CreateObject("Wscript.Shell")
    objShell.LogEvent EVENT_SUCCESS, _
    "User : " & UserList(objProcess.CSName, objProcess.SessionID) & " 정상적으로 Logoff 하였습니다."
End Function

 

프로세스 Kill Script 와 연관되어 작성한 User Logoff Script이다. Xen APP서버를 서비스 하는 경우 User에 대한 정보를 일반적인 OS상에 존재하는 WMI 값에서 가져올 수 없다. Xen APP은 RDP Session으로 접근하는것이 라는 ICA Session 자체로 표시되기 때문에 User Name값을 가져올 경우에는 Citrix WMI값을 이용하여 Function화 하면 쉽게 User Name을 가져올 수 있다.

또 아래부분을 보면 Event Log로 전달하는 부분이 Function을 참고하셔도 활용할 수 있는 범위가 많을 것이라 생각된다.

신고
Posted by hotpoto

티스토리 툴바