# Source file location
$source1 ="https://ftp.mozilla.org/pub/firefox/releases/11.0/win32/enUS/Firefox%20Setup%2011.0.exe"
$source2 ="https://www.fosshub.com/Code-Blocks.html?dwl=codeblocks-20.03-setup.exe"
$source3 ="https://github.com/x64dbg/x64dbg/releases/download/snapshot/snapshot_2021-07-01_23-17.zip"
$source4 ="https://www.python.org/ftp/python/3.9.6/python-3.9.6-amd64.exe"
$source5 ="https://www.nasm.us/pub/nasm/releasebuilds/2.15.05/win64/nasm-2.15.05-installer-x64.exe"
# Destination to save the file
$destination1 = "C:\Users\cdac\Desktop\Shravan\Softwares\firefox.exe"
$destination2 = "C:\Users\cdac\Desktop\Shravan\Softwares\codeblocks.exe"
$destination3 = "C:\Users\cdac\Desktop\Shravan\softwares\xdbg.zip"
$destination4 = "C:\Users\cdac\Desktop\Shravan\softwares\python.exe"
$destination5 = "C:\Users\cdac\Desktop\Shravan\softwares\nasm.exe"
Invoke-WebRequest -Uri $source1 -OutFile $destination1
Invoke-WebRequest -Uri $source2 -OutFile $destination2
Invoke-WebRequest -Uri $source3 -OutFile $destination3
Invoke-WebRequest -Uri $source4 -OutFile $destination4
Invoke-WebRequest -Uri $source5 -OutFile $destination5
#Installing one software
Start-Process -Wait -FilePath 'C:\Users\cdac\Desktop\Shravan\Softwares\codeblocks.exe' -ArgumentList '/silent' -PassThru
I have written Powershell script which downloads the software tools from the internet through URL and stored in a separate directory but iam not able to install all the softwares which are stored in a separate directory silently using foreach loop. kindly help me in writing script for installing all the softwares stored in a directory using foreach loop.
Thanking you
There isn't enough information to say exactly what's going wrong here - what error are you getting specifically? What behavior are you observing when you run your script? My first guess is that your foreach loop is running through installer names, not the full path like you posted in your example.
That said, if I understand what you're trying to do, here's a quick and dirty way to do what I think you're after;
# Array of installer details
[Hashtable[]]$Installers = #();
# Firefox
$Installers += #{
SoftwareName = "Firefox"
Url = "https://ftp.mozilla.org/pub/firefox/releases/11.0/win32/enUS/Firefox%20Setup%2011.0.exe"
Destination = "C:\Users\cdac\Desktop\Shravan\Softwares\firefox.exe"
Arguments = '/s'
}
#Code Blocks
$Installers += #{
SoftwareName = "CodeBlocks"
Url = "https://www.fosshub.com/Code-Blocks.html?dwl=codeblocks-20.03-setup.exe"
Destination = "C:\Users\cdac\Desktop\Shravan\Softwares\codeblocks.exe"
Arguments = '/silent'
}
function Install-Software([Hashtable]$installer) {
Write-Host "Installing $($installer.SoftwareName)"
Write-Host "Invoke-WebRequest -Uri $($installer.Url) -OutFile $($installer.Destination)"
Write-Host "Start-Process -FilePath $($installer.Destination) -ArgumentList $($installer.Arguments) -Wait"
# Remove Write Host above - uncomment the following lines:
#Invoke-WebRequest -Uri $installer.Url -OutFile $installer.Destination
#Start-Process -FilePath $installer.Destination -ArgumentList $installer.Arguments -Wait
}
foreach($installer in $Installers) {
Install-Software -installer $installer
}
I'd recommend having a look at the PSAppDeployToolkit if you're trying to package applications silently using PowerShell - this helped me a lot back when I was doing a lot of SCCM packaging.
Related
I recently wrote a PowerShell script that downloads the latest release from a public repo and that works as intended. However, I want to change my script so it can access my private repo. Here is the code I have tried so far:
# Download latest release from GitHub
$credentials="myPersonalAccessToken"
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", "token $credentials")
$repo = "myUserName/MyPrivateReleaseRepo"
$file = "MyBinaries.zip"
$releases = "https://api.github.com/repos/$repo/releases"
Write-Host Determining latest release
$tag = (Invoke-WebRequest $releases -Headers $headers | ConvertFrom-Json)[0].tag_name
$download = "https://github.com/$repo/releases/download/$tag/$file"
$name = $file.Split(".")[0]
$zip = "$name-$tag.zip"
$dir = "$name-$tag"
Write-Host Dowloading latest release
Invoke-WebRequest $download -Headers $headers -Out $zip
Write-Host Extracting release files
Expand-Archive $zip -Force
# Cleaning up target dir
Remove-Item "C:\MyOutPutFolder\$name" -Recurse -Force -ErrorAction SilentlyContinue
# Moving from temp dir to target dir
Move-Item $dir\$name -Destination "C:\MyOutPutFolder\$name" -Force
# Removing temp files
Remove-Item $zip -Force
Remove-Item $dir -Recurse -Force
I get the following error only when using my private repo:
Invoke-WebRequest : The remote server returned an error: (404) Not Found
At C:\Script\DownloadLatestGitHubRelease.ps1:25 char:1
+ Invoke-WebRequest $download -Headers $headers -Out $zip
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
I've also tried providing bad credentials vs the correct credentials and got a "Bad Credentials" error when providing the incorrect ones as expected, so I believe I'm using the token correctly.
What am I doing wrong? Thanks in advance for any suggestions.
Landed here trying to do the same thing. After digging into some bash scripts that do similar, I came up with this to do the download:
$token = "<your token from https://github.com/settings/tokens>"
$downloadFolder = "C:\temp";
$ownerSlashRepo = "owner/reop";
$tag = "latest";
$json = Invoke-Webrequest -Uri "https://api.github.com/repos/$ownerSlashRepo/releases/$tag" -Headers #{'Authorization'='token '+$token; 'Accept'='application/json'}
$release = $json.Content | ConvertFrom-Json
$release.assets | %{
$asset = $_;
$x = Invoke-Webrequest -Uri $($asset.url) -OutFile "$downloadFolder\$($asset.name)" -Headers #{'Authorization'='token '+$token; 'Accept'='application/octet-stream'}
}
This downloads every file from the release, but you could filter it to just download one as needed, something like:
$release.assets | ?{$_.name -eq 'foo.zip'} | %{
To answer your question, in the original code you're attempting to use the token with https://github.com. I tried similar at first and got similar results to what you describe. I think it is only good for https://api.github.com and the REST API. I also found I had to specify Accept:application/octet-stream when downloading the asset.
I uploaded a file to a cloud which gives me direct download link.
Downloading it by clicking on this link works fine, but when I try to download it via System.Net.WebClient.DownloadFile on Powershell, it downloads the file, but when I open it it says that the file is corrupted and unreadable.
That's the code:
$WebClient = New-Object System.Net.WebClient
$WebClient.DownloadFile("https://xxxxxx.com/xxxxx/xxx.exe","C:\Users\user\Desktop\xxx.exe")
Any solution?
Strange, this logic works for me.
You could try adding $WebClient.Dispose() ?
or other PowerShell download methods such as:
$uri = "https://xxxxxx.com/xxxxx/xxx.exe"
$path = "C:\Users\user\Desktop\xxx.exe"
Invoke-WebRequest -Uri $uri -OutFile $path
3 ways to download files with PowerShell
<#
# 1. Invoke-WebRequest
The first and most obvious option is the Invoke-WebRequest cmdlet. It is built
into PowerShell and can be used in the following method:
#>
$url = "http://mirror.internode.on.net/pub/test/10meg.test"
$output = "$PSScriptRoot\10meg.test"
$start_time = Get-Date
Invoke-WebRequest -Uri $url -OutFile $output
Write-Output "Time taken: $((Get-Date).Subtract($start_time).Seconds) second(s)"
<#
2. System.Net.WebClient
A common .NET class used for downloading files is the System.Net.WebClient class.
#>
$url = "http://mirror.internode.on.net/pub/test/10meg.test"
$output = "$PSScriptRoot\10meg.test"
$start_time = Get-Date
$wc = New-Object System.Net.WebClient
$wc.DownloadFile($url, $output)
# OR
(New-Object System.Net.WebClient).DownloadFile($url, $output)
Write-Output "Time taken: $((Get-Date).Subtract($start_time).Seconds) second(s)"
<#
3. Start-BitsTransfer
If you haven't heard of BITS before, check this out. BITS is primarily designed
for asynchronous file downloads, but works perfectly fine synchronously too
(assuming you have BITS enabled).
#>
$url = "http://mirror.internode.on.net/pub/test/10meg.test"
$output = "$PSScriptRoot\10meg.test"
$start_time = Get-Date
Import-Module BitsTransfer
Start-BitsTransfer -Source $url -Destination $output
# Or
Start-BitsTransfer -Source $url -Destination $output -Asynchronous
Write-Output "Time taken: $((Get-Date).Subtract($start_time).Seconds) second(s)"
Here is what I personally use daily, from a function in my personal module imported via my profile.
$webclient = New-Object System.Net.WebClient
$url = 'https://download.microsoft.com/download/B/A/4/BA4A7E71-2906-4B2D-A0E1-80CF16844F5F/dotNetFx45_Full_setup.exe'
$filename = [System.IO.Path]::GetFileName($url)
$file = "$TechToolsUNC\$filename"
$webclient.DownloadFile($url,$file)
Start-Process $file -Wait
I would speculate that his is not about powershell, but other factors on your machine or network, most likely antivirus agent etc.
On Windows, is it possible to upload a file to a webshare without use net use or New-PSDrive? (I have PowerShell 3.0 available)
Now I use:
net use Z: http://share.net/mypath/my2path/ /user:<domain\username> <password>
Or:
New-PSDrive -Name Z -PSProvider FileSystem -Root http://share.net/mypath/my2path/ -Credential domain\user
Since you did not say what type of file you wanted to upload, you may need to add the -ContentType switch to the command. Change the fileToUpload variable to be the path to your file. Otherwise, this should work:
$credentials = Get-Credential
$fileToUpload = "c:\temp\myfile.txt"
$uri = "http://share.net/mypath/my2path/"
Invoke-WebRequest -uri $uri -Method Put -Infile $fileToUpload -Credential $credentials
I am trying to do a foreach loop to pull down a file from AWS. When I run Invoke-WebRequest -Uri $S3InstallerLoc -OutFile $S3OutFileoutside of a foreach loop on the server itself it pulls my test file down. When I stick it inside a foreach loop it does not pull down the file. When I attempt to do this from another server I am getting the following error: Invoke-WebRequest : The underlying connection was closed: An unexpected error occurred on a send.
Here is the entirety of the script:
$Servers = "AWS-GPOTEST"
$S3InstallerLoc = "https://s3-us-west-2.amazonaws.com/bucketname/test.txt"
$S3OutFile = "C:\Windows\Temp\Test.txt"
ForEach ($Server in $Servers)
{
Invoke-WebRequest -Uri $S3InstallerLoc -OutFile $S3OutFile
}
In the case that you are running a version of Powershell before 6.0 and that you are running this within a WinRM session you should use the UseBasicParsing parameter.
As in:
Invoke-Command -ComputerName $Servers -ScriptBlock {Invoke-WebRequest -Uri $Using:S3InstallerLoc -OutFile $Using:S3OutFile -UseBasicParsing}
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-webrequest?view=powershell-6
Using local variables in scripts:
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_remote_variables?view=powershell-6#using-local-variables
I am trying to create function to download a file from internet where the path to the files is defined in multiple text files on different client computers.
This is what I have come up with so far.
$Company = Get-Content "C:\ProgramData\test\Company.txt"
$CompanyURLFile = "https://onegeek.dk/MSI/$Company.rar"
$CompanyUpdateFile="C:\ProgramData\test\conf\conf.rar"
Invoke-WebRequest -Uri $CompanyURLFile -OutFile $CompanyUpdateFile
The code above will fail because it cant use "$Company" in line 2
If I use this insteadt everything works fine.
$CompanyURLFile = "https://onegeek.dk/MSI/CYPL.rar"
How do I fix this
The solution was to add "| Select-Object -
First 1"
$Company = Get-Content "C:\ProgramData\test\Company.txt" | Select-Object -
First 1
$CompanyURLFile = "https://onegeek.dk/MSI/$Company.rar"
$CompanyUpdateFile="C:\ProgramData\test\conf\conf.rar"
Invoke-WebRequest -Uri $CompanyURLFile -OutFile $CompanyUpdateFile