Skip to content

Commit 2ef0660

Browse files
committed
install-win: rework to use sbnb.raw, fancy formatting
1 parent f60581c commit 2ef0660

File tree

1 file changed

+153
-128
lines changed

1 file changed

+153
-128
lines changed

scripts/install-win.ps1

Lines changed: 153 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1,128 +1,153 @@
1-
# This script automates Sbnb Linux bootable USB creation process on Windows.
2-
# It downloads and installs the sbnb.efi file onto a selected disk.
3-
# It also allows the user to provide a Tailscale key and a custom script to be executed during Sbnb Linux boot.
4-
#
5-
# More info at https://github.com/sbnb-io/sbnb
6-
7-
param (
8-
[string]$SbnbEfiPath
9-
)
10-
11-
Write-Output "Welcome to Sbnb Linux bootable USB creation"
12-
13-
# Step 1: Find latest release and download sbnb.efi.zip if not provided
14-
if (-not $SbnbEfiPath) {
15-
$repoUrl = "https://api.github.com/repos/sbnb-io/sbnb/releases/latest"
16-
$releaseInfo = Invoke-RestMethod -Uri $repoUrl
17-
$latestRelease = $releaseInfo.tag_name
18-
$downloadUrl = $releaseInfo.assets | Where-Object { $_.name -eq "sbnb.efi.zip" } | Select-Object -ExpandProperty browser_download_url
19-
20-
Write-Output "Sbnb Linux latest release: $latestRelease"
21-
Write-Output "Download URL: $downloadUrl"
22-
23-
# Get the size of the download
24-
$webRequest = Invoke-WebRequest -Uri $downloadUrl -Method Head
25-
$fileSize = [math]::Round($webRequest.Headers['Content-Length'] / 1MB, 2)
26-
27-
# Ask user if they agree to continue
28-
$confirmation = Read-Host "The file size is $fileSize MB. Do you want to continue with the download? (y/n)"
29-
if ($confirmation -ne "y") {
30-
Write-Output "Download cancelled."
31-
exit
32-
}
33-
34-
Write-Output "Downloading sbnb.efi.zip..."
35-
$wc = New-Object net.webclient
36-
$wc.DownloadFile($downloadUrl, "sbnb.efi.zip")
37-
38-
# Step 2: Decompress sbnb.efi.zip to a temporary directory
39-
$tempDir = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName())
40-
[System.IO.Directory]::CreateDirectory($tempDir)
41-
42-
Write-Output "Decompressing sbnb.efi.zip to $tempDir..."
43-
Add-Type -AssemblyName System.IO.Compression.FileSystem
44-
[System.IO.Compression.ZipFile]::ExtractToDirectory("sbnb.efi.zip", $tempDir)
45-
46-
$SbnbEfiPath = "$tempDir\sbnb.efi"
47-
} else {
48-
Write-Output "Using provided sbnb.efi file: $SbnbEfiPath"
49-
}
50-
51-
# Step 3: Enumerate all disks and ask user to input disk number
52-
$disks = Get-WmiObject -Query "SELECT * FROM Win32_DiskDrive" | Sort-Object -Property Model
53-
for ($i = 0; $i -lt $disks.Count; $i++) {
54-
$diskInfo = "${i}: $($disks[$i].DeviceID) - $($disks[$i].Model) - $($disks[$i].Name)"
55-
Write-Host $diskInfo
56-
}
57-
58-
$selectedDiskNumber = Read-Host "Enter the number of the disk to flash into"
59-
$selectedDrive = $disks[$selectedDiskNumber].Index
60-
61-
# Step 4: Double confirm user agrees with selection
62-
$confirmation = Read-Host "You have selected disk $($disks[$selectedDiskNumber].Model) (Index: $selectedDrive). All data on this disk will be destroyed. Are you sure you want to proceed? (y/n)"
63-
if ($confirmation -ne "y") {
64-
Write-Output "Operation cancelled."
65-
exit
66-
}
67-
68-
# Step 5: Remove all existing partitions and create ESP partition
69-
Write-Output "Removing all existing partitions on disk $($disks[$selectedDiskNumber].Model) (Index: $selectedDrive)..."
70-
Get-Disk -Number $selectedDrive | Clear-Disk -RemoveData -Confirm:$false
71-
72-
# Get the size of the selected disk
73-
$disk = Get-Disk -Number $selectedDrive
74-
$diskSize = $disk.Size
75-
76-
# Determine the partition size
77-
$maxSize = 16GB
78-
$partitionSize = if ($diskSize -lt $maxSize) { $diskSize } else { $maxSize }
79-
80-
Write-Output "Creating ESP partition on disk $($disks[$selectedDiskNumber].Model) (Index: $selectedDrive) with a size of $partitionSize bytes..."
81-
$partition = New-Partition -DiskNumber $disk.Number -Size $partitionSize -AssignDriveLetter
82-
Start-Sleep -Seconds 5
83-
Format-Volume -FileSystem FAT32 -NewFileSystemLabel "sbnb" -DriveLetter $partition.DriveLetter
84-
Write-Output "Partition created and formatted with drive letter: $($partition.DriveLetter)"
85-
86-
# Step 6: Decompress and place sbnb.efi on the ESP partition
87-
$espDriveLetter = $partition.DriveLetter
88-
if (-not [string]::IsNullOrEmpty($espDriveLetter)) {
89-
$espPath = "$($espDriveLetter):\EFI\Boot"
90-
[System.IO.Directory]::CreateDirectory($espPath)
91-
} else {
92-
Write-Output "Error: Unable to determine the ESP drive letter."
93-
exit
94-
}
95-
96-
Write-Output "Copying sbnb.efi to $espPath\bootx64.efi..."
97-
Copy-Item -Path $SbnbEfiPath -Destination "$espPath\bootx64.efi"
98-
99-
# Step 7: Ask user to provide Tailscale key and place it on the ESP partition
100-
$tailscaleKey = Read-Host "Please provide your Tailscale key (press Enter to skip)"
101-
if (-not [string]::IsNullOrEmpty($tailscaleKey)) {
102-
$tailscaleKeyPath = "$($espDriveLetter):\sbnb-tskey.txt"
103-
[System.IO.File]::WriteAllText($tailscaleKeyPath, $tailscaleKey)
104-
Write-Output "Tailscale key saved to $tailscaleKeyPath"
105-
} else {
106-
Write-Output "No Tailscale key provided. Skipping this step."
107-
}
108-
109-
# Step 7.1: Ask user to provide the path to a script file and place it on the ESP partition
110-
$scriptFilePath = Read-Host "Please provide the path to your script file (this script will be saved to sbnb-cmds.sh and executed during Sbnb Linux boot) (press Enter to skip)"
111-
$scriptFilePath = $scriptFilePath.Trim('"')
112-
if (-not [string]::IsNullOrEmpty($scriptFilePath) -and (Test-Path $scriptFilePath)) {
113-
$scriptContent = Get-Content -Path $scriptFilePath -Raw
114-
# Convert to Unix format by replacing Windows line endings with Unix line endings
115-
$scriptContent = $scriptContent -replace "`r`n", "`n"
116-
117-
$scriptPath = "$($espDriveLetter):\sbnb-cmds.sh"
118-
[System.IO.File]::WriteAllText($scriptPath, $scriptContent)
119-
Write-Output "Script saved to $scriptPath"
120-
} else {
121-
Write-Output "No valid script file provided. Skipping this step."
122-
}
123-
124-
# Step 8: Set GPT partition type
125-
Write-Output "Setting GPT partition type to C12A7328-F81F-11D2-BA4B-00A0C93EC93B..."
126-
Set-Partition -DiskNumber $disk.Number -PartitionNumber $partition.PartitionNumber -GptType "{C12A7328-F81F-11D2-BA4B-00A0C93EC93B}"
127-
128-
Write-Output "Operation completed successfully."
1+
# This script automates Sbnb Linux bootable USB creation process on Windows.
2+
# It downloads, decompresses, and installs the sbnb.raw file onto a selected disk.
3+
# It also allows the user to provide a Tailscale key and a custom script to be executed during Sbnb Linux boot.
4+
# More info at https://github.com/sbnb-io/sbnb
5+
6+
param (
7+
[string]$SbnbRawPath
8+
)
9+
10+
Write-Host "=========================================" -ForegroundColor Cyan
11+
Write-Host " Welcome to Sbnb Linux Bootable USB Creation " -ForegroundColor Cyan
12+
Write-Host "=========================================" -ForegroundColor Cyan
13+
14+
# Step 1: Find latest release and download sbnb.raw.zip if not provided
15+
if (-not $SbnbRawPath) {
16+
$repoUrl = "https://api.github.com/repos/sbnb-io/sbnb/releases/latest"
17+
$releaseInfo = Invoke-RestMethod -Uri $repoUrl
18+
$latestRelease = $releaseInfo.tag_name
19+
$downloadUrl = $releaseInfo.assets | Where-Object { $_.name -eq "sbnb.raw.zip" } | Select-Object -ExpandProperty browser_download_url
20+
21+
Write-Host "Sbnb Linux latest release: $latestRelease" -ForegroundColor Green
22+
Write-Host "Download URL: $downloadUrl" -ForegroundColor Green
23+
24+
# Get the size of the download
25+
$webRequest = Invoke-WebRequest -Uri $downloadUrl -Method Head
26+
$fileSize = [math]::Round($webRequest.Headers['Content-Length'] / 1MB, 2)
27+
28+
# Ask user if they agree to continue
29+
$confirmation = Read-Host "The file size is $fileSize MB. Do you want to continue with the download? (y/n)"
30+
if ($confirmation -ne "y") {
31+
Write-Host "Download cancelled." -ForegroundColor Red
32+
exit
33+
}
34+
35+
Write-Host "Downloading sbnb.raw.zip..." -ForegroundColor Yellow
36+
$wc = New-Object net.webclient
37+
$wc.DownloadFile($downloadUrl, "sbnb.raw.zip")
38+
39+
# Step 2: Decompress sbnb.raw.zip to a temporary directory
40+
$tempDir = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName())
41+
[System.IO.Directory]::CreateDirectory($tempDir)
42+
43+
Write-Host "Decompressing sbnb.raw.zip to $tempDir..." -ForegroundColor Yellow
44+
Add-Type -AssemblyName System.IO.Compression.FileSystem
45+
[System.IO.Compression.ZipFile]::ExtractToDirectory("sbnb.raw.zip", $tempDir)
46+
47+
$SbnbRawPath = "$tempDir\sbnb.raw"
48+
} else {
49+
Write-Host "Using provided sbnb.raw file: $SbnbRawPath" -ForegroundColor Green
50+
}
51+
52+
# Step 3: Enumerate all disks and ask user to input disk number
53+
$disks = Get-WmiObject -Query "SELECT * FROM Win32_DiskDrive" | Sort-Object -Property Model
54+
Write-Host "Available Disks:" -ForegroundColor Cyan
55+
for ($i = 0; $i -lt $disks.Count; $i++) {
56+
$diskInfo = "${i}: $($disks[$i].DeviceID) - $($disks[$i].Model) - $($disks[$i].Name)"
57+
Write-Host $diskInfo -ForegroundColor Green
58+
}
59+
60+
$selectedDiskNumber = Read-Host "Enter the number of the disk to flash into"
61+
$selectedDrive = $disks[$selectedDiskNumber].Index
62+
63+
# Step 4: Double confirm user agrees with selection
64+
Write-Host "WARNING: You have selected disk $($disks[$selectedDiskNumber].Model) (Index: $selectedDrive)." -ForegroundColor Red -BackgroundColor Yellow
65+
Write-Host "ALL DATA ON THIS DISK WILL BE DESTROYED!" -ForegroundColor Red -BackgroundColor Yellow
66+
$confirmation = Read-Host "Are you absolutely sure you want to proceed? (y/n)"
67+
if ($confirmation -ne "y") {
68+
Write-Host "Operation cancelled." -ForegroundColor Red
69+
exit
70+
}
71+
72+
# Step 5: Write sbnb.raw to the selected disk
73+
Write-Host "Writing sbnb.raw to disk $($disks[$selectedDiskNumber].Model) (Index: $selectedDrive)..." -ForegroundColor Yellow
74+
$disk = Get-Disk -Number $selectedDrive
75+
$disk | Clear-Disk -RemoveData -Confirm:$false
76+
$disk | Set-Disk -IsOffline $false
77+
$disk | Set-Disk -IsReadOnly $false
78+
79+
$rawFile = [System.IO.File]::OpenRead($SbnbRawPath)
80+
$diskStream = [System.IO.FileStream]::new("\\.\PhysicalDrive$selectedDrive", [System.IO.FileMode]::Open, [System.IO.FileAccess]::Write)
81+
$rawFile.CopyTo($diskStream)
82+
$rawFile.Close()
83+
$diskStream.Close()
84+
85+
# Reread partitions from disk after writing sbnb.raw
86+
Write-Host "Rereading partitions from disk $($disks[$selectedDiskNumber].Model) (Index: $selectedDrive)..." -ForegroundColor Yellow
87+
$disk | Update-Disk
88+
89+
# Step 6: Change first partition GPT type to normal data GUID
90+
Write-Host "Changing first partition GPT type to normal data GUID..." -ForegroundColor Yellow
91+
Set-Partition -DiskNumber $selectedDrive -PartitionNumber 1 -GptType "{EBD0A0A2-B9E5-4433-87C0-68B6B72699C7}"
92+
93+
$partition = Get-Partition -DiskNumber $selectedDrive | Select-Object -First 1
94+
95+
# Assign a drive letter to the first partition
96+
Write-Host "Assigning drive letter to the first partition..." -ForegroundColor Yellow
97+
$driveLetter = (66..90 | ForEach-Object {[char]$_} | Where-Object { -not (Get-Volume -FileSystemLabel $_ -ErrorAction SilentlyContinue) })[0]
98+
99+
if (-not $partition.DriveLetter) {
100+
$accessPath = "$driveLetter`:\"
101+
Add-PartitionAccessPath -DiskNumber $selectedDrive -PartitionNumber $partition.PartitionNumber -AccessPath $accessPath
102+
Write-Host "Assigned drive letter $driveLetter to the first partition." -ForegroundColor Green
103+
} else {
104+
Write-Host "Drive letter $($partition.DriveLetter) is already assigned to the first partition." -ForegroundColor Green
105+
}
106+
107+
# Step 7: Place sbnb-tskey.txt and sbnb-cmds.sh on the first partition
108+
$partition = Get-Partition -DiskNumber $selectedDrive | Select-Object -First 1
109+
$espDriveLetter = $partition.DriveLetter
110+
if (-not [string]::IsNullOrEmpty($espDriveLetter)) {
111+
$espPath = "$($espDriveLetter):\"
112+
} else {
113+
Write-Host "Error: Unable to determine the ESP drive letter." -ForegroundColor Red
114+
exit
115+
}
116+
117+
# Step 7.1: Ask user to provide Tailscale key and place it on the ESP partition
118+
$tailscaleKey = Read-Host "Please provide your Tailscale key (press Enter to skip)"
119+
if (-not [string]::IsNullOrEmpty($tailscaleKey)) {
120+
$tailscaleKeyPath = "$($espDriveLetter):\sbnb-tskey.txt"
121+
Write-Host "Tailscale key saving to $tailscaleKeyPath" -ForegroundColor Yellow
122+
[System.IO.File]::WriteAllText($tailscaleKeyPath, $tailscaleKey)
123+
Write-Host "Tailscale key saved to $tailscaleKeyPath" -ForegroundColor Green
124+
} else {
125+
Write-Host "No Tailscale key provided. Skipping this step." -ForegroundColor Yellow
126+
}
127+
128+
# Step 7.2: Ask user to provide the path to a script file and place it on the ESP partition
129+
$scriptFilePath = Read-Host "Please provide the path to your script file (this script will be saved to sbnb-cmds.sh and executed during Sbnb Linux boot) (press Enter to skip)"
130+
$scriptFilePath = $scriptFilePath.Trim('"')
131+
if (-not [string]::IsNullOrEmpty($scriptFilePath) -and (Test-Path $scriptFilePath)) {
132+
$scriptContent = Get-Content -Path $scriptFilePath -Raw
133+
# Convert to Unix format by replacing Windows line endings with Unix line endings
134+
$scriptContent = $scriptContent -replace "`r`n", "`n"
135+
136+
$scriptPath = "$($espDriveLetter):\sbnb-cmds.sh"
137+
[System.IO.File]::WriteAllText($scriptPath, $scriptContent)
138+
Write-Host "Script saved to $scriptPath" -ForegroundColor Green
139+
} else {
140+
Write-Host "No valid script file provided. Skipping this step." -ForegroundColor Yellow
141+
}
142+
# Step 7.3: Remove the drive letter from the first partition
143+
Write-Host "Removing drive letter from the first partition..." -ForegroundColor Yellow
144+
Remove-PartitionAccessPath -DiskNumber $selectedDrive -PartitionNumber $partition.PartitionNumber -AccessPath "$($partition.DriveLetter):\"
145+
Write-Host "Drive letter removed from the first partition." -ForegroundColor Green
146+
147+
# Step 8: Change GPT type to EFI
148+
Write-Host "Changing GPT partition type to EFI..." -ForegroundColor Yellow
149+
Set-Partition -DiskNumber $selectedDrive -PartitionNumber $partition.PartitionNumber -GptType "{C12A7328-F81F-11D2-BA4B-00A0C93EC93B}"
150+
151+
Write-Host "=========================================" -ForegroundColor Cyan
152+
Write-Host " Operation completed successfully. " -ForegroundColor Cyan
153+
Write-Host "=========================================" -ForegroundColor Cyan

0 commit comments

Comments
 (0)