在批处理中排除递归副本中的文件夹

时间:2013-10-23 18:49:17

标签: batch-file recursion copy xcopy

基本上我们正在将大约50个桌面从XP迁移到7.我无法安装任何额外的程序来完成此任务。我正在做的是编写一个脚本,将桌面,收藏夹和我的文档以及一些特定的文件类型从原始机器复制到用户的共享驱动器。之后将能够将所有文件移动到他们正在获得的新机器上。我正在尝试递归搜索Windows并获取您将在脚本中看到的所有.pst文件和其他文件,并将它们备份到共享上的文件夹(但不是在目录结构中,我只想要所有文件)一个目录,无论它们来自哪里),但我的文档除外。他们在“我的文档”中放入的任何内容都应该在搜索中排除。无论如何,这就是我的开始:

@echo off
cls
set USRDIR=
set SHARE=
set /P USRDIR=Enter Local User Directory:  
set /p SHARE=Enter Shared Drive Name:  

set UPATH="c:\Documents and Settings\%USRDIR%"
set SPATH="g:\!MIGRATION"

set ESRI="%UPATH%\Application Data\ESRI"

net use g: /delete
net use g: \\server\%SHARE%
md %SPATH% %SPATH%\GIS %SPATH%\Outlook %SPATH%\Desktop %SPATH%\Documents %SPATH%\Favorites
if exists %ESRI% md %SPATH%\ESRI
md %SPATH%\misc %SPATH%\misc\GISfiles %SPATH%\misc\XMLfiles %SPATH%\misc\CSVfiles

for /R %%x in (*.mxd) do copy "%%x" "%SPATH%\GIS\"
for /R %%x in (*.dbf) do copy "%%x" "%SPATH%\misc\GISfiles\"
for /R %%x in (*.xml) do copy "%%x" "%SPATH%\misc\XMLfiles\"
for /R %%x in (*.csv) do copy "%%x" "%SPATH%\misc\CSVfiles\"
for /R %%x in (*.pst) do copy "%%x" "%SPATH%\Outlook\"
if exist %ESRI% xcopy /y /d /s /i /z %ESRI% %SPATH%\ESRI && echo ESRI YES || ESRI NO
xcopy /y /d /s /i /z "%UPATH%\Desktop" "%SPATH%\Desktop" && echo DESK YES || DESK NO
xcopy /y /d /s /i /z "%UPATH%\My Documents" "%SPATH%\Documents" && echo DOCS YES || DOCS NO
xcopy /y /d /s /i /z "%UPATH%\Favorites" "%SPATH%\Favorites" && echo FAVS YES || FAVS NO

echo "Script Complete!"
pause

然后我决定我想排除我的文件以防万一,所以我最终没有一堆重复,他们放在我的文档中的任何内容最终被复制两次。所以我把那个递归块改为:

for /R %%x in (*.mxd) do xcopy /y /d /z /exclude:"\My Documents\" "%%x" "%SPATH%\GIS\"
for /R %%x in (*.dbf) do xcopy /y /d /z /exclude:"\My Documents\" "%%x" "%SPATH%\misc\GISfiles\"
for /R %%x in (*.xml) do xcopy /y /d /z /exclude:"\My Documents\" "%%x" "%SPATH%\misc\XMLfiles\"
for /R %%x in (*.csv) do xcopy /y /d /z /exclude:"\My Documents\" "%%x" "%SPATH%\misc\CSVfiles\"
for /R %%x in (*.pst) do xcopy /y /d /z /exclude:"\My Documents\" "%%x" "%SPATH%\Outlook\"

无论如何,我的问题是,这是最有效的方法吗?有没有更好的办法?我很好奇,因为我没有人在这里反弹想法或其他任何东西,我是这里唯一的网站支持。如果有人看到更好的方式或认为这是他们将如何做到这一点,请告诉我。那里有更多的文件类型,但我删除了大部分文件类型,因此代码示例不是那么长,留下足以得到重点。

编辑:为了说清楚,我不是这个组织的IT部门。我是该部门与单独IT部门的技术支持联络员。我们的实际IT部门将此称为迁移,但它或多或少是一个简单的“让我们在没有做任何准备工作的情况下停止新机器”的汤三明治操作。我无法以任何方式安装,删除或更改系统,我只能备份文件。

3 个答案:

答案 0 :(得分:1)

从Microsoft尝试User State Migration Tool - 我用它在不到30天的时间内移动了大约400个系统。脚本运行需要一些设置,但它确实做得非常好(并且没有安装程序)。

在默认模式下,它会获取所有PST文件,文档,桌面,收藏夹以及大量其他文件夹/注册表设置。它也可以为计算机上的所有用户(可能受上次登录日期或配置文件数量限制)执行此操作,只要运行它的用户是本地管理员即可。

它可能适用于您需要的功能,也可能不适用,但在设计迁移时它是一个不错的选择。听起来你想要做的就是通过删除ini文件中的额外代码来完成USMT。

答案 1 :(得分:1)

通常,最好的选择是将批处理文件中的处理减少到最小,尽可能多地留下命令。但是如果你必须多次迭代文件系统,那么最好只进行一次传递并批量处理。

改编自更一般的批次。我已经进行了更改以根据您的需要进行调整,但是没有添加更具体的东西(您的ESRI文件夹)。根据需要进行调整。

