Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Hi guys im currently working in a school and Ive created a script to scan all student folders for sepcific file types, I was wondering if there was a way I could have it make a copy of the specific file type before deleting it? I couldnt think of a way to do it as both xcopy and robocopy require a source address within the syntax. Here is my script

@echo off
net use X: \\LOCATION FOR STUDENT FOLDERS
net use Y: \\LOCATION FOR COPIED FILES
net use Z: \\LOCATION FOR .TXT FILE OF DELETED FILES
X:
cls
Echo Deleting bat files please wait...
del /s *.bat > Z:\DeletedFiles.txt 2>&1
Echo Deleting CMD files please wait...
del /s *.cmd >> Z:\DeletedFiles.txt 2>&1
Echo Deleting VBS files please wait...
del /s *.vbs >> Z:\DeletedFiles.txt 2>&1
Echo Deleting Executable files please wait...
del /s *.exe >> Z:\DeletedFiles.txt 2>&1
mountvol X:\ /D
mountvol Y:\ /D
mountvol Z:\ /D
cls
Echo Process Completed. Drives Unmounted
set /p=Press Any Key To Close

Im assuming it isnt as easy (let alone even possible) as entering in something like below?

xcopy *.bat Y:\

By the way powershell scripts arent at my disposal as I dont have rights to run them (silly education department) but if there is a powershell alternative please post that too as it would be good for me to learn.

share|improve this question
    
I think it's as easy as "xcopy *.bat Y:\" –  David Dai Aug 13 '14 at 1:23
    
@DavidDai Not the case, i have tested it in my test environment and it will only copy whatever is in the root of mounted student folder drive, it will not recursively go through each students folder and copy each specified file it finds. the deleting side of it works perfectly though –  Super Geoff Aug 13 '14 at 2:02

2 Answers 2

up vote 4 down vote accepted

Using FORFILES

This way might be even easier to digest:

forfiles /P C:\Windows /S /M *.dll /C "cmd /c @echo @path"

This is an example you can run from the command line without hurting anything.

Here's how you might use it in your script:

forfiles /P X:\ /S /M *.bat /C "cmd /c @copy @path Y:\"

Using FOR

FOR /R X:\ %%B IN (*.bat) DO (
    copy "%%~fB" Y:\
    REM you could do the delete in here too, 
    REM but it's probably faster the way you have it
)

How this works:

The FOR command with the /R switch looks recursively through the provided directory (in this case X:\ for the pattern defined in the IN section. Here we're giving it the pattern *.bat. For each file found, it runs the statement after DO. The file that is found will be put into the %%B variable (you could choose any letter).

By using (...) after the DO we allow for running multiple commands on each iteration of the loop.

%%~fB is a special way of treating the value of %%B. The ~ begins all such special formatters and by itself removes quotation marks if they exist. f formats the value as a full path name, in case it's being used as relative.

Running for /? at the command line gives a very detailed account of FOR's capabilities and the formatting flags that can be used.

Note

We're using %%B instead of %B as the help would show you because it's inside a batch file. Here are some samples of FOR that you can run directly at the command line:

FOR /R C:\Windows %Q IN (*.ttf) DO @echo I am a font: "%Q"
FOR /R C:\Windows %Q IN (*.dll) DO @echo Full path to DLL: %~fQ

If those were in a batch file you'd need to use double percent signs.

About PowerShell

I also wanted to point out that you don't require any special permissions to run powershell scripts.

If you're getting an error about execution policy, this is just a safety measure, and within powershell (not in the script) you can run:

Set-ExecutionPolicy Bypass

You should read more about execution policy to get a full grasp of the possible settings.

If you are running a powershell script through a scheduled task, you can change the execution policy when you invoke it, like this:

powershell.exe -ExecutionPolicy Bypass

A full invocation from a scheduled task might look like this:

powershell.exe -NoProfile -NonInteractive -NoLogo -ExecutionPolicy Bypass -File C:\Scripts\script.ps1
share|improve this answer
    
sorry to ask and seem like the definition of an uneducated IT guy but I have never used a for loop before although I generally learn very quickly. Could you please show me how I would incorporate the for loop into my script? –  Super Geoff Aug 13 '14 at 2:24
    
As written, I think it would do exactly what you wanted. I will edit with an explanation of how it's working. –  briantist Aug 13 '14 at 2:25
    
Excellent explanation, thanks a lot! –  Super Geoff Aug 13 '14 at 2:39
    
I also just now added a section on FORFILES (I always forget about that command until I'm waist deep in a FOR loop). It might be easier to use. –  briantist Aug 13 '14 at 2:39

Use FOR loops:

SETLOCAL EnableExtensions
For /R "X:\" %%I IN (*.bat) do (
    xcopy /i "%%I" "Y:\%%~nxI"
    del "%%I"
)

So your script could be:

@echo off
SETLOCAL EnableExtensions
net use X: \\LOCATION FOR STUDENT FOLDERS
net use Y: \\LOCATION FOR COPIED FILES
net use Z: \\LOCATION FOR .TXT FILE OF DELETED FILES
X:
cls
Echo Deleting bat, cmd, vbs, and exe files please wait...
For /R "X:\" %%I IN (*.*) do (
    set "isTrue="
    if (%%~xI == ".bat") set isTrue=1
    if (%%~xI == ".cmd") set isTrue=1
    if (%%~xI == ".vbs") set isTrue=1
    if (%%~xI == ".exe") set isTrue=1
    if defined isTrue (
        xcopy "%%I" "Y:\%%~nxI"
        del /s "%%I" > "Z:\DeletedFiles.txt" 2>&1
    )
)
mountvol X:\ /D
mountvol Y:\ /D
mountvol Z:\ /D
cls
Echo Process Completed. Drives Unmounted
set /p=Press Any Key To Close
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.