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

• 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 oAPI.Return(oBag)
WScript.Quit
Else
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

• 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

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 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
• 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 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.

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
• 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
• 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

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