Search code examples
powershellcommand-line-argumentspath-variables

How do I create a temporary path within a PowerShell script?


Given the code below, how do I set a variable that I can use to call the 7z executable? The env:Path approach at the top works once but then the terminal must be reloaded or the command cannot be found. Powershell seems to be treating it as a string, not as an executable call. Ultimately, I need to be able to pull this value in from the environment.

# $env:Path += "C:\Program Files\7-Zip"
# works once, then the terminal must be reloaded

$7zip = "C:\Program Files\7-Zip\7z.exe"
$dirAsStr = "C:\Program Files\7-Zip\7z.exe"
$dirAsDir = Get-Item $dirAsStr

$extract_files = "somewhere"
$output = "someplace"

# $dirAsDir a -t7z $output\format_files.7z $extract_files\format.*
# ParserError: Unexpected token 'a' in expression or statement.
# $7zip a -t7z $output\format_files.7z $extract_files\format.*
# ParserError: Unexpected token 'a' in expression or statement.

C:\"Program Files"\7-Zip\7z.exe a -t7z $output\format_files.7z $extract_files\format.*
# works fine

Solution

  • $env:Path += "C:\Program Files\7-Zip"

    should be $env:Path += ";C:\Program Files\7-Zip" (note the ;) and it is effective for the remainder of the current session (process) only.

    That is, you can then invoke 7-Zip as 7z ... in the same session.

    If you want this modification to persist, i.e. to be available in all future sessions:

    • Either: Place the command in your $PROFILE file.

    • Or: Modify the persistent definition of the Path environment variable in the registry, e.g. interactively via sysdm.cpl

      • Note: Robustly updating Path programmatically is nontrivial, unfortunately - see this answer.

    $7zip a -t7z...

    In order to execute commands whose names or paths are stored in variables, you must invoke them via &, the call operator (which is a syntactic necessity in PowerShell):

    & $7zip a -t7z ...
    

    The same goes for command names or paths that are quoted as a whole:

    • C:\"Program Files"\7-Zip\7z.exe happens to work without &, because the argument starts with an unquoted string.

      • A an aside: Starting with a quoted string and appending an unquoted one is fundamentally unsupported in PowerShell; e.g.,
        & "C:\Program Files\"7-Zip\7z.exe wouldn't work, because the 7-Zip\7z.exe part would become a separate argument - see this answer.
    • By contrast, "C:\Program Files"\7-Zip\7z.exe" would require &

    By contrast, use of & is optional with verbatim, unquoted command names and paths (e.g, 7z, C:\tools\7z.exe)

    See this answer for details.