Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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
add comment

1 Answer

up vote 2 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
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.