For loop to hit each user on a machine

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
motanicus
Posts: 19
Joined: 26 Mar 2013 11:13

Re: For loop to hit each user on a machine

#16 Post by motanicus » 26 Mar 2013 16:06

motanicus wrote:Here's what I've come up with, need syntax check if anyone is good with it:

Code: Select all


for /f "delims=" %%z in ('dir "%systemdrive%\users\" /ad /b')
SET "target=%systemdrive%\users\%%z\AppData\Local\Microsoft\Outlook\Backup\"

for /f "delims=" %%a in ('dir c:\*.pst /b /s /a-d') do (
xcopy /y /i /f %systemdrive%\users\%%z\AppData\Roaming\Microsoft\Templates\*.* %target%\Templates\ >> "%target%\backup.log"
xcopy /y /i /f %systemdrive%\users\%%z\AppData\Roaming\Microsoft\Stationery\*.* %target%\Stationery\ >> "%target%\backup.log"
xcopy /y /i /f %systemdrive%\users\%%z\AppData\Roaming\Microsoft\Signatures\*.* %target%\Signatures\ >> "%target%\backup.log"
call :next "%%a"
goto :EOF
)

:next
set c=
:loop
if exist "%target%\%~n1%c%%~x1" set /a c=c+1 & goto :loop
echo copying %1 to "%target%\%~n1%c%%~x1"
copy /b "%~1" "%target%\%~n1%c%%~x1"
>>"%target%\backup.log" echo copy /b "%target%\%~n1%c%%~x1" "%~1"
goto :EOF


So I guess to clarify what I'm wanting to happen -- in this example, I'm trying to add this code to be executed on the same profile that it finds each *st file as WELL as copying the PST/OST file itself where %%z is defined as the user profile variable in the first 'for' clause:

Code: Select all

xcopy /y /i /f %systemdrive%\users\%%z\AppData\Roaming\Microsoft\Templates\*.* %target%\Templates\ >> "%target%\backup.log"
xcopy /y /i /f %systemdrive%\users\%%z\AppData\Roaming\Microsoft\Stationery\*.* %target%\Stationery\ >> "%target%\backup.log"
xcopy /y /i /f %systemdrive%\users\%%z\AppData\Roaming\Microsoft\Signatures\*.* %target%\Signatures\ >> "%target%\backup.log"

motanicus
Posts: 19
Joined: 26 Mar 2013 11:13

Re: For loop to hit each user on a machine

#17 Post by motanicus » 26 Mar 2013 16:11

I went ahead and tried executing the new code which seems to work. It's still giving a lot of 'file not found' for the *.*st when it can't find the files in the profile it's looking in, but it IS copying over the .pst file where it does exist. I'm just hoping to trim the log file down by looping the "for /f "delims=" %%a in ('dir c:\*.pst /b /s /a-d') do" statement that you provided so that it isn't retrying all of the logic for locations that the PST doesn't exist.

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

Re: For loop to hit each user on a machine

#18 Post by foxidrive » 26 Mar 2013 16:15

I meant are the filenames of the files to save unique. If they have archive files then they could have filename clashes, unless directory structure is copied.

That then leads to cyclic copy errors, unless a staging folder can be used to back it all up to and move the staging folder later.


I just read your post above - you will have problems using the logic you had. It's going to copy every ?st in c: drive to every profile.

motanicus
Posts: 19
Joined: 26 Mar 2013 11:13

Re: For loop to hit each user on a machine

#19 Post by motanicus » 26 Mar 2013 16:17

motanicus wrote:I went ahead and tried executing the new code which seems to work. It's still giving a lot of 'file not found' for the *.*st when it can't find the files in the profile it's looking in, but it IS copying over the .pst file where it does exist. I'm just hoping to trim the log file down by looping the "for /f "delims=" %%a in ('dir c:\*.pst /b /s /a-d') do" statement that you provided so that it isn't retrying all of the logic for locations that the PST doesn't exist.


I lied, it didn't work correctly, so you're probably right about the logic being fubar. heh... to be honest I am not the most avid with scripting so I'm hoping someone who may know better can give some insight as far as that portion is concerned, to prevent the loop from failing. At this point it's giving me no output.

motanicus
Posts: 19
Joined: 26 Mar 2013 11:13

Re: For loop to hit each user on a machine

#20 Post by motanicus » 26 Mar 2013 16:28

foxidrive wrote:I meant are the filenames of the files to save unique. If they have archive files then they could have filename clashes, unless directory structure is copied.

That then leads to cyclic copy errors, unless a staging folder can be used to back it all up to and move the staging folder later.


I just read your post above - you will have problems using the logic you had. It's going to copy every ?st in c: drive to every profile.


