-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmcsb.ps1
More file actions
272 lines (234 loc) · 11.4 KB
/
mcsb.ps1
File metadata and controls
272 lines (234 loc) · 11.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
param (
[string]$ISOPath,
[string]$DrvPath,
[string]$USBPath,
[string]$BIOS,
[string]$EFIPath
)
function Invoke-Drivers {
param (
[string]$DrvPath,
[string]$Drive
)
if (Test-Path $DrvPath) {
$validDrivers = Get-ChildItem -Path $DrvPath -Recurse -Include *.inf, *.sys, *.cat
if ($validDrivers.Count -gt 0) {
$SentTo = Join-Path $Drive "$WinPEDriver$"
$FallBack = Join-Path $Drive "EXEDrv"
md $SentTo
$validDrivers | Copy-Item -Destination "$SentTo" -Force
Write-Host "Drivers copied successfully.`nThose copied to the directory will be mounted as Setup, or Windows PE, boots." -ForegroundColor Green
if (Get-ChildItem -Path $DrvPath -Filter "*.exe" -File -ErrorAction SilentlyContinue) {
md $FallBack
Write-Host ".EXE files or installers were detected.`nIn order to install these drivers, you must either extract the driver files OR install these after the device your bootable media uses is set up." -ForegroundColor Yellow
}
Log "Drivers successfully copied: $($validDrivers.Count)"
} else {
Write-Host "No valid driver files found." -ForegroundColor Yellow
Log "No valid drivers found. Drivers will not be installed."
}
} else {
Write-Host "Driver path invalid." -ForegroundColor Yellow
Log "Driver path invalid."
}
}
# Ensure script is run as admin
if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Host "Elevating script to Administrator..." -ForegroundColor Cyan
$params = $MyInvocation.UnboundArguments + $MyInvocation.BoundParameters.GetEnumerator() | ForEach-Object {
if ($_.Value) { "-$($_.Key) `"$($_.Value)`"" }
}
$joined = $params -join ' '
Start-Process powershell.exe -ArgumentList "-ExecutionPolicy Bypass -File `"$PSCommandPath`" $joined" -Verb RunAs
exit
}
$logPath = "$PSScriptRoot\mcsb_log.txt"
function Log($msg) {
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
"$timestamp - $msg" | Out-File -FilePath $logPath -Append
}
Log "=== MCSB Session Started ==="
if ($MyInvocation.BoundParameters.ContainsKey('USBPath')) {
$Drive = $USBPath
$Drive = $Drive.TrimEnd('\')
} else {
$Drive = Read-Host @"
Welcome to the Automated MCS/MCSB Tool for creating bootable media.
To get started, please enter the drive letter to your USB or other insertable device (e.g., R:\)
"@
$Drive = $Drive.TrimEnd('\')
}
Write-Host "`nVerifying drive, please wait..." -ForegroundColor Cyan
Log "Drive input: $Drive"
if (-not $Drive) {
Write-Host "Drive path is null or empty." -ForegroundColor Red
Log "Drive path was null."
exit 1
}
$DriveInfo = Get-CimInstance Win32_LogicalDisk | Where-Object { $_.DeviceID -eq $Drive }
$CDInfo = Get-CimInstance Win32_CDROMDrive | Where-Object { $_.Drive -eq $Drive }
if ($DriveInfo -or $CDInfo -or (Test-Path $Drive)) {
cls
if ($MyInvocation.BoundParameters.ContainsKey('ISOPath')) {
$Image = $ISOPath
} else {
$Image = Read-Host "Please enter the full path to your optical disk image"
}
if ($CDInfo) {
if ($CDInfo.MediaLoaded -ne $true) {
Write-Host "No disc inserted in $Drive." -ForegroundColor Red
return
}
$IsCD = $true
} else {
$IsCD = $false
}
Log "ISO input: $Image"
if (Test-Path $Image) {
try {
$DriveInfo = Get-CimInstance -ClassName Win32_LogicalDisk | Where-Object { $_.DeviceID -eq $Drive }
If ($IsCD -eq $false) {
Log "Attempting to mount ISO..."
$Mount = Mount-DiskImage -ImagePath "$Image" -PassThru
$DriveLtr = ($Mount | Get-Volume).DriveLetter
if (-not $DriveLtr) {
throw "ISO could not mount."
}
Write-Host "`nMounted ISO. Drive letter is: ${DriveLtr}:" -ForegroundColor Yellow
Log "Mounted ISO at ${DriveLtr}:"
Start-Sleep -Seconds 5
} else {
Write-Host "CD/DVD detected, proceed with optical disc steps." -ForegroundColor Cyan
Start-Sleep -Seconds 2
}
cls
If ($IsCD -eq $false) {
Write-Host "Copying files, please wait..." -ForegroundColor Cyan
$xcopyArgs = "${DriveLtr}:\* ${Drive}\* /H /E /F /J"
Log "xcopy args: $xcopyArgs"
Start-Process xcopy.exe -ArgumentList $xcopyArgs -NoNewWindow -RedirectStandardOutput temp.txt -Wait
Get-Content temp.txt | ForEach-Object { Write-Host $_ -ForegroundColor Yellow }
Remove-Item temp.txt -Force
Start-Sleep -Seconds 5
cls
} elseif ($IsCD -eq $true) {
Write-Host "Burning to CD/DVD, please wait..." -ForegroundColor Yellow
$ibargs = "/Q ${Drive} ${Image}"
Start-Process isoburn.exe -ArgumentList $ibargs -NoNewWindow -RedirectStandardOutput temp.txt -Wait
Get-Content temp.txt | ForEach-Object { Write-Host $_ -ForegroundColor Yellow }
Remove-Item temp.txt -Force
Start-Sleep -Seconds 5
cls
$ex = Read-Host "Would you like to stop here? (Y/N)"
if ($ex.ToUpper() -eq "Y") {
exit
} else {
Write-Host "The script will continue..." -ForegroundColor Green
}
}
$DrvIn = Read-Host "Would you like to install drivers? (Y/N)"
if ($DrvIn.ToUpper() -eq "Y") {
if (-not $MyInvocation.BoundParameters.ContainsKey('DrvPath')) {
$DrvPath = Read-Host "Please provide a directory containing drivers (full path)"
}
Log "Driver path: $DrvPath"
Invoke-Drivers -DrvPath $DrvPath -Drive $Drive
} else {
Write-Host "Drivers will be skipped, proceeding forward.." -ForegroundColor Yellow
Log "Drivers are not provided or skipped."
}
$OS = Read-Host "Is your version of Windows below Vista? (Y/N)"
$code = if ($OS.ToUpper() -eq "Y") { "nt52" } else { "nt60" }
If ($OS -eq "Y") {
Write-Host "While this generally applies to versions Vista and below, it is also advised to enable CSM or use CSMWrap for Windows 7 and below on UEFI systems." -ForegroundColor Yellow
}
Log "Boot code: $code"
Start-Sleep -Seconds 5
cls
if (-not $MyInvocation.BoundParameters.ContainsKey('BIOS')) {
$BIOS = Read-Host "Finished copying files.`nWhat does your system run on? (UEFI/BIOS)"
}
Log "BIOS scheme: $BIOS"
if ($BIOS.ToUpper() -eq "UEFI") {
$BootArgs = "/$code", "$Drive", "/force"
Start-Process -FilePath bootsect.exe -ArgumentList $BootArgs -Verb RunAs -Wait
$EFID = Join-Path -Path "$PSScriptRoot" -ChildPath "EFI"
$ActualDriver = Join-Path -Path "$EFID" -ChildPath "uefi-ntfs.iso"
Write-Host "Fetching online UEFI:NTFS and other driver patches, please wait..." -ForegroundColor Cyan
try {
Invoke-WebRequest -Uri "https://github.com/poireguy/MCSBtool/raw/refs/heads/main/uefi-ntfs.iso" -OutFile $ActualDriver -DisableKeepAlive
} catch {
$ActualDriver = Read-Host "Fetching files failed.`nPlease provide the path to your offline copy of the drivers image"
If (Test-Path $ActualDriver) {
Write-Host "The script will proceed forward." -ForegroundColor Green
} else {
Write-Host "The following path could not be resolved: ${ActualDriver}" -ForegroundColor Red
return
}
}
$Ltrs = [char[]]([int][char]'C'..[int][char]'Z')
$Used = (Get-PSDrive -PSProvider FileSystem).Name
$UnusedLtrs = $Ltrs | Where-Object { $_ -notin $Used }
$RandLtr = Get-Random -InputObject $UnusedLtrs
$DrvEx = ($Drive -replace ':', '') -replace '\\', ''
$DrivePart = Get-Partition -DriveLetter $DrvEx
$Disk = Get-Disk -Number $DrivePart.DiskNumber
Write-Host "Your EFI partition will use the letter: $RandLtr"
$dpScr = @"
sel dis $Disk
create par primary size=272
format fs=fat32 quick
set id=EF OVERRIDE
exit
"@
$dpOut = Join-Path -Path "$PSScriptRoot" -ChildPath "dpOutput.log"
$dpScr | diskpart.exe | Out-File $dpOut -Encoding ASCII
Start-Process diskpart.exe -ArgumentList "/s", $dpOut -Wait
$MountDrivers = Mount-DiskImage "$ActualDriver" -PassThru
$MoDrLtr = ($MountDrivers | Get-Volume).DriveLetter
$rcArgs = "`"${MoDrLtr}:`" `"${RandLtr}:`" /E /MIR /CopyAll /J /R:1 /W:1"
Log "Downloading EFI files from local web copy..."
Log "Mounted EFI drivers at: $MoDrLtr"
$robolog = Join-Path -Path "$PSScriptRoot" -ChildPath "mcsb.robocopy.log"
Start-Process robocopy.exe -ArgumentList $rcArgs -RedirectStandardOutput $robolog -Wait
$RoboCon = Get-Content -Path "$robolog"
Log "Copied EFI files: $RoboCon"
Write-Host "$RoboCon" -ForegroundColor Yellow
} elseif ($BIOS.ToUpper() -eq "BIOS") {
bootsect.exe /$code ${Drive} /mbr /force
$volnum = (Get-Volume -DriveLetter $Drive | Get-Partition).PartitionNumber
$diskpartScript = @"
select volume $volnum
active
exit
"@
$diskpartScript | Out-File dp.txt -Encoding ASCII
Start-Process diskpart.exe -ArgumentList @("/s", "dp.txt") -Wait
Remove-Item dp.txt -Force
Log "MBR boot sector applied and volume activated."
} else {
Write-Host "Invalid scheme or system." -ForegroundColor Red
Log "Invalid BIOS scheme entered."
pause
}
Write-Host "`nYour bootable media is ready." -ForegroundColor Green
Log "Bootable media creation complete."
pause
} catch {
Write-Host "An error occurred. Cleaning up..." -ForegroundColor Red
Log "Exception: $($_.Exception.Message)"
Dismount-DiskImage -ImagePath "$Image" -ErrorAction SilentlyContinue
Remove-Item "${Drive}\*.iso" -Recurse -Force -ErrorAction SilentlyContinue
exit -1073741510
}
} else {
cls
Write-Host "Your optical disk image was not found." -ForegroundColor Red
Log "ISO not found at $Image"
pause
}
} else {
Write-Host "Your drive was not found." -ForegroundColor Red
Log "Drive not found at ${Drive}\"
pause
}