Reputation: 13
I'm attempting to create a batch file for my company's users to use to migrate files from their older 'personal folder' network share to our new OneDrive implementation.
The problem is, some of our users have change the default sync folder for OneDrive to whatever drive and path they wanted, instead of keeping the default (*c:\users\username*)...for example, the one I'm using to test my BAT file against is using:
D:\OneDrive - Business
However, it does still have to work when it contains more or less delimiters, like C:\OneDrive or C:\This Is Where I Foolishly Store Stuff.
At this point, I've tried using REG QUERY to output to a text file from the UserFolder key in the registry to get the path, and now I'm trying to extract this path FROM the text file in question and set it to a variable. The text file that is created looks like the following:
HKEY_CURRENT_USER\SOFTWARE\Microsoft\OneDrive\Accounts\Business1
UserFolder REG_SZ D:\OneDrive - Business
What I want to do is set the "D:\OneDrive - Business" to a variable to use in a scripted MOVE command.
My code is so awful, that I will refrain from posting it unless someone decides its necessary to answer my question.
I'm sure that for at least a DOZEN of you, this is child's play, so I would really appreciate any help that is provided me!!!
Thanks!!
Upvotes: 1
Views: 375
Reputation: 41206
You can combine the output of the [MSDN]: reg with [MSDN]: findstr (to filter out some useless data), and iterate over what's left using [SS64]: for.
Here's the code (it must be run from a batch file):
@echo off
set _KEY_NAME=HKEY_CURRENT_USER\SOFTWARE\Microsoft\OneDrive\Accounts\Business1
set _VALUE_NAME=UserFolder
set _VALUE_DATA=
for /f "tokens=1,2,*" %%f in ('reg query %_KEY_NAME% /v %_VALUE_NAME% /t REG_SZ 2^>NUL ^| findstr %_VALUE_NAME%') do (
set _VALUE_DATA="%%h"
)
echo Data: %_VALUE_DATA%
This is based on the fact that on my machine (Win10), reg query %_KEY_NAME% /v %_VALUE_NAME% /t REG_SZ
(with different values for the _KEY_NAME and _VALUE_NAME), output:
HKEY_CURRENT_USER\SOFTWARE\_DummyKey _DummyValue REG_SZ D:\OneDrive - Business End of search: 1 match(es) found.
@EDIT0: After looking at @Mofi's solution, I realized that I had no error handling. Added some.
Upvotes: 0
Reputation: 49216
Here is one batch solution for this task:
@echo off
for /F "skip=1 tokens=1,2*" %%A in ('%SystemRoot%\System32\reg.exe QUERY HKCU\SOFTWARE\Microsoft\OneDrive\Accounts\Business1 /v UserFolder 2^>nul') do if /I "%%A" == "UserFolder" if not "%%C" == "" set "UserFolder=%%C" & goto UserFolderSet
echo No user folder for OneDrive found in Windows registry.
goto :EOF
:UserFolderSet
echo Found user folder: "%UserFolder%"
Better readable is this version doing exactly the same:
@echo off
for /F "skip=1 tokens=1,2*" %%A in ('%SystemRoot%\System32\reg.exe QUERY HKCU\SOFTWARE\Microsoft\OneDrive\Accounts\Business1 /v UserFolder 2^>nul') do (
if /I "%%A" == "UserFolder" (
if not "%%C" == "" (
set "UserFolder=%%C"
goto UserFolderSet
)
)
)
echo No user folder for OneDrive found in Windows registry.
goto :EOF
:UserFolderSet
echo Found user folder: "%UserFolder%"
The command FOR executes the command REG in a background command process with capturing its output written to handle STDOUT.
An error message output by REG to handle STDERR is suppressed by redirecting it to device NUL because of 2^>nul
. The redirection operator >
is escaped with caret character ^
which is necessary to interpret >
first as literal character by Windows command interpreter on parsing the FOR command line. But later on execution of REG command line with 2>nul
by FOR >
is interpreted as redirection operator. An error message could occur if the registry value does not exist at all in Windows registry.
FOR processes each non empty line of captured output of REG command by splitting the line up into substrings (tokens) using space and tab as delimiter (default).
The option skip=1
instructs FOR to skip the first line of captured output.
The option tokens=1,2*
instructs FOR that first space/tab delimited string being here value name UserFolder
should be assigned to first loop variable A
.
The second space/tab delimited string being here type REG_SZ
should be assigned to loop variable B
being the next character in ASCII table. Now it should be clear why loop variables are case-sensitive while environment variables are not case-sensitive. This loop variable is not further processed here although it might be good in case of type is REG_EXPAND_SZ
instead of REG_SZ
as in this case the directory path contains most likely also 1 or more environment variable references which must be expanded before having real directory path.
The string after the spaces/tabs after second space/tab delimited string being in your example D:\OneDrive - Business
should be assigned without further splitting up on spaces/tabs to loop variable C
because of *
after 2
in options string tokens=1,2*
.
The first IF condition makes sure the right line is processed as on Windows XP the output of REG starts with a header where only the first line would be skipped.
The second IF condition makes sure the user folder value has a non empty value.
The string of interest is finally assigned to environment variable UserFolder
and the FOR loop is exited with a jump to the commands below label UserFolderSet
.
The commands below the FOR loop are executed if the registry value was not found in Windows registry.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
for /?
goto /?
if /?
set /?
Read also the Microsoft article about Using Command Redirection Operators.
Upvotes: 1
Reputation:
I won't use a text file but directly Reg.exe
to read the registry value
@Echo off
Set "Key=HKCU\SOFTWARE\Microsoft\OneDrive\Accounts\Business1"
Set "Val=UserFolder"
For /f "Tokens=2* delims= " %%A in (
'Reg query "%Key%" /V %Val% ^|find /i "%Val%" '
) Do Set "%Val%=%%B"
Set %Val%
Upvotes: 0
Reputation: 38719
Perhaps:
For /F "EOL=H Tokens=2*" %%A In ('Reg Query "HKCU\SOFTWARE\Microsoft\OneDrive\Accounts\Business1" /V "UserFolder"') Do Set "var=%%B"
Echo(%%var%% = %var%
Pause
Upvotes: 0