Skip to content

Commit

Permalink
Update scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronparker committed Oct 10, 2024
1 parent bc1910b commit d41e3ba
Show file tree
Hide file tree
Showing 69 changed files with 324 additions and 413 deletions.
4 changes: 2 additions & 2 deletions scripts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Image scripts for customising Windows 10/11 Enterprise and Enterprise multi-sess

Scripts use [Evergreen](https://stealthpuppy.com/evergreen/) to determine the latest version of an application. Running each script will install the latest version on a clean image or update an existing application install on a gold image or existing session hosts.

Where supported, application installers will save install logs to `$Env:ProgramData\Nerdio\Logs`.
Where supported, application installers will save install logs to `$Env:SystemRoot\Logs\ImageBuild`.

| **Script** | **Notes** |
|-------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
Expand Down Expand Up @@ -51,4 +51,4 @@ Once run on the target VM, the VM or image should have the specified application

Scripts here will uninstall target applications. Run on gold images or target session hosts when users are not signed in, as applications will be forcibly uninstalled.

Where supported, uninstall commands will save uninstall logs to `$Env:ProgramData\Nerdio\Logs`.
Where supported, uninstall commands will save uninstall logs to `$Env:SystemRoot\Logs\ImageBuild`.
25 changes: 17 additions & 8 deletions scripts/image/000_PrepImage.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,35 @@ for customization. It performs the following tasks:
#execution mode: Combined
#tags: Image

# If we're on Windows 11, configure the registry settings
if ((Get-CimInstance -ClassName "CIM_OperatingSystem").Caption -like "Microsoft Windows 1*") {

# Prevent Windows from installing stuff during deployment
reg add "HKLM\Software\Policies\Microsoft\Windows\CloudContent" /v "DisableWindowsConsumerFeatures" /d 1 /t "REG_DWORD" /f | Out-Null
reg add "HKLM\Software\Policies\Microsoft\WindowsStore" /v "AutoDownload" /d 2 /t "REG_DWORD" /f | Out-Null

# https://www.reddit.com/r/Windows11/comments/17toy5k/prevent_automatic_installation_of_outlook_and_dev/
reg delete "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\DevHomeUpdate" /f | Out-Null
reg delete "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\OutlookUpdate" /f | Out-Null
reg delete "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler_Oobe\DevHomeUpdate" /f | Out-Null
reg delete "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler_Oobe\OutlookUpdate" /f | Out-Null

# https://learn.microsoft.com/en-us/windows/deployment/update/waas-wu-settings#allow-windows-updates-to-install-before-initial-user-sign-in
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator" /v "ScanBeforeInitialLogonAllowed" /d 1 /t "REG_DWORD" /f | Out-Null
}

# Start menu customisation
# reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer" /v SpecialRoamingOverrideAllowed /t REG_DWORD /d 1 /f

# Enable time zone redirection
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" /v fEnableTimeZoneRedirection /t REG_DWORD /d 1 /f
# Enable time zone redirection - this can be configure via policy as well
Write-LogFile -Message "Enable time zone redirection" -LogLevel 1
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" /v "fEnableTimeZoneRedirection" /t "REG_DWORD" /d 1 /f

# Create logs directory and compress
New-Item -Path "$Env:ProgramData\Nerdio\Logs" -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null
New-Item -Path "$Env:SystemRoot\Logs\ImageBuild" -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null
$params = @{
FilePath = "$Env:SystemRoot\System32\compact.exe"
ArgumentList = "/C /S `"$Env:ProgramData\Nerdio\Logs`""
ArgumentList = "/C /S `"$Env:SystemRoot\Logs\ImageBuild`""
NoNewWindow = $true
Wait = $true
PassThru = $true
ErrorAction = "Stop"
}
Start-Process @params *> $null
Start-Process @params | Out-Null
1 change: 0 additions & 1 deletion scripts/image/011_SupportFunctions.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ Runs the script to install the required PowerShell modules for building AVD imag
# Trust the PSGallery for modules
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
Install-PackageProvider -Name "NuGet" -MinimumVersion "2.8.5.208" -Force -ErrorAction "SilentlyContinue"
#Install-Module -Name PowerShellGet -Force -AllowClobber
Install-PackageProvider -Name "PowerShellGet" -MinimumVersion "2.2.5" -Force -ErrorAction "SilentlyContinue"
foreach ($Repository in "PSGallery") {
if (Get-PSRepository | Where-Object { $_.Name -eq $Repository -and $_.InstallationPolicy -ne "Trusted" }) {
Expand Down
24 changes: 10 additions & 14 deletions scripts/image/013_RegionLanguage.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -43,23 +43,19 @@ else {
}
#endregion

#region Enable the WinRM rule as a workaround for VM provisioning DSC failure with: "Unable to check the status of the firewall"
# https://github.com/Azure/RDS-Templates/issues/435
# https://qiita.com/fujinon1109/items/440c614338fe2535b09e
#region Only run if the LanguagePackManagement module is installed
# Works for Windows 11, test on Windows Server 2025
if (Get-Module -Name "LanguagePackManagement" -ListAvailable) {

Get-NetConnectionProfile | Set-NetConnectionProfile -NetworkCategory "Private"
Get-NetFirewallRule -DisplayGroup "Windows Remote Management" | Enable-NetFirewallRule
Enable-PSRemoting -Force
Get-NetConnectionProfile | Set-NetConnectionProfile -NetworkCategory "Public"
#endregion
# Enable the WinRM rule as a workaround for VM provisioning DSC failure with: "Unable to check the status of the firewall"
# https://github.com/Azure/RDS-Templates/issues/435
# https://qiita.com/fujinon1109/items/440c614338fe2535b09e

# Disable LanguageComponentsInstaller while installing language packs
# See Bug 45044965: Installing language pack fails with error: ERROR_SHARING_VIOLATION for more details
# Disable-ScheduledTask -TaskName "\Microsoft\Windows\LanguageComponentsInstaller\Installation"
# Disable-ScheduledTask -TaskName "\Microsoft\Windows\LanguageComponentsInstaller\ReconcileLanguageResources"
Get-NetConnectionProfile | Set-NetConnectionProfile -NetworkCategory "Private"
Get-NetFirewallRule -DisplayGroup "Windows Remote Management" | Enable-NetFirewallRule
Enable-PSRemoting -Force
Get-NetConnectionProfile | Set-NetConnectionProfile -NetworkCategory "Public"

#region Only run if the LanguagePackManagement module is installed
if (Get-Module -Name "LanguagePackManagement" -ListAvailable) {
$params = @{
Language = $Language
CopyToSettings = $true
Expand Down
138 changes: 82 additions & 56 deletions scripts/image/014_RolesFeatures.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -5,56 +5,72 @@ Configures Windows roles, features, and capabilities by enabling or disabling Wi
.DESCRIPTION
This script is used to configure Windows roles, features, and capabilities on different versions of Windows,
including Windows Server, Windows 11, and Windows 10. It enables or disables specific Windows roles and features based on the operating system version.
.PARAMETER None
.EXAMPLE
.\014_RolesFeatures.ps1
#>

#description: Configures Windows roles, features and capabilities. Enable/disable Windows roles and features
#execution mode: IndividualWithRestart
#tags: Roles, Features, Capabilities, Image
[CmdletBinding(SupportsShouldProcess = $false)]
param ()

#region Script logic
# Add / Remove roles and features (requires reboot at end of deployment)
switch -Regex ((Get-CimInstance -ClassName "CIM_OperatingSystem").Caption) {
#region Windows Server
"Microsoft Windows Server*" {
$params = @{
FeatureName = "Printing-XPSServices-Features", "AzureArcSetup"
Online = $true
NoRestart = $true
WarningAction = "SilentlyContinue"
ErrorAction = "SilentlyContinue"
$Features = @("Printing-XPSServices-Features", "AzureArcSetup", "WindowsServerBackupSnapin", "WindowsServerBackup")
foreach ($Feature in $Features) {
$params = @{
FeatureName = $Feature
Online = $true
NoRestart = $true
WarningAction = "SilentlyContinue"
ErrorAction = "SilentlyContinue"
}
Disable-WindowsOptionalFeature @params
}

$Features = @("RDS-RD-Server", "Server-Media-Foundation", "Search-Service", "Remote-Assistance") # "NET-Framework-Core"
foreach ($Feature in $Features) {
$params = @{
Name = $Feature
WarningAction = "SilentlyContinue"
ErrorAction = "SilentlyContinue"
}
Write-LogFile -Message "Install-WindowsFeature: $Feature" -LogLevel 1
Install-WindowsFeature @params
}
Disable-WindowsOptionalFeature @params

$params = @{
Name = "RDS-RD-Server", "Server-Media-Foundation", "Search-Service", "NET-Framework-Core", "Remote-Assistance"
WarningAction = "SilentlyContinue"
ErrorAction = "SilentlyContinue"
# Remove other capabilities
$Capabilities = @("App.StepsRecorder~~~~0.0.1.0",
"Browser.InternetExplorer~~~~0.0.11.0",
"Downlevel.NLS.Sorting.Versions.Server~~~~0.0.1.0",
"MathRecognizer~~~~0.0.1.0",
"Media.WindowsMediaPlayer~~~~0.0.12.0",
"Microsoft.Windows.MSPaint~~~~0.0.1.0",
"Microsoft.Windows.PowerShell.ISE~~~~0.0.1.0",
"Microsoft.Windows.WordPad~~~~0.0.1.0",
"XPS.Viewer~~~~0.0.1.0")
foreach ($Capability in $Capabilities) {
Write-LogFile -Message "Remove-Capability: $Capability" -LogLevel 1
& "$Env:SystemRoot\System32\dism.exe" /Online /Remove-Capability /CapabilityName:$Capability /NoRestart /Quiet
}
Install-WindowsFeature @params

# Remove Azure Arc Setup from running at sign-in
reg delete "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" /v "AzureArcSetup" /f | Out-Null

# Remove unnecessary shortcuts
Remove-Item -Path "$Env:ProgramData\Microsoft\Windows\Start Menu\Programs\Administrative Tools\Microsoft Azure services.lnk"

# Enable services
if ((Get-WindowsFeature -Name "RDS-RD-Server").InstallState -eq "Installed") {
foreach ($service in "Audiosrv", "WSearch") {
try {
$params = @{
Name = $service
StartupType = "Automatic"
WarningAction = "SilentlyContinue"
ErrorAction = "SilentlyContinue"
}
Set-Service @params
}
catch {
$_.Exception.Message
foreach ($service in "Audiosrv", "WSearch") {
try {
$params = @{
Name = $service
StartupType = "Automatic"
WarningAction = "SilentlyContinue"
ErrorAction = "SilentlyContinue"
}
Set-Service @params
}
catch {
$_.Exception.Message
}
}
break
Expand All @@ -63,44 +79,54 @@ switch -Regex ((Get-CimInstance -ClassName "CIM_OperatingSystem").Caption) {

#region Windows 11
"Microsoft Windows 11 Enterprise*|Microsoft Windows 11 Pro*" {
$params = @{
FeatureName = "Printing-XPSServices-Features", "SMB1Protocol", "WorkFolders-Client", "MicrosoftWindowsPowerShellV2Root", "MicrosoftWindowsPowerShellV2"
Online = $true
NoRestart = $true
WarningAction = "SilentlyContinue"
ErrorAction = "SilentlyContinue"
$Features = @("Printing-XPSServices-Features", "SMB1Protocol", "WorkFolders-Client", "MicrosoftWindowsPowerShellV2Root", "MicrosoftWindowsPowerShellV2")
foreach ($Feature in $Features) {
$params = @{
FeatureName = $Feature
Online = $true
NoRestart = $true
WarningAction = "SilentlyContinue"
ErrorAction = "SilentlyContinue"
}
Disable-WindowsOptionalFeature @params
}
Disable-WindowsOptionalFeature @params
break
}
#endregion

#region Windows 10
"Microsoft Windows 10 Enterprise*|Microsoft Windows 10 Pro*" {
$params = @{
FeatureName = "Printing-XPSServices-Features", "SMB1Protocol", "WorkFolders-Client", `
$Features = @("Printing-XPSServices-Features", "SMB1Protocol", "WorkFolders-Client", `
"FaxServicesClientPackage", "WindowsMediaPlayer", "MicrosoftWindowsPowerShellV2Root", `
"MicrosoftWindowsPowerShellV2"
Online = $true
NoRestart = $true
WarningAction = "SilentlyContinue"
ErrorAction = "SilentlyContinue"
"MicrosoftWindowsPowerShellV2")
foreach ($Feature in $Features) {
$params = @{
FeatureName = $Feature
Online = $true
NoRestart = $true
WarningAction = "SilentlyContinue"
ErrorAction = "SilentlyContinue"
}
Disable-WindowsOptionalFeature @params
}
Disable-WindowsOptionalFeature @params

$params = @{
Name = "Media.WindowsMediaPlayer~~~~0.0.12.0", "XPS.Viewer~~~~0.0.1.0", `
$Features = @("Media.WindowsMediaPlayer~~~~0.0.12.0", "XPS.Viewer~~~~0.0.1.0", `
"App.Support.QuickAssist~~~~0.0.1.0", "MathRecognizer~~~~0.0.1.0", `
"Browser.InternetExplorer~~~~0.0.11.0", "Print.Fax.Scan~~~~0.0.1.0"
IncludeManagementTools = $true
WarningAction = "SilentlyContinue"
ErrorAction = "SilentlyContinue"
"Browser.InternetExplorer~~~~0.0.11.0", "Print.Fax.Scan~~~~0.0.1.0")
foreach ($Feature in $Features) {
$params = @{
Name = $Feature
IncludeManagementTools = $true
WarningAction = "SilentlyContinue"
ErrorAction = "SilentlyContinue"
}
Uninstall-WindowsFeature @params
}
Uninstall-WindowsFeature @params
break
}
#endregion

default {
Write-LogFile -Message "Failed to determine OS" -LogLevel 1
}
}
6 changes: 5 additions & 1 deletion scripts/image/015_Customise.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,13 @@ New-Item -Path $Path -ItemType "Directory" -Force -ErrorAction "SilentlyContinue
$Installer = Get-EvergreenApp -Name "stealthpuppyWindowsCustomisedDefaults" | Where-Object { $_.Type -eq "zip" } | `
Select-Object -First 1 | `
Save-EvergreenApp -CustomPath $Path

# Extract the installer
Expand-Archive -Path $Installer.FullName -DestinationPath $Path -Force
$InstallFile = Get-ChildItem -Path $Path -Recurse -Include "Install-Defaults.ps1"

# Install the Customised Defaults
Push-Location -Path $InstallFile.Directory
& .\Install-Defaults.ps1 -Language $Language -TimeZone $TimeZone -AppxMode $AppxMode
& $InstallFile.FullName -Language $Language -TimeZone $TimeZone -AppxMode $AppxMode
Pop-Location
#endregion
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ The path where the agents will be downloaded. The default path is "$Env:SystemDr

#region Script logic
New-Item -Path $Path -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null
New-Item -Path "$Env:ProgramData\Nerdio\Logs" -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null
New-Item -Path "$Env:SystemRoot\Logs\ImageBuild" -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null

# Run tasks/install apps
#region Microsoft Azure Virtual Desktop Multimedia Redirection Extensions
Expand All @@ -40,7 +40,7 @@ catch {
}

# Install MMR
$LogFile = "$Env:ProgramData\Nerdio\Logs\MicrosoftWvdMultimediaRedirection$($App.Version).log" -replace " ", ""
$LogFile = "$Env:SystemRoot\Logs\ImageBuild\MicrosoftWvdMultimediaRedirection$($App.Version).log" -replace " ", ""
$params = @{
FilePath = "$Env:SystemRoot\System32\msiexec.exe"
ArgumentList = "/package `"$($OutFile.FullName)`" /quiet /log $LogFile"
Expand Down
4 changes: 2 additions & 2 deletions scripts/image/101_Avd-AgentMicrosoftWvdRtcService.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ The path where the agents will be downloaded. The default path is "$Env:SystemDr

#region Script logic
New-Item -Path $Path -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null
New-Item -Path "$Env:ProgramData\Nerdio\Logs" -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null
New-Item -Path "$Env:SystemRoot\Logs\ImageBuild" -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null

# Run tasks/install apps
#region Microsoft Remote Desktop WebRTC Redirector Service
Expand All @@ -40,7 +40,7 @@ catch {
}

# Install RTC
$LogFile = "$Env:ProgramData\Nerdio\Logs\MicrosoftWvdRtcService$($App.Version).log" -replace " ", ""
$LogFile = "$Env:SystemRoot\Logs\ImageBuild\MicrosoftWvdRtcService$($App.Version).log" -replace " ", ""
$params = @{
FilePath = "$Env:SystemRoot\System32\msiexec.exe"
ArgumentList = "/package `"$($OutFile.FullName)`" /quiet /log $LogFile"
Expand Down
4 changes: 2 additions & 2 deletions scripts/image/102_MicrosoftFSLogixApps.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ $Versions = @"

#region Script logic
New-Item -Path $Path -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null
New-Item -Path "$Env:ProgramData\Nerdio\Logs" -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null
New-Item -Path "$Env:SystemRoot\Logs\ImageBuild" -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null

# Download and unpack
Import-Module -Name "Evergreen" -Force
Expand Down Expand Up @@ -94,7 +94,7 @@ Expand-Archive -Path $OutFile.FullName -DestinationPath $Path -Force
foreach ($file in "FSLogixAppsSetup.exe") {
$Installers = Get-ChildItem -Path $Path -Recurse -Include $file | Where-Object { $_.Directory -match "x64" }
foreach ($Installer in $Installers) {
$LogFile = "$Env:ProgramData\Nerdio\Logs\$($Installer.Name)$($App.Version).log" -replace " ", ""
$LogFile = "$Env:SystemRoot\Logs\ImageBuild\$($Installer.Name)$($App.Version).log" -replace " ", ""
$params = @{
FilePath = $Installer.FullName
ArgumentList = "/install /quiet /norestart /log $LogFile"
Expand Down
6 changes: 3 additions & 3 deletions scripts/image/103_MicrosoftNET.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Installs the Microsoft .NET Desktop LTS and Current Runtimes using the default i
.NOTES
- This script requires the Evergreen module to be installed.
- The script creates a log file at "$Env:ProgramData\Nerdio\Logs\Microsoft.NET.log" to capture installation logs.
- The script creates a log file at "$Env:SystemRoot\Logs\ImageBuild\Microsoft.NET.log" to capture installation logs.
#>

#description: Installs the Microsoft .NET Desktop LTS
Expand All @@ -26,7 +26,7 @@ Installs the Microsoft .NET Desktop LTS and Current Runtimes using the default i

#region Script logic
New-Item -Path $Path -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null
New-Item -Path "$Env:ProgramData\Nerdio\Logs" -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null
New-Item -Path "$Env:SystemRoot\Logs\ImageBuild" -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null

# Download
Import-Module -Name "Evergreen" -Force
Expand All @@ -35,7 +35,7 @@ $App = Get-EvergreenApp -Name "Microsoft.NET" | `
$OutFile = Save-EvergreenApp -InputObject $App -CustomPath $Path -ErrorAction "Stop"

foreach ($file in $OutFile) {
$LogFile = "$Env:ProgramData\Nerdio\Logs\Microsoft.NET.log" -replace " ", ""
$LogFile = "$Env:SystemRoot\Logs\ImageBuild\Microsoft.NET.log" -replace " ", ""
$params = @{
FilePath = $file.FullName
ArgumentList = "/install /quiet /norestart /log $LogFile"
Expand Down
Loading

0 comments on commit d41e3ba

Please sign in to comment.