Search code examples
windowsbatch-filecmdrobocopy

Batch File Copy User Profiles With an Age Limitations


I thought this would be easy but I'm stuck. I have a batch file that will let me back up all 'Actual' (not system) user profiles which is fine & working good. However, an age limitation to the profile folders being backed up has to be applied. Only backing up all the user profiles folder with a last modified date of 60 days is allowed, rather just blind copying the whole lot (time & disk space etc.)

I thought adding the /MAXAGE switch to the robocopy line would suffice but seems even if the profile is recently active (within the date copy criteria) important files older than 60 days within the folder structures are left out - which is not good!

I had a look into Forfiles which seemed would be useable but doesn't deal with folder dates, just files (it seems?). Also the Dir /T:W switch but outputs syntax I can't blend into the current batch file.

Here is the code...

@echo off
pushd %~dp0
color 5F
for /F "Skip=1 Tokens=* Delims=\" %%G in (
'"WMIc Path Win32_UserProfile Where (Special!='True') Get LocalPath"'
    ) Do for /F "delims= " %%H in ("%%G") do (
for /F "Tokens=3,4 delims=\" %%I in ("%%H") do (
robocopy "%%H" "C:\IT\%%I" /XD AppData /XD "Application Data" /XD "Local Settings" /XD *Drive* /MAXAGE:60 /E /R:0 /XA:SH
    )   
  )
)
pause

So my question is, how can I make it check the last modified date of a user profile folder & back it up (including subfolders/files that maybe older than 60 days) as long as the root user profile folder has modified attribute within the last 60 days, else older, dont back up.

Hope that makes sense, thanks for any info / tips anyone may advise.

C:\Users\Admin   Last Mod 12/12/2020 (>backup)
C:\Users\Dez.Smith Last Mod 19/11/2020 (>backup)
c:\Users\Smiley.Pippet Last Mod 16/09/2020 (<dont backup)

etc....

New Code...

@echo off
color 5F
for /f "tokens=2 delims==;." %%a in ('"wmic path Win32_UserProfile where (Special!='True' and LastUseTime is not null) get LastUseTime,LocalPath /VALUE | find "LastUseTime""') Do (
for /f "tokens=2 delims==" %%b in ('"wmic path Win32_UserProfile where (Special!='True' and LastUseTime is not null) get LastUseTime,LocalPath /VALUE | find "LocalPath""') Do (
echo %%a
pause
if %%a GTR 20200109230000 echo %%b
    )
    )
)
pause

From the output of the command I get

LastUseTime=20201212194437.654000+000
LocalPath=C:\Users\Admin

I was thinking I can strip that into what I need. So have trimmed the date to just 20201212194437 & also just C:\Users\Admin.

If I set a number to 60 days or what ever 20200109230000 (%%a) (1st Sept 11:00pm 00 secs) I thought I could use the GTR switch against it to then robocopy %%b but it doesn't echo back...Not sure whats happening as if I echo %%a & %%b they resolve the snippets I want...cheers


Solution

  • The following script might accomplish what you want (see the rem-comments in the code):

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    
    rem // Define constants here:
    set "_TARGET=D:\Backup\Profiles" & rem // (destination directory of the backup)
    set /A "_MAXAGE=60"              & rem // (maximum age in days of user profile)
    
    rem // Retrieve current date/time:
    for /F "delims=" %%U in ('
        wmic path Win32_OperatingSystem get LocalDateTime /VALUE
    ') do for /F "delims=" %%V in ("%%U") do set "%%V"
    rem // Loop through non-special non-roaming user profiles:
    for /F "delims=" %%U in ('
        wmic path Win32_UserProfile where "Special=FALSE and RoamingConfigured=FALSE and LastUseTime is not null and LocalPath is not null" ^
            get LastUseTime^,LocalPath /VALUE
    ') do for /F "tokens=1* delims==" %%V in ("%%U") do (
        rem // Store current item, which can be the last usage date or the source path:
        set "%%V=%%W" & set "Name=%%~nxW" & setlocal EnableDelayedExpansion
        rem // Check what the current item is:
        if "%%V"=="LastUseTime" (
            endlocal
            rem // Current item is last usage date, so get difference to current date:
            call set /A "RelUseDate=(((%LocalDateTime:~,4%*12+%LocalDateTime:~4,2%)*36525+%LocalDateTime:~6,2%00)-((%%LastUseTime:~,4%%*12+%%LastUseTime:~4,2%%)*36525+%%LastUseTime:~6,2%%00))/100"
        ) else if !RelUseDate! leq %_MAXAGE% (
            rem // Current item is source path, so copy when last usage data is not too long ago:
            ECHO robocopy "!LocalPath!" "!_TARGET!\!Name!" *.* /PURGE /XD "AppData" /XJ
            endlocal
        ) else endlocal
    )
    
    endlocal
    exit /B