2

I'm working on a script that automatically installs software. One of the programs to be installed includes its own command line commands and sub-commands when installed. The goal is to use the program's provided commands to perform an action after its installation.

But running the command right after the program's installation I'm greeted by: " is not recognized as an internal or external command , operable program or batch file"

If I open a new Powershell or cmd window the command is available in that instance.

What is the easiest way to to grant the script access to the commands?

Morgan
  • 31
  • 3

2 Answers2

5

codewario's helpful answer explains the problem and shows you how to modify the $env:PATH variable in-session by manually appending a new directory path.

While that is a pragmatic solution, it requires that you know the specific directory path of the recently installed program.

If you don't - or you just want a generic solution that doesn't require you to hard-code paths - you can refresh the value of $env:PATH (the PATH environment variable) from the registry, via the [Environment]::GetEnvironmentVariable() .NET API method:

$env:PATH = [Environment]::GetEnvironmentVariable('Path', 'Machine'),
            [Environment]::GetEnvironmentVariable('Path', 'User') -join ';'

This updates $env:PATH in-session to the same value that future sessions will see.
Note how the machine-level value (list of directories) takes precedence over the user-level one, due to coming first in the composite value.

Note:

  • If you happen to have made in-session-only $env:PATH modifications before calling the above, these modifications are lost.
    If applicable, this includes modifications made by your $PROFILE file.

  • Hypothetically, other processes could have made additional modifications to the persistent Path variable definitions as well since your session started, which the call above will pick up too (as will future sessions).

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • I would just caution users before implementing this unless they have a use case which requires an absolute up-to-date PATH within the current process. There's are reasons environment variables don't automatically propagate down to child processes which have already started. That said, there are definitely times when this sort of thing is useful/required. One great example is the `refreshenv` command provided by Chocolatey. – codewario Mar 10 '22 at 15:21
  • And if you are installing the within the same process you need it in, you would (I hope) know where it's going to end up. – codewario Mar 10 '22 at 15:22
  • @BendertheGreatest, if you're running some installer, you shouldn't need to know or care about the installation location (at least not for the purpose of installation). As for the general concern: processes may _choose_ to react to environment changes (assuming the changing process sends out a notification broadcast), and this is just a manual way of doing the same. There's certainly no intrinsic security concern, given that future processes will see the newly persisted value. – mklement0 Mar 10 '22 at 15:25
  • It's less of a security concern and more regarding the state of the process' environment, and bringing in potentially inadvertent changes. Just something for folks to be aware of And to be fair I guess it's not like PowerShell is going to be often running the kind of code at length where this would really matter. – codewario Mar 10 '22 at 15:57
  • Indeed, @BendertheGreatest, I'd expect such inadvertent changes to be quite rare; the last bullet point in the answer points it out as a possibility. On balance, I think the convenience of the refresh-from-registry solution, especially given that you needn't deal with specific paths, outweighs the risk of running into inadvertent changes. However, inadvertently discarding in-session changes made by `$PROFILE` (first bullet point) is perhaps a likelier scenario. – mklement0 Mar 10 '22 at 16:00
3

This is because the PATH environment variable gets updated, but existing processes don't see that update unless they specifically query the registry for the live value of the update the PATH environment variable, then update PATH within its own process. If you need to continue in the same process, the workaround is to add the installation location to the PATH variable yourself after the program has been installed:

Note: I don't recommend updating the live value from the registry instead of the below in most cases. Other processes can modify that value, not just your own. It can introduce unnecessary risk, whereas appending only what you know should have changed is a more pragmatic approach. In addition, it adds code complexity for a case that often doesn't need to be generalized to that point.

# This will update the PATH variable for the current process
$env:PATH += ";C:\Path\To\New\Program\Folder;"
codewario
  • 19,553
  • 20
  • 90
  • 159