0

Folks,

I'm trying to set a variable using a for loop and executing a command based on the set variable. But when I do try to do that I get odd behaviour.

The command:

FOR /D %%G in (*) DO SET matr=%%~nG&& robocopy %matr%\AppData\Local\Microsoft\Outlook "E:\Backup - %computername%\Users\%matr%\AppData\Local\Microsoft\Outlook" /s /b /log+:"E:\Backup - %computername%\Log de Backup.txt" /v /A-:SHR /r:2 /w:5 /tee

Explanation:

For every folder in a given folder (C:\Users\, stated earlier on my script), set a variable called matr with the name of the folder. The aim is to, at every loop, look for the next folder inside C:\Users and set the variable as the name of the folder. After that, I run robocopy using the variable as starting point for the source. For exemple, the first folder found on C:\Users would be administrator, and that should make my robocop use administrator\Appdata\Local\Microsoft\Outlook as source. The destination would use the variable too to target a folder in an external drive, in an specific folder in it.

This is the behaviour I get when I run the script with administrative privileges:

E:\>cd /D C:\Users\ 

C:\Users>FOR / %G in (*) DO SET matr=%~nG  && robocopy \AppData\Local\Microsoft\Outlook "E:\Backup - P43971\Users\\AppData\Local\Microsoft\Outlook" /s /b /log+:"E:\Backup - P43971\Log de Backup.txt" /v /A-:SHR /r:2 /w:5 /tee 

C:\Users>SET matr=Administrador  && robocopy \AppData\Local\Microsoft\Outlook "E:\Backup - P43971\Users\\AppData\Local\Microsoft\Outlook" /s /b /log+:"E:\Backup - P43971\Log de Backup.txt" /v /A-:SHR /r:2 /w:5 /tee  

I don't understand why the variable gets blanked out. I tried putting SETLOCAL ENABLEDELAYEDEXPANSION and using !matr! instead of %matr% but to no avail. When using !matr! instead of %matr% the batch recognizes it as direct text and not a variable call.

Relevant parts of the code:

SETLOCAL ENABLEDELAYEDEXPANSION

cd /D C:\Users\

FOR /D %%G in (*) DO SET matr=%%~nG&& robocopy %matr%\AppData\Local\Microsoft\Outlook "E:\Backup - %computername%\Users\%matr%\AppData\Local\Microsoft\Outlook" /s /b /log+:"E:\Backup - %computername%\Log de Backup.txt" /v /A-:SHR /r:2 /w:5 /tee

echo Outlook backup done!
echo.

pause

Behavior when NOT setting enabledelayedexpansion AND using single %matr%:

E:\>cd /D C:\Users\ 

C:\Users>FOR / %G in (*) DO SET matr=%~nG  && robocopy \AppData\Local\Microsoft\Outlook "E:\Backup - P43971\Users\\AppData\Local\Microsoft\Outlook" /s /b /log+:"E:\Backup - P43971\Log de Backup.txt" /v /A-:SHR /r:2 /w:5 /tee 

C:\Users>SET matr=Administrador  && robocopy \AppData\Local\Microsoft\Outlook "E:\Backup - P43971\Users\\AppData\Local\Microsoft\Outlook" /s /b /log+:"E:\Backup - P43971\Log de Backup.txt" /v /A-:SHR /r:2 /w:5 /tee  

Behaviour when setting enabledelayedexpansion and using double %%matr%%:

E:\>cd /D C:\Users\ 

C:\Users>FOR / %G in (*) DO SET matr=%~nG  && robocopy %matr%\AppData\Local\Microsoft\Outlook "E:\Backup - P43971\Users\%matr%\AppData\Local\Microsoft\Outlook" /s /b /log+:"E:\Backup - P43971\Log de Backup.txt" /v /A-:SHR /r:2 /w:5 /tee 

C:\Users>SET matr=Administrador  && robocopy %matr%\AppData\Local\Microsoft\Outlook "E:\Backup - P43971\Users\%matr%\AppData\Local\Microsoft\Outlook" /s /b /log+:"E:\Backup - P43971\Log de Backup.txt" /v /A-:SHR /r:2 /w:5 /tee  

Behaviour when set enabledelayedexpansion and using single !matr!:

E:\>cd /D C:\Users\ 

C:\Users>FOR / %G in (*) DO SET matr=%~nG  && robocopy !matr!\AppData\Local\Microsoft\Outlook "E:\Backup - P43971\Users\!matr!\AppData\Local\Microsoft\Outlook" /s /b /log+:"E:\Backup - P43971\Log de Backup.txt" /v /A-:SHR /r:2 /w:5 /tee 

