Get automatic notification when running low on BES licenses

This VBScript uses native SQL connectivity via ADO to query your BlackBerry Enterprise Server configuration database for the current number of users. Since the license total is not stored in the database you have to set it as a variable in the script. It then compare the two numbers and if your defined threshold is exceeded, it will email you a notification. Just schedule the script to run daily. Download a zipped version here, or copy below.

Convert a mailbox GUID to the user and display name

If certain MAPI limits are reached when working with sessions, items, attachments, etc., Exchange will deny further access to that user to that object type.  When this happens event ID 9646 is logged in the Application log.  The description of the event contains a mailbox GUID that is causing the issue, but the GUID alone does nothing to indicate what user/mailbox is affected.

Microsoft KB 899663 instructs how to manually transpose GUID into a format that can be used in an LDAP filter so that you can search for a match.  Why do all this by hand when a script can do it for you?  I took an existing script I had that already does the transposition and added an AD search to return the matching dn.  The dn is passed to a name translation function that converts the dn to the NT4 format (domain\username) and displays the match with username and display name.

In addition to the VBScript file, I have also included a compiled version that uses SAPIEN Script Host as the engine.  This is a self-contained, runs-in-memory-only, no-DOS-box-comes-up engine from PrimalScript.  Running the compiled version is nice since you don’t have to ensure that CScript is the default host and no DOS box appears while the script is running.

The zip file with both versions is available here .

Script to format an LDAP filter for readability

Articles in the "Format LDAP Filter for Readability" series

  1. Script to format an LDAP filter for readability [This article]
  2. New version of LDAP formatting script

I have automated DLs that use LDAP filters for membership criteria.  These filters are stored as binary data in the extensionData attribute of the group object, so they are not easily accessible by users who want to know what filter is being applied to a DL they own.

It was easy enough to extract the LDAP filter from the attribute, convert it to a string value, and display it.  But users don’t generally know how to read LDAP filters, let alone represented as a long line of text.  So I started looking for utilities or scripts that would take an LDAP filter, parse it, and display it with nesting.  Uh, yeah, there aren’t any.  I was determined, and so countless hours later I have a function that do such a thing.

The difficult part was keeping track of the level of nesting/indentation at any point. Since a filter can be written in almost any order as long as the resulting equation equals what you want, I couldn’t use any kind of static detection. Just because an open parentheses is following by another one doesn’t mean that you are, say, three levels nested. So the important part of the script keeps track of the indentation level as the cursor position moves through the filter.

I replace ampersands in the filter with crosshatches while working with it because I was having weird results otherwise, most likely because the ampersand is an operator in both LDAP and VBScript. And because the output is to an IE window and the indentation uses non-breaking spaces instead of the traditional tab (which doesn’t exist in HTML), I substitute the HTML string for a non-breaking space with a unique string of letters so the ampersand in that doesn’t get in the way.

Because this is part of a bigger script, I pulled out just the portion that formats the LDAP filter and displays it in an IE window. You just need to provide the “raw” filter, whether directly in the script or some other method. Copy and paste the code below or download it here.

Add comment notification to simplebog 3.0

Since I am using approval for comments on my site, I had no way of knowing when someone posted a comment pending approval.  And since you can’t simply look for comments to posts without going into the database directly, I needed a way to know when someone has posted a comment and to which post it belongs.

To do this, add this subroutine to the end of functions.asp, which is the CDO code to send a message.  I didn’t use variables that are assigned in config.asp, so you will have to set them in the subroutine directly for SMTP server, from address, to address, and domain name in the body. 

Then you need to add code to functions.asp to call this subroutine from the subroutine that inserts the comment.  Find the subroutine labeled InsertComment(), which should be around line 475 depending on other mods of mine or your own that you may have inserted.  Right before the existing line: 

insert this code:

This is necessary because the comments are not accessed by using the blog entry ID, but the blog entry’s date.  So it is necessary to cross-reference the entry ID to the entry date, and then link to the comments for a given entry ID on that date.  The last line calls the email function which will include a hyperlink to the comments for the blog entry that has a new comment.

