Summary: Microsoft Scripting Guy, Ed Wilson, talks about translating VBScript script into Windows PowerShell, and he says it is not a very good idea.
Hey, Scripting Guy! I love VBScript. I know, I know. It is not fashionable these days to say that, but it is a fact. I love using VBScript. It is powerful, and over the last ten years or so, I have written literally hundreds of scripts that we use at my company on a daily basis. I simply do not have time to translate these scripts in Windows PowerShell. I am sorry, but that is all there is to it…just sayin’.
—ML
Hello ML,
Microsoft Scripting Guy, Ed Wilson, is here. The Scripting Wife and I are going through what could be called TechEd withdrawl. After nearly a week of non-stop activity, literally from 6:00 AM to midnight each day, we find ourselves missing the fun, engagement, and excitement—like a rabbit locked out of a vegetable garden. It was too much, and now it is too little. Luckily, in a few weeks there is the TechStravaganza 2013 in Atlanta, and then there is TechEd 2013 Europe in Madrid. So we get a chance to do it all over again.
Anyway, ML, I thought I would take some time to review some of my email sent to scripter@microsoft.com, and I came across your letter. Here are some thoughts…
Do not translate VBScript into Windows PowerShell…
Never. Never. Never. Never. Never!
Of the more than 3,000 VBScript scripts I wrote years ago, I have translated fewer than two dozen into Windows PowerShell. Each of those was for academic purposes, not for real-life purposes. The reason is that Windows PowerShell and VBScript are completely different. You may as well try to turn applesauce into mashed potatoes. It might seem like a good idea at the time—but dude! (or dudette!), I am not certain of a really acceptable outcome.
Need some proof? OK, how about this one:
This script is a basic WMI script from the Scripting Guys Script Center Repository. It is called Retrieving BIOS Information, and it does a great job. In fact, I have used this particular script on more than one occasion over the last decade and a half—in production and in teaching situations. Here is the script:
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colBIOS = objWMIService.ExecQuery _
("Select * from Win32_BIOS")
For each objBIOS in colBIOS
Wscript.Echo "Build Number: " & objBIOS.BuildNumber
Wscript.Echo "Current Language: " & objBIOS.CurrentLanguage
Wscript.Echo "Installable Languages: " & objBIOS.InstallableLanguages
Wscript.Echo "Manufacturer: " & objBIOS.Manufacturer
Wscript.Echo "Name: " & objBIOS.Name
Wscript.Echo "Primary BIOS: " & objBIOS.PrimaryBIOS
Wscript.Echo "Release Date: " & objBIOS.ReleaseDate
Wscript.Echo "Serial Number: " & objBIOS.SerialNumber
Wscript.Echo "SMBIOS Version: " & objBIOS.SMBIOSBIOSVersion
Wscript.Echo "SMBIOS Major Version: " & objBIOS.SMBIOSMajorVersion
Wscript.Echo "SMBIOS Minor Version: " & objBIOS.SMBIOSMinorVersion
Wscript.Echo "SMBIOS Present: " & objBIOS.SMBIOSPresent
Wscript.Echo "Status: " & objBIOS.Status
Wscript.Echo "Version: " & objBIOS.Version
For i = 0 to Ubound(objBIOS.BiosCharacteristics)
Wscript.Echo "BIOS Characteristics: " & _
objBIOS.BiosCharacteristics(i)
Next
Next
Translating to Windows PowerShell…
So we have a great VBScript script that retrieves bios information from local and remote computers, and it is something we use all the time. So we decide to translate it to Windows PowerShell. Here is the result:
$strComputer = "."
$colItems = get-wmiobject -class "Win32_BIOS" -namespace "root\CIMV2" `
-computername $strComputer
foreach ($objItem in $colItems) {
write-host "BIOS Characteristics: " $objItem.BiosCharacteristics
write-host "BIOS Version: " $objItem.BIOSVersion
write-host "Build Number: " $objItem.BuildNumber
write-host "Caption: " $objItem.Caption
write-host "Code Set: " $objItem.CodeSet
write-host "Current Language: " $objItem.CurrentLanguage
write-host "Description: " $objItem.Description
write-host "Identification Code: " $objItem.IdentificationCode
write-host "Installable Languages: " $objItem.InstallableLanguages
write-host "Installation Date: " $objItem.InstallDate
write-host "Language Edition: " $objItem.LanguageEdition
write-host "List Of Languages: " $objItem.ListOfLanguages
write-host "Manufacturer: " $objItem.Manufacturer
write-host "Name: " $objItem.Name
write-host "Other Target Operating System: " $objItem.OtherTargetOS
write-host "Primary BIOS: " $objItem.PrimaryBIOS
write-host "Release Date: " $objItem.ReleaseDate
write-host "Serial Number: " $objItem.SerialNumber
write-host "SMBIOS BIOS Version: " $objItem.SMBIOSBIOSVersion
write-host "SMBIOS Major Version: " $objItem.SMBIOSMajorVersion
write-host "SMBIOS Minor Version: " $objItem.SMBIOSMinorVersion
write-host "SMBIOS Present: " $objItem.SMBIOSPresent
write-host "Software Element ID: " $objItem.SoftwareElementID
write-host "Software Element State: " $objItem.SoftwareElementState
write-host "Status: " $objItem.Status
write-host "Target Operating System: " $objItem.TargetOperatingSystem
write-host "Version: " $objItem.Version
write-host
}
This is an actual script that comes from the Script Center Repository: List BIOS Information. I am including the link because it is a perfect example of a horrible Windows PowerShell script, and anyone teaching a Windows PowerShell class should have access to a script such as this. (And no, I did not write this script—it was bulk uploaded four years ago using the Scripting Guys Live ID…Oh well.)
Comparing the two scripts, I see very little difference. Here are the two scripts (somewhat truncated) side-by-side:
Writing the script in Windows PowerShell…
Instead of translating VBScript into Windows PowerShell, take advantage of the inherent capabilities of Windows PowerShell instead of forcing Windows PowerShell to do VBScript. Indeed, it is not my intention to make fun of VBScript, because I have also seen Windows PowerShell code that was written in C#, or C++, or Perl.
The cool thing is that Windows PowerShell is very flexible, and it is possible to get things up and running easily. Here is the previous BIOS script, written so that it takes advantage of Windows PowerShell:
Get-WmiObject Win32_Bios
That is it.
This connects to WMI and retrieves BIOS information. It can also be written by using the CIM cmdlets from Windows PowerShell 3.0 as shown here:
Get-CimInstance Win32_Bios
The thing that is incredible in both examples is that there are fewer LETTERS in the command than there are LINES in the previous script.
So, ML, please, please, please, please do not translate your old VBScript scripts into Windows PowerShell. If you do, you will do the following:
- Waste your time redoing something that already works.
- Waste your time by writing very bad Windows PowerShell code.
- Come away confused as to what “all the fuss” surrounding Windows PowerShell is about.
- Contribute to the already too large pool of bad Windows PowerShell code.
ML, your job as an IT pro is to get stuff done, not to write code (Windows PowerShell, VBScript, or otherwise). Therefore, if you have something that works, stay with it.
If or when you need NEW code, I would advise you to write it in Windows PowerShell. To get started, see the Scripting with Windows PowerShell in the Script Center. You might also want to pick up a copy of my book, Windows PowerShell 3.0 Step by Step, and follow along there.
ML, there are my thoughts about translating VBScript to Windows PowerShell. Join me tomorrow when I will talk about more cool Windows PowerShell stuff.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy