Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 26 additions & 15 deletions scripts/guests/windows/install-autotest.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ param (
[Parameter()]
[switch]$NoNetReporting,
[Parameter()]
[switch]$Cleanup
[switch]$NoCleanup,
[Parameter()]
[switch]$WithTools
)

$ErrorActionPreference = "Stop"
Expand All @@ -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"
Expand All @@ -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) {
Expand All @@ -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
Expand All @@ -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"
}
37 changes: 37 additions & 0 deletions scripts/guests/windows/unattend-persisthw.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
<settings pass="oobeSystem">
<component name="Microsoft-Windows-International-Core" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<InputLocale>0409:00000409</InputLocale>
<SystemLocale>en-US</SystemLocale>
<UILanguage>en-US</UILanguage>
<UserLocale>en-US</UserLocale>
</component>
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<UserAccounts>
<LocalAccounts>
<LocalAccount wcm:action="add">
<Group>Administrators</Group>
<Name>root</Name>
</LocalAccount>
</LocalAccounts>
</UserAccounts>
<OOBE>
<HideEULAPage>true</HideEULAPage>
<HideLocalAccountScreen>true</HideLocalAccountScreen>
<HideOEMRegistrationScreen>true</HideOEMRegistrationScreen>
<HideOnlineAccountScreens>true</HideOnlineAccountScreens>
<HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
<ProtectYourPC>3</ProtectYourPC>
</OOBE>
</component>
</settings>
<settings pass="generalize">
<component name="Microsoft-Windows-PnpSysprep" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<PersistAllDeviceInstalls>true</PersistAllDeviceInstalls>
</component>
<component name="Microsoft-Windows-Security-SPP" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SkipRearm>1</SkipRearm>
</component>
</settings>
</unattend>
23 changes: 15 additions & 8 deletions scripts/guests/windows/win-diskclone.sh
100755 → 100644
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -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"}
Expand All @@ -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
Loading