diff --git a/scripts/guests/windows/install-autotest.ps1 b/scripts/guests/windows/install-autotest.ps1 index bd623d461..5c6587b0c 100644 --- a/scripts/guests/windows/install-autotest.ps1 +++ b/scripts/guests/windows/install-autotest.ps1 @@ -5,7 +5,9 @@ param ( [Parameter()] [switch]$NoNetReporting, [Parameter()] - [switch]$Cleanup + [switch]$NoCleanup, + [Parameter()] + [switch]$WithTools ) $ErrorActionPreference = "Stop" @@ -14,6 +16,10 @@ if (!(Test-Path "$PSScriptRoot\id_rsa.pub")) { throw "Cannot find id_rsa.pub for SSH configuration" } +if ($WithTools) { + Read-Host -Prompt "Did you install PV tools manually?" +} + # Sometimes enabling updates will disrupt installation and rebooting. # This is a temporary measure at most, but Microsoft makes disabling updates really difficult... Write-Output "Disabling updates" @@ -22,13 +28,10 @@ Stop-Service wuauserv Set-Service wuauserv -StartupType Disabled Write-Output "Installing SSH" -$SSHDownloadPath = "$env:TEMP\OpenSSH-Win64-v9.8.1.0.msi" -Invoke-WebRequest -UseBasicParsing -Uri "https://github.com/PowerShell/Win32-OpenSSH/releases/download/v9.8.1.0p1-Preview/OpenSSH-Win64-v9.8.1.0.msi" -OutFile $SSHDownloadPath -$exitCode = (Start-Process -Wait msiexec.exe -ArgumentList "/i", $SSHDownloadPath, "/passive", "/norestart" -PassThru).ExitCode +$exitCode = (Start-Process -Wait msiexec.exe -ArgumentList "/i `"$PSScriptRoot\OpenSSH-Win64-v9.8.3.0.msi`" /passive /norestart" -PassThru).ExitCode if ($exitCode -ne 0) { throw } -Remove-Item -Force $SSHDownloadPath -ErrorAction SilentlyContinue Copy-Item "$PSScriptRoot\id_rsa.pub" "$env:ProgramData\ssh\administrators_authorized_keys" -Force icacls.exe "$env:ProgramData\ssh\administrators_authorized_keys" /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F" if ($LASTEXITCODE -ne 0) { @@ -37,15 +40,18 @@ if ($LASTEXITCODE -ne 0) { New-NetFirewallRule -Action Allow -Program "$env:ProgramFiles\OpenSSH\sshd.exe" -Direction Inbound -Protocol TCP -LocalPort 22 -DisplayName sshd Write-Output "Installing Git Bash" -$GitDownloadPath = "$env:TEMP\Git-2.47.1-64-bit.exe" -Invoke-WebRequest -UseBasicParsing -Uri "https://github.com/git-for-windows/git/releases/download/v2.47.1.windows.1/Git-2.47.1-64-bit.exe" -OutFile $GitDownloadPath -$exitCode = (Start-Process -Wait $GitDownloadPath -ArgumentList "/silent" -PassThru).ExitCode +$exitCode = (Start-Process -Wait "$PSScriptRoot\Git-2.49.0-64-bit.exe" -ArgumentList "/silent" -PassThru).ExitCode if ($exitCode -ne 0) { throw } -Remove-Item -Force $GitDownloadPath -ErrorAction SilentlyContinue Set-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Type String -Value "$env:ProgramFiles\Git\bin\bash.exe" -Force +Write-Output "Disabling automatic disk optimization" +schtasks /change /disable /tn "\Microsoft\Windows\Defrag\ScheduledDefrag" +if ($exitCode -ne 0) { + throw +} + if (!$NoNetReporting) { Write-Output "Installing network reporting script" Copy-Item "$PSScriptRoot\netreport.ps1" "$env:SystemDrive\" -Force @@ -56,23 +62,28 @@ if (!$NoNetReporting) { Register-ScheduledTask -InputObject $task -TaskName "XCP-ng Test Network Report" } -if ($Cleanup) { +if (!$NoCleanup) { Read-Host -Prompt "Unplug Internet, run Disk Cleanup and continue" + # You should check at least "Temporary files" in Disk Cleanup Write-Output "Cleaning up component store" dism.exe /Online /Cleanup-Image /StartComponentCleanup /ResetBase Write-Output "Cleaning up SoftwareDistribution" - Stop-Service wuauserv, BITS -ErrorAction SilentlyContinue + Stop-Service wuauserv, BITS Remove-Item -Recurse -Force -ErrorAction SilentlyContinue "$env:windir\SoftwareDistribution\Download\*" Write-Output "Cleaning up Defender signatures" & "$env:ProgramFiles\Windows Defender\MpCmdRun.exe" -RemoveDefinitions -All - - Write-Output "Optimizing system drive" - defrag.exe $env:SystemDrive /O } Write-Output "Resealing" Stop-Process -Name sysprep -ErrorAction SilentlyContinue -& "$env:windir\System32\Sysprep\sysprep.exe" /generalize /oobe /shutdown /unattend:$PSScriptRoot\unattend.xml +if ($WithTools) { + # WS2025 eval only allows 1 rearm, save this for later + Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SoftwareProtectionPlatform" -Name SkipRearm -Type DWord -Value 1 + & "$env:windir\System32\Sysprep\sysprep.exe" "/generalize" "/oobe" "/shutdown" "/unattend:$PSScriptRoot\unattend-persisthw.xml" +} +else { + & "$env:windir\System32\Sysprep\sysprep.exe" "/generalize" "/oobe" "/shutdown" "/unattend:$PSScriptRoot\unattend.xml" +} diff --git a/scripts/guests/windows/unattend-persisthw.xml b/scripts/guests/windows/unattend-persisthw.xml new file mode 100644 index 000000000..3c3f074e0 --- /dev/null +++ b/scripts/guests/windows/unattend-persisthw.xml @@ -0,0 +1,37 @@ + + + + + 0409:00000409 + en-US + en-US + en-US + + + + + + Administrators + root + + + + + true + true + true + true + true + 3 + + + + + + true + + + 1 + + + diff --git a/scripts/guests/windows/win-diskclone.sh b/scripts/guests/windows/win-diskclone.sh old mode 100755 new mode 100644 index dd7616da0..63c813a7a --- a/scripts/guests/windows/win-diskclone.sh +++ b/scripts/guests/windows/win-diskclone.sh @@ -1,6 +1,13 @@ #!/bin/bash set -eu +win_diskclean() { + mkdir -p "/run/win-diskclone/$1" + mount $1 "/run/win-diskclone/$1" + find "/run/win-diskclone/$1" -maxdepth 1 \( -iname pagefile.sys -or -iname hiberfil.sys -or -iname swapfile.sys \) -delete + umount "/run/win-diskclone/$1" +} + src=$1 dst=$2 @@ -22,7 +29,7 @@ sfdisk -d $src | sfdisk $dst echo "Cloning non-data partitions" for srcpart in $(sfdisk -d $src | grep start= | - grep -v type=EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 | + grep -v 'type=EBD0A0A2-B9E5-4433-87C0-68B6B72699C7\|type=DE94BBA4-06D1-4D40-A16A-BFD50179D6AC' | cut -d ':' -f 1) do dstpart=${srcpart/"$src"/"$dst"} @@ -31,16 +38,16 @@ do done echo "Cloning data partitions" +mkdir -p /run/win-diskclone for srcpart in $(sfdisk -d $src | - grep type=EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 | + grep 'type=EBD0A0A2-B9E5-4433-87C0-68B6B72699C7\|type=DE94BBA4-06D1-4D40-A16A-BFD50179D6AC' | cut -d ':' -f 1) do dstpart=${srcpart/"$src"/"$dst"} - echo "Deleting pagefiles" - mkdir -p /mnt/$srcpart && - mount $srcpart /mnt/$srcpart && - find /mnt/$srcpart -maxdepth 1 -iname pagefile.sys -or -iname hiberfil.sys -or -iname swapfile.sys -delete - umount /mnt/$srcpart - echo "Cloning $srcpart to $dstpart" + echo "Cleaning $srcpart" + win_diskclean $srcpart + echo "Cloning NTFS $srcpart to $dstpart" ntfsclone -O $dstpart $srcpart done + +sync