236 lines
9.1 KiB
PowerShell
236 lines
9.1 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
Get-EdgeEnterpriseMSI
|
|
|
|
.DESCRIPTION
|
|
Imports all device configurations in a folder to a specified tenant
|
|
|
|
.PARAMETER Channel
|
|
Channel to download, Valid Options are: Dev, Beta, Stable, EdgeUpdate, Policy.
|
|
|
|
.PARAMETER Platform
|
|
Platform to download, Valid Options are: Windows or MacOS, if using channel "Policy" this should be set to "any"
|
|
Defaults to Windows if not set.
|
|
|
|
.PARAMETER Architecture
|
|
Architecture to download, Valid Options are: x86, x64, arm64, if using channel "Policy" this should be set to "any"
|
|
Defaults to x64 if not set.
|
|
|
|
.PARAMETER Version
|
|
If set the script will try and download a specific version. If not set it will download the latest.
|
|
|
|
.PARAMETER Folder
|
|
Specifies the Download folder
|
|
|
|
.PARAMETER Force
|
|
Overwrites the file without asking.
|
|
|
|
.NOTES
|
|
Version: 1.2
|
|
Author: Mattias Benninge
|
|
Creation Date: 2020-07-01
|
|
|
|
Version history:
|
|
|
|
1.0 - Initial script development
|
|
1.1 - Fixes and improvements by @KarlGrindon
|
|
- Script now handles multiple files for e.g. MacOS Edge files
|
|
- Better error handling and formating
|
|
- URI Validation
|
|
1.2 - Better compability on servers (force TLS and remove dependency to IE)
|
|
|
|
|
|
https://docs.microsoft.com/en-us/mem/configmgr/apps/deploy-use/deploy-edge
|
|
|
|
.EXAMPLE
|
|
|
|
Download the latest version for the Beta channel and overwrite any existing file
|
|
.\Get-EdgeEnterpriseMSI.ps1 -Channel Beta -Folder D:\SourceCode\PowerShell\Div -Force
|
|
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[Parameter(Mandatory = $True, HelpMessage = 'Channel to download, Valid Options are: Dev, Beta, Stable, EdgeUpdate, Policy')]
|
|
[ValidateSet('Dev', 'Beta', 'Stable', 'EdgeUpdate', 'Policy')]
|
|
[string]$Channel = "Stable",
|
|
|
|
[Parameter(Mandatory = $True, HelpMessage = 'Folder where the file will be downloaded')]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string]$Folder = "C:\temp",
|
|
|
|
[Parameter(Mandatory = $false, HelpMessage = 'Platform to download, Valid Options are: Windows or MacOS')]
|
|
[ValidateSet('Windows', 'MacOS', 'any')]
|
|
[string]$Platform = "Windows",
|
|
|
|
[Parameter(Mandatory = $false, HelpMessage = "Architecture to download, Valid Options are: x86, x64, arm64, any")]
|
|
[ValidateSet('x86', 'x64', 'arm64', 'any')]
|
|
[string]$Architecture = "x64",
|
|
|
|
[parameter(Mandatory = $false, HelpMessage = "Specifies which version to download")]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string]$ProductVersion,
|
|
|
|
[parameter(Mandatory = $false, HelpMessage = "Overwrites the file without asking")]
|
|
[Switch]$Force
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
$edgeEnterpriseMSIUri = 'https://edgeupdates.microsoft.com/api/products?view=enterprise'
|
|
|
|
# Validating parameters to reduce user errors
|
|
if ($Channel -eq "Policy" -and ($Architecture -ne "Any" -or $Platform -ne "Any")) {
|
|
Write-Warning ("Channel 'Policy' requested, but either 'Architecture' and/or 'Platform' is not set to 'Any'.
|
|
Setting Architecture and Platform to 'Any'")
|
|
|
|
$Architecture = "Any"
|
|
$Platform = "Any"
|
|
}
|
|
elseif ($Channel -ne "Policy" -and ($Architecture -eq "Any" -or $Platform -eq "Any")) {
|
|
throw "If Channel isn't set to policy, architecture and/or platform can't be set to 'Any'"
|
|
}
|
|
elseif ($Channel -eq "EdgeUpdate" -and ($Architecture -ne "x86" -or $Platform -eq "Windows")) {
|
|
Write-Warning ("Channel 'EdgeUpdate' requested, but either 'Architecture' is not set to x86 and/or 'Platform'
|
|
is not set to 'Windows'. Setting Architecture to 'x86' and Platform to 'Windows'")
|
|
|
|
$Architecture = "x86"
|
|
$Platform = "Windows"
|
|
}
|
|
|
|
Write-Host "Enabling connection over TLS for better compability on servers" -ForegroundColor Green
|
|
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls12
|
|
|
|
# Test if HTTP status code 200 is returned from URI
|
|
try {
|
|
Invoke-WebRequest $edgeEnterpriseMSIUri -UseBasicParsing | Where-Object StatusCode -match 200 | Out-Null
|
|
}
|
|
catch {
|
|
throw "Unable to get HTTP status code 200 from $edgeEnterpriseMSIUri. Does the URL still exist?"
|
|
}
|
|
|
|
Write-Host "Getting available files from $edgeEnterpriseMSIUri" -ForegroundColor Green
|
|
|
|
# Try to get JSON data from Microsoft
|
|
try {
|
|
$response = Invoke-WebRequest -Uri $edgeEnterpriseMSIUri -Method Get -ContentType "application/json" -UseBasicParsing -ErrorVariable InvokeWebRequestError
|
|
$jsonObj = ConvertFrom-Json $([String]::new($response.Content))
|
|
Write-Host "Succefully retrived data" -ForegroundColor Green
|
|
}
|
|
catch {
|
|
throw "Could not get MSI data: $InvokeWebRequestError"
|
|
}
|
|
|
|
# Alternative is to use Invoke-RestMethod to get a Json object directly
|
|
# $jsonObj = Invoke-RestMethod -Uri "https://edgeupdates.microsoft.com/api/products?view=enterprise" -UseBasicParsing
|
|
|
|
$selectedIndex = [array]::indexof($jsonObj.Product, "$Channel")
|
|
|
|
if (-not $ProductVersion) {
|
|
try {
|
|
Write-host "No version specified, getting the latest for $Channel" -ForegroundColor Green
|
|
$selectedVersion = (([Version[]](($jsonObj[$selectedIndex].Releases |
|
|
Where-Object { $_.Architecture -eq $Architecture -and $_.Platform -eq $Platform }).ProductVersion) |
|
|
Sort-Object -Descending)[0]).ToString(4)
|
|
|
|
Write-Host "Latest Version for channel $Channel is $selectedVersion`n" -ForegroundColor Green
|
|
$selectedObject = $jsonObj[$selectedIndex].Releases |
|
|
Where-Object { $_.Architecture -eq $Architecture -and $_.Platform -eq $Platform -and $_.ProductVersion -eq $selectedVersion }
|
|
}
|
|
catch {
|
|
throw "Unable to get object from Microsoft. Check your parameters and refer to script help."
|
|
}
|
|
}
|
|
else {
|
|
Write-Host "Matching $ProductVersion on channel $Channel" -ForegroundColor Green
|
|
$selectedObject = ($jsonObj[$selectedIndex].Releases |
|
|
Where-Object { $_.Architecture -eq $Architecture -and $_.Platform -eq $Platform -and $_.ProductVersion -eq $ProductVersion })
|
|
|
|
if (-not $selectedObject) {
|
|
throw "No version matching $ProductVersion found in $channel channel for $Architecture architecture."
|
|
}
|
|
else {
|
|
Write-Host "Found matching version`n" -ForegroundColor Green
|
|
}
|
|
}
|
|
|
|
|
|
if (Test-Path $Folder) {
|
|
foreach ($artifacts in $selectedObject.Artifacts) {
|
|
# Not showing the progress bar in Invoke-WebRequest is quite a bit faster than default
|
|
$ProgressPreference = 'SilentlyContinue'
|
|
|
|
Write-host "Starting download of: $($artifacts.Location)" -ForegroundColor Green
|
|
# Work out file name
|
|
$fileName = Split-Path $artifacts.Location -Leaf
|
|
|
|
if (Test-Path "$Folder\$fileName" -ErrorAction SilentlyContinue) {
|
|
if ($Force) {
|
|
Write-Host "Force specified. Will attempt to download and overwrite existing file." -ForegroundColor Green
|
|
try {
|
|
Invoke-WebRequest -Uri $artifacts.Location -OutFile "$Folder\$fileName" -UseBasicParsing
|
|
}
|
|
catch {
|
|
throw "Attempted to download file, but failed: $error[0]"
|
|
}
|
|
}
|
|
else {
|
|
# CR-someday: There should be an evaluation of the file version, if possible. Currently the function only
|
|
# checks if a file of the same name exists, not if the versions differ
|
|
Write-Host "$Folder\$fileName already exists!" -ForegroundColor Yellow
|
|
|
|
do {
|
|
$overWrite = Read-Host -Prompt "Press Y to overwrite or N to quit."
|
|
}
|
|
# -notmatch is case insensitive
|
|
while ($overWrite -notmatch '^y$|^n$')
|
|
|
|
if ($overWrite -match '^y$') {
|
|
Write-Host "Starting Download" -ForegroundColor Green
|
|
try {
|
|
Invoke-WebRequest -Uri $artifacts.Location -OutFile "$Folder\$fileName" -UseBasicParsing
|
|
}
|
|
catch {
|
|
throw "Attempted to download file, but failed: $error[0]"
|
|
}
|
|
}
|
|
else {
|
|
Write-Host "File already exists and user chose not to overwrite, exiting script." -ForegroundColor Red
|
|
exit
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
Write-Host "Starting Download" -ForegroundColor Green
|
|
try {
|
|
Invoke-WebRequest -Uri $artifacts.Location -OutFile "$Folder\$fileName" -UseBasicParsing
|
|
}
|
|
catch {
|
|
throw "Attempted to download file, but failed: $error[0]"
|
|
}
|
|
}
|
|
if (((Get-FileHash -Algorithm $artifacts.HashAlgorithm -Path "$Folder\$fileName").Hash) -eq $artifacts.Hash) {
|
|
Write-Host "Calculated checksum matches known checksum`n" -ForegroundColor Green
|
|
}
|
|
else {
|
|
Write-Warning "Checksum mismatch!"
|
|
Write-Warning "Expected Hash: $($artifacts.Hash)"
|
|
Write-Warning "Downloaded file Hash: $((Get-FileHash -Algorithm $($artifacts.HashAlgorithm) -Path "$Folder\$fileName").Hash)`n"
|
|
}
|
|
}
|
|
}
|
|
Else {
|
|
throw "Folder $Folder does not exist"
|
|
}
|
|
Write-Host "-- Script Completed: File Downloaded -- " -ForegroundColor Green
|
|
|
|
Write-Host "Installing..." -ForegroundColor Green
|
|
|
|
cmd /c start /wait msiexec /i "$Folder\$fileName" /qn /norestart
|
|
|
|
Set-Service edgeupdate -StartupType Manual -ErrorAction SilentlyContinue
|
|
Set-Service edgeupdatem -StartupType Manual -ErrorAction SilentlyContinue
|
|
|
|
Unregister-ScheduledTask -TaskName MicrosoftEdgeUpdateTaskMachineCore -Confirm:$false -ErrorAction SilentlyContinue
|
|
Unregister-ScheduledTask -TaskName MicrosoftEdgeUpdateTaskMachineUA -Confirm:$false -ErrorAction SilentlyContinue
|
|
|
|
Write-Host "Installed Microsoft Edge" -ForegroundColor Green |