KS-Soft. Network Management Solutions
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister    ProfileProfile    Log inLog in 

Check all HD volumes for free space (variable threshold)
Goto page 1, 2, 3, 4  Next
 
Post new topic   Reply to topic    KS-Soft Forum Index -> Library
View previous topic :: View next topic  
Author Message
greyhat64



Joined: 14 Mar 2008
Posts: 245
Location: USA

PostPosted: Thu Aug 14, 2008 12:45 am    Post subject: Check all HD volumes for free space (variable threshold) Reply with quote

I must first give credit to jivetolkein and his adaptation of Rob van der Woude's freespace.vbs for inspiring me to do this.
His original solution would parse all volumes on a remote server, and check that they don't fall below a critical value. That was great, but I needed the threshold to be a variable. One thing led to another, and I ended up with this:

This script includes:
  • The obligatory elements of the default AHM VBScript template (i.e. script response constants)
  • Flexible argument parsing, type conversion/checking, error checking & syntax notification
  • Flexible threshold checking - physical and percentage
  • Percentage can be entered as a literal (15%% - you must double the % symbol) - or as a decimal (.15)
  • Defaults for Computer ("." - local) and threshold (20%) if argument(s) not supplied
  • Display of total freespace (in GB) AND percentage free.
    Format (literal threshold provided =freespace(freepercent)
    Format (percentage threshold provided =freepercent(freespace)
Code:
' ===========HDFree.vbs===========
' Purpose:  Query a local or remote computer's hard disk volumes for available disk space.
'           The percentage of free space is compared against a user supplied critical threshold.
'
' Syntax:   CSCRIPT HDFree.VBS {computer_name} {threshold}
'           Where:  {computer_name} =name of a WMI enabled computer (local or remote)
'                           Default ="."    (local computer)
'                   {threshold} =minimum freespace
'                      If entered as an integer physical size is checked (in GB)
'                      If a decimal amount or an integer followed by "%%"
'                         percentage free is checked.
'           Examples:  HDFree.vbs Comp1 20   -->Checks all volumes on Comp1 for 20GB freespace
'                      HDFree.vbs Comp2 10%% -->Checks all volumes on Comp2 for 10% freespace
'                      HDFree.vbs Comp3 .15  -->Checks all volumes on Comp3 for 15% freespace
'           Defaults:  Local Computer (".") and 20%
'
' Output:   [status]:{reply}
'           [status] - Required.   Format "scriptRes:{statusmsg}
'                        (see constants defined below)
'           {reply}  - Optional    (on error this script always supplies one).
'                        May include simple description or system error codes
'
' NOTES:   -This script has been modified to comply with (KS-Soft) Advanced Host Monitor's
'           "shell script" method of monitoring.
'          -Inspired by Glynn Seymours adaptation of Rob van der Woude's freespace.vbs
'             http://www.robvanderwoude.com
' ==========Begin Script==========
Option Explicit

DIM sCompStatus, sType, sResult, sSyntaxDesc
DIM iThreshold

' *** Default Values & constants
iThreshold =.2

const statusAlive       ="scriptRes:Host is alive:"
const statusDead        ="scriptRes:No answer:"
const statusUnknown     ="scriptRes:Unknown:"
const statusUnknownHost ="scriptRes:Unknown host:"
const statusOk          ="scriptRes:Ok:"
const statusBad         ="scriptRes:Bad:"
const statusBadContents ="scriptRes:Bad contents:"

const ShowSyntax ="/?"

' *** Parse the command-line arguments, check syntax, & perform necessary type conversions.
Select Case WScript.Arguments.Count
 Case 0     ' *** No command line arguments
   sCompStatus =ParseArg(".",0)
 Case 1     ' *** Argument1 =computer name
   sCompStatus =ParseArg(Wscript.Arguments(0),0)
 Case 2     ' *** Argument2 =Critical threshold
   sCompStatus =ParseArg(Wscript.Arguments(0),0)
   iThreshold =ParseArg(Wscript.Arguments(1),1)
 Case Else  ' *** Maximum is 2 command line parameters - Show syntax
   sCompStatus =ParseArg(ShowSyntax,99)
End Select

' *** If parsed arguments are 'bad' pass the results to StdOut
If InStr(sCompStatus,"scriptRes:") Then
   WScript.StdOut.Write sCompStatus
ElseIf InStr(iThreshold,"scriptRes:") Then
   WScript.StdOut.Write iThreshold
Else
' *** Otherwise call HDFreeTest Function & pass results to StdOut
   WScript.StdOut.Write HDFreeTest(sCompStatus, iThreshold)
End if
' ===========End Script===========
'
' --------Functions & Subs--------
Function   ParseArg(Arg, ArgNum)
' *** Purpose: Parse command-line arguments & display Syntax rules if necessary

 DIM sReply, sSyntaxDesc

const Syntax ="Syntax:  CSCRIPT HDFree.VBS {computer_name} {threshold}"

sSyntaxDesc = vbCrLf & "Where:  {computer_name} =" & _
   "name of a WMI enabled computer (local or remote)" & vbCrLf  & _
   vbTab & "{threshold} =minimum freespace" & vbCrLf & _
   vbTab & vbTab & "An integer value is interpreted as physical size (in GB)" & vbCrLF & _
   vbTab & vbTab & "A decimal value or an integer followed by '%%'" & vbCrLF & _
   vbTab & vbTab & "  is interpreted as a percentage" & vbCrLF & _
   vbTab & vbTab & "Defaults: Computer:  " & Chr(34) &"." & Chr(34) & _
     " (local computer)" & vbCrLF & _
   vbTab & vbTab & vbTab & "  Threshold: 20%" & vbCrLF & _
   "Inspired by Glynn Seymours adaptation of Rob van der Woude's freespace.vbs" & vbCrLf & _
   vbTab & "http://www.robvanderwoude.com"

 If InStr(Arg, "?") Then ArgNum =99
 Select Case ArgNum
   Case 0     ' *** sComputer Argument
     ParseArg =CStr(Arg)
   Case 1     ' *** iThreshold Argument
     On Error Resume Next
     If IsNumeric(Arg) Then
        ParseArg =CSng(Arg)
     Elseif InStrRev(Arg,"%")<>0 Then ParseArg =CSng(Trim(Left(Arg,InStrRev(Arg,"%")-1))/100)
     Else
        ParseArg =statusUnknown & "Syntax: Argument conversion error: " & Arg
        On Error Goto 0
        Exit Function
     End If
     If ParseArg <.01 or ParseArg >99 Then _
        ParseArg=statusUnknown & "Threshold value out of bounds: " & Arg
     On Error Goto 0
   Case Else      ' *** Display script syntax
     ParseArg =statusUnknown & Syntax ' & sSyntaxDesc
' *** -------------------Remove this--^ if you wish to include Syntax Description
   End Select
End Function
' --------------------------------
Function   HDFreeTest(ArgComp, ArgThold)
' *** Purpose: Query Windows servers (WMI) for available Hard Disk free space
 DIM sStatus, sReply
 DIM iFree
 DIM oWMIService, oItem, aItems

 const GB=1073741824

 On Error Resume Next
 Set oWMIService =Getobject("winmgmts://" & ArgComp & "/root/cimv2")
 If Err.Number Then
    HDFreeTest =statusUnknownHost & "Server not found or not responding: Error # " & _
      CStr(Err.Number) & " " & Err.Description
    Exit Function
 End If
 Set aItems =oWMIService.ExecQuery("Select * from Win32_LogicalDisk where DriveType =3",,48)
 If Err.Number Then
    HDFreeTest =statusUnknown & "Error # " & CStr(Err.Number) & " " & Err.Description
    Exit Function
 End If
 On Error GoTo 0
 sStatus=statusOK
 For Each oItem in aItems
   If sReply<>"" Then sReply =sReply & ", "
   'Calculate volume's percentage free space
   iFree =Int(.5+(100 * oItem.FreeSpace / oItem.Size))
' *** If ANY volume falls below the critical threshold, set the AHM status to BAD
' ***    then append this volumes free space and free space percentage to the return message
   If iThreshold <1 Then
      If iFree<iThreshold*100 Then sStatus =statusBad
      sReply =sReply & oItem.Name & iFree & "%" & "(" & Round(oItem.FreeSpace / GB,2) & ")"
   Else
      If Round(oItem.Freespace / GB,2)<iThreshold Then sStatus ="statusBad"
      sReply =sReply & oItem.Name & Round(oItem.FreeSpace / GB,2) & "(" &iFree & "%" & ")"
   End If
 Next
 If sReply =Empty Then
    HDFreeTest =statusUnknown & "Local Hard Disk(s) not found"
 Else
    HDFREETest =sStatus & sReply
 End If
End Function


Comments & suggestions are encouraged
Back to top
View user's profile Send private message Send e-mail
Paul_NHS



Joined: 25 Feb 2009
Posts: 59

PostPosted: Wed Feb 25, 2009 6:42 am    Post subject: Reply with quote

GreyHat64, I liked your script so much I thought we should have a more flexible version.
I have added the ability to supply drive specific sizes on the command line.

Usage: CSCRIPT HDFree.VBS {computer_name} {[drive:]threshold [[drive:]threshold] [.....]}

e.g. CSCRIPT HDFree.VBS Mycomp C:2 D:20%% 10%%
The final free space parameter sets the default for unspecified drives.

p.s. It is worth mentioning the mechanism for running this script.
  1. Select the "Shell Script" test method.
  2. Click on the "Script Manager" icon.
  3. Select "New" for a new script.
  4. Name the script appropriately.
  5. Check the "Start Command" is set to: cmd /c cscript /B /E:VBScript %Script% %Params%
  6. Copy and paste the VBS file into the script box.
  7. Add a hint, e.g. {computer_name} {[drive:]threshold [[drive:]threshold] [.....]}
Now you can select the script from the HostMonitor dropdown and specify the parameters.
Note: You also don't require 2 percent signs in the parameters, one works nicely. e.g. Mycomp C:5% D:10% 20%

If you use this "Shell Script" method and you run a lot of these tests, check the potential problem discussed in the post where the code is shown below.

cheers, Paul

Code:
Please see lower down on this page for the latest code.


Last edited by Paul_NHS on Wed Mar 11, 2009 8:04 am; edited 4 times in total
Back to top
View user's profile Send private message
greyhat64



Joined: 14 Mar 2008
Posts: 245
Location: USA

PostPosted: Wed Feb 25, 2009 8:49 am    Post subject: Reply with quote

Paul_HNS,
I just have one thing to say, NICE!!!
I was working on a similar modification, based on Kapz's request here.
Per his request v7.90 BETA now has a %AlertThresholdValue% variable that can be used for built-in tests like Drive Space, so I think I'm going to let it go.

Your thoughts. . .

I do have a couple of other mods I was working on, mostly to clean up the code. I may even 'trim the fat' and get rid of the verbose syntax description - useful if your running it from the command line, not any help for AHM shell script.
I'll use your new 'base' and post it soon.
Back to top
View user's profile Send private message Send e-mail
Paul_NHS



Joined: 25 Feb 2009
Posts: 59

PostPosted: Thu Feb 26, 2009 3:35 am    Post subject: Reply with quote

I agree, this does most of the things Kapz wants, although I was thinking the response could be tailored to make it easier to use in calculations. The trouble with a tailored response is what information do you return? It is essential to provide the drive name and the size/%, but this means you can't calculate %lastreply% - %reply%.

cheers, Paul
Back to top
View user's profile Send private message
greyhat64



Joined: 14 Mar 2008
Posts: 245
Location: USA

PostPosted: Thu Feb 26, 2009 12:25 pm    Post subject: Reply with quote

Your observation/question is exactly in line with mine, but I believe it's addressable. First, to summarize what we have to date:
  • If no arguments: Process all volumes on local computer with the '.2' default threshold. DONE
  • If computer name supplied: Process all volumes on specified computer with the '.2' default threshold. DONE
  • If a computer and threshold are supplied: Process all volumes on specified computer with the supplied threshold. DONE
  • If a computer and a string of volume:thresholds are supplied along with a supplied other threshold: Process all specified volume:thresholds pairs on the specified computer and process all other voumes with the supplied other threshold. DONE
In order to address Kapz's needs:
  • If a computer and one volume is supplied (no supplied other threshold): Process specified volume on specified computer with the default threshold. {Reply=status:rawfreespace}
  • If a computer and one volume:threshold is supplied (no supplied other threshold): Process only the specified volume on the specified computer with the specified threshold. {Reply=status:rawfreespace}
    - Only the raw value is returned as a reply. That can be used in "Use Warning Status" processing or optional Alert Profile expressions.
    - It's then up to the user to include the additional relavent info in their Test Name or Description fields for sorting purposes.
    - If the user wants to process multiple volumes on the same computer this way then define multiple tests.
    - The question at this point is, what does this script do that v7.90 Beta's[Drive Space] test doesn't do? Fixed & percentage thresholds. But you're still working with rawfreespace for optional processing, so is there value in this? Maybe we leave this to AHM
Additionally, and a possible value add:
  • If a computer and a string of volume:thresholds are supplied (no supplied other threshold): Process only the specified volume:thresholds. {Standard reply}
    - For instance, C: and D: are my critical volumes. Maybe I don't care about E:
Also, for ease of parsing it might make sense for the second argument to be the optionally supplied 'other threshold'. Then all subsequent arguments are volume:[threshold].
- (If ':' in Arg2 then begin processing volume:threshold pairs.)


Your thoughts. . .
xxxxxI'm busy with some other internal projects right now, but will work on this as time permits. Ya wanta race!
xxxxx(You can opt to email me using the supplied link if you want to continue this offline)
Back to top
View user's profile Send private message Send e-mail
Paul_NHS



Joined: 25 Feb 2009
Posts: 59

PostPosted: Fri Feb 27, 2009 3:08 am    Post subject: Reply with quote

Quote:
If a computer and a string of volume:thresholds are supplied along with a supplied other threshold: Process all specified volume:thresholds pairs on the specified computer and process all other voumes with the supplied other threshold. DONE
I wanted it to behave as it did originally, except to modify the behaviour where a specific drive/threshold is supplied. Where a drive/threshold is not supplied, the default test is used.

Quote:
In order to address Kapz's needs:
If a computer and one volume is supplied (no supplied other threshold): Process specified volume on specified computer with the default threshold. {Reply=status:rawfreespace}
This can be dealt with using an additional modifier (/x) to tell the test to eXclusively test only the supplied drive. Using this modifier would cause the test to return only the value (% or GB) to allow testing with %status%.

Quote:
Also, for ease of parsing it might make sense for the second argument to be the optionally supplied 'other threshold'. Then all subsequent arguments are volume:[threshold].
- (If ':' in Arg2 then begin processing volume:threshold pairs.)
This is how it tests for drive:threshold parameters. It seemed the most sensible test as any other supplied value is either free space threshold for all drives, or an error.

Quote:
Ya wanta race!
Too easy! I'm happy to make these changes once we agree on them.

cheers, Paul
Back to top
View user's profile Send private message
greyhat64



Joined: 14 Mar 2008
Posts: 245
Location: USA

PostPosted: Fri Feb 27, 2009 3:57 am    Post subject: Reply with quote

Paul,
It's not in my nature, but I'll try to be brief.
First, I'll state again, you did a great job with your initial modifications. What you did was introduce the volume as a discreet argument.
In my mind, contextually, once you begin providing volumes or volume:threshold pairs your are moving away from the original 'process all volumes' model. But what you did was provide a way around that by providing an additional 'other' threshold.

Why not use that as the trigger. If the 'other' threshold is undefined then ignore nonspecified volumes. At that point no additional parameters (/x) are necessary. If the 'other' threshold is '.2' then we've simply matched the default.

But I'm so impressed with what you've done so far, you can put it together the way you see fit. Go for it!
-Joel
Back to top
View user's profile Send private message Send e-mail
Paul_NHS



Joined: 25 Feb 2009
Posts: 59

PostPosted: Fri Feb 27, 2009 4:21 am    Post subject: Reply with quote

Joel,

I like your idea but I see a potential problem. If you add an additional drive to a server but don't modify the test, the test would ignore the new drive. I would rather have "test everything" as the default and add exceptions, than forget to add drives and lose information.

I will go with my "/x" idea, which I feel is more in keeping with the "add exceptions" nature of the test.

cheers, Paul
Back to top
View user's profile Send private message
greyhat64



Joined: 14 Mar 2008
Posts: 245
Location: USA

PostPosted: Fri Feb 27, 2009 10:30 am    Post subject: Reply with quote

Paul,
You make a good point and I'll make a final plea for my case, but I think we have two very different perspectives.
  • You say include an additional '/x' parameter if you want to exclusively measure volume(s).
  • I say that once you have specified volumes or, especially, volume:threshold pairs the inclusion or ommission of the 'other' threshold should dictate what happens to all other volumes.
  • The user has already thought this through. The intentional specification of volume or volume:threshold pairs and the
    omission of the 'other' threshold implies that they don't care about volumes other than those specified - even newly added ones.
  • So why have the '/x' argument when the presense or absense of the 'other' threshold can accomplish the same thing?
  • What I could see is an additional '/r' parameter to specify 'raw' freespace as a reply.
    - Only available if one volume specified, ignored otherwise.
    - Multiple volumes could be allowed, returning only the value of the first failed volume, and a blank or "OK" value otherwise. What 'dya think?
  • To your point regarding loosing information, nothing says a user couldn't have a 'general' test measuring all volumes for a default or user specified threshold and additional tests measuring targeted volumes at different parameters. You might even set the additional tests as dependants of the first, only running if the first threshold has been crossed.

  • I'm not really going to go this far, but having seen your current modifications you could make the case that a specified 'default' threshold should be a required argument and eliminate the 'hard coded' threshold of ".2".
  • I've never been a fan of hard coded values other than constants, but I included localcomputer (".") and defaulttheshold (".2") in the original so the 'noob' could just plug in the script and get results.
Post your new code when you get a chance. I can't wait to see it.
BTW - Are you a member at Tek-Tips? A great forum site for everything IT, including some good VBScript/PowerShell code - highly recommended.
Back to top
View user's profile Send private message Send e-mail
Paul_NHS



Joined: 25 Feb 2009
Posts: 59

PostPosted: Fri Feb 27, 2009 11:03 am    Post subject: Reply with quote

Joel,

You have won me over to your view - ours are essentially the same, once you add test parameters you are changing the nature of the test, therefore the response should change.

Given that this test will be "tested" once the parameters have been changed, it will be obvious if the change does not produce the desired result.

I don't fancy a raw switch, this is automatically determined by the paramters anyway.

I will leave the default settings as a starting point for newbies.

cheers, Paul
Back to top
View user's profile Send private message
greyhat64



Joined: 14 Mar 2008
Posts: 245
Location: USA

PostPosted: Fri Feb 27, 2009 11:49 am    Post subject: Reply with quote

I can't wait to see it!
Suggestion: I was going to change this part of the code (from the original):
Code:
' *** If parsed arguments are 'bad' pass the results to StdOut
If InStr(sCompStatus,"scriptRes:") Then
   WScript.StdOut.Write sCompStatus
ElseIf InStr(iThreshold,"scriptRes:") Then
   WScript.StdOut.Write iThreshold
Else
' *** Otherwise call HDFreeTest Function & pass results to StdOut
   WScript.StdOut.Write HDFreeTest(sCompStatus, aThreshold)
End if
Eliminating the If statement here, leaving the WScript.StdOut.Write HDFreeTest(sCompStatus, aThreshold) statement to stand alone.

Then insert into the ParseArg function, just above the 'End Function' statement, the following:
Code:
' *** If parsed argument is 'bad' pass the results to StdOut and Quit
 If InStr(ParseArg,"scriptRes:") Then
    WScript.StdOut.Write ParseArg
    WScript.Quit
 End If
I know it's a Quit inside a called Function (sometimes frowned upon), but it's a bit 'cleaner' I think. One test, no ElseIf's, and it exits with the first problem argument.
Back to top
View user's profile Send private message Send e-mail
Paul_NHS



Joined: 25 Feb 2009
Posts: 59

PostPosted: Mon Mar 02, 2009 3:51 am    Post subject: Reply with quote

Here is the definitive version - until we think of more things to add The test will only be performed on specified drives unless a default threshold is supplied.
I have also added extra syntax checking - found a bug which made me look a bit closer.

One thing I found in use on our system was that the script will time out if you fire a whole lot off at once - the "shell script" method is synchronous and can't handle more than about 5 tests at once. The solution is to place the disk space tests in a common folder and set "non-simultaneous test execution" under Special in the folder properties.

[Edit] Latest code as of 15:25, 3/3/2009 - Saves reams of code
[Edit] Latest code as of 09:56, 4/3/2009
[Edit] Latest code as of 10:13, 8/3/2009
[Edit] Latest code as of 10:13, 8/3/2009 - forgot to quote single replies, test type 3.
[Edit] Latest code as of 10:13, 19/10/2010 - Major change to accomodate drive mount points.
[Edit] Latest code as of 20/10/2010 - Fixed volume names returned as \\?\ (Win7 boot volumes), line 210.

Code:
' ===========HDFree.vbs===========
' Purpose:  Query a local or remote computer's hard disk volumes for available disk space.
'           The percentage of free space is compared against a user supplied critical threshold.
'
' Syntax:   CSCRIPT HDFree.VBS {computer_name} {[drive:]threshold [[drive:]threshold...]}
'           Where:  {computer_name} =name of a WMI enabled computer (local or remote)
'                           Default ="."    (local computer)
'                   {threshold} =minimum free space
'                      If entered as an integer physical size is checked (in GB)
'                      If a decimal amount or an integer followed by "%"
'                         percentage free is checked.
'           Examples:  HDFree.vbs Comp1 20   -->Checks all volumes on Comp1 for 20GB free space.
'                      HDFree.vbs Comp2 10% -->Checks all volumes on Comp2 for 10% free space.
'                      HDFree.vbs Comp3 .15  -->Checks all volumes on Comp3 for 15% free space.
'                      HDFree.vbs Comp3 D:.15  -->Checks D: on Comp3 for 15% free space exclusively.
'                                                  No other drives will be checked.
'                                                 Returned status will be the D: drive free space
'                                                  figure in %.
'                      HDFree.vbs Comp3 D:5  -->Checks D: on Comp3 for 5GB free space exclusively
'                                                No other drives will be checked.
'                                               Returned status will be the D: drive free space
'                                                figure in GB.
'                      HDFree.vbs Comp3 D:.15 20% -->Checks D: on Comp3 for 15% free space
'                                                     and all other drives for 20% free space.
'                                                    Returned status will be the free space figures
'                                                     of all drives.
'                      HDFree.vbs Comp3 C:.5 D:20  -->Checks C: for 5%, D: for 20GB free space.
'                                                      No other drives are checked.
'                                                     Returned status will be the free space
'                                                      figures of both drives.
'                      HDFree.vbs Comp3 C:.5 D:20 35%  -->Checks C: for 5%, D: for 20GB and all other
'                                                           drives for 35% free space.
'                                                         Returned status will be the free space
'                                                          figures of all drives.
'           Defaults:  Local Computer (".") and 20%
'
' Output:   [status]:{reply}
'           [status] - Required.   Format "scriptRes:{statusmsg}
'                        (see constants defined below)
'           {reply}  - Optional    (on error this script always supplies one).
'                        May include simple description or system error codes
'
' NOTES:   -This script has been modified to comply with (KS-Soft) Advanced Host Monitor's
'           "shell script" method of monitoring.
'          -Inspired by Glynn Seymours adaptation of Rob van der Woude's freespace.vbs
'             http://www.robvanderwoude.com
'
' Modified Date: yyyy/mm/dd
'                2010/10/19
' ==========Begin Script==========
Option Explicit

DIM sCompStatus', sType, sResult, sSyntaxDesc
DIM iThreshold, iDfltThold, iCount, iTestType, iDrvTest, iTholdTest
DIM aThreshold()

' *** Default Values & constants
iDfltThold =.2

const statusAlive     ="scriptRes:Host is alive:"
const statusDead    ="scriptRes:No answer:"
const statusUnknown   ="scriptRes:Unknown:"
const statusUnknownHost ="scriptRes:Unknown host:"
const statusOk      ="scriptRes:Ok:"
const statusBad     ="scriptRes:Bad:"
const statusBadContents ="scriptRes:Bad contents:"

const ShowSyntax ="/?"

iTholdTest = 0
iDrvTest = 0
' *** Parse the command-line arguments, check syntax, & perform necessary type conversions.
Select Case WScript.Arguments.Count
  Case 0    ' *** No command line arguments
    sCompStatus = ParseArg(".",0)
  Case 1    ' *** Argument1 =computer name
    sCompStatus = ParseArg(Wscript.Arguments(0),0)
  Case Else  ' *** Parse all remaining arguments
    sCompStatus = ParseArg(Wscript.Arguments(0),0)
    For iCount = 0 to WScript.Arguments.Count-2
      iThreshold = ParseArg(Wscript.Arguments(iCount+1),1)
      If InStr(iThreshold, ":") = 2 then
        iDrvTest = iDrvTest + 1 ' How many drive test parameters
      else
        iTholdTest = 1 ' Default threshold parameter supplied
      End If
      ' *** Add all arguments to array
      redim preserve aThreshold(iCount)
      aThreshold(iCount) = iThreshold
    Next
End Select

' *** Determine test type
If iDrvTest = 0 and iTholdTest = 0 then iTestType = 1 ' Test all drives with default threshold
If iDrvTest = 0 and iTholdTest = 1 then iTestType = 2 ' Test all drives with specified threshold
If iDrvTest = 1 and iTholdTest = 0 then iTestType = 3 ' Test only one drive:threshold and return the free space value
If iDrvTest = 1 and iTholdTest = 1 then iTestType = 4 ' Test specified drive:threshold and all other drives with specified threshold
If iDrvTest > 1 and iTholdTest = 0 then iTestType = 5 ' Test only specified drives and return all results
If iDrvTest > 1 and iTholdTest = 1 then iTestType = 4 ' Test specified drive:threshold and all other drives with specified threshold

WScript.StdOut.Write HDFreeTest(sCompStatus, aThreshold)

' ===========End Script=========== '
' --------Functions & Subs--------
Function  ParseArg(Arg, ArgNum)
' *** Purpose: Parse command-line arguments
  Dim ParseOK : ParseOK = True
  const Syntax ="Syntax: CSCRIPT HDFree.VBS {computer_name} {[drive:]threshold [[drive:]threshold] [...]}"

  If InStr(Arg, "?") Then ArgNum =99
  Select Case ArgNum
    Case 0  ' *** sComputer Argument
      ParseArg = CStr(Arg)
    Case 1  ' *** Threshold Argument
      On Error Resume Next
      If InStr(Arg, ":") = 2 Then
        ParseArg = Left(Arg, 2)
        Arg = mid(Arg, 3)
      ElseIf iTholdTest = 1 Then
        ParseArg = statusUnknown & "Syntax: Only one default threshold value allowed: " & Arg
        ParseOK = False
      End If
      If ParseOK Then
        If IsNumeric(Arg) Then
          ParseArg = ParseArg & Arg
        ElseIf InStrRev(Arg,"%")<>0 Then
          Arg = Trim(Left(Arg,InStrRev(Arg,"%")-1))/100
          If Arg > .99 Then
            ParseArg = statusUnknown & "Threshold value out of bounds: " & Arg * 100 & "%"
            ParseOK = False
          ElseIf ParseOK Then
            ParseArg = ParseArg & Arg
          End If
        Else
          ParseArg = statusUnknown & "Syntax: Argument conversion error: " & ParseArg & Arg
          ParseOK = False
        End If
      End If
      If (Arg <.01 or Arg >99) and ParseOK Then
        ParseArg = statusUnknown & "Threshold value out of bounds: " & ParseArg
        ParseOK = False
      End If
    Case Else  ' *** Display script syntax
      ParseArg = statusUnknown & Syntax
  End Select
  On Error Goto 0
  If Not ParseOK Then
    WScript.StdOut.Write ParseArg
    Wscript.Quit
  End If
End Function
' --------------------------------
Function  HDFreeTest(ArgComp, ArgThold)
' *** Purpose: Query Windows servers (WMI) For available Hard Disk free space
  DIM sStatus, sReply, sDrvName
  DIM iFree, iThold, iTestThold, iDefinedThold, iSize
  DIM oWMIService, oItem, aItems
  DIM bLogicalDiskQuery

  const GB=1073741824
 
  bLogicalDiskQuery = False

  ' *** Set default threshold If supplied
  For each iThold in ArgThold
    If instr(iThold, ":") <> 2 then
      iDefinedThold = CSng(iThold)
    End If
  Next

  On Error Resume Next
  Set oWMIService = Getobject("winmgmts://" & ArgComp & "/root/cimv2")
  If Err.Number Then
    HDFreeTest = statusUnknownHost & "Server not found or not responding: Error # " & _
      CStr(Err.Number) & " " & Err.Description
    Exit Function
  End If
  Set aItems = oWMIService.ExecQuery("Select * from Win32_Volume where DriveType =3",,48)
  If Err.Number Then
    HDFreeTest = statusUnknown & "Error # " & CStr(Err.Number) & " " & Err.Description
    Exit Function
  End If
  For Each oItem in aItems 'Ugly test for returned items - XP doesn't support Win32_Volume
     If Err.Number Then
      Err.Clear
      bLogicalDiskQuery = True
      Exit For
     End If
   Exit For
  Next
  If bLogicalDiskQuery Then
   Set aItems = oWMIService.ExecQuery("Select * from Win32_LogicalDisk where DriveType =3",,48)
  else
   Set aItems = oWMIService.ExecQuery("Select * from Win32_Volume where DriveType =3",,48)
  End If
   If Err.Number Then
     HDFreeTest = statusUnknown & "Error # " & CStr(Err.Number) & " " & Err.Description
     Exit Function
   End If
  On Error GoTo 0
  sStatus = statusOK
  For Each oItem in aItems
    If bLogicalDiskQuery Then
      iSize = oItem.Size
      sDrvName = oItem.Name
   Else 'Win32_Volume returns drive name with a trailing backspace and mounted volumes as drive:\path
      iSize = oItem.Capacity
      sDrvName = oItem.Name
      If Len(sDrvName) > 3 Then 'Mount point
         sDrvName = Replace(sDrvName, "\\?\", "")
         sDrvName = Replace(Replace(sDrvName, ":\", "-"), "\", ":")
      Else
         sDrvName = Replace(sDrvName, ":\", ":")
      End If
   End If
    Select Case iTestType
      Case 1 ' Test all drives with default threshold
        iTestThold = iDfltThold
        If sReply <> "" Then sReply = sReply & ", "
          iFree =Int(.5+(100 * oItem.freespace / iSize))
        If iFree<iTestThold*100 Then sStatus = statusBad
      sReply = sReply & sDrvName & iFree & "%" & "(" & Round(oItem.freespace / GB,2) & ")"         
      Case 2 ' Test all drives with specified threshold
        iTestThold = iDefinedThold
        If sReply <> "" Then sReply = sReply & ", "
        iFree =Int(.5+(100 * oItem.freespace / iSize))
        If iTestThold <1 Then
          If iFree<iTestThold*100 Then sStatus = statusBad
          sReply = sReply & sDrvName & iFree & "%" & "(" & Round(oItem.freespace / GB,2) & ")"
        Else
          If Round(oItem.freespace / GB,2)<iTestThold Then sStatus = statusBad
          sReply = sReply & sDrvName & Round(oItem.freespace / GB,2) & "(" &iFree & "%" & ")"
        End If
      Case 3 ' Test only one drive:threshold and return the free space value
        For each iThold in ArgThold
          If Ucase(left(iThold, 2)) = Ucase(sDrvName) then
            iTestThold = CSng(mid(iThold, 3))
            iFree =Int(.5+(100 * oItem.freespace / iSize))
            If iTestThold < 1 Then
              If iFree<iTestThold*100 Then sStatus = statusBad
              sReply = """" & sReply & iFree & " %"""
            Else
              If Round(oItem.freespace / GB,2)<iTestThold Then sStatus = statusBad
              sReply = """" & sReply & Round(oItem.freespace / GB,2) & " GB"""
            End If
          End If
        Next
      Case 4 ' Test specified drive:threshold and all other drives with specified threshold
        If sReply <> "" Then sReply = sReply & ", "
        iTestThold = iDefinedThold
        For each iThold in ArgThold
          If Ucase(left(iThold, 2)) = Ucase(sDrvName) then
            iTestThold = CSng(mid(iThold, 3))
          End If
        Next
        iFree =Int(.5+(100 * oItem.freespace / iSize))
        If iTestThold <1 Then
          If iFree<iTestThold*100 Then sStatus = statusBad
          sReply = sReply & sDrvName & iFree & "%" & "(" & Round(oItem.freespace / GB,2) & ")"
        Else
          If Round(oItem.freespace / GB,2)<iTestThold Then sStatus = statusBad
          sReply = sReply & sDrvName & Round(oItem.freespace / GB,2) & "(" &iFree & "%" & ")"
        End If
      Case 5 ' Test only specified drives and return all results
        For each iThold in ArgThold
          If Ucase(left(iThold, 2)) = Ucase(sDrvName) then
            If sReply <> "" Then sReply = sReply & ", "
            iTestThold = CSng(mid(iThold, 3))
            iFree =Int(.5+(100 * oItem.freespace / iSize))
            If iTestThold < 1 Then
              If iFree<iTestThold*100 Then sStatus = statusBad
              sReply = sReply & sDrvName & iFree & "%" & "(" & Round(oItem.freespace / GB,2) & ")"
            Else
              If Round(oItem.freespace / GB,2)<iTestThold Then sStatus = statusBad
              sReply = sReply & sDrvName & Round(oItem.freespace / GB,2) & "(" &iFree & "%" & ")"
            End If
          End If
        Next
    End Select
  Next
  If sReply = Empty Then
    HDFreeTest = statusUnknown & "Local Hard Disk(s) not found"
  Else
    HDFREETest = sStatus & sReply
  End If
End Function

cheers, Paul


Last edited by Paul_NHS on Wed Oct 20, 2010 2:19 am; edited 7 times in total
Back to top
View user's profile Send private message
greyhat64



Joined: 14 Mar 2008
Posts: 245
Location: USA

PostPosted: Mon Mar 02, 2009 4:24 pm    Post subject: Reply with quote

Paul,
Good work! Two things:
1. I like what you've done, but what did you think of my idea to 'bury' the passing of 'Bad Argument' results in the ParseArg function? (see previous response)
2. Good find on the "shell script" handles issue. I think I read somewhere that the actual limit is 6, but it probably starts choking before then.

(Not your fault, but. . .) I hate the solution!
I've set up my tree/folders to match our distributed reporting structure, and I have folder level variables set for notifying the tech(s) responsible for that server/server group. This way one alert profile takes care of it all. If I move all disk space checks into one folder I'm back to square one with that.
Why should I have to restructure my test environment to accommodate a known limitation?
NOTE: If this 'non-simultaneous' option were inheritable I could live with it because it wouldn't force me to change my folder structure.

Other possibilities:
1. Use Active Agents on all the servers. If you prefer the server to run most of the testlist you could limit the agent to only running shell scripts.
- In my environment, seldom will any individual server have more than five shell scripts.
- Some people (myself included) prefer agentless operations where possible - but it's an option.

(Thinking off the top of my head)
2. Use a 'master' shell script (???). Keep a count of running shell scripts. Similar to:
Code:
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_Process WHERE Name='cscript.exe'")
On second thought, it probably wouldn't work.
- While enabling/disabling tests based on colItems.Count, or executing a wait cycle could prevent additional tests from being launched, it wouldn't prevent simultaneous starts.
- I feel like there is potential here I can't put my finger on it.
3. Go 'Old School'. Use prime numbers for your schedules
- Test every 7min/2sec, 7min/23sec, 11min/5sec, 11min/17sec, . . .). Set each test individually, or create small 'test groups' with the same schedule to minimize overlap.
- This is ugly and would take a bit of planning and manual manipulation.
Back to top
View user's profile Send private message Send e-mail
greyhat64



Joined: 14 Mar 2008
Posts: 245
Location: USA

PostPosted: Mon Mar 02, 2009 4:28 pm    Post subject: Reply with quote

MY OPINION:
Knowing the limitations of this method, AHM should manage this by default without resorting to the "non-simultaneous test execution" trickery you describe.

- The "non-simultaneous test execution" option should be employed to manage other types of dependecies/deficiencies that do NOT have an easily identifiable limitation.
- The AHM application/service could actively keep a count of all running shell script tests and throttle a pending test if the count of actively running scripts reaches the threshold.

- Making this folder level setting inheritable would be a mistake (all tests in the branch would become non-simultaneous) unless you could 'tag' tests as being a member of a non-simultaneous execution group, accomplishing what you have done by putting them all in a separate folder.

Your thoughts. . .
If you agree I'll post a "Wish List" item & tag this thread.
Back to top
View user's profile Send private message Send e-mail
KS-Soft



Joined: 03 Apr 2002
Posts: 11934
Location: USA

PostPosted: Mon Mar 02, 2009 4:47 pm    Post subject: Reply with quote

Normally HostMonitor may perform many Shell Script tests at the same time however this may depend on external programs limitations used by the test

Regards
Alex
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    KS-Soft Forum Index -> Library All times are GMT - 6 Hours
Goto page 1, 2, 3, 4  Next
Page 1 of 4

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group

KS-Soft Forum Index