Don't Translate File and Folder VBScript Scripts into PowerShell

Don't Translate File and Folder VBScript Scripts into PowerShell

  • Comments 8
  • Likes

Summary: Simplify your code and do not translate an old file and folder VBScript script into Windows PowerShell.

Hey, Scripting Guy! Question Hey, Scripting Guy! I know there are not really established patterns and practices for writing VBScript code, or even for writing Windows PowerShell script. But there is code that I like to use—over and over again. I am sending you a bit of code that I use anytime I need to find out if a folder exists. I am thinking of translating it to Windows PowerShell because I know that Windows PowerShell can work with COM objects, and I want to stay with things that I am familiar with. Is this a good idea or what?

—KM

Hey, Scripting Guy! Answer Hello KM,

Microsoft Scripting Guy, Ed Wilson, is here. Today I am relaxing with a cup of Gunpowder green tea. I put a crushed cinnamon stick in the pot along with a bit of hibiscus flower, rose petal, and lemon grass. The tea is nearly perfect. Unfortunately, I am out of Anzac biscuits, so I am down to store-boxed Danish butter cookies. They are OK, but not really authentic.

KM, speaking of things that are not really authentic…

Translating VBScript code directly into Windows PowerShell results in Windows PowerShell script that is not really authentic Windows PowerShell script. Let me provide you with a quick example.

Determine if a folder exists: the VBScript way

To determine if a folder exists by using VBScript, is not too bad of a task—especially if you have written the code a hundred times before. Then it will even seem familiar. 

KM, it is not a great idea to translate VBScript code directly into Windows PowerShell because you lose much of the Windows PowerShell advantage for the sake of only a little bit of familiarity and comfort that comes with the old code. The technique uses the FolderExists method from the FileSystemObject. (This script comes from the Script Center Repository.)

Verify that a folder exists

VBScript

Set objFSO = CreateObject("Scripting.FileSystemObject")

If objFSO.FolderExists("C:\FSO") Then

    Set objFolder = objFSO.GetFolder("C:\FSO")

Else

    Wscript.Echo "Folder does not exist."

End If

Translating VBScript into PowerShell

So, I could not find a direct version of the previous VBScript code in the Script Center Repository—that is probably a good thing. So you know what I did? I took about two minutes, and I pasted the VBScript script into the Windows PowerShell ISE. I then changed just a few things, and voila! I have a VBScript Windows PowerShell script. Not only that, but I went from six lines of code to four! Groovy. Here it is:

Verify that a folder exists

Windows PowerShell

$objFSO = New-Object -ComObject "Scripting.FileSystemObject"

If ($objFSO.FolderExists("C:\FSO"))

    {$objFolder = $objFSO.GetFolder("C:\FSO")}

Else {Write-Host "Folder does not exist."}

This is not the most egregious thing I have ever seen. Look at some of the stuff in the earlier examples of the series. But it is still is a shame because Windows PowerShell has a built-in cmdlet that tests paths.

Note   As a Windows PowerShell best practice, if a Windows PowerShell cmdlet exists to do something, use that cmdlet. Do not revert to WMI, COM, or even .NET classes directly unless there is a very specific and compelling reason to not use the Windows PowerShell cmdlet.

Use the Test-Path cmdlet

Ever since Windows PowerShell 1.0, there has been a Test-Path cmdlet. This cmdlet is awesome in its simplicity and its elegance. The following script duplicates the previous code in that it tests the path to a folder. If the folder exists, it returns the Folder object, and if it does not exist, it displays a string that the folder does not exist. Here it is:

Use Test-Path: Windows PowerShell

if(Test-Path c:\fso)

   {get-item c:\fso}

else {"Folder does not exist"}

There are a couple of differences. First there is no COM object to dispose of. Secondly, the VBScript code did not return an object. It created a folder object, and stored it in a variable, but it did not return the object. Here, I return the object, so there is feedback of the “connection,” and it permits further use of the folder.

Create a folder

In VBScript, it was really easy to create a folder. In fact, it only required two lines of code: Create an instance of the FileSystemObject, and then call the CreateFolder method. This technique is shown here:

Create a Folder: VBScript

Set objFSO = CreateObject("Scripting.FileSystemObject")

Set objFolder = objFSO.CreateFolder("c:\fso")

Hey, guess what? I can do exactly the same thing with Windows PowerShell. I can create an instance of the FileSystemObject and then call the CreateFolder method. This technique is shown here:

