Previous Section Table of Contents Next Section

What Are Functions?

Functions are a way of performing a task and getting something back. For example, VBScript has a function named Date(), which simply looks up and provides the current date according to your computer's internal clock. Functions are used to perform special calculations, retrieve information, look up information, convert data types, manipulate data, and much more.

Input Parameters

Functions may include one or more input parameters, which give the function something to work with and usually are a major part of the function's output. Not all functions need input, however. For example, the Date() function doesn't need any input parameters to function; it knows how to look up the date without any help from you.

Other functions may require multiple input parameters. For example, the InStr() function is used to locate a particular character within a string. Here's how it works.


Dim sVar

Dim iResult

sVar = "Hello!"

iResult = InStr(1, sVar, "l")

After running this short script, iResult will contain the value 3, meaning the Instr() function located the letter l at the third position within the variable sVar. InStr() requires three input parameters:

  1. The character position where the search should start

  2. The string in which to search

  3. The string to search for

NOTE

Of course, I haven't necessarily memorized InStr()'s input parameters. I looked them up in the VBScript documentation. After you use a function a few times in scripts, you'll remember its parameters without looking them up, but I don't use InStr() very often so I always refer to the documentation to see in which order the parameters should be.


Now that you know what a function looks like, refer to this section of the DisableUsers sample script and see if you can spot the functions (I've boldfaced them to make it easy).


' get last login date

  sTheDate = UserObj.get("LastLogin")

  sTheDate = Left(sTheDate,8)

  sTheDate = CDate(sTheDate)



  ' find difference in week between then and now

  iDiff = DateDiff("ww", sTheDate, Now)



  ' if 6 weeks or more then disable the account

  If iDiff >= 6 Then

   iFlags = UserObj.Get("UserFlags")

  End If



  ' if the account is not already disabled...

  If (iFlags And UF_ACCOUNTDISABLE) = 0 Then



   ' disable account

   oUserObj.Put "UserFlags", iFlags Or UF_ACCOUNTDISABLE

   oUserObj.SetInfo



   ' Get user name and write a log entry

   sName = oUserObj.Name

   sResult = Log(sName,iDiff)



  End If

NOTE

I try to keep my scripts nice and pretty by capitalizing function names, but VBScript couldn't care less. DateDiff() and datediff() or even DaTediFf() are all the same as far as VBScript is concerned.


Output Values

All functions return some kind of value to your script. The VBScript documentation can tell you what type of data that is (numeric, date, string, and so on), but you need to decide what to do with it. The most common action is to assign the result to a variable.


' get last login date

  sTheDate = UserObj.get("LastLogin")

  sTheDate = Left(sTheDate,8)

  sTheDate = CDate(sTheDate)

In this case, variable sTheDate is being used to hold the results of a function. In fact, the function is performing an operation with the old value of sTheDate and returning a new value to be stored into sTheDate, overwriting the old value.

The results of a function can also be fed as the input parameter to another function. For example, consider the following few lines of code.


Dim sVar1

sVar1 = "Transcription"

MsgBox Left(Right(sVar1, 9), 6)

The result will be a message box containing "script" and an OK button. Here's what's happening.

  • VBScript executes functions from the inside out. In other words, it looks for the most deeply nested function and starts with that one, and then works its way out.

  • The Right() function is executed first and returns the rightmost 9 characters of whatever is in sVar1. The result, of course, is "scription".

  • The Left() function then takes the leftmost six characters of whatever the Right() function returned, resulting in "script".

  • The Left() function's results are passed to the MsgBox statement, which displays the results.

Nesting functions can make your script difficult to read and troubleshoot, although VBScript itself doesn't mind. You can make your scripts easier to read by breaking each function out into its own line of code.


Dim sVar1

sVar1 = "Transcription"

sVar1 = Right(sVar1, 9)

sVar1 = Left(sVar1, 6)

MsgBox sVar1

This revised snippet takes a bit more reading, but it's clearer what the script is doing.

Intrinsic versus Custom Functions

So far, the functions I've introduced have been intrinsic functions, which means they're built into VBScript. You can look them all up in the VBScript documentation to see how they work. However, you can build your own custom functions. For example, suppose you want a function that writes entries to a log file. That would be a useful function to have, and you could probably use it in any number of different scripts. In fact, the DisableUsers sample script contains a custom function that writes log file entries.


Function Log(oUser,sDate)



 ' Constant for Log file path

 Const sLogFile = "C:\UserMgr1.txt"



 ' Create a FileSystemObject

 Dim oFS

 Set oFS = CreateObject("Scripting.FileSystemObject")



 ' Create a TextStream object

 Dim oTextStream

 Set oTextStream = objFS.OpenTextFile(sLogFile, 8, True)



 ' Write log entry

 oTextStream.WriteLine("Account:" & vbTab & oUser & vbTab & _

 "Inactive  for:" & vbTab & strdate & vbatb & "Weeks" & _

 vbtab & "Disabled on:" & vbTab & Date & vbTab & "at:" & _

 vbTab & Time)



 ' Close file

 oTextStream.Close



 ' Release objects

 Set oFS = Nothing

 Set oTextStream = Nothing



 Log = True



End Function

This function is defined by the Function statement, and all of the code within the function falls between Function and End Function. The Function statement has several important components:

  • The Function statement itself

  • The name of the function, in this case Log

  • The function's input parameters, oUser and sDate

This function is called from within the main script just as if it were an intrinsic function.


' Get user name and write a log entry

   sName = oUserObj.Name

   sResult = Log(sName,iDiff)

The last line of code in the function is Log = True. This is a special line of code, because it uses the function's name on the left side of the assignment operator. This line of code tells VBScript that the function's return value will be True. In a custom function, you use this technique to return a value to whatever called your function-assign the return value to the function's name. You must generally do so in the last line of code before End Function.

However, this is really a bad example of how to write a custom function. It works perfectly, but it's doing a few things that you don't normally want a function to do.

  • The function doesn't return a useful value. You can tell because the calling script doesn't do anything with the value; it just stores it in a variable. If the return value isn't useful, why have it at all? This function could have been written as a subroutine, which doesn't return a value. I'll be covering subroutines in the next section.

  • The function is relying on data that was defined outside of itself. Specifically, the sLogFile variable was defined in the main part of the script, not the function. Generally, functions should be entirely self-contained, making them easier to transport from one script to another without modifications. Listing 5.2 shows a modified script that passes the log filename as an input parameter, because input parameters provide a legitimate way of getting information into a function.

Listing 5.2. DisableUser2.vbs. This script has been modified to have a better-written function.

Dim sTheDate

Dim oUserObj

Dim oObject

Dim oGroupObj

Dim iFlags

Dim iDiff

Dim sResult

Dim sName

Const UF_ACCOUNTDISABLE = &H0002



' Point to Object containing users to check

Set oGroupObj = GetObject("WinNT://MYDOMAINCONTROLLER/Users")



On Error Resume Next

For Each oObject in oGroupObj.Members



 ' Find all User Objects Within Domain Users group

 ' (ignore machine accounts)

 If (oObject.Class = "User") And _

  (InStr(oObject.Name, "$") = 0) then Set oUserObj = _

  GetObject(oObject.ADsPath)

  ' get last login date

  sTheDate = UserObj.get("LastLogin")

  sTheDate = Left(sTheDate,8)

  sTheDate = CDate(sTheDate)



  ' find difference in week between then and now

  iDiff = DateDiff("ww", sTheDate, Now)



  ' if 6 weeks or more then disable the account

  If iDiff >= 6 Then

   iFlags = UserObj.Get("UserFlags")

  End If



  ' if the account is not already disabled...

  If (iFlags And UF_ACCOUNTDISABLE) = 0 Then



   ' disable account

   oUserObj.Put "UserFlags", iFlags Or UF_ACCOUNTDISABLE

   oUserObj.SetInfo



   ' Get user name and write a log entry

   sName = oUserObj.Name

   sResult = Log(sName,iDiff,sLogFile)



  End If



 End If

Next



' Release object

Set oGroupObj = Nothing



Function Log(oUser,sDate,sLog)



 ' Constant for Log file path

 Const sLogFile = "C:\UserMgr1.txt"



 ' Create a FileSystemObject

 Dim oFS

 Set oFS = CreateObject("Scripting.FileSystemObject")



 ' Create a TextStream object

 Dim oTextStream

 Set oTextStream = objFS.OpenTextFile(sLog, 8, True)



 ' Write log entry

 oTextStream.WriteLine("Account:" & vbTab & oUser & vbTab & _

 "Inactive  for:" & vbTab & strdate & vbatb & "Weeks" & _

 vbtab & "Disabled on:" & vbTab & Date & vbTab & "at:" & _

 vbTab & Time)



 ' Close file

 oTextStream.Close



 ' Release objects

 Set oFS = Nothing

 Set oTextStream = Nothing



 Log = True



End Function

The boldfaced code indicates what's been changed. Now, the function is much more appropriate and will be easier to reuse in other scripts. It still isn't returning a useful value, so in the next section I'll show you how to convert it into a subroutine.

    Previous Section Table of Contents Next Section