List usernames for copy.

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
crobertson
Posts: 20
Joined: 25 May 2012 12:34

List usernames for copy.

#1 Post by crobertson » 25 May 2012 12:50

I have a backup program that automatically detects windows version then copies
    Drivers
    Keys
    List all programs installed
    All documents (in all profiles & Predefined folders)
)

I want the ability to exclude some usernames/profiles automatically and ask the user to "Copy this user Yes/No/All". I may just exclude some and copy all others.

I have two methods so far for listing the usernames. One uses a for loop, but I can't put a input prompt in the loop.
The Seconds loops listing all the usernames and you select the number that refers to the user you want to copy, which works good, but we want the ability to exclude some (Administrator) and maybe automate it.
Please ignore these if you have a better way.
Here is my code snippets;
----------------------------------
Type1 -
setlocal EnableDelayedExpansion
:documents
cls
echo.
echo.
echo.
set /P c=Would you like to backup Documents? Y/N?....
if /I "%c%" EQU "N" goto keys

for /f "delims=" %%a in ('dir "%ProfileFolder%\." /b') do (
cls
echo.
echo.
echo.
echo Backing up %%a
pause

echo Desktop
xcopy "%ProfileFolder%\%%a\Desktop\*.*" "%destination%\%FOLDER%\%username%\Desktop\" /e /c /h /k /y
pause
echo favorites
xcopy "%ProfileFolder%\%%a\Favorites\*.*" "%destination%\%FOLDER%\%username%\Favorites\" /e /c /h /k /y
rem xcopy "%ProfileFolder%\%%a\My Documents\*.*" "%destination%\%FOLDER%\%username%\My Documents\" /e /c /h /k /y
xcopy "%ProfileFolder%\%%a\Application Data\Microsoft\Outlook\*.*" "%destination%\%FOLDER%\%username%\Outlook2\" /e /c /h /k /y
rem xcopy "%ProfileFolder%\%%a\Local Settings\Application Data\Microsoft\Outlook\*.*" "%destination%\%FOLDER%\%username%\Outlook\" /e /c /h /k /y
xcopy "%ProfileFolder%\%%a\Application Data\Identities\*.*" "D:\Backup\001\%FOLDER%\%username%\oe\" /e /c /h /k /y

pause

)

:
pause
goto keys
-------------------------------------
Type2 -
@echo off & setLocal enableDELAYedeXpansioN

:start
cls

for /f "tokens=* delims= " %%a in ('dir/b "C:\Documents and Settings" ^| find /n /v "\\\"') do (
echo %%a
)

set /p C= Choose a profile to backup. (Press enter to end) -
echo !C!

set exit=%errorlevel%
if %exit% EQU 1 goto exitusers

::pause
goto start

:exitusers
echo exiting user selection
pause

--------------------------------------------
I'm new at batch files and don't know very much so bear with me.

Ed Dyreen
Expert
Posts: 1569
Joined: 16 May 2011 08:21
Location: Flanders(Belgium)
Contact:

Re: List usernames for copy.

#2 Post by Ed Dyreen » 27 May 2012 01:15

'
Why not use the choice command, and use errorlevel to act upon.

Code: Select all

@echo off
choice /?
pause
You can download choice.COM from internet or extract from http://www.ed-dyreen.com/DOS-KIT/

Do not use goto, it creates ugly code, use call

Code: Select all

setlocal enableDelayedExpansion

if 1 == 1 call :function
echo.errorLevel=!errorLevel!_
pause

exit /b

:function
exit /b 0
goto is for creation of loops, not for jumps in code.

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: List usernames for copy.

#3 Post by foxidrive » 27 May 2012 02:12

Ed Dyreen wrote:'
You can download choice.COM from internet or extract from http://www.ed-dyreen.com/DOS-KIT/


She'll explode in Win 64 bit.

There is a choice.exe somewhere in Windows 7 though.

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: List usernames for copy.

#4 Post by dbenham » 27 May 2012 08:42

crobertson wrote:I have two methods so far for listing the usernames. One uses a for loop, but I can't put a input prompt in the loop.
You have a misconception there. I assume you tried something like:

Code: Select all

for .... %%A in (....) do (
   set /p "var=prompt"
   echo %var%, %%A
)
But the ECHO is not printing the value you entered. You assumed that the input doesn't work. But the value is actually there - you are just not accessing it properly. :wink:

Your problem is that %var% is expanded at parse time, and the entire FOR loop is parsed once before the loop is executed. This is true for any block of code within parentheses. So the value of %var% that you see within the loop is the value that existed before the loop started :!:

There are multiple methods to solve this problem:

1) Get out of the loop context by CALLing a subroutine

Code: Select all

for .... %%A in (....) do call :label "%%A"
exit /b

:label
set /p "var=prompt"
echo %var%, %~1
exit /b

This method generally works, but it is relatively slow. In your case, the performance should not be a problem. But in a tight loop with lots of iterations it can be undesirable.

2) Get out of the loop context by CALLing your command and doubling the percents

Code: Select all

for .... %%A in (....) do (
   set /p "var=prompt"
   call echo %%var%%, %%A
)
This method generally works, but it is actually slower than the first. The slowness can be compounded if you need to CALL multiple commands with the %%var%% value. There are also rare situations where a command like ECHO can fail if there happens to exist a file named ECHO.EXE.

3) Access the current value within the loop context by using delayed expansion.

Code: Select all

setlocal enableDelayedExpansion
for .... %%A in (....) do (
   set /p "var=prompt"
   echo !var!, %%A
)
Delayed expansion does just what the name implies. Instead of expanding the value when the loop is parsed, the value is expanded when the individual command within the loop is executed. This method is by far the fastest. It also has a major advantage in that the contents of !var! will be expanded properly no matter what characters are in the value.

I didn't talk about it before, but %var% expansion can have problems with special characters like ^ & | < >. Those characters can be protected if they are quoted or if they are escaped with ^. But it can get complicated, especially if there are quotes in the middle of the value. The delayed expansion eliminates those complications.

There is one problem with delayed expansion when working with FOR loops: The value of %%A will be corrupted if it contains ! and delayed expansion is enabled. (Technically your user names can contain !, so this is a concern for you) This can be solved by toggling delayed expansion on and off within the loop.

Code: Select all

for .... %%A in (....) do (
  set "A=%%A"
  setlocal enableDelayedExpansion
  set /p "var=prompt"
  echo !var!, !A!
  endlocal
)
Of course the toggling introduces another set of problems if you need the value of var to persist outside the loop. The value is lost after execution of the ENDLOCAL. There are techniques to deal with that too, but that is enough for now.


Dave Benham

Post Reply