C:\Users>SET matr=Administrador  && robocopy !matr!\AppData\Local\Microsoft\Outlook "E:\Backup - P43971\Users\!matr!\AppData\Local\Microsoft\Outlook" /s /b /log+:"E:\Backup - P43971\Log de Backup.txt" /v /A-:SHR /r:2 /w:5 /tee
1
  • On closer inspection, please notice that in each of the 3 run-reports (were they retyped, or patched by cut-and-paste?) the for line reads for / %G - the D is missing. Are you using a proper text-editor like Editplus or Notepad++? If you are, ensure you are saving the file as ANSI, not Unicode. If you are trying to use Notepad or a word-processor, then try using a proper text-editor as these utilities may try to format the file to make "sense". Commented Jan 24, 2018 at 16:08

2 Answers 2

1

Instead of:

FOR /D %%G in (*) DO

You could use this:

For /F "Delims=" %%G In ('Dir /B/AD') Do

Alternatively this suggestion instead uses a different way of parsing the user profile names. It uses WMIC to retrieve all local non-special profile names in a For /F loop:

@Echo Off
Set "SP=AppData\Local\Microsoft\Outlook"
Set "DP=E:\Backup - %ComputerName%"
Set "BL=Log de Backup.txt"
Set "RP=/S /B /A-:RSH /R:2 /W:5 /V /TEE"

For /F Tokens^=2^Delims^=^" %%A In ('WMIC Path Win32_UserProfile Where^
 "Special!='TRUE'" Assoc /AssocClass:Win32_UserAccount 2^>Nul'
) Do For /F "Tokens=1*Delims==" %%B In ('WMIC UserAccount Where^
 "SID='%%A' And LocalAccount='TRUE'" Get Name /Value'
) Do For /F "Tokens=*" %%D In ("%%C"
) Do RoboCopy "%%D\%SP%" "%DP%\Users\%%D\%SP%" %RP% /LOG+:"%DP%\%BL%"

All Users, Default, Default User and Public are examples of special system service profiles which would be ignored using this method but not using the Dir example

Sign up to request clarification or add additional context in comments.

4 Comments

Holy crap, I can't understand half of this. I will try and read about it and report back, thanks!
@RafaelUmbelino, I have fixed some bad typos.
For /F gets me a blank/empty variable when I try to print the variable, the second snipet simply gets ignored in the batch with an error message of something similar to "Description = invalid consult".
Just to make sure you've copied the exact syntax correctly, what is the output when you enter the following single line, unchanged, at your command prompt; For /F Tokens^=2^Delims^=^" %A In ('WMIC Path Win32_UserProfile Where "Special!='TRUE'" Assoc /AssocClass:Win32_UserAccount 2^>Nul') Do @For /F "Tokens=1*Delims==" %B In ('WMIC UserAccount Where "SID='%A' And LocalAccount='TRUE'" Get Name /Value') Do @For /F "Tokens=*" %D In ("%C") Do @Echo [%D]
1

You need to read some SO articles on delayed expansion carefully, and show us how you tried putting SETLOCAL ENABLEDELAYEDEXPANSION and using !matr! instead of %matr% as we can't see your terminal very clearly from here.

The quick answer is to not use matr at all. Try

FOR /D %%G in (*) DO robocopy %%~nG\AppData\Local\Microsoft\Outlook "E:\Backup - %computername%\Users\%%~nG\AppData\Local\Microsoft\Outlook" /s /b /log+:"E:\Backup - %computername%\Log de Backup.txt" /v /A-:SHR /r:2 /w:5 /tee

where %%~nG will probably contain what you expect.

4 Comments

Tried to use that and it appears that robocop is not so robust after all. I get a error message stating either that %~nG wasn't expected OR that it can't be used at that moment. Although when I run the command outside a batch script it works fine. I will edit my post with the relevant parts of the code.
@aphoria: No - %%G throughout or %G throughout - depending on whether the command is being executed as a batch line or diectly from the prompt.
@OP: Are you attempting to run this from within a batch file, or from the prompt? If within a batch file, then It should work as I wrote it. If from the prompt, all %%G/%%~nG should be %G/%~nG. If you are attempting to execute from the prompt, then !var! will not work since delayedexpansion is only in effect in the local environment established by setlocal. In that case, you may use setlocal enabledelayedexpansion&...set var=%G&robocopy..!var!...
I don't have the slightest clue why, but if I put a blank line between cd /D C:\Users` and FOR /D %%G in (*) DO robocopy %%~nG\AppData\Local\Microsoft\Outlook "E:\Backup - %computername%\Users\%%~nG\AppData\Local\Microsoft\Outlook" /s /b /log+:"E:\Backup - %computername%\Log de Backup.txt" /v /A-:SHR /r:2 /w:5 /tee` the batch fails. If I delete the empty line in between, it works.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.