<# .SYNOPSIS Define OOBE Tasks .DESCRIPTION oobe.hwz.osdcloud.ch .NOTES Version: 0.1 Creation Date: 24.11.2025 Author: Akos Bakos Company: SmartCon GmbH Contact: akos.bakos@smartcon.ch Copyright (c) 2024 SmartCon GmbH HISTORY: Date By Comments ---------- --- ---------------------------------------------------------- 24.11.2025 Akos Bakos Script created #> #region Helper Functions function Write-DarkGrayDate { [CmdletBinding()] param ( [Parameter(Position = 0)] [System.String] $Message ) if ($Message) { Write-Host -ForegroundColor DarkGray "$((Get-Date).ToString('yyyy-MM-dd-HHmmss')) $Message" } else { Write-Host -ForegroundColor DarkGray "$((Get-Date).ToString('yyyy-MM-dd-HHmmss')) " -NoNewline } } function Write-DarkGrayHost { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 0)] [System.String] $Message ) Write-Host -ForegroundColor DarkGray $Message } function Write-DarkGrayLine { [CmdletBinding()] param () Write-Host -ForegroundColor DarkGray "=========================================================================" } function Write-SectionHeader { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 0)] [System.String] $Message ) Write-DarkGrayLine Write-DarkGrayDate Write-Host -ForegroundColor Cyan $Message } function Write-DarkGrayHost { [CmdletBinding()] param ( [Parameter(Position = 0)] [System.String] $Message = 'Success!' ) Write-DarkGrayDate Write-Host -ForegroundColor Green $Message } #endregion $Title = "OOBE Tasks" $host.UI.RawUI.WindowTitle = $Title [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 [System.Net.WebRequest]::DefaultWebProxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials $env:APPDATA = "C:\Windows\System32\Config\SystemProfile\AppData\Roaming" $env:LOCALAPPDATA = "C:\Windows\System32\Config\SystemProfile\AppData\Local" $Env:PSModulePath = $env:PSModulePath + ";C:\Program Files\WindowsPowerShell\Scripts" $env:Path = $env:Path + ";C:\Program Files\WindowsPowerShell\Scripts" $Global:Transcript = "$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Start-OOBEDeploy.log" Start-Transcript -Path (Join-Path "$env:ProgramData\Microsoft\IntuneManagementExtension\Logs\OSD\" $Global:Transcript) -ErrorAction Ignore | Out-Null if ((Get-ExecutionPolicy) -ne 'Bypass') { Write-DarkGrayHost "Set-ExecutionPolicy Bypass -Force" Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process -Force } #region Check Internet Connection #================================================= Write-SectionHeader "Check Internet Connection" #================================================= $maxAttempts = 30 $internetConnected = $false # Prefer endpoints required by this script/workflow $tests = @( @{ Type='Http'; Uri='http://www.msftconnecttest.com/connecttest.txt'; Expect='Microsoft Connect Test' }, # NCSI @{ Type='Http'; Uri='https://www.powershellgallery.com/api/v2'; ExpectStatus=200 }, # PSGallery @{ Type='Dns'; Name='api.nuget.org' }, # NuGet DNS @{ Type='Tcp'; Host='download.windowsupdate.com'; Port=443 } # WU TCP ) function Test-NetworkTarget { param([hashtable]$t) try { switch ($t.Type) { 'Http' { $resp = Invoke-WebRequest -Uri $t.Uri -UseBasicParsing -TimeoutSec 5 -ErrorAction Stop if ($t.ContainsKey('Expect') -and $resp.Content -like "*$($t.Expect)*") { return $true } if ($t.ContainsKey('ExpectStatus') -and [int]$resp.StatusCode -eq [int]$t.ExpectStatus) { return $true } return $false } 'Tcp' { $r = Test-NetConnection -ComputerName $t.Host -Port $t.Port -WarningAction SilentlyContinue return [bool]$r.TcpTestSucceeded } 'Dns' { Resolve-DnsName -Name $t.Name -ErrorAction Stop | Out-Null return $true } } } catch { return $false } } for ($attempt = 1; $attempt -le $maxAttempts -and -not $internetConnected; $attempt++) { Write-DarkGrayHost "Checking internet connectivity (Attempt $attempt of $maxAttempts)" foreach ($t in $tests) { $label = if ($t.Type -eq 'Http') { $t.Uri } elseif ($t.Type -eq 'Tcp') { "$($t.Host):$($t.Port)" } else { $t.Name } if (Test-NetworkTarget $t) { Write-DarkGrayHost "Connectivity OK via $($t.Type): $label" $internetConnected = $true break } else { Write-DarkGrayHost "No response from $($t.Type): $label" } } if (-not $internetConnected -and $attempt -eq 3) { # After a few failed tries, bounce the adapter once Write-Host "No internet detected. Attempting to restart the primary network adapter..." -ForegroundColor Yellow $restarted = Restart-PrimaryNetAdapter -Retry 2 -RenewDhcp if ($restarted) { Write-Host "Adapter restarted. Re-checking connectivity..." -ForegroundColor Cyan # Quick re-check loop for ($j=1; $j -le 10 -and -not $internetConnected; $j++) { foreach ($t in $tests) { if (Test-NetworkTarget $t) { $internetConnected = $true; break } } if (-not $internetConnected) { Start-Sleep -Seconds 1 } } } else { Write-Host "Adapter restart skipped or failed." -ForegroundColor Yellow } } if (-not $internetConnected) { Start-Sleep -Seconds 1 } } if (-not $internetConnected) { Write-Host -ForegroundColor Yellow "Still no internet. Continuing; online steps may be skipped." } #endregion #Read-Host -Prompt "Stopping for further troubleshootings. Press Enter to continue..." #region Ensure PSGallery #================================================= Write-SectionHeader "Ensure PSGallery" #================================================= function Ensure-PSGallery { [CmdletBinding()] param() [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 # NuGet provider if (-not (Get-PackageProvider -Name NuGet -ErrorAction SilentlyContinue)) { try { Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -Scope AllUsers | Out-Null } catch { Write-Warning "NuGet install failed: $($_.Exception.Message)" } } # PowerShellGet module (baseline) if (-not (Get-Module -ListAvailable PowerShellGet)) { try { Install-Module PowerShellGet -MinimumVersion 2.2.5 -Force -AllowClobber -Scope AllUsers } catch {} } $repo = Get-PSRepository -Name PSGallery -ErrorAction SilentlyContinue if ($repo -and ($repo.SourceLocation -notlike "https://www.powershellgallery.com/*")) { Write-Warning "PSGallery entry looks corrupt. Resetting..." try { Unregister-PSRepository -Name PSGallery -ErrorAction SilentlyContinue } catch {} $repo = $null } if (-not $repo) { # Cleanup stale registry entries (silent) Get-ChildItem HKLM:\SOFTWARE\Microsoft\PowerShell\PowerShellGet\RegisteredRepositories -ErrorAction SilentlyContinue | Where-Object { $_.PSChildName -eq 'PSGallery' } | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue Get-ChildItem HKCU:\SOFTWARE\Microsoft\PowerShell\PowerShellGet\RegisteredRepositories -ErrorAction SilentlyContinue | Where-Object { $_.PSChildName -eq 'PSGallery' } | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue # Prefer -Default only if supported $hasDefaultParam = (Get-Command Register-PSRepository -ErrorAction SilentlyContinue).Parameters.ContainsKey('Default') try { if ($hasDefaultParam) { Register-PSRepository -Default -ErrorAction Stop } else { Register-PSRepository -Name PSGallery ` -SourceLocation "https://www.powershellgallery.com/api/v2" ` -ScriptSourceLocation "https://www.powershellgallery.com/api/v2" ` -InstallationPolicy Trusted -ErrorAction Stop } } catch { Write-Warning "Registration failed: $($_.Exception.Message)" } $repo = Get-PSRepository -Name PSGallery -ErrorAction SilentlyContinue } if ($repo) { if ($repo.InstallationPolicy -ne 'Trusted') { try { Set-PSRepository -Name PSGallery -InstallationPolicy Trusted -ErrorAction Stop } catch {} } Write-DarkGrayHost "[+] PSGallery OK" } else { Write-Warning "PSGallery unavailable. Check proxy / SSL inspection / connectivity." } } Ensure-PSGallery #endregion #region InstallModuleOSD function InstallModuleOSD { [CmdletBinding()] param () $PSModuleName = 'OSD' $InstalledModule = Get-Module -Name $PSModuleName -ListAvailable -ErrorAction Ignore | Sort-Object Version -Descending | Select-Object -First 1 $GalleryPSModule = Find-Module -Name $PSModuleName -ErrorAction Ignore -WarningAction Ignore if ($GalleryPSModule) { if (($GalleryPSModule.Version -as [version]) -gt ($InstalledModule.Version -as [version])) { Write-DarkGrayHost "[-] Install-Module $PSModuleName $($GalleryPSModule.Version)" Install-Module $PSModuleName -Scope AllUsers -Force -SkipPublisherCheck Import-Module $PSModuleName -Force } } $InstalledModule = Get-Module -Name $PSModuleName -ListAvailable -ErrorAction Ignore | Sort-Object Version -Descending | Select-Object -First 1 if ($GalleryPSModule) { if (($InstalledModule.Version -as [version]) -ge ($GalleryPSModule.Version -as [version])) { Write-DarkGrayHost "[+] $PSModuleName $($GalleryPSModule.Version)" } } } InstallModuleOSD #endregion #region Product activation #================================================= Write-SectionHeader "Windows Activation" #================================================= $host.ui.RawUI.WindowTitle = "Windows Activation" # Check if system is running on VMware $isVMware = $false try { $computerSystem = Get-WmiObject -Class Win32_ComputerSystem -ErrorAction Stop if ($computerSystem.Manufacturer -like "*VMware*") { $isVMware = $true Write-DarkGrayHost "System detected as running on VMware" } else { Write-DarkGrayHost "System not detected as VMware - proceeding with embedded key activation" } } catch { Write-Host -ForegroundColor Yellow "Could not determine if system is running on VMware: $($_.Exception.Message)" # Assume not VMware in case of error } # Physical hardware - try embedded key $embeddedKey = (Get-WmiObject -Class SoftwareLicensingService).OA3xOriginalProductKey if ($embeddedKey) { Write-DarkGrayHost "Found embedded product key" Write-DarkGrayHost "Installing embedded product key" & cscript.exe "$env:windir\system32\slmgr.vbs" /ipk "$embeddedKey" | Out-Null Start-Sleep -Seconds 3 Write-DarkGrayHost "Activating embedded product key" & cscript.exe "$env:windir\system32\slmgr.vbs" /ato | Out-Null } else { Write-Host -ForegroundColor Yellow "No embedded product key found on this system" } # Verify activation status after attempt Start-Sleep -Seconds 5 try { $activationStatus = Get-CimInstance -ClassName SoftwareLicensingProduct | Where-Object { $_.PartialProductKey -ne $null -and $_.Name -like "*Windows*" } | Select-Object -ExpandProperty LicenseStatus if ($activationStatus -eq 1) { Write-DarkGrayHost "Windows activation successful!" } else { Write-Host -ForegroundColor Yellow "Windows may not be properly activated. Status code: $activationStatus" } } catch { Write-Host -ForegroundColor Yellow "Could not verify activation status: $($_.Exception.Message)" } #endregion #region NetFx3 #================================================= Write-SectionHeader "Install NetFX3 - it can take up to 10 minutes" #================================================= $Title = 'Installing AddNetFX3' $host.ui.RawUI.WindowTitle = "$Title" $host.UI.RawUI.BufferSize = New-Object System.Management.Automation.Host.size(2000, 2000) $AddWindowsCapability = Get-MyWindowsCapability -Match 'NetFX' -Detail foreach ($Item in $AddWindowsCapability) { if ($Item.State -ne 'Install') { Write-DarkGrayHost "$($Item.DisplayName)" $Item | Add-WindowsCapability -Online -ErrorAction Ignore | Out-Null } else { Write-DarkGrayHost "$($Item.DisplayName)" } } #endregion #region Remove-Appx #================================================= Write-SectionHeader "Remove-Appx" #================================================= $Title = 'Remove Appx' $host.ui.RawUI.WindowTitle = "$Title" $host.UI.RawUI.BufferSize = New-Object System.Management.Automation.Host.size(2000, 2000) $Global:Transcript = "$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Remove_AppXs.log" Start-Transcript -Path (Join-Path "$env:ProgramData\Microsoft\IntuneManagementExtension\Logs\OSD\" $Global:Transcript) -ErrorAction Ignore | Out-Null #Log Function function Write-LogEntry { param ( [parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$Value, [parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [string]$FileName = "AppXRemoval.log", [switch]$Stamp ) #Build Log File appending System Date/Time to output $LogFile = Join-Path -Path $env:SystemRoot -ChildPath $("Temp\$FileName") $Time = -join @((Get-Date -Format "HH:mm:ss.fff"), " ", (Get-WmiObject -Class Win32_TimeZone | Select-Object -ExpandProperty Bias)) $Date = (Get-Date -Format "MM-dd-yyyy") If ($Stamp) { $LogText = "<$($Value)> " } else { $LogText = "$($Value)" } Try { Out-File -InputObject $LogText -Append -NoClobber -Encoding Default -FilePath $LogFile -ErrorAction Stop } Catch [System.Exception] { Write-Warning -Message "Unable to add log entry to $LogFile.log file. Error message at line $($_.InvocationInfo.ScriptLineNumber): $($_.Exception.Message)" } } #Function to Remove AppxProvisionedPackage Function Remove-AppxProvisionedPackageCustom { # Attempt to remove AppxProvisioningPackage if (!([string]::IsNullOrEmpty($BlackListedApp))) { try { # Get Package Name $AppProvisioningPackageName = Get-AppxProvisionedPackage -Online | Where-Object { $_.DisplayName -like $BlackListedApp } | Select-Object -ExpandProperty PackageName -First 1 Write-Host "$($BlackListedApp) found. Attempting removal ... " -NoNewline Write-LogEntry -Value "$($BlackListedApp) found. Attempting removal ... " # Attempt removeal $RemoveAppx = Remove-AppxProvisionedPackage -PackageName $AppProvisioningPackageName -Online -AllUsers #Re-check existence $AppProvisioningPackageNameReCheck = Get-AppxProvisionedPackage -Online | Where-Object { $_.DisplayName -like $BlackListedApp } | Select-Object -ExpandProperty PackageName -First 1 If ([string]::IsNullOrEmpty($AppProvisioningPackageNameReCheck) -and ($RemoveAppx.Online -eq $true)) { Write-Host @CheckIcon Write-Host " (Removed)" Write-LogEntry -Value "$($BlackListedApp) removed" } } catch [System.Exception] { Write-Host " (Failed)" Write-LogEntry -Value "Failed to remove $($BlackListedApp)" } } } Write-LogEntry -Value "##################################" Write-LogEntry -Stamp -Value "Remove-Appx Started" Write-LogEntry -Value "##################################" #OS Check $OS = (Get-CimInstance -ClassName Win32_OperatingSystem).BuildNumber Switch -Wildcard ( $OS ) { '21*' { $OSVer = "Windows 10" Write-Warning "This script is intended for use on Windows 11 devices. $($OSVer) was detected..." Write-LogEntry -Value "This script is intended for use on Windows 11 devices. $($OSVer) was detected..." Exit 1 } } # Black List of Appx Provisioned Packages to Remove for All Users $BlackListedApps = $null $BlackListedApps = New-Object -TypeName System.Collections.ArrayList $BlackListedApps.AddRange(@( "Microsoft.OutlookForWindows", # Still present in 24H2 "MicrosoftCorporationII.QuickAssist", # Still present in 24H2 "Clipchamp.Clipchamp", # Still present in 24H2 "Microsoft.BingWeather", # Still present in 24H2 "Microsoft.BingNews", # Still present in 24H2 "Microsoft.GamingApp", # Still present in 24H2 "Microsoft.GetHelp", # Still present in 24H2 "Microsoft.Getstarted", # Still present in 24H2 #"Microsoft.Messaging", # May not be in 24H2 by default "Microsoft.MicrosoftOfficeHub", # Still present in 24H2 "Microsoft.MicrosoftSolitaireCollection", # Still present in 24H2 "Microsoft.MicrosoftStickyNotes", # Still present in 24H2 #"Microsoft.MSPaint", # Now "Microsoft.Paint" in 24H2 "Microsoft.Paint", # New name for Paint in 24H2 "Microsoft.People", # Still present in 24H2 "Microsoft.PowerAutomateDesktop", # Still present in 24H2 "Microsoft.StorePurchaseApp", # Still present in 24H2 "Microsoft.Todos", # Still present in 24H2 "microsoft.windowscommunicationsapps", # Still present in 24H2 "Microsoft.WindowsFeedbackHub", # Still present in 24H2 "Microsoft.WindowsMaps", # Still present in 24H2 "Microsoft.WindowsSoundRecorder", # Still present in 24H2 "Microsoft.Xbox.TCUI", # Still present in 24H2 "Microsoft.XboxGameOverlay", # Still present in 24H2 "Microsoft.XboxGamingOverlay", # Still present in 24H2 "Microsoft.XboxIdentityProvider", # Still present in 24H2 "Microsoft.XboxSpeechToTextOverlay", # Still present in 24H2 "Microsoft.YourPhone", # Still present in 24H2 "Microsoft.ZuneMusic", # Still present in 24H2 #"Microsoft.ZuneVideo", # May be "Microsoft.Movies" in 24H2 "Microsoft.BingSearch", # Still present in 24H2 "MicrosoftWindows.CrossDevice", # Still present in 24H2 "Microsoft.Windows.DevHome", # Still present in 24H2 "MSTeams" # Still present in 24H2 )) #Define Icons $CheckIcon = @{ Object = [Char]8730 ForegroundColor = 'Green' NoNewLine = $true } #Define App Count [int]$AppCount = 0 If ($($BlackListedApps.Count) -ne 0) { Write-Output `n"The following $($BlackListedApps.Count) apps were targeted for removal from the device:-" Write-LogEntry -Value "The following $($BlackListedApps.Count) apps were targeted for removal from the device:-" Write-LogEntry -Value "Apps marked for removal:$($BlackListedApps)" Write-Output "" $BlackListedApps #Initialize list for apps not targeted $AppNotTargetedList = New-Object -TypeName System.Collections.ArrayList # Get Appx Provisioned Packages Write-Output `n"Gathering installed Appx Provisioned Packages..." Write-LogEntry -Value "Gathering installed Appx Provisioned Packages..." Write-Output "" $AppArray = Get-AppxProvisionedPackage -Online | Select-Object -ExpandProperty DisplayName # Loop through each Provisioned Package foreach ($BlackListedApp in $BlackListedApps) { # Function call to Remove Appx Provisioned Packages defined in the Black List if (($BlackListedApp -in $AppArray)) { $AppCount ++ Try { Remove-AppxProvisionedPackageCustom -BlackListedApp $BlackListedApp } Catch { Write-Warning `n"There was an error while attempting to remove $($BlakListedApp)" Write-LogEntry -Value "There was an error when attempting to remove $($BlakListedApp)" } } else { $AppNotTargetedList.AddRange(@($BlackListedApp)) } } #Update Output Information If (!([string]::IsNullOrEmpty($AppNotTargetedList))) { Write-Output `n"The following apps were not removed. Either they were already removed or the Package Name is invalid:-" Write-LogEntry -Value "The following apps were not removed. Either they were already removed or the Package Name is invalid:-" Write-LogEntry -Value "$($AppNotTargetedList)" Write-Output "" $AppNotTargetedList } If ($AppCount -eq 0) { Write-Output `n"No apps were removed. Most likely reason is they had been removed previously." Write-LogEntry -Value "No apps were removed. Most likely reason is they had been removed previously." } } else { Write-Output "No Black List Apps defined in array" Write-LogEntry -Value "No Black List Apps defined in array" } Stop-Transcript | Out-Null #endregion #region Update Drivers #================================================= Write-SectionHeader "Update Drivers" #================================================= $Title = 'Update Drivers' $host.ui.RawUI.WindowTitle = "$Title" $host.UI.RawUI.BufferSize = New-Object System.Management.Automation.Host.size(2000, 2000) if (!(Get-Module PSWindowsUpdate -ListAvailable -ErrorAction Ignore)) { try { Write-DarkGrayHost "Installing PSWindowsUpdate module" Install-Module PSWindowsUpdate -Force Import-Module PSWindowsUpdate -Force } catch { Write-Warning "Unable to install PSWindowsUpdate Driver Updates : $($_.Exception.Message)" } } if (Get-Module PSWindowsUpdate -ListAvailable -ErrorAction Ignore) { Write-DarkGrayHost "Executing 'Install-WindowsUpdate -UpdateType Driver -AcceptAll -IgnoreReboot'" Install-WindowsUpdate -UpdateType Driver -AcceptAll -IgnoreReboot } #endregion #region Update Windows #================================================= Write-DarkGrayHost "Update Windows" #================================================= $Title = 'Update Windows' $host.ui.RawUI.WindowTitle = "$Title" $host.UI.RawUI.BufferSize = New-Object System.Management.Automation.Host.size(2000, 2000) if (!(Get-Module PSWindowsUpdate -ListAvailable)) { try { Write-DarkGrayHost "Installing PSWindowsUpdate module" Install-Module PSWindowsUpdate -Force Import-Module PSWindowsUpdate -Force } catch { Write-Warning 'Unable to install PSWindowsUpdate Windows Updates' } } if (Get-Module PSWindowsUpdate -ListAvailable -ErrorAction Ignore) { Write-DarkGrayHost "Executing 'Add-WUServiceManager -MicrosoftUpdate -Confirm:$false'" Add-WUServiceManager -MicrosoftUpdate -Confirm:$false #Write-Host -ForegroundColor DarkCyan 'Install-WindowsUpdate -UpdateType Software -AcceptAll -IgnoreReboot' #Install-WindowsUpdate -UpdateType Software -AcceptAll -IgnoreReboot -NotTitle 'Malicious' Write-DarkGrayHost "Executing 'Install-WindowsUpdate -MicrosoftUpdate -AcceptAll -IgnoreReboot'" Install-WindowsUpdate -MicrosoftUpdate -AcceptAll -IgnoreReboot -NotTitle 'Preview' -NotKBArticleID 'KB890830', 'KB5005463', 'KB4481252' } #endregion #region Remove DevHome & Outlook NEW #================================================= Write-DarkGrayHost "Remove DevHome & Outlook NEW" #================================================= $Title = 'Remove DevHome & Outlook NEW' $host.ui.RawUI.WindowTitle = "$Title" $host.UI.RawUI.BufferSize = New-Object System.Management.Automation.Host.size(2000, 2000) $DevHome = "HKLM:\SOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\DevHomeUpdate" $OutlookNew = "HKLM:\SOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\OutlookUpdate" if (Test-Path -Path $DevHome) { Write-DarkGrayHost "Found --> Removing DevHome" Remove-Item -Path $DevHome -Force } if (Test-Path -Path $OutlookNew) { Write-DarkGrayHost "Found --> Removing Outlook NEW" Remove-Item -Path $OutlookNew -Force } #endregion #region Disable PowerShell 2.0 #================================================= Write-DarkGrayHost "Disable PowerShell 2.0" #================================================= $Title = 'Disable PowerShell 2.0' $host.ui.RawUI.WindowTitle = "$Title" $host.UI.RawUI.BufferSize = New-Object System.Management.Automation.Host.size(2000, 2000) #If PowerShell version 2 is installed, it’s possible to bypass the constrained language mode, which normally is being enforced by application control solutions like AppLocker and similar. try { $PoShv2Enabled = Get-WindowsOptionalFeature -FeatureName "MicrosoftWindowsPowerShellV2Root" -Online | Select-Object -ExpandProperty State } catch { Write-Error "Failed to get the state of the PowerShell v2.0 feature: : $($_.Exception.Message)" } # If the feature is enabled, try to disable it if ($PoShv2Enabled -eq "Enabled") { try { Disable-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2Root -ErrorAction Continue -NoRestart } catch { Write-Error "Failed to disable the PowerShell v2.0 feature: $($_.Exception.Message)" } } #endregion #region Stop Start menu from opening on first logon #================================================= Write-SectionHeader "Stop Start menu from opening on first logon" #================================================= $Title = 'Stop Start menu from opening on first logon' $host.ui.RawUI.WindowTitle = "$Title" $host.UI.RawUI.BufferSize = New-Object System.Management.Automation.Host.size(2000, 2000) try { reg.exe load HKLM\TempUser "C:\Users\Default\NTUSER.DAT" | Out-Host reg.exe add "HKLM\TempUser\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v StartShownOnUpgrade /t REG_DWORD /d 1 /f | Out-Host reg.exe unload HKLM\TempUser | Out-Host } catch { Write-Warning "Unable to stop Start menu from opening on first logon: : $($_.Exception.Message)" } #endregion #region Removes Microsoft Quick Assist #================================================= Write-SectionHeader "Removes Microsoft Quick Assist" #================================================= $Title = 'Removes Microsoft Quick Assist' $host.ui.RawUI.WindowTitle = "$Title" $host.UI.RawUI.BufferSize = New-Object System.Management.Automation.Host.size(2000, 2000) # Define the app package name $appPackageName = "MicrosoftCorporationII.QuickAssist" # Function to remove the app for the current user function Remove-AppxPackageByName { param ( [string]$PackageName ) $app = Get-AppxPackage -Name $PackageName -ErrorAction SilentlyContinue if ($app) { Remove-AppxPackage -Package $app.PackageFullName -ErrorAction SilentlyContinue Write-Output "Removed app package $PackageName for current user." } else { Write-Output "App package $PackageName not found for current user." } } # Function to remove the provisioned app function Remove-AppxProvisionedPackageByName { param ( [string]$PackageName ) $app = Get-AppxProvisionedPackage -Online | Where-Object { $_.DisplayName -eq $PackageName } if ($app) { Remove-AppxProvisionedPackage -Online -PackageName $app.PackageName -ErrorAction SilentlyContinue Write-Output "Removed provisioned app package $PackageName." } else { Write-Output "Provisioned app package $PackageName not found." } } try { # Remove Quick Assist for the current user Remove-AppxPackageByName -PackageName $appPackageName # Remove the provisioned package so it does not get installed for new users Remove-AppxProvisionedPackageByName -PackageName $appPackageName Write-Output "Microsoft Quick Assist removal process completed." } catch { Write-Warning 'Unable to remove Microsoft Quick Assist' } #endregion #region OEM Branding #================================================= Write-SectionHeader "OEM Branding" #================================================= $Title = 'OEM Branding' $host.ui.RawUI.WindowTitle = "$Title" $host.UI.RawUI.BufferSize = New-Object System.Management.Automation.Host.size(2000, 2000) try { reg.exe add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OEMInformation" /v SupportPhone /t REG_SZ /d "+41 43 322 26 90" /f /reg:64 | Out-Host reg.exe add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OEMInformation" /v SupportURL /t REG_SZ /d "support@fh-hwz.ch" /f /reg:64 | Out-Host } catch { Write-Warning "Unable to set the OEM Branding: $($_.Exception.Message)" } #endregion #region CMTrace Download #================================================= Write-SectionHeader "CMTrace Download" #================================================= $Title = 'CMTrace Download' $host.ui.RawUI.WindowTitle = "$Title" $host.UI.RawUI.BufferSize = New-Object System.Management.Automation.Host.size(2000, 2000) try { $url = 'https://patchmypc.com/cmtrace' $destDir = 'C:\Program Files\CMTrace' $exePath = Join-Path $destDir 'CMTrace.exe' # Create destination New-Item -Path $destDir -ItemType Directory -Force | Out-Null # Download directly to final path Write-DarkGrayHost "Downloading CMTrace to $exePath..." Invoke-WebRequest -Uri $url -OutFile $exePath -ErrorAction Stop | Out-Null # Basic validation (PE header "MZ") $header = [byte[]](Get-Content -Path $exePath -Encoding Byte -TotalCount 2) if ($header.Length -ne 2 -or $header[0] -ne 0x4D -or $header[1] -ne 0x5A) { Remove-Item $exePath -Force -ErrorAction SilentlyContinue throw "Downloaded file doesn't look like a valid executable." } } catch { Write-Warning "Unable to download CMTrace: $($_.Exception.Message)" } #Read-Host -Prompt "Stopping for further troubleshootings. Press Enter to continue..." Stop-Transcript | Out-Null