Skip to content

Instantly share code, notes, and snippets.

@milnak
Last active August 15, 2024 18:08
Show Gist options
  • Save milnak/88d66ea79df519e3f07a30ee10531d5a to your computer and use it in GitHub Desktop.
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
<#
.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