Done with using getprofiles.cmd
to echo the profiles and using main.cmd
with a for loop to process the profile paths.
main.cmd:
@echo off
setlocal
:: Install Wireshark.
echo Wireshark-win64-2.4.6.exe /S
:: Update Wireshark app data in user profiles.
for /f "tokens=*" %%A in ('getprofiles.cmd "\AppData\Roaming"') do (
call :skip_profile "%%~A" "\\Administrator\\" "\\MSSQL\$SQLEXPRESS\\" || (
echo mkdir "%%~A\Wireshark\"
echo xcopy preferences "%%~A\Wireshark"
)
)
exit /b
:skip_profile
for %%A in (%*) do (
if not "%%~A" == "" if /i not "%%~A" == "%~1" (
echo "%~1"| findstr /i "%%~A" >nul 2>nul
if not errorlevel 1 (
echo Skip account "%~1"
exit /b 0
)
)
)
exit /b 1
getprofiles.cmd:
@echo off
setlocal
if "%~1" == "/?" goto :help
:: ProfileList key that contains profile paths.
set "ProfileListKey=HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"
:: Get profiles directory path.
set "ProfilesDirectory="
for /f "tokens=1,3" %%A in (
'reg query "%ProfileListKey%" /v "ProfilesDirectory"'
) do if /i "%%~A" == "ProfilesDirectory" call set "ProfilesDirectory=%%~B"
if not defined ProfilesDirectory (
>&2 echo ProfilesDirectory is undefined
exit /b 1
)
:: Search all profile paths in profiles directory and echo existing paths appended with the 1st script argument.
for /f "delims=" %%A in (
'reg query "%ProfileListKey%"'
) do call :ProfilePath "%%~A" "%~1"
exit /b
:ProfilePath
setlocal
set "arg1=%~1"
:: Validate 1st call argument is a profile subkey.
if not defined arg1 exit /b 1
if /i "%arg1%" == "%ProfileListKey%" exit /b 1
if "%arg1:~,1%" == " " exit /b 1
:: Echo existing profile paths with defined 2nd argument appended.
for /f "tokens=1,3" %%A in (
'reg query "%arg1%" /v ProfileImagePath^|find /i "%ProfilesDirectory%"'
) do (
if "%%~A" == "ProfileImagePath" (
if exist "%%~B%~2" echo "%%~B%~2"
)
)
exit /b
:help
echo Prints profile paths from the registry that exist in the Profiles Directory.
echo 1st argument can be a path to be appended to the profile path.
echo i.e. "\AppData\Roaming" is appended to become "C:\Users\...\AppData\Roaming".
exit /b
The script main.cmd
echoes the results for testing. Remove the echoes
to actually use if commands are valid.
The ProfileList
key in the registry stores the path to find the
profiles and has subkeys with data such as path of each profile on
the machine.
main.cmd
can avoid profiles such as Administrator
and MSSQL$SQLEXPRESS
.
The called label :skip_profile
takes the profile path as 1st argument.
Following arguments are for patterns and if matched, will be a skipped
profile.
findstr
is being used for checking the profile path for a match with
regular expressions so use findstr /?
for syntax requirements.
Case is set as insensitive as to use of /i
.
The getprofiles.cmd
script gets the ProfilesDirectory
path which
is where the user profile folders can be found. It then querys the key
to get the profile keys by using the called label of :ProfilePath
.
The label checks if the ProfilesDirectory
path is found in each
profile path found. It then checks if the path exists before echoing
the path. If the optional 1st parameter is passed, then it will be
appended and the path will be validated as that path.
A test outputs:
Wireshark-win64-2.4.6.exe /S
mkdir "C:\Users\Michael\AppData\Roaming\Wireshark\"
xcopy preferences "C:\Users\Michael\AppData\Roaming\Wireshark"
which seems OK as I only have 1 user profile on my current machine.
You could probably merge the code together to make just 1 script though
I decided to leave getprofiles.cmd
as reusable for other uses.