Private/Invoke-DownloadIntuneTool.ps1
function Invoke-DownloadIntuneTool { <# .SYNOPSIS Downloads the latest IntuneWinAppUtil.exe from GitHub and caches it under %APPDATA%\IntuneWinAppUtilGUI\bin. .DESCRIPTION - Forces TLS 1.2 for GitHub downloads. - Creates (or ensures) the bin directory under $env:APPDATA\IntuneWinAppUtilGUI\bin. - Removes any stale IntuneWinAppUtil.exe in the bin directory. - Downloads the repository master ZIP, extracts it to a unique temp folder, locates IntuneWinAppUtil.exe, and copies it into the bin directory. - Cleans up all temp files/folders in a finally block. - Returns the full path to the cached IntuneWinAppUtil.exe. - Throws on failure (caller can catch and show a message box). .PARAMETER DestinationRoot Optional base path for the cache (default: $env:APPDATA\IntuneWinAppUtilGUI). .PARAMETER RepoZipUrl Optional ZIP URL (default: master branch of Microsoft-Win32-Content-Prep-Tool). .OUTPUTS [string] Full path to IntuneWinAppUtil.exe. .EXAMPLE $exe = Invoke-DownloadIntuneTool # $exe now points to %APPDATA%\IntuneWinAppUtilGUI\bin\IntuneWinAppUtil.exe #> [CmdletBinding()] param( [string]$DestinationRoot = (Join-Path $env:APPDATA 'IntuneWinAppUtilGUI'), [string]$RepoZipUrl = 'https://github.com/microsoft/Microsoft-Win32-Content-Prep-Tool/archive/refs/heads/master.zip' ) # Ensure TLS 1.2 for GitHub try { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 } catch {} $binDir = Join-Path $DestinationRoot 'bin' $exePath = Join-Path $binDir 'IntuneWinAppUtil.exe' $tempZip = Join-Path $env:TEMP ("IntuneWinAppUtil-{0}.zip" -f ([guid]::NewGuid())) $tempDir = Join-Path $env:TEMP ("IntuneExtract-{0}" -f ([guid]::NewGuid())) try { # Prepare target folder and clean stale exe New-Item -ItemType Directory -Path $binDir -Force | Out-Null if (Test-Path $exePath) { Remove-Item $exePath -Force -ErrorAction SilentlyContinue } # Download Invoke-WebRequest -Uri $RepoZipUrl -OutFile $tempZip -UseBasicParsing -ErrorAction Stop # Extract (fallback if overwrite overload isn't available) New-Item -ItemType Directory -Path $tempDir -Force | Out-Null $zipType = [System.IO.Compression.ZipFile] $hasOverwrite = $zipType.GetMethod( 'ExtractToDirectory', [Reflection.BindingFlags]'Public, Static', $null, @([string], [string], [bool]), $null ) if ($hasOverwrite) { [System.IO.Compression.ZipFile]::ExtractToDirectory($tempZip, $tempDir, $true) } else { [System.IO.Compression.ZipFile]::ExtractToDirectory($tempZip, $tempDir) } # Locate exe $found = Get-ChildItem -Path $tempDir -Recurse -Filter 'IntuneWinAppUtil.exe' -File -ErrorAction SilentlyContinue | Select-Object -First 1 if (-not $found) { throw "IntuneWinAppUtil.exe not found in the extracted archive." } # Copy into cache Copy-Item -Path $found.FullName -Destination $exePath -Force return $exePath } catch { throw $_ } finally { # Best-effort cleanup foreach ($p in @($tempZip, $tempDir)) { try { if (Test-Path $p) { if (Test-Path $p -PathType Container) { Remove-Item $p -Recurse -Force -ErrorAction SilentlyContinue } else { Remove-Item $p -Force -ErrorAction SilentlyContinue } } } catch {} } } } |