Last active
August 15, 2024 18:08
-
-
Save milnak/88d66ea79df519e3f07a30ee10531d5a to your computer and use it in GitHub Desktop.
Scoop Bootstrap Generator: Mirror scoop configuration for a new device from an existing - superset of 'scoop export' #scoop
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <# | |
| .SYNOPSIS | |
| Scoop Bootstrap Script Generator | |
| .DESCRIPTION | |
| Create a scoop bootstrap, copying config from an existing installation. | |
| .EXAMPLE | |
| PS C:\> ./scoop-bootstrap-generator.ps1 | Out-File scoop-bootstrap.ps1 | |
| .LINK | |
| Scoop homepage: https://scoop.sh/ | |
| .NOTES | |
| Run on machine with installed and configured scoop, and pipe output to file or Set-Clipboard. | |
| Run that output file on a new machine and scoop configuration will mirror the source machine. | |
| #> | |
| Function Write-Header { | |
| @' | |
| <# | |
| .SYNOPSIS | |
| Scoop Bootstrap Script | |
| .DESCRIPTION | |
| Installs scoop, apps, sets configuration and aliases. | |
| .EXAMPLE | |
| PS C:\> ./scoop-bootstrap.ps1 | |
| .LINK | |
| Scoop homepage: https://scoop.sh/ | |
| .NOTES | |
| '@ | |
| "Generated from {0} on {1}" -f $env:computername, (Get-Date) | |
| @' | |
| #> | |
| '@ | |
| } | |
| Function Write-ScoopInstall { | |
| @' | |
| if (-not (Get-Command 'scoop' -ErrorAction SilentlyContinue)) { | |
| Write-Host -ForegroundColor Yellow 'Installing scoop' | |
| Set-ExecutionPolicy RemoteSigned -Scope CurrentUser | |
| if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]'Administrator')) { | |
| Invoke-WebRequest -UseBasicParsing get.scoop.sh | Invoke-Expression | |
| } else { | |
| if ($Host.UI.PromptForChoice("Confirm", "Install scoop as admin?" -f $args[0], ("&Yes", "&No"), 1) -eq 0) { | |
| Invoke-Expression "& {$(Invoke-RestMethod get.scoop.sh)} -RunAsAdmin" | |
| } else { | |
| return | |
| } | |
| } | |
| } | |
| '@ | |
| } | |
| Function Write-Config { | |
| @' | |
| Write-Host -ForegroundColor Yellow 'Adding config' | |
| '@ | |
| # NOTE: Required because 'scoop config' returns a PSCustomObject | |
| $config = scoop config | |
| $configs = $config | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name | ForEach-Object { [PSCustomObject]@{ Name = $_; Value = $config.$_ } } | |
| $configs | Where-Object Name -notin @( 'alias', 'scoop_repo', 'last_update', 'scoop_branch' ) ` | |
| | ForEach-Object { "scoop config $($_.Name) '$($_.Value)'" } | |
| } | |
| Function Write-Buckets { | |
| @' | |
| Write-Host -ForegroundColor Yellow 'Adding buckets' | |
| '@ | |
| # NOTE: Redirection neeed. See https://github.com/ScoopInstaller/Scoop/issues/5216 | |
| $apps = scoop list 6> $null | Select-Object Source, Name | Sort-Object -Property @{ Expression = { $_.Source -eq 'main' }; Descending = $true }, Name | |
| # Determine what buckets we'll need | |
| # git is required for buckets | |
| 'scoop install main/git' | |
| # main is installed by default | |
| $apps | Select-Object -Unique Source | Where-Object Source -ne 'main' | ForEach-Object { | |
| "scoop bucket add $($_.Source)" | |
| } | |
| } | |
| Function Write-Apps { | |
| @' | |
| Write-Host -ForegroundColor Yellow 'Installing apps' | |
| '@ | |
| # NOTE: Redirection neeed. See https://github.com/ScoopInstaller/Scoop/issues/5216 | |
| $apps = scoop list 6> $null | Select-Object Source, Name | Sort-Object -Property @{ Expression = { $_.Source -eq 'main' }; Descending = $true }, Name | |
| $apps | ForEach-Object { | |
| "scoop install $($_.Source)/$($_.Name)" | |
| } | |
| } | |
| Function Write-Export { | |
| @' | |
| Write-Host -ForegroundColor Yellow 'Installing git' | |
| '@ | |
| # git is required for buckets | |
| # See https://github.com/ScoopInstaller/Scoop/issues/5252 | |
| 'scoop install main/git' | |
| @' | |
| Write-Host -ForegroundColor Yellow 'Importing configuration' | |
| '@ | |
| '$tempfile = [IO.Path]::GetTempFileName()' | |
| '@''' | |
| scoop export --config | |
| '''@ | Out-File $tempfile' | |
| '' | |
| 'scoop import $tempfile' | |
| 'Remove-Item $tempfile' | |
| } | |
| Function Write-Aliases { | |
| # NOTE: This is required as 'scoop alias list' doesn't include descriptions | |
| # NOTE: How to get scoop home folder? | |
| $aliases = Get-ChildItem -LiteralPath "${env:HOMEDRIVE}${env:HOMEPATH}/scoop/shims" -File -Recurse -Filter 'scoop-*.ps1' ` | |
| | Select-Object @{Name = 'Name'; Expression = { $_.BaseName.SubString(6) } }, @{Name = 'Command'; Expression = { Get-Content $_.FullName ` | |
| | Select-String -Pattern '^# Summary: (.*)' -NotMatch } | |
| }, @{Name = 'Summary'; Expression = { (Get-Content $_.FullName | Select-String -Pattern '^# Summary: (.*)').Matches[0].Groups[1] } } | |
| @' | |
| Write-Host -ForegroundColor Yellow 'Adding aliases' | |
| '@ | |
| $aliases | ForEach-Object { | |
| "scoop alias add '$($_.Name)' '$($_.Command)' '$($_.Summary)'" | |
| } | |
| } | |
| if (-not (Get-Command 'scoop' -ErrorAction SilentlyContinue)) { | |
| 'This script must be run on a machine that has scoop installed and configured.' | |
| return | |
| } | |
| Write-Header | |
| Write-ScoopInstall | |
| # Write-Config | |
| # Write-Buckets | |
| # Write-Apps | |
| Write-Export | |
| Write-Aliases |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment