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