Use PowerShell to Leverage Existing VBScript Scripts

Summary: Learn how to use Windows PowerShell and still leverage your existing VBScript scripts.

Microsoft Scripting Guy, Ed Wilson, here. This week we will have one guest blogger for the entire week. Sean Kearney has written a series of blog posts about Windows PowerShell and the Legacy. I am not going to be redundant by reposting his biography each and every day.

Integrating Windows PowerShell with Legacy Environments—Part 5

Note: This is part four of a five part series of articles about interacting with the legacy. Part one talked about retrieving exit codes, part two discussed working with exit codes. Part three talked about passing parameters to legacy commands, and in part four we talked about using legacy commands in a Windows PowerShell environment.

The past few days, we have shown examples of how Windows PowerShell will interact will legacy systems quite happily. Now we are going to show you a practical example. You see, today the memo…the BIG memo…came through the system: “We’re deploying Exchange Server 2007.”

You have two reactions:

“WOOOHOOOOOO!! We’re moving to Exchange Server 2007! I can’t wait! I can’t wait!”

Then, of course, it hits. Project plans, budgets, time, sleep (or lack of)—and the most important bit bursts out of your mouth, “What do you mean I can’t manage it with VBScript?”

Up until this point, you had an entire ecosystem of servers running just fine—BATS on the left and VBScript on the right.

You almost swore a blue streak. Then you caught my series of blogs on Hey! Scripting Guy, and your blood settled down. “Windows PowerShell will work the Legacy,” they say. You read up, and decided to take a look at the situation.

Your original script for creating new users with Dsquery.exe, and then populating them in Exchange with your special VBScript script looked a little like this:

---------------- NEWUSER.CMD ----------------

@echo off
Rem our Target OU for the User

rem Get the Name of the User

SET /P First="First Name:"
SET /P Last="Last Name :"

REM Build our Distinguished DN to add under Our Branches OU


SET DN=CN=%First% %Last%,%ROOTDN%

SET SAMID=%First:~0,1%%Last%
SET UPN=%SAMID%@techdays.local
SET DISPLAY=%First% %Last%

REM Create user
DSADD USER "%FULLDN%" -samid "%SAMID%" -upn "%UPN%" -fn "%FIRST%" -ln "%LAST%" -display "%DISPLAY%" -pwd *

REM Create Email 

IF %ERRORLEVEL% NEQ 0 ( ECHO Failed to Create Email address.  Check Logs ) ELSE (ECHO Successfully Created Email)

---------------- NEWUSER.CMD ----------------

It was a simple, but effective, script that you ran for each new user. It worked fine for Exchange Server 2003 with the VBScript portion, so why can’t we retrofit it for this new server that needs Windows PowerShell?

We can!

First, let us enable a user in the new Exchange Server 2007 console to get a sample cmdlet. We’ll use “Mr. Trouble,” who has been pestering us for an email address. Today we gave him one. (It does not matter that we assigned all the Junk email to his address, does it?)

Enable-Mailbox -Identity 'Contoso.local/Staff/Mister.Trouble' -Alias 'Mister.Trouble' -Database 'SRV-Exch2007First Storage GroupMyExchDB'

The sample shows that the identity follows a canonical name. When we write the following code:


It shows us that it can also take the following format:


Because our original script is providing the Domain name as well as a SamID, we can leverage that instead in Windows PowerShell.

First we need to accept those parameters that we were going to pass to VBScript. Maybe we will not use them all, but for the moment, let us match them up as follows:


Now we will construct the Identity and switch some of those “static” values from the sample script:

$MyExchangeDatabase='SRV-Exch2007First Storage GroupMyExchDB'

Enable-Mailbox –Identity $ID –Alias $Alias -Database $MyExchangeDatabase

and we should also check for an error and send the status back

IF ($ERROR) Return 13

Put it all together and save it as NEWMAIL.PS1 in the same directory as your NEWUSER.CMD script, then drop this into your Exchange Server:

----------------- NEWMAIL.PS1 -----------------


