VBScript for Windows System Administrators - Part IV

Published:
Well hello again!  Glad to see you've made it this far without giving up.  In this, the fourth installment of my popular series, I'm going to cover functions and subroutines, what they are, and why they are useful.  Just in case you stumbled onto the series in the middle, please take a few minutes and review the previous installments here:

Part 1
Part 2
The Missing Prequel
Part 3

So..  Now that we are once again on the same page, let's get to it.

Functions and subs are basically the same thing, with only a single difference:  A function returns a value, but a sub does not.  Chances are you've already used functions and subs without realizing it.  When you say
 Set oOU = GetObject("LDAP://...")

Open in new window

GetObject is actually a function that returns the object you have given the ADSPath to.  That function is one that is built-in, you don't actually see the code behind it.

But, what is a function?  Why would I want one?  What would I do with one?  Well, imagine you had this list of numbers.  You needed to take each number, multiply it by something else, then concatenate it to a string, and then echo what it is.  You could go like this:

x = 1
                      data = cstr(x * 2) & " apples"
                      wscript.echo data
                      x = 2
                      data = cstr(x * 2) & " apples"
                      wscript.echo data
                      x = 3
                      data = cstr(x * 2) & " apples"
                      wscript.echo data

Open in new window


You can see that it's mostly the same code repeated.  So...

Process 1
                      Process 2
                      Process 3
                      
                      Sub Process(x)
                          data = cstr(x * 2) & " apples"
                          wscript.echo data
                      End Sub

Open in new window


In the above code, the x in parentheses in the declaration line of the sub is the variable that will be passed in.  That variable is only in scope while the function or sub is executing; as soon as the function or sub exits, the variable is destroyed.  This is what is called a local variable.  The above code, when executed, will provide identical output to the code listed above that (the one without a sub), but note how much more user friendly it is:  If we wanted to add 4 or 5 or 6 to be processed, it would be only a single line of code, as opposed to three lines in the previous example.  But now, how about we do something useful with it?  Say you are writing a login script, and you are going to map network drives.  Instead of saying:

...
                      oNetwork.RemoveNetworkDrive "P:", True, True
                      oNetwork.MapNetworkDrive "P:", "\\server\share", True
                      If Err.Number <> 0 then
                          MsgBox "Error mapping drive.  Please contact the administrator."
                          Err.Clear
                      End If
                      oNetwork.RemoveNetworkDrive "Q:", True, True
                      oNetwork.MapNetworkDrive "Q:", "\\server\share2", True
                      If Err.Number <> 0 then
                          MsgBox "Error mapping drive.  Please contact the administrator."
                          Err.Clear
                      End If
                      oNetwork.RemoveNetworkDrive "R:", True, True
                      oNetwork.MapNetworkDrive "R:", "\\server\share3", True
                      If Err.Number <> 0 then
                          MsgBox "Error mapping drive.  Please contact the administrator."
                          Err.Clear
                      End If

Open in new window


Notice above that for every drive you want to map, you need to add 6 more lines of code.  That's very time consuming, and it makes for large files that are difficult to read.  So, make it a sub!

Sub MapDrive(DriveLetter, NetworkPath)
                          On Error Resume Next
                          oNetwork.RemoveNetworkDrive DriveLetter, True, True
                          oNetwork.MapNetworkDrive DriveLetter, NetworkPath, True
                          If Err.Number <> 0 then
                              MsgBox "Error mapping drive.  Please contact the administrator."
                              Err.Clear
                          End If
                      End Sub

Open in new window


Now, whenever we want to map a drive, we can just include that code in the script, and do it simply by saying:

MapDrive "P:","\\server\share"
                      MapDrive "Q:","\\server\share2"
                      MapDrive "R:","\\server\share3"

Open in new window


I'm sure you can see how this will make life easier.  So, now an example of a function:

Function AddTogether(x,y)
                          AddTogether = x + y
                      End Function

Open in new window


See how the only line of the function itself (not the declaration or the end) actually sets the name of the function to a value?  That is how you return the value to the code that called the function.  While that might be a pretty simple example, it illustrates the concept perfectly.  Call it like this:

q = AddTogether(2,3)
                      wscript.echo q

Open in new window


The value of q would be 5.  You could also simply say

wscript.echo AddTogether(2,3)

Open in new window


And get the same result.  Again, how is this useful?  Well, how about this function:

Function IsLocked(UserDN)
                          Set oUser = GetObject("LDAP://" & UserDN)
                          Set oLockout = oUser.Get("LockOutTime")
                          If Err.Number = -2147463155 Then
                              IsLocked = False
                              Exit Function
                          End If
                          If oLockout.LowPart = 0 and oLockout.HighPart = 0 Then
                              IsLocked = False
                          Else
                              IsLocked = True
                          End If
                      End Function

Open in new window


So now, we are going to return a true or false on if a user account is locked out.  Use it as such:

If IsLocked("CN=John Doe,OU=Employees,DC=domain,DC=local") Then Wscript.Echo "Locked"

Open in new window


Note that with functions, you can use parentheses when you call them, but with subs, you cannot.  I don't know, some strange rules built into the language, that's just how it is.  Since I prefer to use parentheses, I usually write all my subs as functions.  Functions do not HAVE to return a value, it's simply that they can.


Next installment we'll cover recursion.  That's when functions REALLY get fun.  Until then...

Happy coding,
exx
3
4,317 Views

Comments (0)

Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.