2

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!

Rishav
  • 3,818
  • 1
  • 31
  • 49
Chris Higg
  • 23
  • 1
  • 1
  • 3
  • 3
    how to know the value of `specific user`? There is probably more than one users folder. – Stephan May 17 '18 at 17:47
  • It would be the user who is logged in at that time. When you run Wireshark, it will populate the Wireshark folder and preferences file within the users %APPDATA% directory. User would be the only person to use that computer also so it shouldn't be changing to multiple users. – Chris Higg May 17 '18 at 18:33
  • have you considered `cd %userprofile%\appdata\Roaming` – Gerhard May 17 '18 at 20:24
  • Yes I have tested this, because I am the 'system' when deploying/testing it will still direct you to: C:\Windows\System32\config\systemprofile\AppData\Roaming\ – Chris Higg May 17 '18 at 20:31
  • 1
    don't wanna post this as an answer because it is more a solution to the underlying problem you have and not the question you asked but sccm is very well able to run as user. you would probably have to split the application into two parts because the setup will need admin rights but creating a folder in appdata is possible with user rights so a second application that just does this should work. Also you should always install for all users not just the logged in one, what if no user is logged in at the time of the deployment? best not to make too many assumptions but cover all cases – Syberdoor May 18 '18 at 05:37
  • Off-topic hint: Use __COPY__ instead of __XCOPY__ on copying just a single file like `preferences` or __XCOPY__ with target argument __not__ ending with a backslash prompts if `Wireshark` is a file or a directory. __XCOPY__ interprets target as directory path if target argument string ends with a backslash (before closing double quote). – Mofi May 18 '18 at 14:35

4 Answers4

2

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.

michael_heath
  • 5,262
  • 2
  • 12
  • 22
  • Used both .cmd files and program not installing. It looks like it creates the directories for all the users on the machine but when I go to where the directories should be created, there is nothing there.Here is the output within cmd prompt: c:\Users\chris.higgin\Desktop\Apptest\Wireshark>main.cmd Wireshark-win64-2.4.6.exe /S mkdir "C:\Users\jenn.lopez\AppData\Roaming\Wireshark\" xcopy preferences "C:\Users\jenn.lopez\AppData\Roaming\Wireshark" So it also installed within my user directory, Administrator and MSSQL$SQLEXPRESS. Couldn't add the cmd promp as response is too long – Chris Higg May 23 '18 at 13:45
  • The output from the CMD prompt you show is the echo of commands. It is not executing commands. Remove the 3 echo keywords from `main.cmd` to allow the command to execute. Ensure `xcopy` arguments are correct. If the code needs adjustment to avoid `MSSQL$SQLEXPRESS` or other and need help then notify. – michael_heath May 23 '18 at 14:54
  • Thank you for that info. Would the process need to happen for Administrator? Or wouldn't it be sufficient with just the current user/other users that have been on the machine? How would I go about removing MSSQL$SQLEXPRESS and Administrator (assuming it would not be needed) from being included within the included directories? – Chris Higg May 25 '18 at 15:26
  • Advise keep Administrator clear of issues so skip it. Just users group seems good. See revised `main.cmd` code and description on how to skip the profiles you mention at end of your comment. – michael_heath May 26 '18 at 05:20
0

Here's a batch file that may help you. It creates the directory you tell it in all user's %APPDATA% directories it finds if you don't specify a username, or creates the directory in only the specific user's %APPDATA% directory if you do specify a username.

@ECHO OFF
SETLOCAL
SETLOCAL ENABLEEXTENSIONS
SETLOCAL ENABLEDELAYEDEXPANSION

SET BAT=%~NX0
SET ROOTDIR=C:\Users

IF "%~1" == "" (
    GOTO USAGE
)
SET "DIR=%~1"
SET "USER=%~2"
IF NOT "%USER%" == "" (
    IF EXIST %ROOTDIR%\%USER%\AppData\Roaming\ (
        IF NOT EXIST "%ROOTDIR%\%USER%\AppData\Roaming\%DIR%" (
            MKDIR "%ROOTDIR%\%USER%\AppData\Roaming\%DIR%"
            ECHO Created %ROOTDIR%\%USER%\AppData\Roaming\%DIR%
        )
    )
    GOTO :EOF
)

FOR /F "DELIMS=" %%D IN ('DIR /A:D /B %ROOTDIR%') DO (
    IF EXIST %ROOTDIR%\%%D\AppData\Roaming\ (
        IF NOT EXIST "%ROOTDIR%\%%D\AppData\Roaming\%DIR%" (
            MKDIR "%ROOTDIR%\%%D\AppData\Roaming\%DIR%"
            ECHO Created %ROOTDIR%\%%D\AppData\Roaming\%DIR%
        )
    )
)
GOTO :EOF

:: --------------------------------------------------------------------------
:USAGE
ECHO.
ECHO   A batch file that creates a directory in every user's %%APPDATA%% directory
ECHO   if no username is specified or creates the directory only for the specific
ECHO   user if the username is specified.
ECHO.
ECHO   Usage: %BAT% ^<directory^> [username]
GOTO :EOF
Christopher Maynard
  • 5,702
  • 2
  • 17
  • 23
0

Find the owner of the EXPLORER.EXE process:

for /f "TOKENS=1,2,*" %%a in ('tasklist /FI "IMAGENAME eq explorer.exe" /FO LIST /V') do if /i "%%a %%b"=="User Name:" (set domain_user=%%c)

for /f "TOKENS=1,2 DELIMS=\" %%a in ("%domain_user%") do set domain=%%a && set LoggedInUserID=%%b

 

VBScab
  • 1
  • 2
0

for /f "TOKENS=1,2,*" %%a in ('tasklist /FI "IMAGENAME eq explorer.exe" /FO LIST /V') do if /i "%%a %%b"=="User Name:" (set domain_user=%%c)

for /f "TOKENS=1,2 DELIMS=" %%a in ("%domain_user%") do set domain=%%a && set LoggedInUserID=%%b

COYPER
  • 1
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 13 '22 at 16:48