2

I installed AWS SAM from the msi installer from AWS for windows. after running the installer, I ran sam --version in cmd and powershell.

PS C:\Users\dgupta> sam --version
SAM CLI, version 1.26.0

It returns the version I just installed. However in VS code, I opened a terminal and ran sam --version it errors out.

Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
Try the new cross-platform PowerShell https://aka.ms/pscore6

sam : The term 'sam' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name,                                                                                                               g of the name,    
or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ sam --version
+ ~~~
    + CategoryInfo          : ObjectNotFound: (sam:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

why is this happening ? doesn't VS Code terminal and normal terminal have access to the same environment variables ?

mklement0
  • 312,089
  • 56
  • 508
  • 622
Dhruv
  • 583
  • 6
  • 14
  • 1
    I am not sure what exactly fixed it, I think its docker related. the sam command couldnt be found. so I deleted and reinstalled docker. edited the path for python.exe in the path variable. re-installed SAM and instead of restarting the computer, I turned it off and started it without the windows updates. – Dhruv Jul 19 '21 at 17:12

1 Answers1

5

It's impossible to diagnose your problem without further information, but perhaps these troubleshooting tips help:

If you're invoking an external executable (sam) by name only, your problem must be that the directory in which the executable resides isn't listed in the $env:PATH environment variable defined for the current process.

However, it is possible that the external sam executable's directory isn't in $env:PATH and that sam is an auxiliary PowerShell command of the same name that knows the true sam's location and invokes it behind the scenes. For instance an alias - such as New-Alias sam 'C:\path\to\sam.exe' - or a function - such as function sam { & C:\path\to\sam.exe $args } - could be defined.

From the PowerShell session where sam is found:

  • To determine what type of command the name sam refers to in your session, use the following and check the value of the CommandType column:
Get-Command sam
  • If the command type is Application, you are indeed dealing with an external executable, and the Source column will report its full path, from which you can glean the executable's directory path (which you can determine directly with Split-Path (Get-Command -Type Application sam).Path

    • You then need to diagnose why that directory isn't in $env:Path in the other session - see first section below.
  • If the command type isn't Application:

    • You need to determine where the auxiliary alias or function is defined and why your other session doesn't see it, which, if the problem is reproducible in new sessions, must be connected to what profile files (as reflected in the automatic $PROFILE variable) were loaded.

Diagnose why a directory is missing from $env:PATH:

Possible reasons:

  • You've just installed an executable, and the installer modified the persistent $env:PATH definition in the registry.

    • Any running processes started before this modification or even started afterwards but from such a process do not see the modification.

    • Solution:

      • Start a new session, which in your case means restarting Visual Studio Code, but be sure to start it from the Start Menu / taskbar / File Explorer, as they are aware of the modified environment. When in doubt, log off and back on to your Windows session, or reboot your machine.

      • Alternatively, refresh $env:PATH from the registry in-session - see below.

  • Something in your current PowerShell session has (possibly inadvertently) removed sam's directory from the in-process $env:PATH variable.

    • Solution:

      • Refresh the in-process $env:PATH definition from the registry with the following command (note that any prior in-process modifications are then lost):
$env:PATH = [Environment]::GetEnvironmentVariable('Path', 'Machine') + ';' + [Environment]::GetEnvironmentVariable('Path', 'User')

If these solutions don't help (persistently), the problem must be connected to what profile files are loaded into the different environments - see next section.


Diagnose what profile files were loaded into a session:

PowerShell's profile files are (by default) loaded (dot-sourced) on session startup and allow sessions to be customized, which can include things such as custom alias definitions, functions, and even in-process $env:PATH additions.

There are multiple profile files, all of which are loaded (by default), if present, along two independent dimensions: all-users vs. current-user, and all-hosts vs. current-host (a host being the PowerShell host environment, such as a regular console window or the terminal in Visual Studio Code).

The automatic $PROFILE variable reports the current-user, current-host profile-file path, but actually has normally invisible properties listing all paths (you can make them visible with $PROFILE | select * - see this answer).

What profiles are loaded into a session for a given user is determined by the following factors:

  • Fundamentally, whether profile loading is suppressed altogether, using the CLI's -NoProfile switch.

  • If not suppressed (the default, even with -Command and -File invocations):

    • What edition of PowerShell you're using: The comes-with Windows, legacy Windows PowerShell edition (whose latest and final version is 5.1), whose CLI is powershell.exe, vs. the install-on-demand cross-platform PowerShell (Core) edition, whose CLI is pwsh.exe, have separate profile locations.

    • The type of the host environment, as reflected in the automatic $Host variable.

To see what command line was used to invoke the current session, run the following:

[Environment]::CommandLine

Note:

  • In a PowerShell Integrated Console in Visual Studio Code you'll always see -NoProfile among the parameters, but the profiles may still be loaded during startup, depending on the settings of PowerShell extension

It follows from the above that different host environments load different sets of profile files, and in the PowerShell Integrated Console provided by Visual Studio Code's PowerShell extension, different profile files are indeed loaded (if loading is enabled via the settings) - compared to regular console windows[1]

If you want your PowerShell Integrated Consoles to load the same current-user profile as regular console windows:

  • Via Visual Studio Code's settings, make sure that the PowerShell: Enable Profile Loading setting is enabled.

  • From a PowerShell Integrated Console, run psedit $PROFILE to open the host-specific current-user profile for editing.

  • Add the following content:

. ($PROFILE -replace '\.VSCode', '.PowerShell')

[1] Note that you can use PowerShell in the Visual Studio Code terminal even without the PowerShell extension, and such session do use the same profiles as regular console windows - see this answer.

mklement0
  • 312,089
  • 56
  • 508
  • 622