winutil/functions/private/Invoke-MicroWin-Helper.ps1
Chris Titus 54a575274d
Test 2024 03 21 (#1748)
* Fix unattended answer file woes for MicroWin (#1724)

* Update applications.json

Fake app add made by linux fanboy

* Compile Winutil

* Update files

- Add detections for whether the image to be processed by MicroWin is Windows 10 or later
- Add procedure to clear the indexes ComboBox (WinForms term) every time an ISO is specified

* Update screen-install.png (#1464)

* Compile Winutil

* applications.jsonAdded Foxit Reader app and updated Foxit Editor to show the difference.

* applications.json

Added Foxit Reader app and updated Foxit Editor to show the difference.

* Compile Winutil

* Fix Broken Link and add syncthingtray (#1508)

* Compile Winutil

* Remove Nano-Removed bugged Nano package for now

* Remove Nano

-Removed bugged Nano package for now

* Compile Winutil

* tweaks and fetures tabs clean up automation from inputXML.xaml

* tweaks and fetures tabs clean up automation from inputXML.xaml

* fixed some commas in tweaks.json file

* recompile

* Update tweaks.json

* Compile Winutil

* Choosing Alternate Scartch Path and Busy Messages

* Choosing Alternate Scartch Path and Busy Messages

* Change Selected index to be pro

* Compile Winutil

* Improve detection for Professional editions

* Update files

Updated the Test-CompatibleImage function to compare against a desired version, which is useful for determining if the Specialize pass needs to be added to the unattended answer file

* Automatic conversion of ESD files

Automatically convert the install.esd file from installation media into a WIM file that can be mounted, then delete the ESD file

* pull workflow github actions (#1716)

* Update close-old-issues.yaml

* Compile Winutil

* Update close-old-issues.yaml

* Update close-old-issues.yaml

* Update close-old-issues.yaml

* Compile Winutil

---------

Co-authored-by: ChrisTitusTech <ChrisTitusTech@users.noreply.github.com>

* Update files

Force unattended answer file to use UTF-8 encoding

---------

Co-authored-by: Chris Titus <dfm.titus@gmail.com>
Co-authored-by: ChrisTitusTech <ChrisTitusTech@users.noreply.github.com>
Co-authored-by: Samq64 <81489795+Samq64@users.noreply.github.com>
Co-authored-by: Chris Titus <contact@christitus.com>
Co-authored-by: LoopTJ <34551682+LoopTJ@users.noreply.github.com>
Co-authored-by: Roc Wang <rocwang911@gmail.com>
Co-authored-by: Jes Herring <123990927+jesjess243@users.noreply.github.com>
Co-authored-by: ogfrm <96927197+ogfrm@users.noreply.github.com>
Co-authored-by: LeeDowA <157072913+LeeDowA@users.noreply.github.com>

* add tightvnc to address issue #1718 (#1721)

* Compile Winutil

* Add 'FireFox ESR' and 'lightshot' Apps to 'application.json' File (#1720)

* Add 'FireFox ESR' and 'lightshot' Apps to 'application.json' File

* Update 'FireFox ESR' description

* Compile Winutil

* Fix typo in the Description of 'Get-Oscdimg.ps1' private function (#1743)

* Compile Winutil

* IPv6 update (#1739)

* Compile Winutil

* Change ipv6 disable method

* Compile Winutil

* IPv6 + Teredo

* Compile Winutil

* IPv6 registry

* Compile Winutil

* Update Winutil

* Compile Winutil

* Fix to original command

* Compile Winutil

---------

Co-authored-by: Joanty24 <Joanty24@users.noreply.github.com>
Co-authored-by: Chris Titus <contact@christitus.com>

* Compile Winutil

* Implement New Winget Install Method (#1738)

- Removed Get-LatestHash from Install-WinUtilWinget.ps1, replaced by Get-WinUtilWingetLatest.ps1.
- Added new Winget Install method in case of choco failing to install. Environment refresh line included.
- Get-WinUtilWingetPrerequisites added: Downloads the prerequisites required for the latest version of Winget.
- Get-WinUtilWingetLatest added: Uses the GitHub API to find the latest version of Winget and download it along with the accompanied License1.xml file.

Fixes:
- Removed --scope=machine from winget install command in Install-WinUtilProgramWinget. Non-UWP Apps fail to install if scope is set to machine. Error code: 0x80070005. More information commented in file.

* Compile Winutil

* Change order for easier launch in README and fix outdated info (#1732)

* Update README.md

* Update README.md

---------

Co-authored-by: NewCodingAI <165050080+NewCodingAI@users.noreply.github.com>

* Upgrade Fix in #1181 (#1730)

* Compile Winutil

* Fixed Ventoy drive copy typo and began conversion of DISM commands into DISM cmdlets (#1727)

* Fixed Ventoy drive copy typo

* DISM cmdlet Update (Part 1)

Began replacing basic DISM commands with cmdlets from the DISM module.

This change only affects the mount, unmount, and export operations. All other operations still use DISM

---------

Co-authored-by: Chris Titus <contact@christitus.com>

* Compile Winutil

---------

Co-authored-by: CodingWonders <101426328+CodingWonders@users.noreply.github.com>
Co-authored-by: ChrisTitusTech <ChrisTitusTech@users.noreply.github.com>
Co-authored-by: Samq64 <81489795+Samq64@users.noreply.github.com>
Co-authored-by: LoopTJ <34551682+LoopTJ@users.noreply.github.com>
Co-authored-by: Roc Wang <rocwang911@gmail.com>
Co-authored-by: Jes Herring <123990927+jesjess243@users.noreply.github.com>
Co-authored-by: ogfrm <96927197+ogfrm@users.noreply.github.com>
Co-authored-by: LeeDowA <157072913+LeeDowA@users.noreply.github.com>
Co-authored-by: Peter Gallwas <peg0252@arastudent.ac.nz>
Co-authored-by: Mr.k <mineshtine28546271@gmail.com>
Co-authored-by: Joan Solana Raduà <joansolana@proton.me>
Co-authored-by: Joanty24 <Joanty24@users.noreply.github.com>
Co-authored-by: Rux <jonathan.e.rux@gmail.com>
Co-authored-by: ModernTTY <165050080+ModernTTY@users.noreply.github.com>
Co-authored-by: NewCodingAI <165050080+NewCodingAI@users.noreply.github.com>
Co-authored-by: Justawildwolf <62820836+blusewill@users.noreply.github.com>
2024-03-28 12:39:23 -07:00

657 lines
23 KiB
PowerShell

function Invoke-MicroWin-Helper {
<#
.SYNOPSIS
checking unit tests
.PARAMETER Name
no parameters
.EXAMPLE
placeholder
#>
}
function Test-CompatibleImage() {
<#
.SYNOPSIS
Checks the version of a Windows image and determines whether or not it is compatible with a specific feature depending on a desired version
.PARAMETER Name
imgVersion - The version of the Windows image
desiredVersion - The version to compare the image version with
#>
param
(
[Parameter(Mandatory = $true, Position=0)] [string] $imgVersion,
[Parameter(Mandatory = $true, Position=1)] [Version] $desiredVersion
)
try {
$version = [Version]$imgVersion
return $version -ge $desiredVersion
} catch {
return $False
}
}
function Remove-Features([switch] $dumpFeatures = $false, [switch] $keepDefender = $false) {
<#
.SYNOPSIS
Removes certain features from ISO image
.PARAMETER Name
dumpFeatures - Dumps all features found in the ISO into a file called allfeaturesdump.txt. This file can be examined and used to decide what to remove.
keepDefender - Should Defender be removed from the ISO?
.EXAMPLE
Remove-Features -keepDefender:$false
#>
$appxlist = dism /English /image:$scratchDir /Get-Features | Select-String -Pattern "Feature Name : " -CaseSensitive -SimpleMatch
$appxlist = $appxlist -split "Feature Name : " | Where-Object {$_}
if ($dumpFeatures)
{
$appxlist > allfeaturesdump.txt
}
$appxlist = $appxlist | Where-Object {
$_ -NotLike "*Printing*" -AND
$_ -NotLike "*TelnetClient*" -AND
$_ -NotLike "*PowerShell*" -AND
$_ -NotLike "*NetFx*"
}
if ($keepDefender) { $appxlist = $appxlist | Where-Object { $_ -NotLike "*Defender*" }}
foreach($feature in $appxlist)
{
$status = "Removing feature $feature"
Write-Progress -Activity "Removing features" -Status $status -PercentComplete ($counter++/$appxlist.Count*100)
Write-Debug "Removing feature $feature"
# dism /image:$scratchDir /Disable-Feature /FeatureName:$feature /Remove /NoRestart > $null
}
Write-Progress -Activity "Removing features" -Status "Ready" -Completed
}
function Remove-Packages
{
$appxlist = dism /English /Image:$scratchDir /Get-Packages | Select-String -Pattern "Package Identity : " -CaseSensitive -SimpleMatch
$appxlist = $appxlist -split "Package Identity : " | Where-Object {$_}
$appxlist = $appxlist | Where-Object {
$_ -NotLike "*ApplicationModel*" -AND
$_ -NotLike "*indows-Client-LanguagePack*" -AND
$_ -NotLike "*LanguageFeatures-Basic*" -AND
$_ -NotLike "*Package_for_ServicingStack*" -AND
$_ -NotLike "*.NET*" -AND
$_ -NotLike "*Store*" -AND
$_ -NotLike "*VCLibs*" -AND
$_ -NotLike "*AAD.BrokerPlugin",
$_ -NotLike "*LockApp*" -AND
$_ -NotLike "*Notepad*" -AND
$_ -NotLike "*immersivecontrolpanel*" -AND
$_ -NotLike "*ContentDeliveryManager*" -AND
$_ -NotLike "*PinningConfirMationDialog*" -AND
$_ -NotLike "*SecHealthUI*" -AND
$_ -NotLike "*SecureAssessmentBrowser*" -AND
$_ -NotLike "*PrintDialog*" -AND
$_ -NotLike "*AssignedAccessLockApp*" -AND
$_ -NotLike "*OOBENetworkConnectionFlow*" -AND
$_ -NotLike "*Apprep.ChxApp*" -AND
$_ -NotLike "*CBS*" -AND
$_ -NotLike "*OOBENetworkCaptivePortal*" -AND
$_ -NotLike "*PeopleExperienceHost*" -AND
$_ -NotLike "*ParentalControls*" -AND
$_ -NotLike "*Win32WebViewHost*" -AND
$_ -NotLike "*InputApp*" -AND
$_ -NotLike "*AccountsControl*" -AND
$_ -NotLike "*AsyncTextService*" -AND
$_ -NotLike "*CapturePicker*" -AND
$_ -NotLike "*CredDialogHost*" -AND
$_ -NotLike "*BioEnrollMent*" -AND
$_ -NotLike "*ShellExperienceHost*" -AND
$_ -NotLike "*DesktopAppInstaller*" -AND
$_ -NotLike "*WebMediaExtensions*" -AND
$_ -NotLike "*WMIC*" -AND
$_ -NotLike "*UI.XaML*"
}
foreach ($appx in $appxlist)
{
$status = "Removing $appx"
Write-Progress -Activity "Removing Apps" -Status $status -PercentComplete ($counter++/$appxlist.Count*100)
dism /English /image:$scratchDir /Remove-Package /PackageName:$appx /NoRestart
}
Write-Progress -Activity "Removing Apps" -Status "Ready" -Completed
}
function Remove-ProvisionedPackages([switch] $keepSecurity = $false)
{
<#
.SYNOPSIS
Removes AppX packages from a Windows image during MicroWin processing
.PARAMETER Name
keepSecurity - Boolean that determines whether to keep "Microsoft.SecHealthUI" (Windows Security) in the Windows image
.EXAMPLE
Remove-ProvisionedPackages -keepSecurity:$false
#>
$appxProvisionedPackages = Get-AppxProvisionedPackage -Path "$($scratchDir)" | Where-Object {
$_.PackageName -NotLike "*AppInstaller*" -AND
$_.PackageName -NotLike "*Store*" -and
$_.PackageName -NotLike "*dism*" -and
$_.PackageName -NotLike "*Foundation*" -and
$_.PackageName -NotLike "*FodMetadata*" -and
$_.PackageName -NotLike "*LanguageFeatures*" -and
$_.PackageName -NotLike "*Notepad*" -and
$_.PackageName -NotLike "*Printing*" -and
$_.PackageName -NotLike "*Wifi*" -and
$_.PackageName -NotLike "*Foundation*"
}
if ($?)
{
if ($keepSecurity) { $appxProvisionedPackages = $appxProvisionedPackages | Where-Object { $_.PackageName -NotLike "*SecHealthUI*" }}
$counter = 0
foreach ($appx in $appxProvisionedPackages)
{
$status = "Removing Provisioned $($appx.PackageName)"
Write-Progress -Activity "Removing Provisioned Apps" -Status $status -PercentComplete ($counter++/$appxProvisionedPackages.Count*100)
dism /English /image:$scratchDir /Remove-ProvisionedAppxPackage /PackageName:$($appx.PackageName) /NoRestart
}
Write-Progress -Activity "Removing Provisioned Apps" -Status "Ready" -Completed
}
else
{
Write-Host "Could not get Provisioned App information. Skipping process..."
}
}
function Copy-ToUSB([string] $fileToCopy)
{
foreach ($volume in Get-Volume) {
if ($volume -and $volume.FileSystemLabel -ieq "ventoy") {
$destinationPath = "$($volume.DriveLetter):\"
#Copy-Item -Path $fileToCopy -Destination $destinationPath -Force
# Get the total size of the file
$totalSize = (Get-Item $fileToCopy).length
Copy-Item -Path $fileToCopy -Destination $destinationPath -Verbose -Force -Recurse -Container -PassThru |
ForEach-Object {
# Calculate the percentage completed
$completed = ($_.BytesTransferred / $totalSize) * 100
# Display the progress bar
Write-Progress -Activity "Copying File" -Status "Progress" -PercentComplete $completed -CurrentOperation ("{0:N2} MB / {1:N2} MB" -f ($_.BytesTransferred / 1MB), ($totalSize / 1MB))
}
Write-Host "File copied to Ventoy drive $($volume.DriveLetter)"
return
}
}
Write-Host "Ventoy USB Key is not inserted"
}
function Remove-FileOrDirectory([string] $pathToDelete, [string] $mask = "", [switch] $Directory = $false)
{
if(([string]::IsNullOrEmpty($pathToDelete))) { return }
if (-not (Test-Path -Path "$($pathToDelete)")) { return }
$yesNo = Get-LocalizedYesNo
Write-Host "[INFO] In Your local takeown expects '$($yesNo[0])' as a Yes answer."
# Specify the path to the directory
# $directoryPath = "$($scratchDir)\Windows\System32\LogFiles\WMI\RtBackup"
# takeown /a /r /d $yesNo[0] /f "$($directoryPath)" > $null
# icacls "$($directoryPath)" /q /c /t /reset > $null
# icacls $directoryPath /setowner "*S-1-5-32-544"
# icacls $directoryPath /grant "*S-1-5-32-544:(OI)(CI)F" /t /c /q
# Remove-Item -Path $directoryPath -Recurse -Force
# # Grant full control to BUILTIN\Administrators using icacls
# $directoryPath = "$($scratchDir)\Windows\System32\WebThreatDefSvc"
# takeown /a /r /d $yesNo[0] /f "$($directoryPath)" > $null
# icacls "$($directoryPath)" /q /c /t /reset > $null
# icacls $directoryPath /setowner "*S-1-5-32-544"
# icacls $directoryPath /grant "*S-1-5-32-544:(OI)(CI)F" /t /c /q
# Remove-Item -Path $directoryPath -Recurse -Force
$itemsToDelete = [System.Collections.ArrayList]::new()
if ($mask -eq "")
{
Write-Debug "Adding $($pathToDelete) to array."
[void]$itemsToDelete.Add($pathToDelete)
}
else
{
Write-Debug "Adding $($pathToDelete) to array and mask is $($mask)"
if ($Directory) { $itemsToDelete = Get-ChildItem $pathToDelete -Include $mask -Recurse -Directory }
else { $itemsToDelete = Get-ChildItem $pathToDelete -Include $mask -Recurse }
}
foreach($itemToDelete in $itemsToDelete)
{
$status = "Deleting $($itemToDelete)"
Write-Progress -Activity "Removing Items" -Status $status -PercentComplete ($counter++/$itemsToDelete.Count*100)
if (Test-Path -Path "$($itemToDelete)" -PathType Container)
{
$status = "Deleting directory: $($itemToDelete)"
takeown /r /d $yesNo[0] /a /f "$($itemToDelete)"
icacls "$($itemToDelete)" /q /c /t /reset
icacls $itemToDelete /setowner "*S-1-5-32-544"
icacls $itemToDelete /grant "*S-1-5-32-544:(OI)(CI)F" /t /c /q
Remove-Item -Force -Recurse "$($itemToDelete)"
}
elseif (Test-Path -Path "$($itemToDelete)" -PathType Leaf)
{
$status = "Deleting file: $($itemToDelete)"
takeown /a /f "$($itemToDelete)"
icacls "$($itemToDelete)" /q /c /t /reset
icacls "$($itemToDelete)" /setowner "*S-1-5-32-544"
icacls "$($itemToDelete)" /grant "*S-1-5-32-544:(OI)(CI)F" /t /c /q
Remove-Item -Force "$($itemToDelete)"
}
}
Write-Progress -Activity "Removing Items" -Status "Ready" -Completed
}
function New-Unattend {
# later if we wont to remove even more bloat EU requires MS to remove everything from English(world)
# Below is an example how to do it we probably should create a drop down with common locals
# <settings pass="specialize">
# <!-- Specify English (World) locale -->
# <component name="Microsoft-Windows-International-Core" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
# <SetupUILanguage>
# <UILanguage>en-US</UILanguage>
# </SetupUILanguage>
# <InputLocale>en-US</InputLocale>
# <SystemLocale>en-US</SystemLocale>
# <UILanguage>en-US</UILanguage>
# <UserLocale>en-US</UserLocale>
# </component>
# </settings>
# <settings pass="oobeSystem">
# <!-- Specify English (World) locale -->
# <component name="Microsoft-Windows-International-Core" 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>en-US</InputLocale>
# <SystemLocale>en-US</SystemLocale>
# <UILanguage>en-US</UILanguage>
# <UserLocale>en-US</UserLocale>
# </component>
# </settings>
# using here string to embedd unattend
# <RunSynchronousCommand wcm:action="add">
# <Order>1</Order>
# <Path>net user administrator /active:yes</Path>
# </RunSynchronousCommand>
# this section doesn't work in win10/????
# <settings pass="specialize">
# <component name="Microsoft-Windows-SQMApi" 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">
# <CEIPEnabled>0</CEIPEnabled>
# </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">
# <ConfigureChatAutoInstall>false</ConfigureChatAutoInstall>
# </component>
# </settings>
$unattend = @'
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend"
xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<#REPLACEME#>
<settings pass="auditUser">
<component name="Microsoft-Windows-Deployment" 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">
<RunSynchronous>
<RunSynchronousCommand wcm:action="add">
<Order>1</Order>
<CommandLine>CMD /C echo LAU GG&gt;C:\Windows\LogAuditUser.txt</CommandLine>
<Description>StartMenu</Description>
</RunSynchronousCommand>
</RunSynchronous>
</component>
</settings>
<settings pass="oobeSystem">
<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">
<OOBE>
<HideOEMRegistrationScreen>true</HideOEMRegistrationScreen>
<SkipUserOOBE>false</SkipUserOOBE>
<SkipMachineOOBE>false</SkipMachineOOBE>
<HideOnlineAccountScreens>true</HideOnlineAccountScreens>
<HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
<HideEULAPage>true</HideEULAPage>
<ProtectYourPC>3</ProtectYourPC>
</OOBE>
<FirstLogonCommands>
<SynchronousCommand wcm:action="add">
<Order>1</Order>
<CommandLine>cmd.exe /c echo 23&gt;c:\windows\csup.txt</CommandLine>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>2</Order>
<CommandLine>CMD /C echo GG&gt;C:\Windows\LogOobeSystem.txt</CommandLine>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>3</Order>
<CommandLine>powershell -ExecutionPolicy Bypass -File c:\windows\FirstStartup.ps1</CommandLine>
</SynchronousCommand>
</FirstLogonCommands>
</component>
</settings>
</unattend>
'@
$specPass = @'
<settings pass="specialize">
<component name="Microsoft-Windows-SQMApi" 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">
<CEIPEnabled>0</CEIPEnabled>
</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">
<ConfigureChatAutoInstall>false</ConfigureChatAutoInstall>
</component>
</settings>
'@
if ((Test-CompatibleImage $imgVersion $([System.Version]::new(10,0,22000,1))) -eq $false)
{
# Replace the placeholder text with an empty string to make it valid for Windows 10 Setup
$unattend = $unattend.Replace("<#REPLACEME#>", "").Trim()
}
else
{
# Replace the placeholder text with the Specialize pass
$unattend = $unattend.Replace("<#REPLACEME#>", $specPass).Trim()
}
$unattend | Out-File -FilePath "$env:temp\unattend.xml" -Force -Encoding utf8
}
function New-CheckInstall {
# using here string to embedd firstrun
$checkInstall = @'
@echo off
if exist "C:\windows\cpu.txt" (
echo C:\windows\cpu.txt exists
) else (
echo C:\windows\cpu.txt does not exist
)
if exist "C:\windows\SerialNumber.txt" (
echo C:\windows\SerialNumber.txt exists
) else (
echo C:\windows\SerialNumber.txt does not exist
)
if exist "C:\unattend.xml" (
echo C:\unattend.xml exists
) else (
echo C:\unattend.xml does not exist
)
if exist "C:\Windows\Setup\Scripts\SetupComplete.cmd" (
echo C:\Windows\Setup\Scripts\SetupComplete.cmd exists
) else (
echo C:\Windows\Setup\Scripts\SetupComplete.cmd does not exist
)
if exist "C:\Windows\Panther\unattend.xml" (
echo C:\Windows\Panther\unattend.xml exists
) else (
echo C:\Windows\Panther\unattend.xml does not exist
)
if exist "C:\Windows\System32\Sysprep\unattend.xml" (
echo C:\Windows\System32\Sysprep\unattend.xml exists
) else (
echo C:\Windows\System32\Sysprep\unattend.xml does not exist
)
if exist "C:\Windows\FirstStartup.ps1" (
echo C:\Windows\FirstStartup.ps1 exists
) else (
echo C:\Windows\FirstStartup.ps1 does not exist
)
if exist "C:\Windows\winutil.ps1" (
echo C:\Windows\winutil.ps1 exists
) else (
echo C:\Windows\winutil.ps1 does not exist
)
if exist "C:\Windows\LogSpecialize.txt" (
echo C:\Windows\LogSpecialize.txt exists
) else (
echo C:\Windows\LogSpecialize.txt does not exist
)
if exist "C:\Windows\LogAuditUser.txt" (
echo C:\Windows\LogAuditUser.txt exists
) else (
echo C:\Windows\LogAuditUser.txt does not exist
)
if exist "C:\Windows\LogOobeSystem.txt" (
echo C:\Windows\LogOobeSystem.txt exists
) else (
echo C:\Windows\LogOobeSystem.txt does not exist
)
if exist "c:\windows\csup.txt" (
echo c:\windows\csup.txt exists
) else (
echo c:\windows\csup.txt does not exist
)
if exist "c:\windows\LogFirstRun.txt" (
echo c:\windows\LogFirstRun.txt exists
) else (
echo c:\windows\LogFirstRun.txt does not exist
)
'@
$checkInstall | Out-File -FilePath "$env:temp\checkinstall.cmd" -Force -Encoding Ascii
}
function New-FirstRun {
# using here string to embedd firstrun
$firstRun = @'
# Set the global error action preference to continue
$ErrorActionPreference = "Continue"
function Remove-RegistryValue
{
param (
[Parameter(Mandatory = $true)]
[string]$RegistryPath,
[Parameter(Mandatory = $true)]
[string]$ValueName
)
# Check if the registry path exists
if (Test-Path -Path $RegistryPath)
{
$registryValue = Get-ItemProperty -Path $RegistryPath -Name $ValueName -ErrorAction SilentlyContinue
# Check if the registry value exists
if ($registryValue)
{
# Remove the registry value
Remove-ItemProperty -Path $RegistryPath -Name $ValueName -Force
Write-Host "Registry value '$ValueName' removed from '$RegistryPath'."
}
else
{
Write-Host "Registry value '$ValueName' not found in '$RegistryPath'."
}
}
else
{
Write-Host "Registry path '$RegistryPath' not found."
}
}
function Stop-UnnecessaryServices
{
$servicesToExclude = @(
"AudioSrv",
"AudioEndpointBuilder",
"BFE",
"BITS",
"BrokerInfrastructure",
"CDPSvc",
"CDPUserSvc_dc2a4",
"CoreMessagingRegistrar",
"CryptSvc",
"DPS",
"DcomLaunch",
"Dhcp",
"DispBrokerDesktopSvc",
"Dnscache",
"DoSvc",
"DusmSvc",
"EventLog",
"EventSystem",
"FontCache",
"LSM",
"LanmanServer",
"LanmanWorkstation",
"MapsBroker",
"MpsSvc",
"OneSyncSvc_dc2a4",
"Power",
"ProfSvc",
"RpcEptMapper",
"RpcSs",
"SCardSvr",
"SENS",
"SamSs",
"Schedule",
"SgrmBroker",
"ShellHWDetection",
"Spooler",
"SysMain",
"SystemEventsBroker",
"TextInputManagementService",
"Themes",
"TrkWks",
"UserManager",
"VGAuthService",
"VMTools",
"WSearch",
"Wcmsvc",
"WinDefend",
"Winmgmt",
"WlanSvc",
"WpnService",
"WpnUserService_dc2a4",
"cbdhsvc_dc2a4",
"edgeupdate",
"gpsvc",
"iphlpsvc",
"mpssvc",
"nsi",
"sppsvc",
"tiledatamodelsvc",
"vm3dservice",
"webthreatdefusersvc_dc2a4",
"wscsvc"
)
$runningServices = Get-Service | Where-Object { $servicesToExclude -notcontains $_.Name }
foreach($service in $runningServices)
{
Stop-Service -Name $service.Name -PassThru
Set-Service $service.Name -StartupType Manual
"Stopping service $($service.Name)" | Out-File -FilePath c:\windows\LogFirstRun.txt -Append -NoClobber
}
}
"FirstStartup has worked" | Out-File -FilePath c:\windows\LogFirstRun.txt -Append -NoClobber
$Theme = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize"
Set-ItemProperty -Path $Theme -Name AppsUseLightTheme -Value 1
Set-ItemProperty -Path $Theme -Name SystemUsesLightTheme -Value 1
# figure this out later how to set updates to security only
#Import-Module -Name PSWindowsUpdate;
#Stop-Service -Name wuauserv
#Set-WUSettings -MicrosoftUpdateEnabled -AutoUpdateOption 'Never'
#Start-Service -Name wuauserv
Stop-UnnecessaryServices
$taskbarPath = "$env:AppData\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar"
# Delete all files on the Taskbar
Get-ChildItem -Path $taskbarPath -File | Remove-Item -Force
Remove-RegistryValue -RegistryPath "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Taskband" -ValueName "FavoritesRemovedChanges"
Remove-RegistryValue -RegistryPath "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Taskband" -ValueName "FavoritesChanges"
Remove-RegistryValue -RegistryPath "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Taskband" -ValueName "Favorites"
# Stop-Process -Name explorer -Force
$process = Get-Process -Name "explorer"
Stop-Process -InputObject $process
# Wait for the process to exit
Wait-Process -InputObject $process
Start-Sleep -Seconds 3
# Delete Edge Icon from the desktop
$edgeShortcutFiles = Get-ChildItem -Path $desktopPath -Filter "*Edge*.lnk"
# Check if Edge shortcuts exist on the desktop
if ($edgeShortcutFiles)
{
foreach ($shortcutFile in $edgeShortcutFiles)
{
# Remove each Edge shortcut
Remove-Item -Path $shortcutFile.FullName -Force
Write-Host "Edge shortcut '$($shortcutFile.Name)' removed from the desktop."
}
}
Remove-Item -Path "$env:USERPROFILE\Desktop\*.lnk"
Remove-Item -Path "C:\Users\Default\Desktop\*.lnk"
# ************************************************
# Create WinUtil shortcut on the desktop
#
$desktopPath = "$($env:USERPROFILE)\Desktop"
# Specify the target PowerShell command
$command = "powershell.exe -NoProfile -ExecutionPolicy Bypass -Command 'irm https://christitus.com/win | iex'"
# Specify the path for the shortcut
$shortcutPath = Join-Path $desktopPath 'winutil.lnk'
# Create a shell object
$shell = New-Object -ComObject WScript.Shell
# Create a shortcut object
$shortcut = $shell.CreateShortcut($shortcutPath)
if (Test-Path -Path "c:\Windows\cttlogo.png")
{
$shortcut.IconLocation = "c:\Windows\cttlogo.png"
}
# Set properties of the shortcut
$shortcut.TargetPath = "powershell.exe"
$shortcut.Arguments = "-NoProfile -ExecutionPolicy Bypass -Command `"$command`""
# Save the shortcut
$shortcut.Save()
# Make the shortcut have 'Run as administrator' property on
$bytes = [System.IO.File]::ReadAllBytes($shortcutPath)
# Set byte value at position 0x15 in hex, or 21 in decimal, from the value 0x00 to 0x20 in hex
$bytes[0x15] = $bytes[0x15] -bor 0x20
[System.IO.File]::WriteAllBytes($shortcutPath, $bytes)
Write-Host "Shortcut created at: $shortcutPath"
#
# Done create WinUtil shortcut on the desktop
# ************************************************
Start-Process explorer
'@
$firstRun | Out-File -FilePath "$env:temp\FirstStartup.ps1" -Force
}