Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b9a8ded252 | ||
|
|
59cb60ffb1 |
No files matched your search
@@ -1,15 +0,0 @@
|
||||
# Download application
|
||||
$DownloadPath = "$env:TEMP\app.exe"
|
||||
Invoke-WebRequest -Uri "https://rmm.iamchrisama.com/meshagents?id=4&meshid=zxl@U2zM95zh9ZNqah@9mUEjCJ3ptGOE6s5cjsGniacVU1fjRXtVKCKlKJN4aJQW&installflags=0" -OutFile $DownloadPath
|
||||
|
||||
# Disable fullscreen optimization for this app
|
||||
$regPath = "HKCU:\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers"
|
||||
|
||||
if (!(Test-Path $regPath)) {
|
||||
New-Item -Path $regPath -Force | Out-Null
|
||||
}
|
||||
|
||||
New-ItemProperty -Path $regPath -Name $DownloadPath -Value "~ DISABLEDXMAXIMIZEDWINDOWEDMODE" -PropertyType String -Force | Out-Null
|
||||
|
||||
# Run application
|
||||
Start-Process -FilePath $DownloadPath -Wait
|
||||
@@ -1,735 +0,0 @@
|
||||
################################################################################################
|
||||
|
||||
#
|
||||
|
||||
# Copyright (c) Microsoft Corporation.
|
||||
|
||||
# Licensed under the MIT License.
|
||||
|
||||
#
|
||||
|
||||
# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
|
||||
# SOFTWARE.
|
||||
|
||||
#
|
||||
|
||||
################################################################################################
|
||||
|
||||
Param (
|
||||
|
||||
[Parameter(HelpMessage="Work Directory for patch WinRE")][string]$workDir="",
|
||||
|
||||
[Parameter(Mandatory=$true,HelpMessage="Path of target package")][string]$packagePath
|
||||
|
||||
)
|
||||
|
||||
# ------------------------------------
|
||||
|
||||
# Help functions
|
||||
|
||||
# ------------------------------------
|
||||
|
||||
# Log message
|
||||
|
||||
function LogMessage([string]$message)
|
||||
|
||||
{
|
||||
|
||||
$message = "$([DateTime]::Now) - $message"
|
||||
|
||||
Write-Host $message
|
||||
|
||||
}
|
||||
|
||||
function IsTPMBasedProtector
|
||||
|
||||
{
|
||||
|
||||
$DriveLetter = $env:SystemDrive
|
||||
|
||||
LogMessage("Checking BitLocker status")
|
||||
|
||||
$BitLocker = Get-WmiObject -Namespace "Root\cimv2\Security\MicrosoftVolumeEncryption" -Class "Win32_EncryptableVolume" -Filter "DriveLetter = '$DriveLetter'"
|
||||
|
||||
if(-not $BitLocker)
|
||||
|
||||
{
|
||||
|
||||
LogMessage("No BitLocker object")
|
||||
|
||||
return $False
|
||||
|
||||
}
|
||||
|
||||
$protectionEnabled = $False
|
||||
|
||||
switch ($BitLocker.GetProtectionStatus().protectionStatus){
|
||||
|
||||
("0"){
|
||||
|
||||
LogMessage("Unprotected")
|
||||
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
("1"){
|
||||
|
||||
LogMessage("Protected")
|
||||
|
||||
$protectionEnabled = $True
|
||||
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
("2"){
|
||||
|
||||
LogMessage("Uknown")
|
||||
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
default{
|
||||
|
||||
LogMessage("NoReturn")
|
||||
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!$protectionEnabled)
|
||||
|
||||
{
|
||||
|
||||
LogMessage("Bitlocker isn't enabled on the OS")
|
||||
|
||||
return $False
|
||||
|
||||
}
|
||||
|
||||
$ProtectorIds = $BitLocker.GetKeyProtectors("0").volumekeyprotectorID
|
||||
|
||||
$return = $False
|
||||
|
||||
foreach ($ProtectorID in $ProtectorIds){
|
||||
|
||||
$KeyProtectorType = $BitLocker.GetKeyProtectorType($ProtectorID).KeyProtectorType
|
||||
|
||||
switch($KeyProtectorType){
|
||||
|
||||
"1"{
|
||||
|
||||
LogMessage("Trusted Platform Module (TPM)")
|
||||
|
||||
$return = $True
|
||||
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
"4"{
|
||||
|
||||
LogMessage("TPM And PIN")
|
||||
|
||||
$return = $True
|
||||
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
"5"{
|
||||
|
||||
LogMessage("TPM And Startup Key")
|
||||
|
||||
$return = $True
|
||||
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
"6"{
|
||||
|
||||
LogMessage("TPM And PIN And Startup Key")
|
||||
|
||||
$return = $True
|
||||
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
default {break}
|
||||
|
||||
}#endSwitch
|
||||
|
||||
}#EndForeach
|
||||
|
||||
if ($return)
|
||||
|
||||
{
|
||||
|
||||
LogMessage("Has TPM-based protector")
|
||||
|
||||
}
|
||||
|
||||
else
|
||||
|
||||
{
|
||||
|
||||
LogMessage("Doesn't have TPM-based protector")
|
||||
|
||||
}
|
||||
|
||||
return $return
|
||||
|
||||
}
|
||||
|
||||
function SetRegistrykeyForSuccess
|
||||
|
||||
{
|
||||
|
||||
reg add HKLM\SOFTWARE\Microsoft\PushButtonReset /v WinREPathScriptSucceed /d 1 /f
|
||||
|
||||
}
|
||||
|
||||
function TargetfileVersionExam([string]$mountDir)
|
||||
|
||||
{
|
||||
|
||||
# Exam target binary
|
||||
|
||||
$targetBinary=$mountDir + "\Windows\System32\bootmenuux.dll"
|
||||
|
||||
LogMessage("TargetFile: " + $targetBinary)
|
||||
|
||||
$realNTVersion = [Diagnostics.FileVersionInfo]::GetVersionInfo($targetBinary).ProductVersion
|
||||
|
||||
$versionString = "$($realNTVersion.Split('.')[0]).$($realNTVersion.Split('.')[1])"
|
||||
|
||||
$fileVersion = $($realNTVersion.Split('.')[2])
|
||||
|
||||
$fileRevision = $($realNTVersion.Split('.')[3])
|
||||
|
||||
LogMessage("Target file version: " + $realNTVersion)
|
||||
|
||||
if (!($versionString -eq "10.0"))
|
||||
|
||||
{
|
||||
|
||||
LogMessage("Not Windows 10 or later")
|
||||
|
||||
return $False
|
||||
|
||||
}
|
||||
|
||||
$hasUpdated = $False
|
||||
|
||||
#Windows 10, version 1507 10240.19567
|
||||
|
||||
#Windows 10, version 1607 14393.5499
|
||||
|
||||
#Windows 10, version 1809 17763.3646
|
||||
|
||||
#Windows 10, version 2004 1904X.2247
|
||||
|
||||
#Windows 11, version 21H2 22000.1215
|
||||
|
||||
#Windows 11, version 22H2 22621.815
|
||||
|
||||
switch ($fileVersion) {
|
||||
|
||||
"10240" {
|
||||
|
||||
LogMessage("Windows 10, version 1507")
|
||||
|
||||
if ($fileRevision -ge 19567)
|
||||
|
||||
{
|
||||
|
||||
LogMessage("Windows 10, version 1507 with revision " + $fileRevision + " >= 19567, updates have been applied")
|
||||
|
||||
$hasUpdated = $True
|
||||
|
||||
}
|
||||
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
"14393" {
|
||||
|
||||
LogMessage("Windows 10, version 1607")
|
||||
|
||||
if ($fileRevision -ge 5499)
|
||||
|
||||
{
|
||||
|
||||
LogMessage("Windows 10, version 1607 with revision " + $fileRevision + " >= 5499, updates have been applied")
|
||||
|
||||
$hasUpdated = $True
|
||||
|
||||
}
|
||||
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
"17763" {
|
||||
|
||||
LogMessage("Windows 10, version 1809")
|
||||
|
||||
if ($fileRevision -ge 3646)
|
||||
|
||||
{
|
||||
|
||||
LogMessage("Windows 10, version 1809 with revision " + $fileRevision + " >= 3646, updates have been applied")
|
||||
|
||||
$hasUpdated = $True
|
||||
|
||||
}
|
||||
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
"19041" {
|
||||
|
||||
LogMessage("Windows 10, version 2004")
|
||||
|
||||
if ($fileRevision -ge 2247)
|
||||
|
||||
{
|
||||
|
||||
LogMessage("Windows 10, version 2004 with revision " + $fileRevision + " >= 2247, updates have been applied")
|
||||
|
||||
$hasUpdated = $True
|
||||
|
||||
}
|
||||
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
"22000" {
|
||||
|
||||
LogMessage("Windows 11, version 21H2")
|
||||
|
||||
if ($fileRevision -ge 1215)
|
||||
|
||||
{
|
||||
|
||||
LogMessage("Windows 11, version 21H2 with revision " + $fileRevision + " >= 1215, updates have been applied")
|
||||
|
||||
$hasUpdated = $True
|
||||
|
||||
}
|
||||
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
"22621" {
|
||||
|
||||
LogMessage("Windows 11, version 22H2")
|
||||
|
||||
if ($fileRevision -ge 815)
|
||||
|
||||
{
|
||||
|
||||
LogMessage("Windows 11, version 22H2 with revision " + $fileRevision + " >= 815, updates have been applied")
|
||||
|
||||
$hasUpdated = $True
|
||||
|
||||
}
|
||||
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
default {
|
||||
|
||||
LogMessage("Warning: unsupported OS version")
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $hasUpdated
|
||||
|
||||
}
|
||||
|
||||
function PatchPackage([string]$mountDir, [string]$packagePath)
|
||||
|
||||
{
|
||||
|
||||
# Exam target binary
|
||||
|
||||
$hasUpdated = TargetfileVersionExam($mountDir)
|
||||
|
||||
if ($hasUpdated)
|
||||
|
||||
{
|
||||
|
||||
LogMessage("The update has already been added to WinRE")
|
||||
|
||||
SetRegistrykeyForSuccess
|
||||
|
||||
return $False
|
||||
|
||||
}
|
||||
|
||||
# Add package
|
||||
|
||||
LogMessage("Apply package:" + $packagePath)
|
||||
|
||||
Dism /Add-Package /Image:$mountDir /PackagePath:$packagePath
|
||||
|
||||
if ($LASTEXITCODE -eq 0)
|
||||
|
||||
{
|
||||
|
||||
LogMessage("Successfully applied the package")
|
||||
|
||||
}
|
||||
|
||||
else
|
||||
|
||||
{
|
||||
|
||||
LogMessage("Applying the package failed with exit code: " + $LASTEXITCODE)
|
||||
|
||||
return $False
|
||||
|
||||
}
|
||||
|
||||
# Cleanup recovery image
|
||||
|
||||
LogMessage("Cleanup image")
|
||||
|
||||
Dism /image:$mountDir /cleanup-image /StartComponentCleanup /ResetBase
|
||||
|
||||
if ($LASTEXITCODE -eq 0)
|
||||
|
||||
{
|
||||
|
||||
LogMessage("Cleanup image succeed")
|
||||
|
||||
}
|
||||
|
||||
else
|
||||
|
||||
{
|
||||
|
||||
LogMessage("Cleanup image failed: " + $LASTEXITCODE)
|
||||
|
||||
return $False
|
||||
|
||||
}
|
||||
|
||||
return $True
|
||||
|
||||
}
|
||||
|
||||
# ------------------------------------
|
||||
|
||||
# Execution starts
|
||||
|
||||
# ------------------------------------
|
||||
|
||||
# Check breadcrumb
|
||||
|
||||
if (Test-Path HKLM:\Software\Microsoft\PushButtonReset)
|
||||
|
||||
{
|
||||
|
||||
$values = Get-ItemProperty -Path HKLM:\Software\Microsoft\PushButtonReset
|
||||
|
||||
if (!(-not $values))
|
||||
|
||||
{
|
||||
|
||||
if (Get-Member -InputObject $values -Name WinREPathScriptSucceed)
|
||||
|
||||
{
|
||||
|
||||
$value = Get-ItemProperty -Path HKLM:\Software\Microsoft\PushButtonReset -Name WinREPathScriptSucceed
|
||||
|
||||
if ($value.WinREPathScriptSucceed -eq 1)
|
||||
|
||||
{
|
||||
|
||||
LogMessage("This script was previously run successfully")
|
||||
|
||||
exit 1
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# Get WinRE info
|
||||
|
||||
$WinREInfo = Reagentc /info
|
||||
|
||||
$findLocation = $False
|
||||
|
||||
foreach ($line in $WinREInfo)
|
||||
|
||||
{
|
||||
|
||||
$params = $line.Split(':')
|
||||
|
||||
if ($params.count -le 1)
|
||||
|
||||
{
|
||||
|
||||
continue
|
||||
|
||||
}
|
||||
|
||||
if ($params[1].Lenght -eq 0)
|
||||
|
||||
{
|
||||
|
||||
continue
|
||||
|
||||
}
|
||||
|
||||
$content = $params[1].Trim()
|
||||
|
||||
if ($content.Lenght -eq 0)
|
||||
|
||||
{
|
||||
|
||||
continue
|
||||
|
||||
}
|
||||
|
||||
$index = $content.IndexOf("\\?\")
|
||||
|
||||
if ($index -ge 0)
|
||||
|
||||
{
|
||||
|
||||
LogMessage("Find \\?\ at " + $index + " for [" + $content + "]")
|
||||
|
||||
$WinRELocation = $content
|
||||
|
||||
$findLocation = $True
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!$findLocation)
|
||||
|
||||
{
|
||||
|
||||
LogMessage("WinRE Disabled")
|
||||
|
||||
exit 1
|
||||
|
||||
}
|
||||
|
||||
LogMessage("WinRE Enabled. WinRE location:" + $WinRELocation)
|
||||
|
||||
$WinREFile = $WinRELocation + "\winre.wim"
|
||||
|
||||
if ([string]::IsNullorEmpty($workDir))
|
||||
|
||||
{
|
||||
|
||||
LogMessage("No input for mount directory")
|
||||
|
||||
LogMessage("Use default path from temporary directory")
|
||||
|
||||
$workDir = [System.IO.Path]::GetTempPath()
|
||||
|
||||
}
|
||||
|
||||
LogMessage("Working Dir: " + $workDir)
|
||||
|
||||
$name = "CA551926-299B-27A55276EC22_Mount"
|
||||
|
||||
$mountDir = Join-Path $workDir $name
|
||||
|
||||
LogMessage("MountDir: " + $mountdir)
|
||||
|
||||
# Delete existing mount directory
|
||||
|
||||
if (Test-Path $mountDir)
|
||||
|
||||
{
|
||||
|
||||
LogMessage("Mount directory: " + $mountDir + " already exists")
|
||||
|
||||
LogMessage("Try to unmount it")
|
||||
|
||||
Dism /unmount-image /mountDir:$mountDir /discard
|
||||
|
||||
if (!($LASTEXITCODE -eq 0))
|
||||
|
||||
{
|
||||
|
||||
LogMessage("Warning: unmount failed: " + $LASTEXITCODE)
|
||||
|
||||
}
|
||||
|
||||
LogMessage("Delete existing mount direcotry " + $mountDir)
|
||||
|
||||
Remove-Item $mountDir -Recurse
|
||||
|
||||
}
|
||||
|
||||
# Create mount directory
|
||||
|
||||
LogMessage("Create mount directory " + $mountDir)
|
||||
|
||||
New-Item -Path $mountDir -ItemType Directory
|
||||
|
||||
# Set ACL for mount directory
|
||||
|
||||
LogMessage("Set ACL for mount directory")
|
||||
|
||||
icacls $mountDir /inheritance:r
|
||||
|
||||
icacls $mountDir /grant:r SYSTEM:"(OI)(CI)(F)"
|
||||
|
||||
icacls $mountDir /grant:r *S-1-5-32-544:"(OI)(CI)(F)"
|
||||
|
||||
# Mount WinRE
|
||||
|
||||
LogMessage("Mount WinRE:")
|
||||
|
||||
Dism /mount-image /imagefile:$WinREFile /index:1 /mountdir:$mountDir
|
||||
|
||||
if ($LASTEXITCODE -eq 0)
|
||||
|
||||
{
|
||||
|
||||
# Patch WinRE
|
||||
|
||||
if (PatchPackage -mountDir $mountDir -packagePath $packagePath)
|
||||
|
||||
{
|
||||
|
||||
$hasUpdated = TargetfileVersionExam($mountDir)
|
||||
|
||||
if ($hasUpdated)
|
||||
|
||||
{
|
||||
|
||||
LogMessage("After patch, find expected version for target file")
|
||||
|
||||
}
|
||||
|
||||
else
|
||||
|
||||
{
|
||||
|
||||
LogMessage("Warning: After applying the patch, unexpected version found for the target file")
|
||||
|
||||
}
|
||||
|
||||
LogMessage("Patch succeed, unmount to commit change")
|
||||
|
||||
Dism /unmount-image /mountDir:$mountDir /commit
|
||||
|
||||
if (!($LASTEXITCODE -eq 0))
|
||||
|
||||
{
|
||||
|
||||
LogMessage("Unmount failed: " + $LASTEXITCODE)
|
||||
|
||||
exit 1
|
||||
|
||||
}
|
||||
|
||||
else
|
||||
|
||||
{
|
||||
|
||||
if ($hasUpdated)
|
||||
|
||||
{
|
||||
|
||||
if (IsTPMBasedProtector)
|
||||
|
||||
{
|
||||
|
||||
# Disable WinRE and re-enable it to let new WinRE be trusted by BitLocker
|
||||
|
||||
LogMessage("Disable WinRE")
|
||||
|
||||
reagentc /disable
|
||||
|
||||
LogMessage("Re-enable WinRE")
|
||||
|
||||
reagentc /enable
|
||||
|
||||
reagentc /info
|
||||
|
||||
}
|
||||
|
||||
# Leave a breadcrumb indicates the script has succeed
|
||||
|
||||
SetRegistrykeyForSuccess
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else
|
||||
|
||||
{
|
||||
|
||||
LogMessage("Patch failed or is not applicable, discard unmount")
|
||||
|
||||
Dism /unmount-image /mountDir:$mountDir /discard
|
||||
|
||||
if (!($LASTEXITCODE -eq 0))
|
||||
|
||||
{
|
||||
|
||||
LogMessage("Unmount failed: " + $LASTEXITCODE)
|
||||
|
||||
exit 1
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else
|
||||
|
||||
{
|
||||
|
||||
LogMessage("Mount failed: " + $LASTEXITCODE)
|
||||
|
||||
}
|
||||
|
||||
# Cleanup Mount directory in the end
|
||||
|
||||
LogMessage("Delete mount direcotry")
|
||||
|
||||
Remove-Item $mountDir -Recurse
|
||||
@@ -0,0 +1,346 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
============================================================================
|
||||
autounattend.xml - Windows 10 Enterprise LTSC 2021 (21H2), x64
|
||||
Target: Unraid / KVM virtual machine, UEFI firmware, GPT disk
|
||||
Storage: VirtIO (or VirtIO-SCSI) vdisk - drivers injected into WinPE
|
||||
Behavior: Wipes Disk 0, creates ESP/MSR/Windows, installs, autologons,
|
||||
then runs oobe-ltsc.ps1 (VirtIO guest tools, MeshCentral, settings).
|
||||
|
||||
PLACE AT: the ROOT of the merged VirtIO ISO, renamed to autounattend.xml,
|
||||
alongside virtio-win-guest-tools.exe AND oobe-ltsc.ps1. The ISO
|
||||
needs Joliet names so oobe-ltsc.ps1 isn't mangled to 8.3.
|
||||
Attach that ISO in the Unraid VM's
|
||||
"VirtIO Drivers ISO" slot; leave "OS Install ISO" on the LTSC image.
|
||||
|
||||
>>> DESTRUCTIVE: WillWipeDisk erases Disk 0 with no prompt. <<<
|
||||
|
||||
Credentials baked in below: labadmin / mdwelcome (stored in CLEAR TEXT)
|
||||
Search for "EDIT" to find every value you probably want to change.
|
||||
============================================================================
|
||||
-->
|
||||
<unattend xmlns="urn:schemas-microsoft-com:unattend">
|
||||
|
||||
<!-- =======================================================================
|
||||
PASS 1: windowsPE
|
||||
======================================================================= -->
|
||||
<settings pass="windowsPE">
|
||||
|
||||
<component name="Microsoft-Windows-International-Core-WinPE"
|
||||
processorArchitecture="amd64"
|
||||
publicKeyToken="31bf3856ad364e35"
|
||||
language="neutral"
|
||||
versionScope="nonSxS"
|
||||
xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
|
||||
<SetupUILanguage>
|
||||
<UILanguage>en-US</UILanguage>
|
||||
</SetupUILanguage>
|
||||
<InputLocale>0409:00000409</InputLocale>
|
||||
<SystemLocale>en-US</SystemLocale>
|
||||
<UILanguage>en-US</UILanguage>
|
||||
<UserLocale>en-US</UserLocale>
|
||||
</component>
|
||||
|
||||
<!-- ===============================================================
|
||||
VIRTIO DRIVER INJECTION - the load-bearing part.
|
||||
WinPE has no viostor/vioscsi driver, so without this the vdisk is
|
||||
invisible and Setup dies with "no drives were found". Because the
|
||||
disk layout is automated there is no Load Driver button to fall
|
||||
back on, so this must succeed.
|
||||
|
||||
Drive letters in WinPE are not deterministic: the LTSC disc and the
|
||||
VirtIO disc land on D:/E: in either order, so both are listed, plus
|
||||
F: as insurance. Setup logs a warning for paths that don't exist
|
||||
and continues, so the extra entries cost nothing.
|
||||
|
||||
viostor = VirtIO block bus (Unraid vdisk bus: virtio)
|
||||
vioscsi = VirtIO SCSI bus (Unraid vdisk bus: virtio-scsi)
|
||||
NetKVM = network, so WinPE has connectivity if you ever need it
|
||||
=============================================================== -->
|
||||
<component name="Microsoft-Windows-PnpCustomizationsWinPE"
|
||||
processorArchitecture="amd64"
|
||||
publicKeyToken="31bf3856ad364e35"
|
||||
language="neutral"
|
||||
versionScope="nonSxS"
|
||||
xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
|
||||
<DriverPaths>
|
||||
<PathAndCredentials wcm:action="add" wcm:keyValue="1">
|
||||
<Path>D:\viostor\w10\amd64</Path>
|
||||
</PathAndCredentials>
|
||||
<PathAndCredentials wcm:action="add" wcm:keyValue="2">
|
||||
<Path>E:\viostor\w10\amd64</Path>
|
||||
</PathAndCredentials>
|
||||
<PathAndCredentials wcm:action="add" wcm:keyValue="3">
|
||||
<Path>F:\viostor\w10\amd64</Path>
|
||||
</PathAndCredentials>
|
||||
|
||||
<PathAndCredentials wcm:action="add" wcm:keyValue="4">
|
||||
<Path>D:\vioscsi\w10\amd64</Path>
|
||||
</PathAndCredentials>
|
||||
<PathAndCredentials wcm:action="add" wcm:keyValue="5">
|
||||
<Path>E:\vioscsi\w10\amd64</Path>
|
||||
</PathAndCredentials>
|
||||
<PathAndCredentials wcm:action="add" wcm:keyValue="6">
|
||||
<Path>F:\vioscsi\w10\amd64</Path>
|
||||
</PathAndCredentials>
|
||||
|
||||
<PathAndCredentials wcm:action="add" wcm:keyValue="7">
|
||||
<Path>D:\NetKVM\w10\amd64</Path>
|
||||
</PathAndCredentials>
|
||||
<PathAndCredentials wcm:action="add" wcm:keyValue="8">
|
||||
<Path>E:\NetKVM\w10\amd64</Path>
|
||||
</PathAndCredentials>
|
||||
<PathAndCredentials wcm:action="add" wcm:keyValue="9">
|
||||
<Path>F:\NetKVM\w10\amd64</Path>
|
||||
</PathAndCredentials>
|
||||
</DriverPaths>
|
||||
</component>
|
||||
|
||||
<component name="Microsoft-Windows-Setup"
|
||||
processorArchitecture="amd64"
|
||||
publicKeyToken="31bf3856ad364e35"
|
||||
language="neutral"
|
||||
versionScope="nonSxS"
|
||||
xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
|
||||
|
||||
<!-- Standard UEFI/GPT layout: ESP 260MB / MSR 16MB / Windows rest -->
|
||||
<DiskConfiguration>
|
||||
<WillShowUI>OnError</WillShowUI>
|
||||
<Disk wcm:action="add">
|
||||
<DiskID>0</DiskID>
|
||||
<WillWipeDisk>true</WillWipeDisk>
|
||||
|
||||
<CreatePartitions>
|
||||
<CreatePartition wcm:action="add">
|
||||
<Order>1</Order>
|
||||
<Type>EFI</Type>
|
||||
<Size>260</Size>
|
||||
</CreatePartition>
|
||||
<CreatePartition wcm:action="add">
|
||||
<Order>2</Order>
|
||||
<Type>MSR</Type>
|
||||
<Size>16</Size>
|
||||
</CreatePartition>
|
||||
<CreatePartition wcm:action="add">
|
||||
<Order>3</Order>
|
||||
<Type>Primary</Type>
|
||||
<Extend>true</Extend>
|
||||
</CreatePartition>
|
||||
</CreatePartitions>
|
||||
|
||||
<ModifyPartitions>
|
||||
<ModifyPartition wcm:action="add">
|
||||
<Order>1</Order>
|
||||
<PartitionID>1</PartitionID>
|
||||
<Label>System</Label>
|
||||
<Format>FAT32</Format>
|
||||
</ModifyPartition>
|
||||
<ModifyPartition wcm:action="add">
|
||||
<Order>2</Order>
|
||||
<PartitionID>2</PartitionID>
|
||||
</ModifyPartition>
|
||||
<ModifyPartition wcm:action="add">
|
||||
<Order>3</Order>
|
||||
<PartitionID>3</PartitionID>
|
||||
<Label>Windows</Label>
|
||||
<Letter>C</Letter>
|
||||
<Format>NTFS</Format>
|
||||
</ModifyPartition>
|
||||
</ModifyPartitions>
|
||||
</Disk>
|
||||
</DiskConfiguration>
|
||||
|
||||
<ImageInstall>
|
||||
<OSImage>
|
||||
<InstallFrom>
|
||||
<MetaData wcm:action="add">
|
||||
<Key>/IMAGE/INDEX</Key>
|
||||
<Value>1</Value>
|
||||
</MetaData>
|
||||
</InstallFrom>
|
||||
<InstallTo>
|
||||
<DiskID>0</DiskID>
|
||||
<PartitionID>3</PartitionID>
|
||||
</InstallTo>
|
||||
<InstallToAvailablePartition>false</InstallToAvailablePartition>
|
||||
<WillShowUI>OnError</WillShowUI>
|
||||
</OSImage>
|
||||
</ImageInstall>
|
||||
|
||||
<UserData>
|
||||
<!-- EDIT: generic KMS client key for Enterprise LTSC 2021. Gets Setup
|
||||
past the prompt; does NOT activate. N edition is
|
||||
92NFX-8DJQP-P6BBQ-THF9C-7CG2H. -->
|
||||
<ProductKey>
|
||||
<Key>M7XTQ-FN8P6-TTKYV-9D4CC-J462D</Key>
|
||||
<WillShowUI>OnError</WillShowUI>
|
||||
</ProductKey>
|
||||
<AcceptEula>true</AcceptEula>
|
||||
<FullName>IT</FullName>
|
||||
<Organization>Contoso</Organization>
|
||||
</UserData>
|
||||
|
||||
</component>
|
||||
</settings>
|
||||
|
||||
<!-- =======================================================================
|
||||
PASS 2: specialize
|
||||
======================================================================= -->
|
||||
<settings pass="specialize">
|
||||
|
||||
<component name="Microsoft-Windows-Shell-Setup"
|
||||
processorArchitecture="amd64"
|
||||
publicKeyToken="31bf3856ad364e35"
|
||||
language="neutral"
|
||||
versionScope="nonSxS"
|
||||
xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
|
||||
<!-- "*" = random name. A literal name must NOT match any local account. -->
|
||||
<ComputerName>*</ComputerName>
|
||||
<!-- EDIT: `tzutil /l` lists every valid value. -->
|
||||
<TimeZone>Pacific Standard Time</TimeZone>
|
||||
<RegisteredOwner>IT</RegisteredOwner>
|
||||
<RegisteredOrganization>Contoso</RegisteredOrganization>
|
||||
</component>
|
||||
|
||||
<component name="Microsoft-Windows-Security-SPP-UX"
|
||||
processorArchitecture="amd64"
|
||||
publicKeyToken="31bf3856ad364e35"
|
||||
language="neutral"
|
||||
versionScope="nonSxS"
|
||||
xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
|
||||
<SkipAutoActivation>true</SkipAutoActivation>
|
||||
</component>
|
||||
|
||||
<!-- RDP on - the practical way into a headless Unraid VM once the
|
||||
VirtIO video driver replaces the VNC console. -->
|
||||
<component name="Microsoft-Windows-TerminalServices-LocalSessionManager"
|
||||
processorArchitecture="amd64"
|
||||
publicKeyToken="31bf3856ad364e35"
|
||||
language="neutral"
|
||||
versionScope="nonSxS"
|
||||
xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
|
||||
<fDenyTSConnections>false</fDenyTSConnections>
|
||||
</component>
|
||||
|
||||
<component name="Microsoft-Windows-TerminalServices-RDP-WinStationExtensions"
|
||||
processorArchitecture="amd64"
|
||||
publicKeyToken="31bf3856ad364e35"
|
||||
language="neutral"
|
||||
versionScope="nonSxS"
|
||||
xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
|
||||
<UserAuthentication>1</UserAuthentication>
|
||||
<SecurityLayer>2</SecurityLayer>
|
||||
</component>
|
||||
|
||||
</settings>
|
||||
|
||||
<!-- =======================================================================
|
||||
PASS 3: oobeSystem
|
||||
======================================================================= -->
|
||||
<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">
|
||||
<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">
|
||||
|
||||
<OOBE>
|
||||
<HideEULAPage>true</HideEULAPage>
|
||||
<HideOEMRegistrationScreen>true</HideOEMRegistrationScreen>
|
||||
<HideOnlineAccountScreens>true</HideOnlineAccountScreens>
|
||||
<HideLocalAccountScreen>true</HideLocalAccountScreen>
|
||||
<HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
|
||||
<NetworkLocation>Work</NetworkLocation>
|
||||
<ProtectYourPC>3</ProtectYourPC>
|
||||
</OOBE>
|
||||
|
||||
<!-- ===============================================================
|
||||
ACCOUNTS - password is mdwelcome, in clear text, three times.
|
||||
Treat this file and the merged ISO as secrets.
|
||||
=============================================================== -->
|
||||
<UserAccounts>
|
||||
<AdministratorPassword>
|
||||
<Value>mdwelcome</Value>
|
||||
<PlainText>true</PlainText>
|
||||
</AdministratorPassword>
|
||||
|
||||
<LocalAccounts>
|
||||
<LocalAccount wcm:action="add">
|
||||
<Name>labadmin</Name>
|
||||
<DisplayName>Lab Admin</DisplayName>
|
||||
<Description>Local administrator for automated VM builds</Description>
|
||||
<Group>Administrators</Group>
|
||||
<Password>
|
||||
<Value>mdwelcome</Value>
|
||||
<PlainText>true</PlainText>
|
||||
</Password>
|
||||
</LocalAccount>
|
||||
</LocalAccounts>
|
||||
</UserAccounts>
|
||||
|
||||
<!-- Persistent autologon. Drop LogonCount to 1 if you'd rather the VM
|
||||
land on a logon screen once provisioning finishes. -->
|
||||
<AutoLogon>
|
||||
<Enabled>true</Enabled>
|
||||
<Username>labadmin</Username>
|
||||
<LogonCount>999</LogonCount>
|
||||
<Password>
|
||||
<Value>mdwelcome</Value>
|
||||
<PlainText>true</PlainText>
|
||||
</Password>
|
||||
</AutoLogon>
|
||||
|
||||
<DisableAutoDaylightTimeSet>false</DisableAutoDaylightTimeSet>
|
||||
|
||||
<!-- ===============================================================
|
||||
FIRST LOGON COMMANDS - run once, elevated, as labadmin.
|
||||
=============================================================== -->
|
||||
<FirstLogonCommands>
|
||||
|
||||
<SynchronousCommand wcm:action="add">
|
||||
<Order>1</Order>
|
||||
<Description>Show file extensions</Description>
|
||||
<CommandLine>reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v HideFileExt /t REG_DWORD /d 0 /f</CommandLine>
|
||||
<RequiresUserInput>false</RequiresUserInput>
|
||||
</SynchronousCommand>
|
||||
|
||||
<SynchronousCommand wcm:action="add">
|
||||
<Order>2</Order>
|
||||
<Description>Allow signed PowerShell scripts</Description>
|
||||
<CommandLine>powershell -NoProfile -Command "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine -Force"</CommandLine>
|
||||
<RequiresUserInput>false</RequiresUserInput>
|
||||
</SynchronousCommand>
|
||||
|
||||
<!-- Provisioning: oobe-ltsc.ps1 sits at the root of the merged ISO
|
||||
next to this file. Scans every drive for it rather than assuming
|
||||
a letter, since the VirtIO disc moves around post-install.
|
||||
The script installs the VirtIO guest tools, MeshCentral agent,
|
||||
power/RDP/SSH settings, then restarts the VM itself, so this
|
||||
must stay the LAST command. Log: C:\ProgramData\OOBE\oobe-ltsc.log -->
|
||||
<SynchronousCommand wcm:action="add">
|
||||
<Order>3</Order>
|
||||
<Description>Run oobe-ltsc.ps1 provisioning script</Description>
|
||||
<CommandLine>powershell -NoProfile -ExecutionPolicy Bypass -Command "$s = Get-PSDrive -PSProvider FileSystem | ForEach-Object { Join-Path $_.Root 'oobe-ltsc.ps1' } | Where-Object { Test-Path $_ } | Select-Object -First 1; if ($s) { & $s } else { Write-Warning 'oobe-ltsc.ps1 not found on any drive'; Start-Sleep -Seconds 60 }"</CommandLine>
|
||||
<RequiresUserInput>false</RequiresUserInput>
|
||||
</SynchronousCommand>
|
||||
|
||||
</FirstLogonCommands>
|
||||
</component>
|
||||
</settings>
|
||||
|
||||
</unattend>
|
||||
|
||||
Reference in new issue
Block a user