Powershell for archiving old data

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

Viewing 18 reply threads
  • Author
    Posts
    • #156089
      Participant
      Topics: 1
      Replies: 10
      Points: 17
      Rank: Member
    • #156111
      Participant
      Topics: 5
      Replies: 2368
      Points: 5,988
      Helping Hand
      Rank: Community MVP

      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: 5
      Replies: 2368
      Points: 5,988
      Helping Hand
      Rank: Community MVP

      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: 5
      Replies: 2368
      Points: 5,988
      Helping Hand
      Rank: Community MVP

      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: 5
      Replies: 2368
      Points: 5,988
      Helping Hand
      Rank: Community MVP

      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: 5
        Replies: 2368
        Points: 5,988
        Helping Hand
        Rank: Community MVP

        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: 5
      Replies: 2368
      Points: 5,988
      Helping Hand
      Rank: Community MVP

      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: 5
      Replies: 2368
      Points: 5,988
      Helping Hand
      Rank: Community MVP

      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: 5
      Replies: 2368
      Points: 5,988
      Helping Hand
      Rank: Community MVP

      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: 5
      Replies: 2368
      Points: 5,988
      Helping Hand
      Rank: Community MVP

      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: 5
      Replies: 2368
      Points: 5,988
      Helping Hand
      Rank: Community MVP

      … 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
Viewing 18 reply threads
  • The topic ‘Powershell for archiving old data’ is closed to new replies.