[CMD, WMIC, HKLM, HKCU, SETX, PATH, 2001].txt

Discussion in 'Scripting' started by ofernandofilo, Mar 14, 2022.

  1. ofernandofilo

    ofernandofilo MDL Member

    Sep 26, 2015
    237
    140
    10
    #1 ofernandofilo, Mar 14, 2022
    Last edited: Mar 14, 2022
    [CMD, WMIC, HKLM, HKCU, SETX, PATH, 2001]

    the problem is probably more than 20 years old:

    - setx Path "%Path%;NewPath" pollutes the user path with the system path.

    - setx Path "%Path%;NewPath" /M pollutes the system path with the user path.

    - the polution: https://streamable.com/yp43co

    I am not sure if there is a safe native solution that contemplate NON-ANSI directories making exclusive use of the command prompt.

    this is my attempt!

    - using Microsoft Windows [Version 10.0.19042.868]

    0 - check the paths

    Code:
    echo %Path%
    reg query "HKCU\Environment" /v Path
    reg query "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" /v Path
    reg EXPORT "HKCU\Environment" UserEnvironment.reg /y
    reg EXPORT "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" SystemEnvironment.reg /y
    wmic ENVIRONMENT where "username='<SYSTEM>' AND name='Path'" get  variablevalue
    wmic ENVIRONMENT where "username='%COMPUTERNAME%\\%USERNAME%' AND name='Path'" get  variablevalue
    tip: wmic ENVIRONMENT get * [to see more]

    info: a registry backup was performed using the above commands. the files have been saved in the current directory.

    1 - backup user path at %USERPATH%

    - the commands pre-suppose:
    + - non-null path;
    + - functional path;
    - if null or unfunctional path do only step "2"

    Code:
    wmic ENVIRONMENT where "username='%COMPUTERNAME%\\%USERNAME%' AND name='Path'" get  variablevalue | more +1 > %temp%\userpathvalue.txt
    info: there is some pollution* at the end of the string.

    Code:
    set /P USERPATH=<%temp%\userpathvalue.txt
    - add '/' to better see spaces

    Code:
    set "USERPATH=%USERPATH%/"
    info: https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file

    - remove up to 15 end spaces, then remove '/'

    Code:
    set "USERPATH=%USERPATH:        /=/%"
    set "USERPATH=%USERPATH:    /=/%"
    set "USERPATH=%USERPATH:  /=/%"
    set "USERPATH=%USERPATH: /=/%"
    set "USERPATH=%USERPATH:/=%"
    info: the number of spaces introduced was NOT consistent in my tests.

    Code:
    echo %USERPATH%[checking final string]
    setx USERPATH "%USERPATH%"
    * when dealing with invisible characters it is easier to identify them by converting them to hexadecimal, do:

    Code:
    wmic ENVIRONMENT where "username='%COMPUTERNAME%\\%USERNAME%' AND name='Path'" get  variablevalue | more +1 > %tmp%\0 && set /P TEMPREADER=<%tmp%\0
    echo %TEMPREADER% >%tmp%\1 && echo %TEMPREADER%/ && certutil -f -encodehex "%tmp%\1" "%tmp%\2" 11 | more +4 && type "%tmp%\2"
    REM to open on notepad, type: certutil -f -encodehex "%tmp%\1" "%tmp%\2" 5 &&  cmd /C START "" /MAX notepad %tmp%\2
    tip: use 4, 5, 10, 11 (same as none) in encodehex

    see: https://docs.microsoft.com/en-gb/windows/win32/api/wincrypt/nf-wincrypt-cryptbinarytostringa

    2 - set¹²³ user path as %USERPATH% only

    Code:
    setx PATH ^%USERPATH^%
    done!

    ¹ info: setx PATH "%USERPATH%" sets the variable value instead of the literal %USERPATH%

    ² info: using the literal is better, because the behavior becomes dynamic instead of static. i.e., by using the literal instead of the value, only the %USERPATH% variable needs to be changed in the future. whereas, by using the value (i.e., the addresses present inside the variable), the %PATH% user variable must also be updated upon change in %USERPATH% [which is not desirable].

    ³ info: below methods NOT recommended! it works, but it is easier to make mistakes.

    Code:
    reg add "HKEY_CURRENT_USER\Environment" /v PATH /d ^%USERPATH^% /f
    wmic ENVIRONMENT set name="PATH", variablevalue=^%USERPATH^%, username="%COMPUTERNAME%\\%USERNAME%"
    3 - for now on just use %USERPATH%

    Code:
    setx USERPATH "%USERPATH%;ENTER-NEW-PATH-HERE"
    tip: close all programs, especially terminals, before continuing.

    4 - re-check

    Code:
    echo %Path%
    reg query "HKCU\Environment" /v Path
    reg query "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" /v Path
    wmic ENVIRONMENT where "username='<SYSTEM>' AND name='path'" get  variablevalue
    wmic ENVIRONMENT where "username='%COMPUTERNAME%\\%USERNAME%' AND name='path'" get  variablevalue
    5 - visual check

    Code:
    rundll32 sysdm.cpl,EditEnvironmentVariables
    info: the system PATH can only be changed if the previous command was launched with administrative privilege;

    6 - good sources

    "Microsoft - Windows Commands"
    https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/windows-commands

    "SS64 - Windows CMD Shell How-to guides and examples"
    https://ss64.com/nt/syntax.html

    DosTips - The DOS Batch Guide
    https://www.dostips.com/

    "Rob van der Woude's Scripting Page"
    https://www.robvanderwoude.com/

    "TLDP - Appendix N. Converting DOS Batch Files to Shell Scripts"
    https://tldp.org/LDP/abs/html/dosbatch.html

    "Stack Overflow - cmd"
    https://stackoverflow.com/questions/tagged/cmd

    "Super User - cmd.exe"
    https://superuser.com/questions/tagged/cmd.exe

    Dave Benham - dbenham
    https://stackoverflow.com/users/1012053/dbenham

    Jan Erik - jeb
    https://stackoverflow.com/users/463115/jeb

    7 - official sound tracks

    Arnaldo Baptista - Cê Tá Pensando Que Eu Sou Loki? (1974)


    Ivan Lins - Dinorah, Dinorah (1977)


    Bruce Springsteen - Adam Raised a Cain (1978)


    8 - TL;DR: do it! / or don't!

    Code:
    REM the commands pre-suppose
    REM - non-null path;
    REM - functional path;
    REM if null or unfunctionl path don't progress!
    
    reg query "HKCU\Environment" /v Path
    reg query "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" /v Path
    
    reg EXPORT "HKCU\Environment" UserEnvironment.reg /y
    reg EXPORT "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" SystemEnvironment.reg /y
    
    wmic ENVIRONMENT where "username='%COMPUTERNAME%\\%USERNAME%' AND name='Path'" get  variablevalue | more +1 > %temp%\userpathvalue.txt
    set /P USERPATH=<%temp%\userpathvalue.txt
    
    set "USERPATH=%USERPATH%/"
    
    set "USERPATH=%USERPATH:        /=/%"
    set "USERPATH=%USERPATH:    /=/%"
    set "USERPATH=%USERPATH:  /=/%"
    set "USERPATH=%USERPATH: /=/%"
    set "USERPATH=%USERPATH:/=%"
    
    echo %USERPATH%[checking final string] && echo %USERPATH% > %tmp%\0
    certutil -f -encodehex "%tmp%\0" "%tmp%\1" 11 | more +4 && type "%tmp%\1"
    
    setx USERPATH "%USERPATH%"
    
    setx PATH ^%USERPATH^%
    
    echo done!
    
    REM setx USERPATH "%USERPATH%;ENTER-NEW-PATH-HERE"
    
    REM please close all programs
    cheers!
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  2. abbodi1406

    abbodi1406 MDL KB0000001

    Feb 19, 2011
    16,219
    84,894
    340
    Regarding NON-ANSI and the extra spaces

    without filtering, wmic output unicode file with proper CR/LF line ending
    Code:
    wmic ENVIRONMENT where "username='%COMPUTERNAME%\\%USERNAME%' AND name='Path'" get  variablevalue /value > userpathvalue.txt
    
    then you can use this to save the variable as unicode
    Code:
    for /f "tokens=*" %A in ('chcp') do for %B in (%A) do set "oemcp=%~nB"
    >nul chcp 65001
    for /f "tokens=1* delims==" %A in ('find /i "VariableValue" userpathvalue.txt') do set "USERPATH=%B"
    setx PATH ^%USERPATH^%
    setx USERPATH "%USERPATH%"
    >nul chcp %oemcp%
    
    you probably don't need to save and restore original code page

    i suppose Powershell can be used instead, as it fully support unicode
     
  3. ofernandofilo

    ofernandofilo MDL Member

    Sep 26, 2015
    237
    140
    10
    thank you very much for the tips.

    CMD and WMIC seem to have their days numbered, but it's what I know how to use a little.

    PS at least when it launched it was too bureaucratic to run scripts, it asked for some additional authorizations, I never developed interest. maybe today it is simpler.

    anyway thanks for the tips, I should soon perform some tests with them! thank you!
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...