My goal is to have a .bat that I can use to automatically archive folders via copy, rename the original folder and the files within with the current date and then clean out old production files.
- Copy target folders to the "Completed" directory
- Update date on the source folders using the format
Previous Name_Today's Date
(MMDDYY) - Update the date of the INDD files within the source folder using the format
Current Name_Today's Date
(MMDDYY) - "Clean" the source folder by deleting all .VPS and .PDFs files within the source folder
I am a novice but I have pieced together this code from research and sources:
@echo off
setlocal enabledelayedexpansion
for /f "skip=1" %%x in ('wmic os get localdatetime') do if not defined MyDate set MyDate=%%x
set today=%MyDate:~0,4%-%MyDate:~4,2%-%MyDate:~6,2%
xcopy /s /e /q /y "G:\...\Annual_*" "G:\...\_DONE\"
xcopy /s /e /q /y "G:\...\Life_*" "G:\...\_DONE\"
MOVE "G:\...\Annual_*" "G:\...\Annual_today"
MOVE "G:\...\Life_today" "G:\...\Life_today"
FOR /M *.indd /C "cmd /c rename @file \"@fname - today.indd\""
del /s "G:\...\Annual_today" *.pdf
del /s "G:\...\Annual_today" *.vps
del /s "G:\...\Life_today" *.pdf
del /s "G:\...\Life_today" *.vps
"G:\...\New_Job.bat" > output.txt
My end goal is to be able to change the directory path for the source and archive folders so I can reuse this script for different clients files.
Current Issues
As it stands the script doesn't copy and create an archive folder files and just, deletes all VPS and PDF files from all directories, not just the target folder.
I'm not sure if I'm performing the date check correctly to then use it as a variable to rename future folders and files.
I don't know if FOR /M *.indd /C "cmd /c rename @file \"@fname - today.indd\""
is correct to rename the files. The names are a PO number (6digits) then a title, underscore and then the date.
123456_Life_Kit_020819 for example.
Help would be greatly appreciated!
Here's an Example of what the script should do
Copies the WHOLE folder to the _OLD/Archive folder for each one. Then renames the folder and the contents extensions to the "current date". Then deletes the .pdf and .vps files in the NEW date directories only.
Here is an example of the folder structure.
Main directory:
Inside one of the subdirectories:
The only things I'm trying to rename are the MAIN directory folders with the dates (after copying) and then the files within the subdirectory.
No other folders need to be renamed.
Answer
I've included a batch script below that is sort of hybrid since it uses PowerShell but it dynamically builds and executes it but the archive destination per the dest=
variable value is used for processing accordingly.
I did use an approach with Robocopy to exclude the file extension types that you want recursively deleted from the destination/archive folder so it simply doesn't copy unnecessarily and thus no need to delete.
I used a whole bunch of PowerShell cmdlets and such so rather than list them all out, I've included some of those in the Further Resources section for additional learning if you desire to understand further.
Batch Script
Note: Just set the the source, destination, and excluded files per the correlated variables (
src=
,dest=
, andexcludedFiles=
) at
the top of the script below then simply click to run.
SET "src=G:\Folder\Production"
SET "dest=G:\Folder\__Archive"
SET "fname=*.*"
SET "excludedFiles=*.pdf *.vps"
Robocopy "%src%" "%fname%" "%dest%" /E /XF %excludedFiles%
CALL :PSScript
SET PowerShellDir=C:\Windows\System32\WindowsPowerShell\v1.0
CD /D "%PowerShellDir%"
Powershell -ExecutionPolicy Bypass -Command "& '%PSScript%'"
IF EXIST "%PSScript%" DEL /Q /F "%PSScript%"
EXIT
:PSScript
SET PSScript=%temp%\~tmp%~n0.ps1
IF EXIST "%PSScript%" DEL /Q /F "%PSScript%"
ECHO $Main ^= "%dest%"; >"%PSScript%"
ECHO $Today ^= ^(^("{0:MMddyy}" -f ^(get-date^).AddHours^(0^)^).ToString^(^)^) >>"%PSScript%"
ECHO $Folders ^= ^(Get-ChildItem -Directory $Main ^| ^? {$_ -match "([0-9]{6})"}^); >>"%PSScript%"
ECHO $Folders ^| %% { >>"%PSScript%"
ECHO If^($_ -match "([0-9]{6})"){ >>"%PSScript%"
ECHO $root ^= ^(Split-Path -path $_.Fullname^); >>"%PSScript%"
ECHO $oBase ^= ^(Split-Path -path $_.Fullname -leaf^); >>"%PSScript%"
ECHO $nBase ^= ^($oBase.Replace^($matches[1],$Today^)^); >>"%PSScript%"
ECHO Rename-Item "$root\$oBase" "$root\$nBase"; >>"%PSScript%"
ECHO } >>"%PSScript%"
ECHO }; >>"%PSScript%"
ECHO $Folders ^= ^(Get-ChildItem -Directory $Main ^| ^? {$_.Name -match "([0-9]{6})"}^).FullName; >>"%PSScript%"
ECHO $Files ^= ^($Folders ^| %% {Get-ChildItem "$_\*" -File -Include *.indd} ^| ^? {$_.Name -match "[0-9]{6}.*?([0-9]{6})"}^); >>"%PSScript%"
ECHO $Files ^| %% { >>"%PSScript%"
ECHO If^($_.Name -match "[0-9]{6}.*?([0-9]{6})"^) >>"%PSScript%"
ECHO { >>"%PSScript%"
ECHO $x ^= $matches[1]; >>"%PSScript%"
ECHO $root ^= ^(Split-Path -path $_.Fullname^); >>"%PSScript%"
ECHO $nName ^= ^($_.Name.Replace^($x,$today^)^); >>"%PSScript%"
ECHO If^(!^(Test-Path "$root\$nName"^)^){Rename-Item $_.FullName "$root\$nName"}; >>"%PSScript%"
ECHO } >>"%PSScript%"
ECHO }; >>"%PSScript%"
GOTO :EOF
PowerShell Logic
Note: This is the PowerShell alone in case you want to use it, but you simply set the
$Main =
variable value to be that of the archive
folder path of the folders and files with themmddyy
string that
gets updated with those characters of the current date when run.
$Main = "G:\Folder\__Archive";
$Today = (("{0:MMddyy}" -f (get-date).AddHours(0)).ToString())
$Folders = (Get-ChildItem -Directory $Main | ? {$_ -match "([0-9]{6})"});
$Folders | % {
If($_ -match "([0-9]{6})"){
$root = (Split-Path -path $_.Fullname);
$oBase = (Split-Path -path $_.Fullname -leaf);
$nBase = ($oBase.Replace($matches[1],$Today));
Rename-Item "$root\$oBase" "$root\$nBase";
}
};
$Folders = (Get-ChildItem -Directory $Main | ? {$_.Name -match "([0-9]{6})"}).FullName;
$Files = ($Folders | % {Get-ChildItem "$_\*" -File -Include *.indd} | ? {$_.Name -match "[0-9]{6}.*?([0-9]{6})"});
$Files | % {
If($_.Name -match "[0-9]{6}.*?([0-9]{6})")
{
$x = $matches[1];
$root = (Split-Path -path $_.Fullname);
$nName = ($_.Name.Replace($x,$today));
If(!(Test-Path "$root\$nName")){Rename-Item $_.FullName "$root\$nName"};
}
};
PowerShell Version 2.0 Compatible Logic
Batch (PS 2.0)
Note: Just set the the source, destination, and excluded files per the correlated variables (
src=
,dest=
, andexcludedFiles=
) at
the top of the script below then simply click to run.
SET "src=G:\Folder\Production"
SET "dest=G:\Folder\__Archive"
SET "fname=*.*"
SET "excludedFiles=*.pdf *.vps"
Robocopy "%src%" "%fname%" "%dest%" /E /XF %excludedFiles%
CALL :PSScript
SET PowerShellDir=C:\Windows\System32\WindowsPowerShell\v1.0
CD /D "%PowerShellDir%"
Powershell -ExecutionPolicy Bypass -Command "& '%PSScript%'"
IF EXIST "%PSScript%" DEL /Q /F "%PSScript%"
EXIT
:PSScript
SET PSScript=%temp%\~tmp%~n0.ps1
IF EXIST "%PSScript%" DEL /Q /F "%PSScript%"
ECHO $Main ^= "%dest%"; >"%PSScript%"
ECHO $Today ^= ^(^("{0:MMddyy}" -f ^(get-date^).AddHours^(0^)^).ToString^(^)^); >>"%PSScript%"
ECHO $Folders ^= ^(Get-ChildItem $Main ^| ^? {^($_.PSIsContainer^) -and ^($_ -match "([0-9]{6})"^)}^); >>"%PSScript%"
ECHO $Folders ^| %% { >>"%PSScript%"
ECHO If^($_ -match "([0-9]{6})"^){ >>"%PSScript%"
ECHO $root ^= ^(Split-Path -path $_.Fullname^); >>"%PSScript%"
ECHO $oBase ^= ^(Split-Path -path $_.Fullname -leaf^); >>"%PSScript%"
ECHO $nBase ^= ^($oBase.Replace^($matches[1],$Today^)^); >>"%PSScript%"
ECHO Rename-Item "$root\$oBase" "$root\$nBase"; >>"%PSScript%"
ECHO } >>"%PSScript%"
ECHO }; >>"%PSScript%"
ECHO $Folders ^= ^(Get-ChildItem $Main ^| ^? {^($_.PSIsContainer^) -and ^($_ -match "([0-9]{6})"^)}^); >>"%PSScript%"
ECHO $Files ^= ^($Folders ^| %% {Get-ChildItem $_.FullName -Recurse -Include *.indd ^| ^? {^(!$_.PSIsContainer^) -and ^($_.Name -match "[0-9]{6}.*?([0-9]{6})"^)}}^);>>"%PSScript%"
ECHO $Files ^| %% { >>"%PSScript%"
ECHO If^($_.Name -match "[0-9]{6}.*?([0-9]{6})"^) >>"%PSScript%"
ECHO { >>"%PSScript%"
ECHO $x ^= $matches[1]; >>"%PSScript%"
ECHO $root ^= ^(Split-Path -path $_.Fullname^); >>"%PSScript%"
ECHO $nName ^= ^($_.Name.Replace^($x,$today^)^); >>"%PSScript%"
ECHO If^(!^(Test-Path "$root\$nName"^)^){Rename-Item $_.FullName "$root\$nName"}; >>"%PSScript%"
ECHO } >>"%PSScript%"
ECHO }; >>"%PSScript%"
GOTO :EOF
PowerShell (PS 2.0)
Easy Execute Note: Save this as a text file with a
.ps1
extension to a folder such asG:\Folder\Archiver.ps1
and then from
the PowerShell command line put a dot, a single blank space, and then
the full script name and path enclosed by double quotes press
Enter
.
$Main = "G:\Folder\__Archive";
$Today = (("{0:MMddyy}" -f (get-date).AddHours(0)).ToString());
$Folders = (Get-ChildItem $Main | ? {($_.PSIsContainer) -and ($_ -match "([0-9]{6})")});
$Folders | % {
If($_ -match "([0-9]{6})"){
$root = (Split-Path -path $_.Fullname);
$oBase = (Split-Path -path $_.Fullname -leaf);
$nBase = ($oBase.Replace($matches[1],$Today));
Rename-Item "$root\$oBase" "$root\$nBase";
}
};
$Folders = (Get-ChildItem $Main | ? {($_.PSIsContainer) -and ($_ -match "([0-9]{6})")});
$Files = ($Folders | % {Get-ChildItem $_.FullName -Recurse | ? {(!$_.PSIsContainer) -and ($_.Name -match "[0-9]{6}.*?([0-9]{6})")}});
$Files | % {
If($_.Name -match "[0-9]{6}.*?([0-9]{6})")
{
$x = $matches[1];
$root = (Split-Path -path $_.Fullname);
$nName = ($_.Name.Replace($x,$today));
If(!(Test-Path "$root\$nName")){Rename-Item $_.FullName "$root\$nName"};
}
};
No comments:
Post a Comment