Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am trying to put together a Powershell script that will:

-Search recursively from a root directory
-Exclude files with existing "yyyyMMdd " file name prefix
-Rename the files not excluded above with ""yyyyMMdd " file name prefix based on their specific LastWriteTime

Note: ideally, this script should include all file type extensions

I have tried myself, but it would seem to be above my head, as my attempts are not going well.

Thanks, in advance.

http://ss64.com/ps/syntax-stampme.html

#StampMe.ps1
param( [string] $fileName)

# Check the file exists
if (-not(Test-Path $fileName)) {break}

# Display the original name
"Original filename: $fileName"

$fileObj = get-item $fileName

# Get the date
$DateStamp = get-date -uformat "%Y-%m-%d@%H-%M-%S"

$extOnly = $fileObj.extension

if ($extOnly.length -eq 0) {
   $nameOnly = $fileObj.Name
   rename-item "$fileObj" "$nameOnly-$DateStamp"
   }
else {
   $nameOnly = $fileObj.Name.Replace( $fileObj.Extension,'')
   rename-item "$fileName" "$nameOnly-$DateStamp$extOnly"
   }

# Display the new name
"New filename: $nameOnly-$DateStamp$extOnly"

I am hoping to change the line:

$DateStamp = get-date -uformat "%Y-%m-%d@%H-%M-%S"

To be LastWriteTime instead of get-date, but I have no idea how to make this happen.

This code (from another Super User question):

Get-ChildItem "Test.pdf" | Rename-Item -newname {$_.LastWriteTime.toString("yyyyMMdd") + " Test.pdf"}

...successfully renames a single file, but I can't seem to integrate this into the larger script.


With regards to running the above recursively, I have tried this (also from http://ss64.com/ps/syntax-stampme.html):

foreach ($file in get-ChildItem *.* -recurse) { ./StampMe.ps1 $file.name }

Which succeeds to apply the PS script to files in the root directory, but fails to apply to any files in the sub-folder tree that propagates from the root directory.

share|improve this question
1  
"my attempts are not going well" - Please show us your code snippets anyway. Remember, we are not a script writing service – nixda Dec 22 '13 at 10:03
    
I don't have any original code snippets, just code I have found searching on the internet. I have edited the main question to include what I have discovered, so far. – Ryan Dec 22 '13 at 23:29
up vote 3 down vote accepted

This script should do exactly what you want

  • Search recursively from a root directory
  • Exclude files with existing "yyyyMMdd " file name prefix
  • Rename the files not excluded above with ""yyyyMMdd " file name prefix based on their specific LastWriteTime

Warning: You should test this script first because renaming could be dangerous. Remove the # in front of Rename-Itemafter you have verified that only intentional files will be renamed.

Long version

$folder = "C:\somefolder"
$files = get-childitem -path $folder -recurse | where { -not $_.PSIsContainer }
[datetime]$dirDate = New-Object DateTime

foreach ($file In $files) {

    $strDate = $file.Name.substring(0,8)

    if (-Not [DateTime]::TryParseExact($strDate, "yyyyMMdd", 
        [System.Globalization.CultureInfo]::InvariantCulture, 
        [System.Globalization.DateTimeStyles]::None, [ref]$dirDate)) {

        $newName = $file.lastwritetime.tostring("yyyyMMdd ") + $file.name
        echo $newName
        #Rename-Item -path $file.Fullname -newname $newName
    }   
}

Short version

[datetime]$dirDate = New-Object DateTime

dir "C:\somefolder" -r | ? { ! $_.PSIsContainer } | % {          

    if ( ! [DateTime]::TryParseExact($_.Name.substring(0,8), "yyyyMMdd", 
        [System.Globalization.CultureInfo]::InvariantCulture, 
        [System.Globalization.DateTimeStyles]::None, [ref]$dirDate)) {

        $newName = $_.lastwritetime.tostring("yyyyMMdd ") + $_.name
        echo $newName
        #Ren $_.Fullname $newName
    }
}

Used stackoverflow answers

share|improve this answer
    
This worked perfectly. Your effort is sincerely appreciated. Thanks. – Ryan Dec 23 '13 at 4:58
    
@Ryan Please remember to accept an answer if you found it helpful. You can click the big checkbox left of an answer to accept it. – Rik Dec 23 '13 at 10:10
    
@Rik. Thanks for the tip. I did try to vote the answer up but was prevented by lack of "reputation". – Ryan Dec 23 '13 at 18:35

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .