3

Being that most of my work is done remotely, I have a batch script which downloads all my tools from my FTP server to the client's PC. I just copy and paste the text into notepad on the client's PC and save it as a batch and run it.

This works great, but the problem is, the programs I use get updated every so often - so I would be downloading old versions. By doing a little research, I found that PowerShell can download files directly from the web.

Download a file via HTTP from a script in Windows

How to execute PowerShell commands from a batch file?

It seems that all the pieces are there, but I don't know anything about PowerShell at all and I'm a total amateur with batch. Further, I guess you can't just call up PowerShell in the batch script and start writing in PowerShell.

So here is the end goal; To write a batch script which uses PowerShell to download files from different websites (I would provide URLs). Instead of downloading the files from my FTP server, the script would download the programs right from the source.

7
  • Test with Invoke-WebRequest with PowerShell. See docs.microsoft.com/en-us/powershell/module/… Commented Aug 6, 2017 at 22:22
  • 1
    Consider using chocolatey
    – LotPings
    Commented Aug 6, 2017 at 22:43
  • There's also How to download files from command line in Windows, like Wget is doing? which, at the time of this writing, contains at least these three answers: Community Answer showing PowerShell, and Another Community answer showing PowerShell, and Yet another Community answer showing PowerShell
    – TOOGAM
    Commented Aug 6, 2017 at 23:11
  • Thank you so much for taking the time. McDonald's, I’m not sure if this answers my question. As indicated, I looked over these commands before posting and agree that PowerShell can help. When I remote into a client’s PC, I copy and paste my batch script text into notepad on the client's PC. Running it downloads my tools from my FTP server onto the client’s PC. I would need something similarly easy to implement which would download these files from their websites instead. I think the end goal would be to write a batch script which uses PowerShell to download files from multiple websites. Commented Aug 7, 2017 at 21:09
  • With regards to the links kindly provided by TOOGAM, I have already seen each one of those articles. I looked over Wget before posting. At that time, I had trouble understanding how to implement it in such a way that would result in the aforementioned end goal. In what little I understand about Wget, i think it also needs to be installed on the client’s computer. I am trying to minimize steps. Right now I simply cut, paste, run. I also wouldn't want to install programs on client’s machines that they didn't ask for. I feel the task can be accomplished in a much easier, more direct way. Commented Aug 7, 2017 at 21:12

2 Answers 2

3

This method uses the PowerShell version 2 onward compatible and uses System.Net.WebClient class.

Creates an array then adds required URL's to the array. Specify your download location, then for each item in your array, generate a filename which the System.Net.WebClient file parameter requires by using the PowerShell -Split Operator for the string from the last occurrence of the forward slash.

$Urls = @()
$Urls += "https://your/first/download/path/.ext"
$Urls += "https://your/next/download/path/.ext"

$OutPath = "C:\Path\to\download\"

ForEach ( $item in $Urls) {
$file = $OutPath +  ($item).split('/')[-1]
(New-Object System.Net.WebClient).DownloadFile($item, $file)
}

Alternatively use the Invoke-WebRequest as per @McDonald's comment or the Invoke-WebRequest alias wget which are both available from PowerShell version 3 onwards but may be slower

$Urls = @()
$Urls += "https://your/first/download/path/.ext"
$Urls += "https://your/next/download/path/.ext"

$OutPath = "C:\Path\to\download\"

ForEach ( $item in $Urls) {
$file = $OutPath +  ($item).split('/')[-1]
Invoke-WebRequest -Uri $item -Outfile $file
}

Save either script as "C:\Path\to\download_script.ps1"

create and run .bat file with the content

PowerShell -File  "C:\Path\to\download_script.ps1"

or run the .ps1 file from PowerShell

EDIT To accommodate your comment into my answer you can change the array into a multi column array and call the item heading as a . attribute

$Urls = @()
$item = "" | Select path,outpath,name
$item.path = "https://your/first/download/path/.ext"
$item.outpath = "C:\Path\to\download\"
$item.name = "Name1.ext"
$Urls = $Urls + $item

$item = "" | Select path,outpath,name
$item.path = "https://your/next/download/path/.ext"
$item.outpath = "C:\Path\to\download\"
$item.name = "Name2.ext"
$Urls = $Urls + $item

ForEach ( $item in $Urls) {
$file = ($item.outpath) + ($item.name)
(New-Object System.Net.WebClient).DownloadFile($item.path, $file)
}
5
  • Thank you so much for all your time and effort! It only now occurs to my sleep deprived brain that i can just copy and paste this into PowerShell on the client's PC. No need for the batch. Forgive my ignorance, but is there a way for me to choose the saved file name as well? Commented Aug 8, 2017 at 22:59
  • @Christopher Moore see edit where you can change the file names and down load paths
    – Antony
    Commented Aug 9, 2017 at 5:11
  • Just found a typo. Invoke-WebRequest -Uri $i -Outfile $file should be Invoke-WebRequest -Uri $item -Outfile $file
    – Mark
    Commented Feb 5, 2021 at 3:33
  • Oops @Mark $item my mistake
    – Antony
    Commented Feb 6, 2021 at 8:54
  • Note that the final backslash in the Outpath is important
    – SeesSound
    Commented May 12, 2021 at 2:22
2

Here is an example that i made for you to download some batch codes from a file that can be created if not exist, and of course you can add what you want of urls in this file !

So just give a try and tell me the result on your side !

@echo off
Mode 110,3 & color 0A
Title Download file from web using powershell and batch by Hackoo 2017
Set "List_Urls_File=Urls.txt"
If not exist "%List_Urls_File%" Call :Create_Urls_File
Setlocal enabledelayedexpansion
@For /f "delims=" %%a in ('Type "%List_Urls_File%"') do (
    Set "URL=%%a"
    Rem we set the Filename from the variable !url!
    @for %%# in (!url!) do ( set "File=%%~xn#" )
    Rem Check if the file name contains a dot "." 
    Rem If not we increment the counter +1 for file to be download
        ECHO !File! | FIND /I ".">Nul 2>&1
        If "!errorlevel!" NEQ "0" (
            Set /a Count+=1
            cls & echo(
            echo               Downloading file "File-!Count!.bat" from URL : "!URL!"
            Call :BalloonTip 'information' 10 '"Downloading File-!Count!.bat"' "'Please wait... Downloading File-!Count!.bat....'" 'info' 4
            Call :Download "%%a" "File-!Count!.bat"
        ) else (
            cls & echo(
            echo    Downloading file "!File!" from URL : "!URL!"
            Call :BalloonTip 'information' 10 '"Downloading !File!"' "'Please wait... Downloading !File!....'" 'info' 4

            Call :Download "%%a" "!File!"
        )
)
Explorer "%~dp0" & exit
::*********************************************************************************
:Download <url> <File>
Powershell.exe -command "(New-Object System.Net.WebClient).DownloadFile('%1','%2')"
exit /b
::*********************************************************************************
:Create_Urls_File
(
    echo https://pastebin.com/raw/XvyhRzT6
    echo https://pastebin.com/raw/QqnZ0MjQ
    echo https://pastebin.com/raw/tHsKw15V
    echo https://pastebin.com/raw/VCnTbLB6
    echo https://pastebin.com/raw/3zUTrWUz
    echo https://pastebin.com/raw/31auQeFz
    echo https://pastebin.com/raw/xF0uXThH
    echo https://pastebin.com/raw/uzsGQD1h
    echo https://pastebin.com/raw/3TmVYiZJ
    echo https://pastebin.com/raw/Ntc8SZLU
    echo https://pastebin.com/raw/jnpRBhwn
    echo https://www.virustotal.com/static/bin/vtuploader2.2.exe
    echo http://devbuilds.kaspersky-labs.com/devbuilds/KVRT/latest/full/KVRT.exe
)>"%List_Urls_File%"
exit /b
::*********************************************************************************
:BalloonTip $notifyicon $time $title $text $icon $Timeout
PowerShell  ^
  [reflection.assembly]::loadwithpartialname('System.Windows.Forms') ^| Out-Null; ^
 [reflection.assembly]::loadwithpartialname('System.Drawing') ^| Out-Null; ^
 $notify = new-object system.windows.forms.notifyicon; ^
  $notify.icon = [System.Drawing.SystemIcons]::%1; ^
  $notify.visible = $true; ^
  $notify.showballoontip(%2,%3,%4,%5); ^
  Start-Sleep -s %6; ^
  $notify.Dispose()
%End PowerShell%
exit /B
::*************************************************************************

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .