Search code examples
windowscmdcommand-lineenvironment-variablescommand-prompt

Environment variable only works for elevated (admin) command prompt but does not for normal command prompt


I am using Windows 11 Pro Version: 21H2 (Build: 22000.978)

So I have OpenSSH on my device which is also added to system path variable as shown below in the command prompt snippet.

C:\Windows\System32>set path  
Path=C:\oraclexe\app\oracle\product\11.
\VMware Workstation\bin\;C:\WINDOWS\sys
1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Pr
\ProgramData\nvm;C:\Program Files\nodej
m Files\dotnet\;C:\Android\android-sdk\
in;C:\Program Files\Git\cmd;C:\Program

I have OpenSSH inside System32 in string value of my Path variable.

I'm inside System32 folder in my command prompt (normal window | non-admin) and I opened the Explorer in the current directory by entering:

explorer .

I do see OpenSSH folder, but when I try to go inside (change directory) to OpenSSH, the command prompt throws an error denoting that the path does not exist. But it does exist on the drive!

C:\Windows\System32>cd OpenSSH
The system cannot find the path specified.

I directed my Explorer to System32 which contains OpenSSH folder, but I cannot access or change my directory from the command prompt.

And obviously I cannot access ssh.exe which is located inside OpenSSH directory.

But interestingly, when I elevate the shell (open CMD as administrator) and try to access the OpenSSH directory or even the file ssh.exe, it worked! When I use the where command for ssh, it points to that right directory as shown below:

Command prompt as standard user:

C:\Windows\System32>ssh
'ssh' is not recognized as an internal or external command,
operable program or batch file.

Command prompt as administrator:

C:\Users\Admin>where ssh
C:\Windows\System32\OpenSSH\ssh.exe

I cannot access ssh.exe from a normal shell. But if I elevate it then I can access ssh.exe.

It just does not work for cmd in normal window but works when cmd is opened as administrator.


Solution

  • Please read first at least the Microsoft documentation about the Windows File System Redirector and best also the documentation pages WOW64 Implementation Details and Registry Keys Affected by WOW64.

    When a 32-bit application on 64-bit Windows starts cmd.exe either with %SystemRoot%\System32\cmd.exe or with %ComSpec% or with cmd.exe or in worst case with just cmd, there is started the 32-bit version of the Windows Command Processor in directory %SystemRoot%\SysWOW64 because of the file system redirector.

    The file system redirector is also responsible for redirecting each access of %SystemRoot%\System32\OpenSSH to %SystemRoot%\SysWOW64\OpenSSH which does not exist on 64-bit Windows because of the OpenSSH package is available only as 64-bit application suite on 64-bit Windows on being available at all (depends on version of Windows).

    The usage of Run as administrator results on 64-bit Windows in starting 64-bit cmd.exe in %SystemRoot%\System32 and therefore no file system redirection is done on any access to files and directories in %SystemRoot%\System32. For more details see Why does 'Run as administrator' change (sometimes) batch file's current directory?

    In a Windows batch file can be used the following code:

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    
    rem Expect ssh.exe in OpenSSH in Windows system directory by default.
    set "ExeSSH=%SystemRoot%\System32\OpenSSH\ssh.exe"
    if exist "%ExeSSH%" goto RunSSH
    
    rem Expect ssh.exe in OpenSSH in native Windows system directory
    rem on batch file processed by 32-bit cmd.exe on 64-bit Windows.
    set "ExeSSH=%SystemRoot%\Sysnative\OpenSSH\ssh.exe"
    if exist "%ExeSSH%" goto RunSSH
    
    rem Search for OpenSSH using environment variable PATH.
    rem The environment variable ExeSSH is undefined by the
    rem next command line on no file ssh.exe found by cmd.exe.
    for %%I in (ssh.exe) do set "ExeSSH=%%~$PATH:I"
    if defined ExeSSH goto RunSSH
    
    rem There could not be found the executable ssh.exe anywhere.
    echo ERROR: Could not find ssh.exe in any directory.
    echo/
    pause
    exit /B 1
    
    :RunSSH
    rem Use here "%ExeSSH%" ... to run this executable.
    echo Found: "%ExeSSH%"
    endlocal
    

    This batch file can be used on Windows XP and all newer Windows versions whereby on the older Windows versions is most likely output just the error message that the executable ssh.exe could not be found because of not being installed by default.