Search code examples
regexwindowsbatch-filevbscriptwebsphere

Windows Script to Parse names of WebSphere JVMs from a command output


I am writing a (batch file or VBScript) to nicely shutdown all the running WebSphere JVMs on a Windows server, but need help with some text handling. I want the script to run and parse the output of the "serverstatus" command to get the names of Application Servers on the box and store the matches (with carriage returns) in a variable for use in the rest of the script.

Sample command output:

C:\WebSphere\AppServer\bin>serverstatus -all
ADMU0116I: Tool information is being logged in file
       C:\WebSphere\AppServer\profiles\MySrv01\logs\serverStatus.log
ADMU0128I: Starting tool with the MySrv01 profile
ADMU0503I: Retrieving server status for all servers
ADMU0505I: Servers found in configuration:
ADMU0506I: Server name: MyCluster_MySrv01
ADMU0506I: Server name: MyCluster_MySrv01_1
ADMU0506I: Server name: MyNextCluster_MySrv04
ADMU0506I: Server name: MyNextCluster_MySrv04_1
ADMU0506I: Server name: nodeagent
ADMU0508I: The Application Server "MyCluster_MySrv01" is STARTED
ADMU0508I: The Application Server "MyCluster_MySrv01_1" is STARTED
ADMU0508I: The Application Server "MyNextCluster_MySrv04" is STARTED
ADMU0509I: The Application Server "MyNextCluster_MySrv04_1" cannot be
       reached. It appears to be stopped.
ADMU0508I: The Node Agent "nodeagent" is STARTED

*nodeagent should NOT match. The jury is still out on whether I want to target all app servers or just those with a status of "STARTED".


Solution

  • Here's an alternative to using Regex. It simply reads stdout and processes all started app servers - the app servers are stored in an array called AppServers. Tested on W2K3. Edit: We have added a way to log output to a file by adding a log write function (don't forget to add the const ForAppending at the start of the script that we have just added to this answer). The log write function takes the format of:

    Logwrite "some text to write - delete file if exists", "c:\Path\filename.txt", 1
    Logwrite "some text to write - append to file, don't delete", "c:\path\filename.txt", 0
    

    It is a crude function, but does what you ask. I hope that helps. :)

    option explicit
    Const ForAppending = 8
    Dim objShell, objWshScriptExec, objStdOut
    Dim objCmdString, strLine, appServers(), maxAppServers
    Dim x
    
    ' File Path / Location to serverstatus.bat ----
    objCmdString = "C:\WebSphere\AppServer\bin\serverstatus.bat -all"
    
    Set objShell = CreateObject("WScript.Shell")
    Set objWshScriptExec = objShell.Exec(objCmdString)
    Set objStdOut = objWshScriptExec.StdOut
    
    MaxAppServers = -1
    
    ' While we're looping through the response from the serverstatus command, look for started application servers
    ' and store them in an ever expanding array AppServers.
    ' The Variable MaxAppServers should always contain the highest number of AppServers (ie: ubound(AppServers))
    
    While Not objStdOut.AtEndOfStream
       strLine = objStdOut.ReadLine
       If InStr(LCase(strLine), "admu0508i: the application server """) Then
          MaxAppServers = MaxAppServers + 1
          ReDim Preserve AppServers(MaxAppServers)
          AppServers(MaxAppServers) = wedge(strLine, Chr(34))
       End If
    Wend
    
    If MaxAppServers => 0 then 
        For x = 0 To ubound(AppServers)    ' You could just use For x = 1 to MaxAppServers in this case.
            ' Add your instructions here.........
            ' ... We are simply echoing out the AppServer name below as an example to a log file as requested below.
             Logwrite AppServers(x), "c:\Output.log", 0
        Next
    End If
    
    Function Wedge(wStr, wOpr)
    ' This clunky function simply grabs a section of a string the is encapsulated by wOpr.
    ' NOTE: This function expects wOpr to be a single character (eg; for our purpose, it is pulling data between double quotes).
    
        Dim wFlag, wCount, wFinish
    
        wflag = False
        wFinish = False
        wCount = 1
        Wedge = ""
    
        Do Until wCount > Len(wStr) Or wFinish
           If Mid(wStr, wCount, 1) = wOpr Then
               If wFlag Then
                  wFinish = True
               Else
                  wFlag = True
               End If
           Else
               If wFlag Then Wedge = Wedge & Mid(wStr, wCount, 1)                                 
           End If
           wCount = wCount + 1
        Loop
     End Function
    
    Function logwrite (lstrtxt, lwLogfile, lwflag)
        Dim lwObjFSO, lwObjFile, fstr, lwcounter, lwc
        fstr = lstrtxt
        Set lwObjFSO = CreateObject("Scripting.FileSystemObject")
        If lwflag=1 And lwObjFSO.FileExists(lwLogFile) Then lwObjfso.deletefile(lwLogFile)
        If lwObjFSO.FileExists(lwLogFile) then
            On Error Resume next
            Set lwObjFile = lwObjFSO.OpenTextFile(lwLOgFile, ForAppending)
            lwCounter = 20000
            Do While Err.number = 70 And lwCounter > 0
                wscript.echo "ERROR: Retrying output - Permission denied; File may be in use!"
                For lwc = 1 To 1000000
                Next
                Err.clear
                Set lwObjFile = lwObjFSO.OpenTextFile(lwLogFile, ForAppending)
                lwCounter = lwCounter-1
            Loop
            If Err.number <> 0 Then
                wscript.echo "Error Number: "&Err.number
                wscript.quit
            End If
            On Error goto 0
        Else
            Set lwObjFile = lwObjFSO.CreateTextFile(lwLogFile)
        End If
        wscript.echo (fstr)
        lwObjFile.Write (fstr) & vbcrlf
        lwObjFile.Close
        Set lwObjFSO=Nothing
        Set lwObjfile=Nothing
    
     End Function