Now, that is all fine and dandy.  You will receive the email with the link, but when you follow it to your site, you probably won’t have an active session so you will have to log in.  The way the admin default and login pages work, you will lose the link to the entry you need to approve so you have to click the link in the email again.  I work around this by implementing the use of query strings so the site remembers where you were trying to go before you had to log in.

To add this feature, edit admindefault.asp.  At line 8, replace the Response.Redirect line with the following code: 

This builds a query string of the URL you were going to go to before you are redirected to the login page.  Now edit adminlogin.asp.  At line 34, before the If statement to check for a postback, insert the following line: 

This retrieves the query string and puts it into a variable.  At line 39, before the SQL statement to select the users from the database, insert the following code: 

This extra code is added to accommodate you entering a bad password or if you are logging in without following a comment link.  At line 74, comment out Johann’s Response.Redirect line after a successful login and then insert and replace the Response.Redirect for no user found with this: 

This sends you to the page you were intending to go to in the first place.  If you entered a bad password, this also preserves the original URL after the login page reloads.

Last, but not least, you need to a hidden form field that will store the original URL when you submit the form to log in.  Near the end of the file, insert a line before the close form tag and paste this: 

I hope that’s not too complicated to follow.  It’s a little more convoluted for this modification because it is necessary to add code in multiple places in multiple files, rather than just a chunk of code in one file.  But, now you will receive an email when a comment is posted and be easily able to approve or deny the comment just by following the link in the email.

Updated: Copy DLs from one user to another

The first version of the script really was quick and dirty, requiring you to manually put the source and target users’ DNs in the script.  Since a coworker has been using the script, I thought it appropriate to update it to prompt for the usernames.  In addition, I added a new feature I recently read about, which is to output the results in real-time to a GUI.  This is done by creating an object for IE and writing the output similar to wscript.echo, but with the Write method of the object.

Like the original script, since we use automated DLs, too, I look for an indication that a given DL is a SmartDL and skip it.  And I now use PrimalScript to work with my scripts, so I use its packager to make an exectuable.  This makes it easier and nicer for non-IT end-users who will be running scripts like these.

Download it here, or copy/paste below.

How to add CAPTCHA to simpleblog 3.0

Johann almost added CAPTCHA verification to simpleblog 3, but he notes on his blog that he decided not to after looking at the pros and cons.  He says that simpleblog isn’t a target of comment spam because of the inability to post html or javascript code into a comment.  I disagree, however, because you still get targeted by comment spam by the very nature that bots will still post comments.  Even with approval enabled, I still have to delete the pending comments, and there can be A LOT of them.

Johann included a copy of Emir Tuzul’s free ASP CAPTCHA implementation, but never incorporated it into simpleblog.  I looked at how the code works and how Johann implemented comments, and I have successfully added CAPTCHA verification to the comments system.  Since doing so a few days ago, not a single spam comment has been left.  If you are interested, this is how to do it.

Since Johann included version 2 of the CAPTCHA code page, you do not need to download anything, but you can opt to use version 3 beta 1, which uses more character obfuscation to make it harder for bots to determine the characters in the image.

Edit functions.asp to add the following code to the end of the file, which is the verification function:

Add the following code to functions.asp in the CommentsGet subroutine, which for me starts at line 351.  It may be different for you since I think I have added other code higher in the file.  This adds the actual CAPTCHA image to the comments form.  You will add this code after the call for GetEmoticons and the line break, which for me means inserting this at line 454:

At line 481 (after the declaration of the str_userIP variable), insert this, which puts the characters entered into the form in a variable:

Lastly, replace the code that inserts the comment into the database with the code below, starting at line 492 (after the comment  "insert Comment."  Instead of simply inserting the comment into the database, this will compare the entered characters to the actual ones in the image.  If they match, the comment is inserted.  If not, I use a JavaScript alert to present a popup box and then redirect the user back to the post:

You’re done!  Save functions.asp and then go add a comment to one of your posts.  Intentionally enter incorrect characters to confirm the popup works and that the comment did not get added.  The only thing missing from this is that it doesn’t preserve the comment in the session.  This means that if a real person incorrectly enters the code, when returned to the post to try and enter another code, the actual comment data will have to be entered again.  Name, email, and URL don’t have to because they are stored in a cookie on the client.  Perhaps I will add that at a later time.