Powershell for archiving old data

Welcome Forums General PowerShell Q&A Powershell for archiving old data

This topic contains 20 replies, has 2 voices, and was last updated by

 
Participant
2 months, 1 week ago.

  • Author
    Posts
  • #156089

    Participant
    Topics: 1
    Replies: 10
    Points: 17
    Rank: Member
  • #156111

    Participant
    Topics: 1
    Replies: 1529
    Points: 2,587
    Helping Hand
    Rank: Community Hero

    You have to ask a specific question about Powershell code you wrote. Id would be helpful as well when you post the code you already have and explain what's not working as expected.

    • #156113

      Participant
      Topics: 1
      Replies: 10
      Points: 17
      Rank: Member

      This is what I have so far, but I'd like to add a shortcut for each file that is deleted with the name of the file.ARCHIVED

       

      # Delete all Files in C:\temp older than 30 day(s)
      $Path = "C:\temp"
      $Daysback = "-30"

      $CurrentDate = Get-Date
      $DatetoDelete = $CurrentDate.AddDays($Daysback)
      Get-ChildItem $Path -Recurse ( | Where-Object { $_.LastWriteTime -lt $DatetoDelete } | Remove-Item

  • #156117

    Participant
    Topics: 1
    Replies: 1529
    Points: 2,587
    Helping Hand
    Rank: Community Hero

    Correct me if I'm wrong but you're not archiving the files – you're deleting them. Instead of the Remove-Item you could use a Foreach-Object loop, copy the files to a location of your choice and with the New-Item cmdlet with the parameter -ItemType eihter with SymbolicLink, Junction or HardLink you can create the shortcut.

    Regardless of that – when you post code please format it as code using the code tag button (pre) of the icon bar of the post editor.

  • #156125

    Participant
    Topics: 1
    Replies: 10
    Points: 17
    Rank: Member

    Apologies for not using the code tag. Let me try explain what I'm trying to achieve as I'm fairly new to Powershell.

    We have a file server with several gigabytes of old data within various folders. We don't have to move the files to another location as we'll be creating a backup for the file server so we can restore the data should we need to at a later date.

     

    What we want to do is rename the file being deleted with a marker with its original_ARCHIVED. We know the files aren't being archived but rather deleted, so our users will assume the files were archived.

    If you know a way of doing this, please can you post the code I'd really appreciate it. Thanks

  • #156128

    Participant
    Topics: 1
    Replies: 1529
    Points: 2,587
    Helping Hand
    Rank: Community Hero

    Ah ... ok ... that's even easier. Instead of creating a working shortcut you just use the original file name and create an empty file with the specified name change ... like this:

    $Path = "C:\temp"
    $Daysback = "-30"
    
    $CurrentDate = Get-Date
    $DatetoDelete = $CurrentDate.AddDays($Daysback)
    Get-ChildItem -Path $Path -Recurse  | 
        Where-Object { $_.LastWriteTime -lt $DatetoDelete } | 
            ForEach-Object {
                Remove-Item -Path $_.FullName
                $NewName = Join-Path -Path $_.Directory -ChildPath ($_.BaseName + '_archived' + $_.Extension)
                New-Item -Path $NewName -ItemType File
            }
  • #156222

    Participant
    Topics: 1
    Replies: 10
    Points: 17
    Rank: Member

    Thanks so much for your assistance with this script, I'll be testing it this evening when I can arrange an outage. One more query, if I wanted to date stamp the name of the file after _archived. Would that be possible?

  • #156245

    Participant
    Topics: 1
    Replies: 1529
    Points: 2,587
    Helping Hand
    Rank: Community Hero

    Would that be possible?

    Yes. Definitely. 😉

  • #156248

    Participant
    Topics: 1
    Replies: 10
    Points: 17
    Rank: Member

    Would you mind updating your script to include this please? I'd really appreciate it. Thanks

    • #156254

      Participant
      Topics: 1
      Replies: 1529
      Points: 2,587
      Helping Hand
      Rank: Community Hero

      Actually yes. I'm sure you will be able to figure that out by yourself really fast. Just try to analize what the code does and google how to do a time stamp in Powershell and you will become a Powershell hero really quickly. 😉
      Good luck and have a lot of fun.

  • #156264

    Participant
    Topics: 1
    Replies: 10
    Points: 17
    Rank: Member

    Will try and workout how I do this over the weekend. Really appreciate all your help with this query. Thanks

  • #156293

    Participant
    Topics: 1
    Replies: 10
    Points: 17
    Rank: Member

    Finally cracked it, thought I'd share my code with you. Would you have done it another way?

    $Path = "C:\temp"
    $Daysback = "-30"
    
    $CurrentDate = Get-Date
    $DatetoDelete = $CurrentDate.AddDays($Daysback)
    $time = get-date -format dd-MM-yyyy
    
    Get-ChildItem -Path $Path -Recurse  | 
        Where-Object { $_.LastWriteTime -lt $DatetoDelete } | 
            ForEach-Object {
                Remove-Item -Path $_.FullName
                $NewName = Join-Path -Path $_.Directory -ChildPath ($_.BaseName + '_archived_' + $time + $_.Extension)
                New-Item -Path $NewName -ItemType File
            }
  • #156297

    Participant
    Topics: 1
    Replies: 1529
    Points: 2,587
    Helping Hand
    Rank: Community Hero

    Great. I'm proud of you. And thanks for sharing.

    To simplify your code a tiny bit ... you already have a DateTime in a variable ... you can use this:

    $Path = "C:\temp"
    $Daysback = "-30"
    
    $CurrentDate = Get-Date
    $DatetoDelete = $CurrentDate.AddDays($Daysback)
    
    Get-ChildItem -Path $Path -Recurse  | 
        Where-Object { $_.LastWriteTime -lt $DatetoDelete } | 
            ForEach-Object {
                Remove-Item -Path $_.FullName
                $NewName = Join-Path -Path $_.Directory -ChildPath ($_.BaseName + '_archived_' + $($CurrentDate.ToString('dd-MM-yyyy')) + $_.Extension)
                New-Item -Path $NewName -ItemType File
            }
  • #156300

    Participant
    Topics: 1
    Replies: 10
    Points: 17
    Rank: Member

    Thanks for the feedback, I'll definitely keep practising and hopefully manage to master Powershell in the future.

     

    Just incase I want to run this script on other servers which have multiple drives (C: E: F:) can I add these to the $Path or would you suggest another way?

  • #156306

    Participant
    Topics: 1
    Replies: 1529
    Points: 2,587
    Helping Hand
    Rank: Community Hero

    Just incase I want to run this script on other servers which have multiple drives (C: E: F:) can I add these to the $Path or would you suggest another way?

    There are a lot of improvements thinkable. You could it simply wrap it in a loop iterating over the drives one after the other. Or you could run it in parallel to increase the speed.. Or you could provide the drive you like to treat as a parameter to decide case by case what drive to treat ... 😉

  • #161796

    Participant
    Topics: 1
    Replies: 10
    Points: 17
    Rank: Member

    Would you recommend I search multiple drives (C,E,F) like this or should I use get-psdrive -p "FileSystem ?

    $Path = "C:\","E:\","F:\"
    $Daysback = "-30"
    
    $CurrentDate = Get-Date
    $DatetoDelete = $CurrentDate.AddDays($Daysback)
    
    Get-ChildItem -Path $Path -Recurse  | 
        Where-Object { $_.LastWriteTime -lt $DatetoDelete } | 
            ForEach-Object {
                Remove-Item -Path $_.FullName
                $NewName = Join-Path -Path $_.Directory -ChildPath ($_.BaseName + '_archived_' + $($CurrentDate.ToString('dd-MM-yyyy')) + $_.Extension)
                New-Item -Path $NewName -ItemType File
            }
  • #161822

    Participant
    Topics: 1
    Replies: 1529
    Points: 2,587
    Helping Hand
    Rank: Community Hero

    Would you recommend I search multiple drives (C,E,F) like this or should I use get-psdrive -p "FileSystem ?

    That depends pretty much on what you expect your script to do. If you're sure about to treat always really all local drives you can give it go with Get-PSDrive. If you like to control what local drives to treat you should provide the drive letters explicitly.

  • #165922

    Participant
    Topics: 1
    Replies: 10
    Points: 17
    Rank: Member

    Hi There,

    With my script above is there a way I can pipe the files that change into a CSV?

    Thanks

     

  • #165937

    Participant
    Topics: 1
    Replies: 1529
    Points: 2,587
    Helping Hand
    Rank: Community Hero

    With my script above is there a way I can pipe the files that change into a CSV?

    Sure ... why not? You have the FullName of the file you want to change and you have the $NewName. A good way could be to collect the information you're after in a [PSCustomObject] inside the loop and output it at the end.

  • #166075

    Participant
    Topics: 1
    Replies: 10
    Points: 17
    Rank: Member

    I've changed my script to this but unfortunately it's not outputting to a CSV. Could you possible confirm where I've gone wrong? Thanks

    $Path = "F:\","G:\","H:\"
    $Daysback = "-30"
    $filesRenamed = ""
    
    
     
    
    $CurrentDate = Get-Date
    $DatetoDelete = $CurrentDate.AddDays($Daysback)
    
     
    
    
    Get-ChildItem -Path $Path -Recurse -Attributes !Directory+!System  | 
        Where-Object { $_.LastWriteTime -lt $DatetoDelete `
            -and $_.FullName -notlike "F:\Snap Server\*" `
            -and $_.FullName -notlike "H:\Apps\*" } |
            ForEach-Object {
                $filesRenamed = $filesRenamed + "," + $_.FullName
                Remove-Item -Path $_.FullName
                $NewName = Join-Path -Path $_.Directory -ChildPath ($_.BaseName + '_archived_' + $($CurrentDate.ToString('dd-MM-yyyy')) + $_.Extension)
                New-Item -Path $NewName -ItemType File
            }
            $filesRenamed.TrimStart(",")
    
     
    
            write-host "Files that have been renamed: " + $filesRenamed >> C:\Scripts\RenamedFiles.csv
  • #166094

    Participant
    Topics: 1
    Replies: 1529
    Points: 2,587
    Helping Hand
    Rank: Community Hero

    ... should work like this ...

    $Path = 'F:\','G:\','H:\'
    $Daysback = '-30'
    $CurrentDate = Get-Date
    $DatetoDelete = $CurrentDate.AddDays($Daysback)
    
    $Result = Get-ChildItem -Path $Path -Recurse -File | 
        Where-Object { $_.LastWriteTime -lt $DatetoDelete -and $_.FullName -notlike 'F:\Snap Server\*' -and $_.FullName -notlike 'H:\Apps\*' } |
            ForEach-Object {
                Remove-Item -Path $_.FullName
                $NewName = Join-Path -Path $_.Directory -ChildPath ($_.BaseName + '_archived_' + $($CurrentDate.ToString('dd-MM-yyyy')) + $_.Extension)
                New-Item -Path $NewName -ItemType File | Out-Null
                [PSCustomObject]@{
                    Original = $_.FullName
                    NewItem = $NewName
                }
            }
    
    $Result | Export-Csv -Path C:\Scripts\RenamedFiles.csv -NoTypeInformation

You must be logged in to reply to this topic.