{"id":54463,"date":"2009-02-04T21:04:00","date_gmt":"2009-02-04T21:04:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2009\/02\/04\/hey-scripting-guy-how-can-i-rename-all-of-the-pictures-in-a-folder\/"},"modified":"2009-02-04T21:04:00","modified_gmt":"2009-02-04T21:04:00","slug":"hey-scripting-guy-how-can-i-rename-all-of-the-pictures-in-a-folder","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-rename-all-of-the-pictures-in-a-folder\/","title":{"rendered":"Hey, Scripting Guy! How Can I Rename All of the Pictures in a Folder?"},"content":{"rendered":"<h2><img decoding=\"async\" class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" border=\"0\" alt=\"Hey, Scripting Guy! Question\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" height=\"34\"> <\/h2>\n<p>My scripting husband travels a great deal with his job, and he takes these really cool pictures. Unfortunately, he is somewhat lazy about downloading the pictures from the camera. As a result, we have pictures from Hawaii that are named Phoenix_Desert_05.jpg. Obviously, I know the difference between a desert and a beach, but it is rather annoying when trying to show pictures to your friends, and the pictures are named incorrectly. I am talking about thousands of pictures in hundreds of folders. I started renaming them by hand, and then it&#8217;s like DUH, why don\u2019t I e-mail the scripting guys. My husband talks about you all the time. So what&#8217;s it gonna be big boy, you gonna help me or not? <\/p>\n<p>&#8211; TW<\/p>\n<p><img decoding=\"async\" border=\"0\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" height=\"5\"><img decoding=\"async\" class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" border=\"0\" alt=\"Hey, Scripting Guy! Answer\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" height=\"34\"><\/p>\n<p>Hi TW,<\/p>\n<p>Of course we are going to help you. I don\u2019t think I can either write a script to make your husband download the pictures any sooner or write a script to make him take out the trash. However, I can write a script that will rename all the pictures in a folder with the name you select. You will need to copy the Hawaii pictures into a folder called <b>Hawaii<\/b>, which you can easily do by dragging and dropping. When you are sure you have only Hawaii pictures in the Hawaii folder and only Phoenix_Desert pictures in the <b>Phoenix Desert<\/b> folder, you run the script.<\/p>\n<table id=\"E5C\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td>\n<p class=\"lastInCell\">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 <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/scripts\/desktop\/default.mspx\" target=\"_blank\">these scripts<\/a> in the Script Center Script Repository. The Community-Submitted Scripts Center also has a collection of scripts related to <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/csc\/scripts\/desktop\/default.mspx\" target=\"_blank\">desktop management<\/a>. In addition, there is the <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/desktop.mspx\" target=\"_blank\">Desktop Management archive<\/a> of \u201cHey Scripting Guy!\u201d 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 <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/hubs\/msh.mspx\" target=\"_blank\">Windows PowerShell hub<\/a>.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>Here is the <b>RenameFiles.ps1<\/b> script. To see how to use it, you can type the following commands from within the Windows PowerShell console:<\/p>\n<pre class=\"codeSample\">RenameFiles.ps1 \u2013help\nRenameFiles.ps1 \u2013min\nRenameFiles.ps1 \u2013full\nRenameFiles.ps1 -examples\n<\/pre>\n<p><b>RenameFiles.ps1<\/b><\/p>\n<pre class=\"codeSample\">Param(\n      $path = \"C:\\fso1\",\n      $Prefix = \"Hawaii\",\n      $int = 1,\n      $extension = \".jpg\",\n      [switch]$rename,\n      [switch]$whatif,\n      [switch]$help,\n      [switch]$examples,\n      [switch]$min,\n      [switch]$full\n     )\nfunction Rename-Files()\n {\n  $colFiles = get-childitem -path $path\n  Foreach($file in $colFiles)\n   {\n    if(!$file.psIsContainer)\n       {\n        if ($file.extension -eq \".avi\") { \"skipping $file\" }\n        ELSE\n         {\n          rename-item -path $file.fullname -newname $Prefix$int$extension\n          $int++\n         }\n       } #end if\n   } #end foreach\n } #end rename-Files\nfunction Get-HelpTopic()\n{\n $descriptionText= `\n@\"\n NAME: RenameFiles.ps1\n DESCRIPTION:\n Renames all files in a folder. Useful when\n deleting files from a folder, and then you\n want them to all have unique names in order\n Also useful when merging folders of files and\n you wish to ensure each filename is unique.\n To rename a sequence of files, specify int larger\n than the max number of files in folder, run. Then\n run again beginning with 1.\n This script supports prototyping by using\n the -whatif switch.\n PARAMETERS:\n -path path to files to be renamed\n -prefix first part of name to use\n -int beginning number to use in file name\n -extension file extension to use in file name\n -rename causes script to rename the files\n -whatif Prototypes the command\n -help prints help description and parameters file\n -examples prints only help examples of syntax\n -full prints complete help information\n -min prints minimal help. Modifies -help\n\"@ #end descriptionText\n$examplesText= `\n@\"\n SYNTAX:\n RenameFiles.ps1\n Displays missing parameter, and calls help\n RenameFiles.ps1  -path c:\\pictures\\keywest -prefix keywest -int 1\n -extension .jpg -rename\n Renames all pictures in the c:\\pictures\\keywest folder to begin with\n prefix of keywest starting counting with 1 and extnsion of .jpg.\n Example first picture will be named keywest1.jpg\n RenameFiles.ps1 -path c:\\pictures\\keywest -prefix keywest -int 1\n -extnesion .jpg -whatif\n  Displays what if: Perform operation rename files in c:\\pictures\\keywest\n  using prefix keywest beginning with number 1\n  using extension .jpg.\n  filenames will be pattern: keywest1.jpg\n RenameFiles.ps1 -pa c:\\pictures\\keywest -pre keywest -int 1\n -ext .jpg -r\n  Renames all files in c:\\pictures\\keywest folder using prefix keywest\n  beginning with number 1 using the extension .jpg. filenames will\n  be in the pattern: keywest1.jpg\n RenameFiles.ps1 -help\n Prints the help topic for the script\n RenameFiles.ps1 -help -full\n Prints full help topic for the script\n RenameFiles.ps1 -help -examples\n Prints only the examples for the script\n RenameFiles.ps1 -examples\n Prints only the examples for the script\n\"@ #end examplesText\n$remarks = `\n\"\nREMARKS\n     For more information, type: $($MyInvocation.ScriptName) -help -full\n\" #end remarks\n  if($examples) { $examplesText ; $remarks ; exit }\n  if($full)     { $descriptionText; $examplesText ; exit }\n  if($min)      { $descriptionText ; exit }\n  $descriptionText; $remarks\n  exit\n} #end Get-HelpTopic function\nFunction Get-WhatIf()\n{\n \"\n  what if: Perform operation rename files in $path\n  using prefix $prefix beginning with number $int\n  using extension $extension.\n  filenames will be pattern: $Prefix$int$extension\n \"\n exit\n} #end Get-WhatIf\n# Entry Point\nif($examples)  { Get-HelpTopic }\nif($full)      { Get-HelpTopic }\nif($whatif)    { Get-WhatIf }\nif($help)      { Get-HelpTopic }\nif(!$rename)   {\"missing parameter\" ; Get-HelpTopic }\nif($rename)    { Rename-Files }\n<\/pre>\n<p>The <b>RenameFiles.ps1<\/b> script is a rather long script, but most of the length is taken up by the Help topic. The actual code that renames the files is rather short. Let\u2019s start at the beginning, and work our way through the script. The first thing we come to is a series of command-line parameters. The <b>Param<\/b> statement is used to create command-line parameters. When you have a variable and assign a value to that variable, the parameter has a default value. <\/p>\n<p>This can be quite useful because it allows the script to run with a set of defaults that do not need overriding, which gives you a point-and-click type of functionality. Later, when you have other values you wish to use, you can easily override them from the command line, without the need to physically edit the script. Several of the parameters are switched parameters: They only take effect when they are present on the command line. This adds some safety to the script and offers a variety of flexibility in displaying the Help information. To cause the script to actually rename files, you need to run the script with the <b>\u2013rename<\/b> switch. If you want to see what the script would do, you can run it with the <b>\u2013whatif<\/b> switch. <\/p>\n<p>Each of these switches causes the script to execute a different function. The command-line parameters are seen here:<\/p>\n<pre class=\"codeSample\">&nbsp;<\/pre>\n<pre class=\"codeSample\">Param(\n      $path = \"C:\\fso1\",\n      $Prefix = \"Hawaii\",\n      $int = 1,\n      $extension = \".jpg\",\n      [switch]$rename,\n      [switch]$whatif,\n      [switch]$help,\n      [switch]$examples,\n      [switch]$min,\n      [switch]$full\n     )\n<\/pre>\n<p>The <b>Rename-Files<\/b> function is used to rename the files in the folder. To do this, it uses the <b>Get-ChildItem<\/b> cmdlet to obtain a collection of all the files in the folder specified by the <b>$path<\/b> variable. It then uses the <b>ForEach<\/b> statement to walk through the collection of files. If an item in the collection is a folder (indicated by the <b>psIsContainer<\/b> property), it is skipped. Also if the file is an .avi file, it is also skipped. Once the function has filtered out the distracters, it calls the <b>Rename-Item<\/b> cmdlet to rename the file by using the pattern, the prefix, integer, and file extension. The integer is the next number in the sequence starting with the value the <b>$int<\/b> variable is set to. By default it will start numbering at 1. The <b>$int<\/b> variable is then incremented by one, and the process starts again. The <b>Rename-Files<\/b> function is seen here:<\/p>\n<pre class=\"codeSample\">&nbsp;<\/pre>\n<pre class=\"codeSample\">function Rename-Files()\n {\n  $colFiles = get-childitem -path $path\n  Foreach($file in $colFiles)\n   {\n    if(!$file.psIsContainer)\n       {\n        if ($file.extension -eq \".avi\") { \"skipping $file\" }\n        ELSE\n         {\n          rename-item -path $file.fullname -newname $Prefix$int$extension\n          $int++\n         }\n       } #end if\n   } #end foreach\n } #end rename-Files\n&nbsp;<\/pre>\n<p>The <b>Get-HelpTopic<\/b> function is the longest section of the script. It uses a <b>here<\/b> string to create the Help topic. The Help topic is stored in different variables and is displayed in response to different command-line switches. This enables the <b>RenameFiles.ps1<\/b> script to behave similarly to Windows PowerShell cmdlets. For more information about this technique, you can refer to the Microsoft Press book, <a href=\"http:\/\/www.microsoft.com\/MSPress\/books\/authors\/auth9541.aspx\" target=\"_blank\">Windows PowerShell Scripting Guide<\/a>.<\/p>\n<p>A <b>here<\/b> string begins with the <b>@&#8221;<\/b> and ends with <b>&#8220;@<\/b>. There are different sections of the Help text. Each section is assigned to a different variable. The sections are the description, the examples, and the remarks. This is seen here (in a truncated fashion):<\/p>\n<pre class=\"codeSample\">$descriptionText= `\n@\"\n NAME: RenameFiles.ps1\n DESCRIPTION:\n\"@\n$examplesText= `\n@\"\n SYNTAX:\n RenameFiles.ps1\n\"@\n$remarks = `\n\"\nREMARKS\n\"@\n<\/pre>\n<p>Depending on which combination of command-line switches was used in launching the script, we will print out the value of the different variables. This evaluation is done by using a series of <b>if<\/b> statements as seen here:<\/p>\n<pre class=\"codeSample\">if($examples) { $examplesText ; $remarks ; exit }\n  if($full)     { $descriptionText; $examplesText ; exit }\n  if($min)      { $descriptionText ; exit }\n  $descriptionText; $remarks\n  Exit\n<\/pre>\n<p>Did&nbsp;you ever wonder what would happen when you typed a command on the command line? The Windows PowerShell team solved that eternal question by implementing the <b>whatif<\/b> switch. I thought it was a great idea, and implemented it in the <b>RenameFiles.ps1<\/b> script as well. It is useful not only from a &#8220;Gee, I wonder what happens when I type this command&#8221; but also from a troubleshooting perspective, in that it will display the values of the variables you supply to the script. The <b>Get-Whatif<\/b> function is called when the script is run with the <b>\u2013whatif<\/b> parameter. It tells you which operation will be performed, the prefix, the starting integer, file extension, and a sample file name. The <b>Get-Whatif<\/b> function is seen&nbsp;here: <\/p>\n<pre class=\"codeSample\">Function Get-WhatIf()\n{\n \"\n  what if: Perform operation rename files in $path\n  using prefix $prefix beginning with number $int\n  using extension $extension.\n  filenames will be pattern: $Prefix$int$extension\n \"\n exit\n} #end Get-WhatIf\n<\/pre>\n<p>The remainder of the script is the actual entry point. It is used to evaluate the command-line switches and to call the appropriate functions. This is seen :<\/p>\n<pre class=\"codeSample\">if($examples)  { Get-HelpTopic }\nif($full)      { Get-HelpTopic }\nif($whatif)    { Get-WhatIf }\nif($help)      { Get-HelpTopic }\nif(!$rename)   {\"missing parameter\" ; Get-HelpTopic }\nif($rename)    { Rename-Files }\n<\/pre>\n<p>Well, TW, that is it for the <b>RenameFiles.ps1<\/b> script. As you can see, even though the script was rather long, it was rather easy to follow. The pattern of using functions to encapsulate the logic for separate pieces of functionality is a pretty good practice. In addition, the <b>Get-HelpTopic<\/b> function can add a new level of usability to your scripts. We will see you tomorrow when Desktop Week continues.<\/p>\n<p>&nbsp;<\/p>\n<p><b>Ed Wilson and Craig Liebendorfer, Scripting Guys<\/b><\/p>\n","protected":false},"excerpt":{"rendered":"<p>My scripting husband travels a great deal with his job, and he takes these really cool pictures. Unfortunately, he is somewhat lazy about downloading the pictures from the camera. As a result, we have pictures from Hawaii that are named Phoenix_Desert_05.jpg. Obviously, I know the difference between a desert and a beach, but it is [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[38,3,12,45],"class_list":["post-54463","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-files","tag-scripting-guy","tag-storage","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>My scripting husband travels a great deal with his job, and he takes these really cool pictures. Unfortunately, he is somewhat lazy about downloading the pictures from the camera. As a result, we have pictures from Hawaii that are named Phoenix_Desert_05.jpg. Obviously, I know the difference between a desert and a beach, but it is [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/54463","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=54463"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/54463\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=54463"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=54463"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=54463"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}