$null = New-Module { . "$PSScriptRoot/../../Common/Scripts/BrowserAutomation.ps1"; . "$PSScriptRoot/../../Common/Scripts/SoftwareManagement.ps1"; $chocoRunner = { param( [string] $Action = 'install', [string[]] $ArgumentList, [scriptblock] $Guard = { $true }, [Parameter(Position = 0)] [string] $Name, [Parameter(ValueFromRemainingArguments = $true)] [string[]] $AdditionalNames = @() ) [System.Collections.ArrayList] $Names = @(); $null = $Names.Add($Name); $Names.AddRange($AdditionalNames); if (-not ($Force.IsPresent)) { for ($i = $Names.Count - 1; $i -ge 0; $i--) { $name = $Names[$i]; if (-not (& $Guard $name)) { $Names.RemoveAt($i); } } } if ($Names.Count -ge 1) { choco $Action -y @ArgumentList @Names; } }; $wingetRunner = { param( [string] $Action = 'install', [string[]] $ArgumentList, [scriptblock] $Guard = { $true }, [Parameter(Position = 0)] [string] $Name, [Parameter(ValueFromRemainingArguments = $true)] [string[]] $AdditionalNames = @() ) [System.Collections.ArrayList] $Names = @(); $null = $Names.Add($Name); $Names.AddRange($AdditionalNames); [string[]] $arguments = $ArgumentList + (& { if ($Action -eq 'install') { @("--accept-package-agreements") }; }); foreach ($name in $Names) { if ($Force.IsPresent -or (& $Guard $name $PSBoundParameters)) { winget $Action ` --accept-source-agreements ` --source winget ` @arguments ` --exact --id $name ; } } }; <# .SYNOPSIS Checks whether `winget` is working properly. #> function Test-Winget { (Test-Command winget) -and ( & { $output = winget source update winget; $? -and -not ([System.Linq.Enumerable]::Any( [string[]]($output), [System.Func[string,bool]]{ param($line) $line -eq "Cancelled"; })); }); } <# .SYNOPSIS Checks whether the specified package has been installed using Chocolatey. .PARAMETER Name The name of the package to check. #> function Test-ChocoPackage { [OutputType([bool])] param( [string] $Name ); -not [string]::IsNullOrEmpty((choco list --limit-output --exact $name)); } <# .SYNOPSIS Checks whether a `winget` package with the specified id is installed. .PARAMETER ID The id of the package to check. #> function Test-WingetPackage { [OutputType([bool])] param( [string] $Name, [string[]] $ArgumentList ) & { $null = winget list --accept-source-agreements -e --id $Name @ArgumentList; $?; }; } <# .SYNOPSIS Installs the specified packages using chocolatey. .PARAMETER Names The names of the packages to install. #> function Install-ChocoPackage { param( [switch] $Force, [string[]] $ArgumentList, [Parameter(Position=0)] [string] $Name, [Parameter(ValueFromRemainingArguments = $true)] [string[]] $AdditionalNames = @() ) & $chocoRunner @PSBoundParameters -Guard { param($Name) if (Test-ChocoPackage $Name) { Write-Host "Package ``$Name`` is already installed" $false; } else { $true; } }; } <# .SYNOPSIS Uninstalls the specified packages using chocolatey. #> function Uninstall-ChocoPackage { param( [string[]] $ArgumentList, [Parameter(Position=0)] [string] $Name, [Parameter(ValueFromRemainingArguments = $true)] [string[]] $AdditionalNames = @() ) & $chocoRunner @PSBoundParameters -Action 'uninstall' -Guard { param($Name) if (Test-ChocoPackage $Name) { $true; } else { Write-Host "Package ``$Name`` is not installed"; $false; } }; } <# .SYNOPSIS Installs the specified packages using `winget`. .PARAMETER Names The names of the packages to install. #> function Install-WingetPackage { param( [switch] $Force, [string[]] $ArgumentList, [Parameter(Position=0)] [string] $Name, [Parameter(ValueFromRemainingArguments = $true)] [string[]] $AdditionalNames = @() ) & $wingetRunner @PSBoundParameters ` -Guard { param($Name, $Parameters) if (Test-WingetPackage -Name $Name @Parameters) { Write-Host "Package ``$Name`` is already installed" $false; } else { $true; } }; } <# .SYNOPSIS Uninstalls the specified packages using `winget`. #> function Uninstall-WingetPackage { param( [string[]] $ArgumentList, [Parameter(Position=0)] [string] $Name, [Parameter(ValueFromRemainingArguments = $true)] [string[]] $AdditionalNames = @() ) & $wingetRunner @PSBoundParameters -Action 'uninstall' -Guard { param($Name, $Parameters) if (Test-WingetPackage -Name $Name @Parameters) { $true; } else { Write-Host "Package ``$Name`` is not installed" $false; } }; } <# .SYNOPSIS Installs a setup package from the specified source. .PARAMETER Source The location of the setup package. .PARAMETER ArgumentList The arguments to pass to the setup package. .PARAMETER Local A value indicating whether the setup package is stored locally. #> function Install-SetupPackage { param( [string] $Source, [string[]] $ArgumentList = @("/S"), [switch] $Local ) [string] $dir = $null; [string] $filePath = $null; if (-not ($Local.IsPresent)) { $dir = New-TemporaryDirectory; Write-Host "Determining the file name of ``$Source``…"; $fileName = ([uri]$Source).Segments[-1]; Write-Host "Found name ``$fileName``"; $filePath = Join-Path $dir $fileName; Write-Host "Downloading setup file from ``$Source``"; Invoke-WebRequest $Source -OutFile $filePath; } else { $filePath = $Source; } Write-Host "Starting installation of ``$(Split-Path -Leaf $filePath)``"; Start-Process -Wait -WorkingDirectory (Split-Path -Parent $filePath) -FilePath $filePath -ArgumentList $ArgumentList; if ($dir) { Remove-Item -Recurse $dir; } } <# .SYNOPSIS Installs a package downloaded from ASUS. .PARAMETER URL The URL to download the package from. #> function Install-AsusPackage { param( [string] $URL ) $file = "AsusPackage.zip"; $dir = New-TemporaryDirectory; $unpackDir = New-TemporaryDirectory; $null = Push-Location $dir; Invoke-WebRequest $URL -OutFile $file; Expand-Archive $file $unpackDir; $null = Pop-Location; Remove-Item -Recurse $dir; $null = Start-Process -Wait -WorkingDirectory $unpackDir -FilePath (Join-Path $unpackDir "AsusSetup.exe") -ArgumentList "/S"; Remove-Item -Recurse $unpackDir; } <# .SYNOPSIS Downloads and installs a package from the AMD website. .PARAMETER URL The URL to download the package from. #> function Install-AmdPackage { param( [string] $URL ) $dir = New-TemporaryDirectory; $cookieBannerSelector = "#onetrust-consent-sdk"; $osSelector = "div[id$='oscategory']>div[id$='-0']"; $downloadSelector = "$osSelector div[id$='panel'] .button a"; $file = Start-CustomBrowserDownload @PSBoundParameters -OutDir $dir -Action { param( [OpenQA.Selenium.Firefox.FirefoxDriver] $Browser ) $osContainer = $Browser.FindElement([OpenQA.Selenium.By]::CssSelector($osSelector)); if (-not ([bool] $osContainer.GetAttribute("cmp-expanded"))) { $osContainer.Click(); } $download = { $browser.FindElement([OpenQA.Selenium.By]::CssSelector($downloadSelector)).Click(); }; try { & $download; } catch { $null = $Browser.ExecuteScript("document.querySelector('$cookieBannerSelector').remove()"); & $download; } }; Start-Process -Wait -WorkingDirectory (Split-Path -Parent "$file") -FilePath "$file" -ArgumentList "/S"; Remove-Item -Recurse $dir; } };