Create a Folder: Windows PowerShell

$objFSO = New-Object -ComObject "Scripting.FileSystemObject"

$objFolder = $objFSO.CreateFolder("c:\fso")

But you know what? As simple as this code is, I can beat it. Here is all there is to create a folder in Windows PowerShell:

md c:\fso

Yep, that is right. Two letters, md, is all that is required to create a new folder in Windows PowerShell.

Note   This is actually one of the first “problems” that I had with VBScript. In DOS, there was the MD command to create a folder. And although the VBScript is only two lines of code, it just did not seem like much of an upgrade to go from a two letter command to two lines of rather obscure code. MD is a function that is built-in to Windows PowerShell, and it brings back the ease-of-use of the old DOS command.

KM, that is all there is to migrating a VBScript folder code to Windows PowerShell. Join me tomorrow when I will have a guest blog post written by Jonathan Tyler about working with event logs. It is good stuff that you will not want to miss. 

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 

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Hi Ed, Hi Teresa,

    I hope you are fine and that everything is OK!!!

    This is abolutely true!

    Translating kind of literally from VbScript ( or Batch ) to PowerShell makes no sense at all!

    And it's a wast of time anyways, if your script works .... why not keep it running?

    If you have good reasons to renew a script ... maybe because it is a bit unreliable or too slow or ...

    it might be a very good idea to rebuild it in Powershell but then you should do it the "Powwrshell-Way"!

    Klaus

  • @K_Schulte you are absolutely correct thank you for bringing this out. Glad to hear from you (its been a while) -- hope all is well, and congrats on your performance in the scripting games.

  • i would:

    $n= read-host -prompt "Dir name";if ($((gci | ?{$_.psiscontainer} | ?{$_.name -match "$n"}).Exists) -eq $TRUE) {write "$n does Exist"}else{write "$n does not Exist";$y= read-host -prompt "Do you want to create dir?"}; if ($y -match "yes"){ni -type d $n}else{write "Ok`nGood-bye"}}

  • Sorry about that. fixed a random brace and as per @jrv suggestion made it better. (even though i still think whitespace is useless)

    $n= read-host -prompt "Dir name"

    if ($((gci | ?{$_.psiscontainer} | ?{$_.name -match "$n"}).Exists) -eq $TRUE) {

    write "$n does Exist"

    }

    else {

    write "$n does not Exist"

    $y= read-host -prompt "Do you want to create dir?"

        if ($y -match "yes"){

          ni -type d $n}

          else{

          write "Ok`nGood-bye"

        }

    }

  • folder_exists_Version_2.ps1 :

    $n= read-host -prompt "Dir name"

    if ($((gci | ?{$_.psiscontainer} | ?{$_.name -match "$n"}).Exists) -eq $TRUE) {

    write "$n does Exist"

    $go= read-host -prompt "Go to $(write $n)?"

    if ($go -match "yes"){

    sl $n

    }

    else{

    write "Ok`nGood-bye"

    }

    }

    else{

    write "$n does not Exist"

    $y= read-host -prompt "Do you want to create $(write $n)?"

    if ($y -match "yes"){

    ni -type d $n

    }

    else{

    write "Ok`nGood-bye"

    }

    }

  • The term 'else' is not recognized as the name of a cmdlet

  • else is part of the if statement. if you are using a powershell terminal then remove whitespace otherwise use ISE (in powershell terminal type 'ise')

    get-help about_if -full | more

      if (<test1>)

             {<statement list 1>}

      [elseif (<test2>)

             {<statement list 2>}]

      [else

             {<statement list 3>}]

  • folder_exists_Version_3.ps1 :

    for (;;){

                            $in = read-host -prompt "Parent Dir [$(gl)]"

                            sl $in

                     $n= read-host -prompt "Dir name"

                     if ($((gci | ?{$_.psiscontainer} | ?{$_.name -match "$n"}).Exists) -eq $TRUE) {

                            write "$n does Exist"

                            $look= read-host -prompt "Go to $(write $n)?"

                                            if ($look -match "yes"){

                                                      sl $n

                                            }

                                           else{

                                                     write "Ok`nGood-bye"

                                           }

                     }else{

                         write "$n does not Exist"

                         $y= read-host -prompt "Do you want to create $(write $n)?"

                                          if ($y -match "yes"){

                                                            ni -type d $n

                                          }

                                          else{

                                                           write "Ok`nGood-bye"

                                          }

                     }

    }