$MyExchangeDatabase='SRV-Exch2007First Storage GroupMyExchDB'

Enable-Mailbox –Identity $ID –Alias $Alias -Database $MyExchangeDatabase

IF ($ERROR) Return 13

----------------- NEWMAIL.PS1 -----------------

Now, replace the following original line:


with this line:

POWERSHELL.EXE –file NEWMAIL.PS1 –executionpolicy RemoteSigned %SAMID% %UPN% %DISPLAY% %DOMAIN%

And life is good!

Now, you thought I was about to say, “Done!” But we do have another option to leverage. What if the Exchange Server is running Windows PowerShell 2.0, and you have remoting enabled? You can leverage that too. A slight change to our Windows PowerShell script:


$Session=NEW-PSSESSION –computername SRV-Exch2007

$MyExchangeDatabase='SRV-Exch2007First Storage GroupMyExchDB'

INVOKE-COMMAND –Session $Session  - SCRIPTBLOCK { ADD-PSSNAPIN Microsoft.Exchange.Powershell.Addin; Enable-Mailbox –Identity $ID –Alias $Alias -Database $MyExchangeDatabase }

IF ($ERROR) Return 13

You even want to add Get-Credential, and possibly combine it with this amazing Hey! Scripting Guy blog by Boe Prox about ensuring that you have the proper credentials first.

There you have a nice example of an existing batch file that is doing its job on a legacy setup and how you can extend it to use on a modern server without breaking your infrastructure. For all the power that is revealed and exposed by Windows PowerShell; it really is just another tool for us to use and leverage as we see fit.

Oh, but what a beautiful tool it is! Remember, the Power of Shell is in you.

Guest blogger week will continue tomorrow with a surprise guest. A special thank you to Sean for writing this week’s blog posts. Hope you enjoyed them. Tune in tomorrow, same batch time, and same batch channel.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

Comments (5)

  1. Logan says:

    Hey Scripting Guy.  Could really use your Powershell knowledge to help me out in a project.  With Powershell v1.0, is it possible to run a .ps1 file in code without it just opening up in notepad?  I know about doing the whole powershell.exe "filepath" in the Run box, but here's the curveball.  The machines that I need running my program…don't have Powershell installed.  Powershell is actually installed on a domain controller server.  With that said, how do I call this .ps1 file and get it to execute the script inside?

    The program is to unlock AD accounts.  Basically you type a username in a text box, the code writes this information into a CSV file, and then calls the Powershell script.  The Powershell script reads the CSV file and unlocks the account.  Round-about away of doing things, but I figured it works and doesn't grant the user access to AD, just the program.  Thanks in advance.

  2. Klaus Schulte says:

    Hey Sean,

    at least you did mention Mr.Trouble again 🙂

    Well, an interesting point to notice: We don't ( and maybe shouldn't ) throw away our old storm prooved working horses if there is no very good reason to do so!

    They may work together well!

    But openly speaking; I'd prefer to so … sometimes!



  3. Sean Kearney says:


    Cool and interesting solution.  But believe it or not this is a bit like re-inventing the wheel.  I believe there are ways to leverage this via DotNet already.   Using Powershell is a cool thing but I would (not being a Dev, but knowing 1% of DotNet) just leverage whatever libraries are available to unlock the A/D account.  

    If you were in a newer setup I would play with Powershell remoting but that still might be overkill.   The other thing is be careful if you're enabling users with the ability to SelfUnlock.  You want to make sure there is an appropriate set of challenges to ensure identity.  (No having them running a 200 meter relay wouldn't count) 😉

    Also look into I think a project an MVP was working on called "Portable Powershell" I believe.

    Cheers !


  4. Logan says:

    I have two different programs that I'm trying to program now.  One of them is trying to unlock the account through exclusively, and the second is trying to call a Powershell script that unlocks the account.  Good thing is I got my program to read the script and try to execute what's in there, bad thing is the Import-ActiveDirectory module isn't working because I'm running it from an XP machine that doesn't have AD installed.  I've been looking at what you had suggested and it sounds promising.  Thanks for the info.

Skip to main content