none
How to use VBScript to invoke PowerShell script and then return value as VB variable RRS feed

  • Question

  • Hey All,

    I found in this very blog how to use VBScript to invoke PowerShell and I have been trying to leverage that for use in SCOM. This is really a SCOM Timed-Script Monitor issue we are having an issue with. The monitor needs to check if a file exists or not in a directory and if it does, the monitor is healthy. Once the file does not exist, the monitor becomes unhealthy and generates an alert. The file that is being monitored is a server PID created by an in house application. As long as the PID is present, monitor is healthy. Once the PID drops out of its filepath, the monitor generates an alert. 

    I tried creating a basic VBScript for the monitor to look for these PIDs:

    Option Explicit
    Dim fso, oAPI, oBag
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set oAPI = CreateObject("MOM.ScriptAPI")
    Set oBag = oAPI.CreatePropertyBag()
    If (fso.FileExists("E:\BOE\SAP 4.0\serverpids\SAPSERV01_SAPSERV01.JobServer.pid")) Then
    Call oBag.AddValue("Status","GOOD")
    Call oAPI.Return(oBag)
    WScript.Quit
    Else
    Call oBag.AddValue("Status","BAD")
    Call oAPI.Return(oBag)
    End If
    WScript.Quit

    The above does work. The problem is that there are 5 unique pid files for this application, each named for the server they run on and there are a total of 7 servers. I am not keen on making 7 single server groups in scom with 5 unique monitors for each. I want to make one monitor per PID using a wildcard. But VBScript method FileSystemObject does not support wildcards. So I cant make the script say ".\serverpids\*.JobServer.pid", it wont work. But what about PowerShell?

    In PowerShell I can very easily invoke a " Test-Path 'E:\BOE\SAP 4.0\*.JobServer.pid' " and have it return True or False when I run it across all 7 servers. So here is my question. How can I use the VBScript portion of my Monitor to invoke a PowerShell command or script for "Test-Path" and have the returned result of True go into a oBag.AddValue("status","good") and a returned result of False go into a oBag.AddValue("status",bad")??

    I got so close already using VBScript to invoke PowerShell with WScript.Shell, but I am stuck on how to get the output of the powershell console "true or false" to get assigned in the VBScript as a variable for the oBag property for SCOM

    Tuesday, February 2, 2016 9:34 PM

Answers

  • The function does not search subdirectories.

    You have to specify the exact path where the ".jobserver.pid" files might reside.

    Based on your first post, the function call would look like this:


    If DoPIDFilesExist("E:\BOE\SAP 4.0\serverpids") Then
      ' Code here
    End If
    

     


    -- Bill Stewart [Bill_Stewart]


    Friday, February 5, 2016 8:34 PM
    Moderator

All replies

  • if fso.Exists("E:\BOE\SAP 4.0\item1.JobServer.pid") Then

    ElseIf fso.Exists("E:\BOE\SAP 4.0\item2.JobServer.pid") Then

    .... etc

    That is how to do it in VBScript.


    \_(ツ)_/



    • Edited by jrv Tuesday, February 2, 2016 10:01 PM
    Tuesday, February 2, 2016 9:59 PM
  • That's a lot of overhead (call PowerShell). I would probably loop through the files (For Each) using a small function that checks for any file names that end with the string ".pid". Here is a sample VBScript function that does it:


    Function DoPIDFilesExist(ByVal PathName)
      DoPIDFilesExist = False
      Dim Folder
      On Error Resume Next
      Set Folder = FSO.GetFolder(PathName)
      If Err.Number <> 0 Then
        Exit Function
      End If
      On Error GoTo 0
      Dim File
      For Each File in Folder.Files
        If StrComp(Right(File.Name, 4), ".pid", vbTextCompare) = 0 Then
          DoPIDFilesExist = True
          Exit Function
        End If
      Next
    End Function
    


    -- Bill Stewart [Bill_Stewart]

    Tuesday, February 2, 2016 10:12 PM
    Moderator
  • I had thought about that too, but realized it wouldn't work in our situation. Thats why I was trying to use a wildcard to drop off the item1, item2 part and have it just check for ".JobServer.pid". That way if any single one (or more) instance of this stops running, the script will generate an Unhealthy status in SCOM and the alert will tell us that .JobServer.pid is not running for item1 ie Server02.

    Each server is a member of a SCOM group, and the script needs to run against all 7 and report back any one of them not having the pid file present (running) and which one it is. Which would  be incredibly easy if the program area didnt have thier app name each pid instance with the server hostname as a prefix on the .pid file and just left it as JobServer.pid.


    • Edited by Kevsharp Wednesday, February 3, 2016 1:59 PM
    Wednesday, February 3, 2016 1:58 PM
  • Your approach is a horrible kludge which is why it is so hard to do.  It runs totally counter to how Config manager is designed.

    Post I'm SCOM forum for guidance in how to accomplish you task with much less pain.

    https://social.technet.microsoft.com/Forums/systemcenter/en-us/home?category=systemcenteroperationsmanager


    \_(ツ)_/

    Wednesday, February 3, 2016 2:11 PM
  • I had thought about that too, but realized it wouldn't work in our situation. Thats why I was trying to use a wildcard to drop off the item1, item2 part and have it just check for ".JobServer.pid".

    The VBScript function I posted can do that if you adjust the condition.

    Instead of


    If StrComp(Right(File.Name, 4), ".pid", vbTextCompare) = 0 Then
    

    You would write


    If StrComp(Right(File.Name, 14), ".jobserver.pid", vbTextCompare) = 0 Then


    -- Bill Stewart [Bill_Stewart]


    Wednesday, February 3, 2016 3:39 PM
    Moderator
  • Your approach is a horrible kludge which is why it is so hard to do.  It runs totally counter to how Config manager is designed.

    Post I'm SCOM forum for guidance in how to accomplish you task with much less pain.

    https://social.technet.microsoft.com/Forums/systemcenter/en-us/home?category=systemcenteroperationsmanager


    \_(ツ)_/

    You are so correct. I have been losing the battle to get the end users to adjust or reprogram their application to drop the hostname each PID file runs on and just generically use the same JobServer.pid naming convention on all 7 servers instead of 7 uniquely named files...server01_server01.JobServer.pid, server02_server02.JobServer.pid, etc. on each server.
    Thursday, February 4, 2016 4:30 PM
  • If StrComp(Right(File.Name, 4), ".pid", vbTextCompare) = 0 Then
    

    You would write


    If StrComp(Right(File.Name, 14), ".jobserver.pid", vbTextCompare) = 0 Then


    -- Bill Stewart [Bill_Stewart]


    In the section of the function (ByVal PathName) and then FSO.GetFolder(PathName), do I put the path in quotes like ("E:\folder") or list it differently? I am very new to VBScript. Thank you for the great direction so far
    Thursday, February 4, 2016 4:56 PM
  • Add the function to your script and then call it like this:


    If DoPIDFilesExist("C:\Program Files\Folder Name") Then
      ' Put the code here that you want to run if there are any .jobserver.pid files in that folder
    End If
    



    -- Bill Stewart [Bill_Stewart]

    Friday, February 5, 2016 3:56 PM
    Moderator
  • I feel really dumb having to ask more questions because it's seems to me that everything I need is there. Here is how I have the VBScript file:

    'Check for PID

            

    Function DoPIDFilesExist(ByVal PathName)
        DoPIDFilesExist = False
        Dim Folder
        On Error Resume Next
        Set Folder = FSO.GetFolder(PathName)
        If Err.Number <> 0 Then
    Exit Function
        End If
        On Error Goto 0
        Dim File
        For Each File In Folder.Files
    If StrComp(Right(File.Name, 14), ".JobServer.pid", vbTextCompare) = 0 Then
    DoPIDFilesExist = True
    Exit Function
    End If
        Next
    End Function

    If DoPIDFilesExist("E:\BOE\") Then
    WScript.Echo "File Exists"
    Else
    WScript.Echo "File Not Found"

    End If

    This was just to test and make sure I understood how to make a function and call it. The issue is that even with the DoPIDFileExist condition being true with .JobServer.pid being in that directory, I always get "File Not Found". And if I remove the Else and just have WScript.Echo "File Exists", nothing comes up. What in the world am I not getting here? Thanks

    Friday, February 5, 2016 8:32 PM
  • The function does not search subdirectories.

    You have to specify the exact path where the ".jobserver.pid" files might reside.

    Based on your first post, the function call would look like this:


    If DoPIDFilesExist("E:\BOE\SAP 4.0\serverpids") Then
      ' Code here
    End If
    

     


    -- Bill Stewart [Bill_Stewart]


    Friday, February 5, 2016 8:34 PM
    Moderator