Dang.
so in essence what I need:
- Script defines %target% variable to include %%z as user profile variable
- Script figures out for each %%z whether it has *.*ST file in that profile (%systemdrive%/users/%%z/{whatever location}/*.*st)
- Script then copies *ST file to %target% + the three associated directories also within that profile into subdirectories of %target% :

Code: Select all

xcopy /y /i /f %systemdrive%\users\%%z\AppData\Roaming\Microsoft\Templates\*.* %target%\Templates\ >> "%target%\backup.log"
xcopy /y /i /f %systemdrive%\users\%%z\AppData\Roaming\Microsoft\Stationery\*.* %target%\Stationery\ >> "%target%\backup.log"
xcopy /y /i /f %systemdrive%\users\%%z\AppData\Roaming\Microsoft\Signatures\*.* %target%\Signatures\ >> "%target%\backup.log"


Sorry for confusion!

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

Re: For loop to hit each user on a machine

#21 Post by foxidrive » 26 Mar 2013 16:30

Here's another question: will you run this batch file when no users are logged into the machine, except the admin account?

motanicus
Posts: 19
Joined: 26 Mar 2013 11:13

Re: For loop to hit each user on a machine

#22 Post by motanicus » 26 Mar 2013 16:36

I'll be remote executing with either PSEXEC or elevated admin prompt, haven't decided on that yet. Users will probably be logged in; however, before the script is called, I have a VBS running that closes the Outlook process and unlocks any files that could be locked prior to the transfer and waits for it to complete. I also planned on actually using the MOVE command rather than XCOPY so that it forces a new account creation prompt when they try to re-open Outlook; but for the sake of testing I wanted to keep it xcopy for now so I'm not shuffling files around on my test PC.

Edit: we also have our PCs set so only one user can be logged in at a time to the desktop, no user switching etc.

motanicus
Posts: 19
Joined: 26 Mar 2013 11:13

Re: For loop to hit each user on a machine

#23 Post by motanicus » 26 Mar 2013 16:46

Also, thanks for spending time on this, I realize that I've got 'ID 10 T' written on my forehead at this point...

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

Re: For loop to hit each user on a machine

#24 Post by foxidrive » 26 Mar 2013 16:57

EDITED: inserted DIR command

This should be non-destructive on your test machine - it will find all PST and OST files in each user profile and create a file with the "same name.pst.movetest" for example, and then move the *.movetest files to the backup folder, and maintain folder structure.

You will get file not found error messages but they are harmless. It's not tested.

Code: Select all

@echo off
for %%a in ("%userprofile%") do (
for /f "delims=" %%b in ('dir "%%~dpa" /ad /b') do (
for /f "delims=" %%c in (' dir "%%~dpa\%%b\*.ost" "%%~dpa\%%b\*.pst" /a-d /b /s') do (
type nul> "%%c.movetest"
md "%%~dpa\%%b\AppData\Local\Microsoft\Outlook\Backup\%%~pc" 2>nul
move "%%c.movetest" "%%~dpa\%%b\AppData\Local\Microsoft\Outlook\Backup\%%~pc" >nul
)
)
)
pause


The version below should be live, and move the PST/OST files if the above works ok.

Code: Select all

@echo off
for %%a in ("%userprofile%") do (
for /f "delims=" %%b in ('dir "%%~dpa" /ad /b') do (
for /f "delims=" %%c in (' dir "%%~dpa\%%b\*.ost" "%%~dpa\%%b\*.pst" /a-d /b /s') do (
md "%%~dpa\%%b\AppData\Local\Microsoft\Outlook\Backup\%%~pc" 2>nul
move "%%c" "%%~dpa\%%b\AppData\Local\Microsoft\Outlook\Backup\%%~pc" >nul
)
)
)
pause

motanicus
Posts: 19
Joined: 26 Mar 2013 11:13

Re: For loop to hit each user on a machine

#25 Post by motanicus » 26 Mar 2013 17:03

getting an error 'c:\users\\ALL' is not a recognized command
'c:\users\\default' is not a recognized command
then
The system cannot find the path specified.

Assuming that there's a phantom \ somewhere but I don't see where it'd be; it seems to be effecting each line though. The code completes really quickly.

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

Re: For loop to hit each user on a machine

#26 Post by foxidrive » 26 Mar 2013 17:07

It occurs to me that if any *.pst *.ost files exist in hidden account folders then they will probably not be moved.

motanicus
Posts: 19
Joined: 26 Mar 2013 11:13

Re: For loop to hit each user on a machine

#27 Post by motanicus » 26 Mar 2013 17:08

foxidrive wrote:It occurs to me that if any *.pst *.ost files exist in hidden account folders then they will probably not be moved.


Yeah the AppData folder is going to be hidden for sure.

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

Re: For loop to hit each user on a machine

#28 Post by foxidrive » 26 Mar 2013 17:13

motanicus wrote:getting an error 'c:\users\\ALL' is not a recognized command


Try the code now. I edited it and put in the DIR command I forgot.

motanicus
Posts: 19
Joined: 26 Mar 2013 11:13

Re: For loop to hit each user on a machine

#29 Post by motanicus » 26 Mar 2013 17:27

awesome it appears to be copying properly. One more caveat :
The end location for the files is :
c:\users\username\appdata\local\microsoft\Outlook\Backup\Users\username

Is there a way to eliminate the trailing \Users\username since the folder we're saving to should already be in that user's profile?

so for User1 it would be
C:\users\User1\appdata\local\microsoft\outlook\backup\*

For user 2 it would be
C:\users\User2\appdata\local\microsoft\outlook\backup\*

etc. ?

if not, this is pretty darn close, and I can deal with that! :)

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

Re: For loop to hit each user on a machine

#30 Post by foxidrive » 26 Mar 2013 17:44

This was convoluted - I think I got it right. It removes the \users\username\

Code: Select all

@echo off
for %%a in ("%userprofile%") do (
for /f "delims=" %%b in ('dir "%%~dpa" /ad /b') do (
pushd "%%~dpa\%%b"
for /f "delims=" %%c in ('dir *.ost *.pst  /a-d /b /s 2^>nul ') do (
call :next "%%~dpa%%b" "%%~dpc" "%%c"
)
popd
)
)
pause
goto :EOF

:next
set "var1=%~1"
set "var2=%~2"
call set "var3=%%var2:%var1%=%%"
md "%~1\AppData\Local\Microsoft\Outlook\Backup\%var3%" 2>nul
move "%~3" "%~1\AppData\Local\Microsoft\Outlook\Backup\%var3%" >nul

Post Reply