How to download a file to $env:temp directory using powershell from cmd console?
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).
Comments
-
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.