Install 7-Zip Using PowerShell
Problem
In this article, I will show you how to install 7-Zip using PowerShell.
The installation process consists of three parts:
- Define download URL and installer location
- Download 7-Zip installer
- Install 7-Zip silently
You can directly apply the third step above if you already have the installer or download it manually. All solutions below share all the steps above. The only difference is at the downloading part.
Using Invoke-WebRequest and Start-Process
First we need to define variables for download URL and installer location. Then, we use Invoke-WebRequest
cmdlet to download the file and put it in the folder.
Next, we perform silent installation using Start-Process
cmdlet that will invoke windows msiexec.exe
built-in process. We add -Wait
parameter to wait until installation process completely finished.
# Define the download URL and installer location
$7zipUrl = "https://www.7-zip.org/a/7z2401-x64.msi"
$installer = "$env:TEMP\7z2401-x64.msi"
# Download 7-Zip installer
Invoke-WebRequest -Uri $7zipUrl -OutFile $installer
# Install 7-Zip silently
Start-Process -FilePath "msiexec.exe" -ArgumentList "/i $installer /qn" -Wait
# Remove installer
Remove-Item $installer
/i
argument specifies that we will run normal installation; meanwhile, /qn
argument means there is no UI during installation process. For complete msiexec.exe
parameters that can be used, you can find in msiexec documentation.
Last, we will remove the installer using Remove-Item
cmdlet, but this step is optional.
Using Invoke-RestMethod and Start-Process
Similar to previous solution, but this one we will use Invoke-RestMethod
cmdlet to download the file. We can use this cmdlet because the communication is using HTTP(S) that is supported by RESTful services.
# Define the download URL and installer location
$7zipUrl = "https://www.7-zip.org/a/7z2401-x64.msi"
$installer = "$env:TEMP\7z2401-x64.msi"
# Download 7-Zip installer
Invoke-RestMethod -Uri $7zipUrl -OutFile $installer
# Install 7-Zip silently
Start-Process -FilePath "msiexec.exe" -ArgumentList "/i $installer /qn" -Wait
# Remove installer
Remove-Item $installer
Using WebClient and Start-Process
We can also use WebClient
class from .NET Framework to download the file since PowerShell is deeply integrated with .NET Framework.
# Define the download URL and installer location
$7zipUrl = "https://www.7-zip.org/a/7z2401-x64.msi"
$installer = "$env:TEMP\7z2401-x64.msi"
# Download 7-Zip installer
$WebClient = New-Object System.Net.WebClient
$webclient.DownloadFile($7zipUrl, $installer)
# Install 7-Zip silently
Start-Process -FilePath "msiexec.exe" -ArgumentList "/i $installer /qn" -Wait
# Remove installer
Remove-Item $installer
Using HttpClient and Start-Process
We can also use HttpClient
from .NET Framework to download the installer, then install 7-Zip silently.
There are two flavors in using .NET Framework C# code from PowerShell. We can create the object using PowerShell syntax as in previous solution or we can also embed C# code in our script then invoke it.
In this case, we present both of the approaches.
Create C# object using PowerShell syntax
In this approach, we need to apply dispose pattern by enclosing each call to HttpClient
constructor, GetStreamAsync
and FileStream
methods with try-finally
block. It is optional to put catch
block if we want to handle the exception specifically.
At finally
block we close the connection after we have used disposable object. Otherwise, we won’t be able to perform silent installation because the process is still being used by another process.
A more concise way to apply dispose pattern in C# is to use using
statement, but since PowerShell doesn’t have the syntax for the pattern we can use try-finally
block as the alternative.
using namespace System.IO
using namespace System.Net.Http
# Define download URL and installer location
$7zipUrl = "https://www.7-zip.org/a/7z2401-x64.msi"
$installer = "$env:TEMP\7z2401-x64.msi"
# Download 7-Zip installer
try {
$client = [HttpClient]::new()
try {
$stream = $client.GetStreamAsync($7zipUrl)
try {
$fileStream = [FileStream]::new($installer, [FileMode]::Create)
$stream.GetAwaiter().GetResult().CopyTo($fileStream)
}
finally {
<#Do this after the try block regardless of whether an exception occurred or not#>
$fileStream.Dispose()
}
}
finally {
<#Do this after the try block regardless of whether an exception occurred or not#>
$stream.Dispose()
}
}
finally {
<#Do this after the try block regardless of whether an exception occurred or not#>
$client.Dispose()
}
# Install 7-Zip silently
Start-Process -FilePath "msiexec.exe" -ArgumentList "/i $installer /qn" -Wait
# Remove installer
Remove-Item $installer
Embed C# code then invoke it from PowerShell
In this approach, we copy and paste our C# code to PowerShell, then enclose it with Add-Type -TypeDefinition
in order to add it to PowerShell session. Then, we will be able to call the method to download the file from PowerShell.
# Define download URL and installer location
$7zipUrl = "https://www.7-zip.org/a/7z2401-x64.msi"
$installer = "$env:TEMP\7z2401-x64.msi"
# Create C# Code to Download 7-Zip installer
Add-Type -TypeDefinition @"
using System.IO;
using System.Net.Http;
public static class Downloader {
public static void DownloadInstaller() {
using (var client = new HttpClient())
{
using (var s = client.GetStreamAsync(@"$7zipUrl"))
{
using (var fs = new FileStream(@"$installer", FileMode.OpenOrCreate))
{
s.Result.CopyTo(fs);
}
}
}
}
}
"@
[Downloader]::DownloadInstaller()
# Install 7-Zip silently
Start-Process -FilePath "msiexec.exe" -ArgumentList "/i $installer /qn" -Wait
# Remove installer
Remove-Item $installer
Conclusion
To install 7-Zip using PowerShell, we could download the file first and then perform silent installation. To download the file, there are some cmdlets we can use: using Invoke-WebRequest
or Invoke-RestMethod
. We can also use .NET Framework class like WebClient
or HttpClient
to download the installer.
If we already have the installer or download it manually, we can perform silent installation directly. After installation process finished, we could remove the installer using Remove-Item
cmdlet and this step is optional.