Deploying applications via SCCM. Currently trying to deploy Wireshark and I am 1st trying to create the directory then copy over a preference file to the users %APPDATA%
. The preference file basically stops the application from checking for auto updates.
Reason I need to create the directory is because it does not exist until Wireshark is launched for the 1st time.
Issue is that when doing this, SCCM is deploying as a system user so %APPDATA%
goes to directory C:\Windows\System32\config\systemprofile\AppData\Roaming\
But I would like to get to C:\Users\SPECIFIC USER\AppData\Roaming
I am deploying the application with a batch file:
Wireshark-win64-2.4.6.exe /S
mkdir %APPDATA%\Wireshark\
xcopy preferences %APPDATA%\Wireshark
This will work locally on my own machine but if I run under PSEXEC (like SCCM would) then it will end up in the incorrect directory.
I am new to creating applications within SCCM as well as using batch files to deploy so please include details if possible. Regardless I appreciate the help!
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.