How to download a file to $env:temp directory using powershell from cmd console?

12,508

Solution 1

tl;dr:

From outside of PowerShell (cmd.exe - Command Prompt or batch file), use escaped double-quoted strings - \"...\" - inside the overall command string - "..." - passed to powershell -command for strings that need interpolation (e.g., expansion of variable references such as $env:temp):

powershell -command "(new-object System.Net.WebClient).DownloadFile('https://example.com/example.zip', \"$env:temp\example.zip\")"

You not only need to fix the incidental problem that Nkosi points out - removing the extraneous : at the end of $env:temp: - but you must generally either not quote the path at all (argument syntax), or use escaped double quotes (expression syntax or values with shell metacharacters) - single-quoted strings don't work, because PowerShell treats their content as a literal and won't expand the environment-variable reference.[1]

For a description of PowerShell's two fundamental parsing modes - argument syntax vs. expression syntax - see Get-Help about_Parsing.

Simplified examples:

  • Without quoting (argument syntax):

    c:\>powershell.exe -noprofile -command "write-output $env:temp\example.zip"
    C:\Users\jdoe\AppData\Local\Temp\example.zip
    
  • With double-quoting (expression syntax or if the value contains shell metacharacters such as , or |):

    c:\>powershell.exe -noprofile -command "write-output \"$env:temp\example.zip\""
    C:\Users\jdoe\AppData\Local\Temp\example.zip
    

Note: When called from the outside, PowerShell requires embedded " chars. to be escaped as \" - unlike inside PowerShell, where `" must be used.

Applied to your command: with (escaped) double-quoting, which is needed, because you're using .NET method syntax, which is parsed with expression syntax:

powershell -command "(new-object System.Net.WebClient).DownloadFile('https://example.com/example.zip', \"$env:temp\example.zip\")"

[1] If you run the same command from PowerShell, you won't see the problem, because the command as a whole is enclosed in "...", which means that the current PowerShell session will expand $env:temp - before it is passed to powershell.exe.
However, when called from cmd.exe, this interpolation is NOT applied - hence the need to either omit quoting or use embedded (escaped) double-quoting.

Solution 2

I would use Invoke-WebRequest with -OutFile:

powershell -command "Invoke-WebRequest -Uri 'http://example.com/file-to-get.txt' -OutFile $env:temp\file-to-get.txt"

NB this requires PowerShell 3.0 (if I remember correctly).

Share:
12,508
BlackJoker
Author by

BlackJoker

Java Developer.

Updated on June 05, 2022

Comments

  • BlackJoker
    BlackJoker almost 2 years

    I can download a file to a constant location from cmd console using powershell like this

    C:\Users\Weijun>powershell -command "(new-object System.Net.WebClient).DownloadFile('https://example.com/example.zip', 'D:\example.zip')"
    

    but i need to download it to system temp directory,using the powershell variable $env:temp,the following doesn't work.(variable not expanded in single-quote)

    powershell -command "(new-object System.Net.WebClient).DownloadFile('https://example.com/example.zip', '$env:temp\example.zip')"
    

    how to pass variable as parameter in method invoke?

    UPDATE: it is a typo for $env:temp:,I amend it.