Hey, Scripting Guy! How Do I Rename All Files in a Folder?

ScriptingGuy1

Hey, Scripting Guy! Question

I want to use SharePoint for our company’s script library, but it will not allow us to upload a VBScript file. It accepts PS1 files just fine, but we still have quite a few VBScripts and we need to keep a central repository of them. We have decided to rename them from .vbs files to .txt files so that we can keep them in SharePoint. I know I can write a VBScript to do this, but it will take too much time to do this, and I am wondering if you can write one for me in Windows PowerShell? I need to learn Windows PowerShell anyway because we are planning our migration to Windows 7, which already has Windows PowerShell built into it. Can you help me?

– SE

SpacerHey, Scripting Guy! Answer

Hi SE,

If we want to use a VBScript to change the file extension of all files in a folder, we can use the script discussed in this “Hey, Scripting Guy!” article. You are right; it would take a few minutes to write such a script from scratch.

This week is Desktop Week-a rather vague series of loosely connected articles that may or may not be related to desktops. But the articles were written on a desktop, so maybe that counts. If you want to see some VBScript examples of Desktop Management scripts, check out these scripts in the Script Center Script Repository. The Community-Submitted Scripts Center also has a collection of scripts related to desktop management. In addition, there is the Desktop Management archive of “Hey Scripting Guy!” articles, which include scripts and explanations as well. The scripts this week will be using Windows PowerShell. To download Windows PowerShell and to find getting started information, see the Windows PowerShell hub.

To rename all the files in a folder, we can use the Rename-FileExtension.ps1 script. It uses the Get-ChildItem cmdlet to obtain a listing of all files in the folder with a specific extension, and then uses the Rename-Item cmdlet to rename the files. The Rename-FileExtension.ps1 script is seen here.

Rename-FileExtension.ps1

Function Rename-FileExtension($path,$oldExtension, $newExtension)
{
 Get-ChildItem -path $path -Filter $oldExtension |
 Foreach-Object {
   if($_.extension.length -gt 0)
    {
      $baseName = $_.name.remove($_.name.length - $_.extension.length)
    }
  ELSE
    { $baseName = $_.name }
 Rename-Item -Path $_.fullname -newname ($baseName + $newExtension)
 }
} #end function
Rename-FileExtension -path "C:\fso" -oldExtension "*.txt1" -newExtension ".txt"

I am intrigued by your use of Microsoft Windows Sharepoint Services for your script repository. It has a number of features that can be used to facilitate collaboration among script writers, and there are a number of templates that can be applied when designing a new SharePoint site. I prefer to use the document collaboration template because it allows for the easy sharing of documents, a discussion list, links to other sites, and a shared calendar. The home page provides a convenient place for announcements related to ongoing projects as well. This is seen here:

Image of the SharePoint home page

 

The shared documents section is the section we will use to form the script library. It can be renamed “Script Repository” or whatever else we wish to call it. We have the ability to manage permissions on a script-by-script basis. As an example, we could restrict access to certain types of troubleshooting scripts to Level 2 Help Desk personnel, and permit access to the more basic scripts to ordinary users. When a script is being modified, we can check out the script. This will allow the name of the script to still be visible, but the status will change to show it is checked out. The shared document library is seen here:

Image of the shared document library

 

The team discussion site provides a good location for members of the IT team to request specific scripts. By replying to a particular script request, duplication of effort can be reduced. As seen in the image following this paragraph, one person is requesting a script that will defragment hard drives on remote servers. If someone decides to write that script, they need only reply to the posting that they will write the script. All members of the IT team should subscribe to the Script Collaboration SharePoint services site. Subscribing to a site causes us to receive e-mail notification when anything changes on the site. This can be the submission of a new script to the shared documents section, a reply to a request for a script, or a new event such as scheduling a meeting of the Scripting Club. The team discussion section of the SharePoint site is seen here:

Image of the team discussion section of the SharePoint site

 

In the Rename-FileExtension.ps1 script, we create a function named Rename-FileExtension. This function will accept three input parameters: the first is the path to the files to be renamed, the second parameter is the old file extension, and the last parameter is the new file extension. This is seen here:

Function Rename-FileExtension($path,$oldExtension, $newExtension)

Inside the script block, we use the Get-ChildItem cmdlet to retrieve a collection of file objects from the folder specified in the $path variable. We use the filter parameter to limit the file objects to files that have the extension specified in the $oldExtension variable. We then pipeline the results to the next command:

Get-ChildItem -path $path -Filter $oldExtension |

We now want to work with each file as it comes across the pipeline. To do this, we use the ForEach-Object cmdlet. The code to be executed on each object is placed inside a script block, which is delimited by a set of curly brackets. We open the script block as seen here:

Foreach-Object {

The command that will be executed on each file object is the Rename-Item cmdlet. The path is represented by the fullname property of the current object on the pipeline ($_). The fullname of a file object contains the complete path. This is seen here:

PS C:\> Get-Item -Path c:\fso\b.txt | Select fullname
FullName
--------
C:\fso\b.txt

The new name of the file will be the base name of the current object on the pipeline plus the new file extension. In Windows PowerShell 2.0, there is a new script property that is added to the file object that will allow us to retrieve the base name of a file—the name of the file without the extension, but in Windows PowerShell 1.0 we will need to retrieve the base name of the file by ourselves. To do this, we first want to see if the file extension is greater than 0. If the file has an extension, we use the remove method to subtract the length of the file extension from the length of the file name. We store the result in the variable $baseName. If the file does not have an extension, we assign the name of the file to the $baseName variable. This is seen here:

if($_.extension.length -gt 0)
    {
      $baseName = $_.name.remove($_.name.length - $_.extension.length)
    }
  ELSE
    { $baseName = $_.name }

After we have the base name of the file, we use the Rename-Item cmdlet to rename the fullname of the file to the new name with the new file extension. This command is shown here:

Rename-Item -Path $_.fullname  -newname ($basename + $newExtension)
 }

To call the function, we pass the path containing the files we want to rename, the old file extension, and the new file extension:

Rename-FileExtension -path "C:\fso" -oldExtension "*.txt1" -newExtension ".txt"

Well, SE, that is about all there is to changing a file extension. Hope you enjoyed the excursion. We will see you tomorrow as Desktop Week continues.

 

Ed Wilson and Craig Liebendorfer, Scripting Guys

0 comments

Discussion is closed.

Feedback usabilla icon