TwistedHelixis Posted April 18, 2018 Posted April 18, 2018 Hello, I assume someone has probably done something like this before and and can just paste what they have done, as I am no good at scripts. Twice a week I need to copy a file on our backup server to a USB drive. The USB drive is only large enough to store 3 of the backup files. I have been doing this manually until now with folder 1,2, & 3 on the USB drive and I copy the file which is in a folder on the servers C drive to one of the folders on the USB drive. I assume a little script and task scheduler should be able to achieve the same thing. BTW the file on the server I need to copy is - C:\iSCSIVirtualDisks\man-vd.vhdx and the USB drive is allocated to the E drive. Many thanks
Carm01 Posted April 18, 2018 Posted April 18, 2018 So, you want the oldest file to be deleted on E:\ and replaced with the newest man-vd.vhdx file , correct ? 1
ShellfishClive Posted April 18, 2018 Posted April 18, 2018 (edited) [color=#696969][font=Monaco]$file="C:\Scripts\Count.txt" $count=Get-Content$file $1=1 $2=2 $3=3 if($count-eq1){ Write-Host"Backup 1" Copy-Item"C:\iSCSIVirtualDisks\man-vd.vhdx"-Destination "E:\Folder 1" Clear-Content$file $2|Set-Content$file } elseif($count-eq2){ Write-Host"Backup 2" Copy-Item"C:\iSCSIVirtualDisks\man-vd.vhdx"-Destination "E:\Folder 2" Clear-Content$file $3|Set-Content$file } else { Write-Host"Backup 3" Copy-Item"C:\iSCSIVirtualDisks\man-vd.vhdx"-Destination "E:\Folder 3" Clear-Content$file $1|Set-Content$file } [/font][/color] This should do what you need, it reads a number from the text file and then backups to that number. When the script finishes it changes the number in the text file so the next time the script runs it will point to the next location and will loop everytime it runs. Hope it helps, let me know if you use it or need help understanding it. Edited April 18, 2018 by ShellfishClive 1
TwistedHelixis Posted April 18, 2018 Author Posted April 18, 2018 So, you want the oldest file to be deleted on E:\ and replaced with the newest man-vd.vhdx file , correct ? Yes @ShellfishClive - Thanks I will do some testing with that.
TwistedHelixis Posted April 18, 2018 Author Posted April 18, 2018 Hmmm can't get the script to work. I created C:\Scripts\Count.txt and made sure I had Folder 1 etc in the E drive. What should I save the script as. I used script.bat - - - Updated - - - oooops hold on
TwistedHelixis Posted April 18, 2018 Author Posted April 18, 2018 OK so testing on windows 10 pc & just using a txt file as the test file to copy it does not work. Deleting everything and just having this one line still does not work Copy-Item"C:\iSCSIVirtualDisks\man-vd.txt"-Destination "E:\Folder 1" What am I doing wrong? 1
TwistedHelixis Posted April 18, 2018 Author Posted April 18, 2018 saved as .ps1 still not working. added a space after Copy-Item and it just copied
TwistedHelixis Posted April 18, 2018 Author Posted April 18, 2018 Giving up for the moment - added all the lines back in to the script and it does not run.
Guest Guest Posted April 18, 2018 Posted April 18, 2018 Your command is not correct it should be: copy-item -path “c:\iscsivirtualdisks\man-vf.txt” - destination “e:\folder 1”
ShellfishClive Posted April 18, 2018 Posted April 18, 2018 (edited) -Path shouldn't matter too much as it knows the first directory is the one that the file should move from. Try running it as admin in ISE mode. In the count.txt file put a 1 in there that predefined as the first number, if it's still erroring would you be able to send me the error message that you are having, it's working fine for me. Sorry for the late reply. Edit: I have attached the file here: Backup Script.ps1 I believe the copying and paste method was messing with the formatting of the document which would cause issues. Edited April 18, 2018 by ShellfishClive 1
Carm01 Posted April 18, 2018 Posted April 18, 2018 I created an AutoIT script that will create a list of all files in question, and get the last modified time from them , sort them from oldest to newest and then isolate the oldest one , delete it, and replace the current one from C:\iSCSIVirtualDisks\man-vd.vhdx to the correct folder. You will need to compile this to an exe via AutoIT and https://www.autoitscript.com/cgi-bin/getfile.pl?autoit3/autoit-v3-setup.exe and you will need the editor https://www.autoitscript.com/cgi-bin/getfile.pl?../autoit3/scite/download/SciTE4AutoIt3.exe You can run this by pressing F5 in after saving the contents of this script into a txt file and renaming to .au3 file You can test it with other file types if you wish There are comments listed in here and things can be commented out to not display information I am presenting the version that has the comments in and another without comments and you are satisfied with the results. I am not sure if this is something you would be interested in working with or not but thought I would provide what I came up with. Use this one to see the results #RequireAdmin #include #include Dim $b[1][2] $filepath = 'E:\' ; this will bethe file/folder path $a = _FileListToArrayRec($filepath, '*.vhdx', $FLTAR_FILES, $FLTAR_RECUR, "", $FLTAR_FULLPATH) ; creates a list of all files within all subfolders of files with the extension .vhdx. YOU WILL HAVE TO CHANGE THE EXTENSION AFTER YOU ARE SATISIFIED _ArrayDisplay($a); displays current files with .vhdx extension remove, add a ; in front of _Arraydisplay to comment it out For $i = 1 To UBound($a) - 1 ; creates a loop of 1 to $a , $a being how many files are in the list $c = FileGetTime($a[$i], $FT_MODIFIED, $FT_STRING) ; gets last modified time the format is as follows: YYYYMMDDHHMMSS and sets to the variable $c $d = $a[$i] ; sets the full file path to the variable $d $fill = $d & "|" & $c ; creates a multi-dimensional array with the full file path in one column and the last modified time in the second column _ArrayAdd($b, $fill) ; adds it to the array Next _ArrayDisplay($b) ;displays current list _ArraySort($b, 0, 0, 0, 1) ; sorts the second column of files assending so the oldest will be on top _ArrayDisplay($b) ; displays the sorted list MsgBox(0, "this is the oldest file on the list", $b[1][0]) ; lists the oldest file $f = StringSplit($b[1][0], '\'); splits the string based on '\' so we can isolate the folder $j = $filepath & $f[uBound($f) - 2]; rebuilds the file path for the replacement file minus the file name MsgBox(0, "folder path for new file", $j); displays the folder where the new file is going to go this can be commented out when compiled. ;FileDelete($b[1][0]) ; deletes the oldest file ;FileCopy('C:\iSCSIVirtualDisks\man-vd.vhdx', $b[1][0],1) Use this one if out are satisfied and ready for a test #RequireAdmin #include #include Dim $b[1][2] $filepath = 'E:\' ; this will be E:\ in your case $a = _FileListToArrayRec($filepath, '*.vhdx', $FLTAR_FILES, $FLTAR_RECUR, "", $FLTAR_FULLPATH) ; creates a list of all files within all sub-folders of files with the extension .vhdx. YOU WILL HAVE TO CHANGE THE EXTENSION AFTER YOU ARE SATISIFIED ;_ArrayDisplay($a); displays current files with .vhdx extension remove, add a ; in front of _Arraydisplay to comment it out For $i = 1 To UBound($a) - 1 ; creates a loop of 1 to $a , $a being how many files are in the list $c = FileGetTime($a[$i], $FT_MODIFIED, $FT_STRING) ; gets last modified time the format is as follows: YYYYMMDDHHMMSS and sets to the variable $c $d = $a[$i] ; sets the full file path to the variable $d $fill = $d & "|" & $c ; creates a multi-dimensional array with the full file path in one column and the last modified time in the second column ;_ArrayAdd($b, $fill) ; adds it to the array Next ;_ArrayDisplay($b) ;displays current list ;_ArraySort($b, 0, 0, 0, 1) ; sorts the second column of files assending so the oldest will be on top ;_ArrayDisplay($b) ; displays the sorted list ;MsgBox(0, "this is the oldest file on the list", $b[1][0]) ; lists the oldest file $f = StringSplit($b[1][0], '\'); splits the string based on '\' so we can isolate the folder $j = $filepath & $f[uBound($f) - 2]; rebuilds the file path for the replacement file minus the file name ;MsgBox(0, "folder path for new file", $j); displays the folder where the new file is going to go this can be commented out when compiled. FileDelete($b[1][0]) ; deletes the oldest file FileCopy('C:\iSCSIVirtualDisks\man-vd.vhdx', $b[1][0],1) 1
TwistedHelixis Posted April 18, 2018 Author Posted April 18, 2018 @ShellfishClive That has worked on my desktop pc. I will see if I have time to test it on my backup server tomorrow. Thanks for taking the time to do this for me, its really appreciated.
TwistedHelixis Posted April 18, 2018 Author Posted April 18, 2018 @Carm01 thanks also for taking the time to do this. I will test both methods out and see which works best for my setup.
Arthur Posted April 19, 2018 Posted April 19, 2018 (edited) I hope you don't mind another PowerShell script? I thought I would have a go too. #Requires -Version 3.0 $Source = "C:\iSCSIVirtualDisks\man-vd.vhdx" $Destination = "E:\" $TargetDir = "{0}{1}" -f $Destination, ((Get-ItemProperty $Source).LastWriteTime).ToString("yyyy-MM-dd HH.mm.ss") If (-not(Test-Path "$TargetDir")) { $Null = New-Item "$TargetDir" -Type Directory; Copy-Item -Path "$Source" -Destination "$TargetDir" -ErrorAction Stop -Verbose } Get-ChildItem -Path $Destination -Directory | Where-Object { $_.Name -match "^\d{4}-\d{2}-\d{2} \d{2}\.\d{2}\.\d{2}$"} | Sort-Object LastWriteTime -Descending | Select-Object -Skip 3 | Remove-Item -Force -Recurse This script copies man-vd.vhdx to a subfolder on your USB drive based on the VHDXs modified date and keeps the last three most recent backups. To save time, if the VHDX doesn't change the file isn't copied again. The main advantages to my script is that you don't require any additional software and it doesn't write any files to the C: drive. I have tested it on Windows 10 and it worked perfectly. Edited April 19, 2018 by Arthur 1
TwistedHelixis Posted April 19, 2018 Author Posted April 19, 2018 I hope you don't mind another PowerShell script? Not at all, the more the merrier. I am to busy to test them today, but thanks to everyone who has helped.
ShellfishClive Posted April 19, 2018 Posted April 19, 2018 Not at all, the more the merrier. I am to busy to test them today, but thanks to everyone who has helped. Let me know if you need a hand with anything I should be around today. I am sure @Arthur will beat me though 2
TwistedHelixis Posted April 19, 2018 Author Posted April 19, 2018 Its amazing how many different ways there are to achieve the same goal. One question, with @Arthur script, when all 3 folders and files are on the USB drive will it delete the oldest folder before it starts to copy the forth folder or does it delete it after it's copied the fourth folder? I can see the remove-item but this is at the end of the script, hence why I am asking.
Arthur Posted April 20, 2018 Posted April 20, 2018 (edited) when all 3 folders and files are on the USB drive will it delete the oldest folder before it starts to copy the forth folder or does it delete it after it's copied the fourth folder? I can see the remove-item but this is at the end of the script, hence why I am asking. Good question. The script in post #14 will delete the oldest folder after the .vhdx has been copied which means there would be a (temporary) fourth folder. It sounds like there may not be room for the fourth folder so what you could do is do the deletion before the copy and change the "Select-Object -Skip" from 3 to 2 so there will always be enough disk space to copy the third .vhdx. i.e. #Requires -Version 3.0 $Source = "C:\iSCSIVirtualDisks\man-vd.vhdx" $Destination = "E:\" $TargetDir = "{0}{1}" -f $Destination, ((Get-ItemProperty $Source).LastWriteTime).ToString("yyyy-MM-dd HH.mm.ss") Get-ChildItem -Path $Destination -Directory | Where-Object { $_.Name -match "^\d{4}-\d{2}-\d{2} \d{2}\.\d{2}\.\d{2}$"} | Sort-Object LastWriteTime -Descending | Select-Object -Skip 2 | Remove-Item -Force -Recurse If (-not(Test-Path "$TargetDir")) { $Null = New-Item "$TargetDir" -Type Directory; Copy-Item -Path "$Source" -Destination "$TargetDir" -ErrorAction Stop -Verbose } However, the issue with this is that because the backup folders are based on the the last modified date/time of the .vhdx file you could end up with only two backups the next time the script is run if the file doesn't change. To solve that you could create the folders based on the date/time the script is run... #Requires -Version 3.0 $Source = "C:\iSCSIVirtualDisks\man-vd.vhdx" $Destination = "E:\" $TargetDir = "{0}{1}" -f $Destination, (Get-Date).ToString("yyyy-MM-dd HH.mm.ss") Get-ChildItem -Path $Destination -Directory | Where-Object { $_.Name -match "^\d{4}-\d{2}-\d{2} \d{2}\.\d{2}\.\d{2}$"} | Sort-Object LastWriteTime -Descending | Select-Object -Skip 2 | Remove-Item -Force -Recurse If (-not(Test-Path "$TargetDir")) { $Null = New-Item "$TargetDir" -Type Directory; Copy-Item -Path "$Source" -Destination "$TargetDir" -ErrorAction Stop -Verbose } This obviously has the opposite issue (which may/may not be a problem in your case?) whereby if the .vhdx doesn't change, each time the script is run you could potentially end up with three backups with identical .vhdx files. Edited April 20, 2018 by Arthur
TwistedHelixis Posted April 24, 2018 Author Posted April 24, 2018 Been very busy so not had time to look at the code you posted. Going to give this some thought as both options would work, I just need to work through the what if scenarios. Thanks
TwistedHelixis Posted May 12, 2018 Author Posted May 12, 2018 BTW I went with option 1 of the two scripts in #18 Even though it does delete the 3rd backup if the vhdx as not changed, I still have two I can access. Option 2 will eventually overwrite all the backups if the vhdx does not change, and if that happened to be a faulty vhdx file, that could be an issue.
TwistedHelixis Posted May 12, 2018 Author Posted May 12, 2018 Whats the best way of setting up task scheduler to run this script, do I need to run powershell as a task?
Katy Posted May 13, 2018 Posted May 13, 2018 Whats the best way of setting up task scheduler to run this script, do I need to run powershell as a task? I'd save it as a .ps1 file then a scheduled task to run powershell.exe with scriptname.ps1 as the parameter (unless there's a special powershell section these days in which case do it that way)
TwistedHelixis Posted May 25, 2018 Author Posted May 25, 2018 (edited) Hi, me again. When the script runs manually it creates the backup file on the USB drive, but the file size of the file is the full size it will eventually be, this is OK if I run the script manually as the Powershell cmd windows remains open for the duration of the copy process, EDIT so when the cmd window closes I can tell it has actually finished. When the script runs using task scheduler the task displays running for a second and then goes back to ready, there is no Powershell window cmd open and I have no idea if the script is still copying. I can see the new folder has been created and the full sized container file has been created. BTW - the copy process should take about 5 hours. Is there anyway of knowing if the task / script is running? Edited May 25, 2018 by TwistedHelixis
Arthur Posted May 25, 2018 Posted May 25, 2018 Is there anyway of knowing if the task / script is running? In Task Scheduler does the task have a status of 'Running' or 'Ready'? You could also check Task Manager to see if PowerShell.exe is running there. What do you have for your scheduled task action commands? e.g. [b]Action[/b] = Start a program [b]Program/script[/b] C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe [b]Add arguments (optional)[/b] -NonInteractive -NoLogo -NoProfile -File "X:\Path\To\Script.ps1" 1
TwistedHelixis Posted May 25, 2018 Author Posted May 25, 2018 I have just gone back on the server and it does now show the task as running. I set task as follows, should I use the parameters supplied by @Arthur ? Program/script powershell Add arguments (optional) X:\Path\To\Script.ps1
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now