@echo off

    setlocal enableextensions enabledelayedexpansion

    rem Ask for share name
    set /P share=Enter Shared drive name:
    if "%share%"=="" (
        call :error "No share name provided"
        goto endProcess
    )

    rem Configure target of copy
    set target=g:

    rem Connect to target
    net use %target% /delete 
    net use %target% \\server\%share%

    if not exist %target% (
        call :error "No connection to server"
        goto endProcess
    )   

    rem Configure directory by extension
    set extensions=.mxd .dbf .xml .csv .pst
    set .mxd=GIS
    set .dbf=misc\GISFiles
    set .xml=misc\XMLFiles
    set .csv=misc\CSVFiles
    set .pst=Outlook

    rem adjust target of copy to user name
    set target=%target%\!MIGRATION\%username%
    if not exist "%target%" (
        mkdir "%target%"
    )

    rem Configure source of copy
    set source=%userprofile%
    if not exist "%source%" (
        call :error "User profile directory not found"
        goto endProcess
    )

    rem Resolve My Documents folder
    call :getShellFolder Personal
    set myDocPath=%shellFolder%

    if not exist "%myDocPath%" (
        call :error "My Documents directory not found"
        goto endProcess
    )

    rem Ensure target directories exists
    mkdir "%target%" > nul 2>nul
    for %%e in ( %extensions% ) do mkdir "%target%\!%%e!" >nul 2>nul

    rem We are going to filter file list using findstr. Generate temp file
    rem with strings, just to ensure final command line is in limits
    rem This will contain not desired folders/files or anything that will be
    rem copied later

    set filterFile="%temp%\filter.temp"
    (
        echo %myDocPath%
        echo \Temporary Internet Files\
        echo \Temp\
    ) > %filterFile%

    rem Process user profile, excluding My Documents, IE Temp and not needed extensions
    for /F "tokens=*" %%f in ('dir /s /b /a-d "%source%" ^| findstr /v /i /g:%filterFile% ^| findstr /i /e "%extensions%" ') do (
        call :processFile "%%~xf" "%%f"
    )

    rem Now, process "especial" folders

    mkdir "%target%\Documents"
    xcopy /y /d /s /i /z "%myDocPath%" "%target%\Documents"

    call :getShellFolder Desktop
    if exist "%shellFolder%" (
        mkdir "%target%\Desktop"
        xcopy /y /d /s /i /z "%shellFolder%" "%target%\Desktop"
        if errorlevel 1 (
            call :error "Failed to copy desktop files"
        )
    )

    call :getShellFolder Favorites
    if exist "%shellFolder%" (
        mkdir "%target%\Favorites"
        xcopy /y /d /s /i /z "%shellFolder%" "%target%\Favorites"
        if errorlevel 1 (
            call :error "Failed to copy favorites"
        )
    )

    rem Finish
    goto :endProcess

rem ** subroutines *******************************************

:processFile
    rem retrieve parameters 
    rem : %1 = file extension
    rem : %2 = file 
    set ext=%~1
    set file=%~2

    rem manage .something files
    if "%ext%"=="%file%" (
        set file=%ext%
        set ext=
    )

    rem manage no extension files
    if "%ext%"=="" (
        rem WILL NOT COPY
        goto :EOF
    )

    rem determine target directory based on file extension
    set extCmd=%%%ext%%%
    for /F "tokens=*" %%d in ('echo %extCmd%^|find /v "%%" ' ) do set folder=%%d

    if "%folder%"=="" (
        rem file extension not in copy list
        goto :EOF
    )

    copy /y /z "%file%" "%target%\%folder%" >nul 2>nul
    if errorlevel 1 (
        call :error "Failed to copy [%file%]"
    ) else (
        echo %file%
    )

    goto :EOF

:getShellFolder
    set _sf=%~1
    set shellFolder=
    if "%_sf%"=="" goto :EOF
    for /F "tokens=2,*" %%# in ('reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" /v "%_sf%" ^| find "%_sf%"') do (
        set shellFolder=%%$
    )
    goto :EOF


:error
    echo.
    echo ERROR : %~1
    echo.
    goto :EOF   


:endProcess

    endlocal
    exit /b

答案 2 :(得分:0)

这会检查并排除以documents\结尾的任何文件夹(或包含它,因此也包含子目录),因为IIRC文件夹可能被称为\documents\\my documents\,并且不区分大小写。< / p>

setlocal enabledelayedexpansion
for /R %%x in (*.mxd) do set "check=%%~dpx" & if /i "!check!"=="!check:documents\=!" copy "%%x" "%SPATH%\GIS\"
for /R %%x in (*.dbf) do set "check=%%~dpx" & if /i "!check!"=="!check:documents\=!" copy "%%x" "%SPATH%\misc\GISfiles\"
for /R %%x in (*.xml) do set "check=%%~dpx" & if /i "!check!"=="!check:documents\=!" copy "%%x" "%SPATH%\misc\XMLfiles\"
for /R %%x in (*.csv) do set "check=%%~dpx" & if /i "!check!"=="!check:documents\=!" copy "%%x" "%SPATH%\misc\CSVfiles\"
for /R %%x in (*.pst) do set "check=%%~dpx" & if /i "!check!"=="!check:documents\=!" copy "%%x" "%SPATH%\Outlook\"
endlocal