2024-02-07 11:18:04 -06:00
function Test-CompatibleImage () {
2024-01-30 12:36:38 -06:00
<#
. SYNOPSIS
2024-03-21 16:23:24 -07:00
Checks the version of a Windows image and determines whether or not it is compatible with a specific feature depending on a desired version
2024-01-30 12:36:38 -06:00
2024-03-21 16:23:24 -07:00
.PARAMETER Name
imgVersion - The version of the Windows image
desiredVersion - The version to compare the image version with
2024-01-30 12:36:38 -06:00
#>
param
(
2024-03-21 16:23:24 -07:00
[ Parameter ( Mandatory = $true , Position = 0 )] [ string ] $imgVersion ,
[ Parameter ( Mandatory = $true , Position = 1 )] [ Version ] $desiredVersion
2024-01-30 12:36:38 -06:00
)
try {
$version = [ Version ] $imgVersion
2024-03-21 16:23:24 -07:00
return $version -ge $desiredVersion
2024-01-30 12:36:38 -06:00
} catch {
return $False
}
}
2024-01-12 00:34:41 -06:00
2023-11-28 16:11:11 -06:00
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
#>
2024-04-20 16:38:43 -05:00
$featlist = ( Get-WindowsOptionalFeature -Path $scratchDir ). FeatureName
2023-11-28 16:11:11 -06:00
if ( $dumpFeatures )
{
2024-04-20 16:38:43 -05:00
$featlist > allfeaturesdump . txt
2023-11-28 16:11:11 -06:00
}
2024-04-20 16:38:43 -05:00
$featlist = $featlist | Where-Object {
2023-11-28 16:11:11 -06:00
$_ -NotLike "*Printing*" -AND
$_ -NotLike "*TelnetClient*" -AND
$_ -NotLike "*PowerShell*" -AND
2024-04-20 16:38:43 -05:00
$_ -NotLike "*NetFx*" -AND
$_ -NotLike "*Media*" -AND
$_ -NotLike "*NFS*"
2023-11-28 16:11:11 -06:00
}
2024-04-20 16:38:43 -05:00
if ( $keepDefender ) { $featlist = $featlist | Where-Object { $_ -NotLike "*Defender*" }}
2023-11-28 16:11:11 -06:00
2024-04-20 16:38:43 -05:00
foreach ( $feature in $featlist )
2023-11-28 16:11:11 -06:00
{
$status = "Removing feature $feature "
2024-04-20 16:38:43 -05:00
Write-Progress -Activity "Removing features" -Status $status -PercentComplete ( $counter ++/ $featlist . Count * 100 )
2023-11-28 16:11:11 -06:00
Write-Debug "Removing feature $feature "
2024-04-20 16:38:43 -05:00
Disable-WindowsOptionalFeature -Path " $scratchDir " -FeatureName $feature -Remove -ErrorAction SilentlyContinue -NoRestart
2023-11-28 16:11:11 -06:00
}
Write-Progress -Activity "Removing features" -Status "Ready" -Completed
2024-04-20 16:38:43 -05:00
Write-Host "You can re-enable the disabled features at any time, using either Windows Update or the SxS folder in <installation media>\Sources."
2023-11-28 16:11:11 -06:00
}
function Remove-Packages
{
2024-04-20 16:38:43 -05:00
$pkglist = ( Get-WindowsPackage -Path " $scratchDir " ). PackageName
2023-11-28 16:11:11 -06:00
2024-04-20 16:38:43 -05:00
$pkglist = $pkglist | Where-Object {
2023-11-28 16:11:11 -06:00
$_ -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
2024-06-29 01:15:39 +03:00
$_ -NotLike "*UI.XaML*"
}
2023-11-28 16:11:11 -06:00
2024-04-20 16:38:43 -05:00
foreach ( $pkg in $pkglist )
2023-11-28 16:11:11 -06:00
{
2024-04-20 16:38:43 -05:00
try {
$status = "Removing $pkg "
Write-Progress -Activity "Removing Apps" -Status $status -PercentComplete ( $counter ++/ $pkglist . Count * 100 )
Remove-WindowsPackage -Path " $scratchDir " -PackageName $pkg -NoRestart -ErrorAction SilentlyContinue
}
catch {
# This can happen if the package that is being removed is a permanent one, like FodMetadata
Write-Host "Could not remove OS package $( $pkg ) "
continue
}
2023-11-28 16:11:11 -06:00
}
Write-Progress -Activity "Removing Apps" -Status "Ready" -Completed
}
2024-01-03 09:49:23 -06:00
function Remove-ProvisionedPackages([switch ] $keepSecurity = $false )
2023-11-28 16:11:11 -06:00
{
2024-01-03 09:49:23 -06:00
<#
. 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
#>
2023-11-28 16:11:11 -06:00
$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
2024-06-29 01:15:39 +03:00
$_ . PackageName -NotLike "*Foundation*"
}
2024-01-02 15:45:06 -06:00
if ($?)
{
2024-01-03 09:49:23 -06:00
if ( $keepSecurity ) { $appxProvisionedPackages = $appxProvisionedPackages | Where-Object { $_ . PackageName -NotLike "*SecHealthUI*" }}
2024-01-02 15:45:06 -06:00
$counter = 0
foreach ( $appx in $appxProvisionedPackages )
{
$status = "Removing Provisioned $( $appx . PackageName ) "
Write-Progress -Activity "Removing Provisioned Apps" -Status $status -PercentComplete ( $counter ++/ $appxProvisionedPackages . Count * 100 )
2024-06-28 16:42:48 +02:00
try {
Remove-AppxProvisionedPackage -Path $scratchDir -PackageName $appx . PackageName -ErrorAction SilentlyContinue
}
catch {
Write-Host "Application $( $appx . PackageName ) could not be removed"
continue
2024-06-29 01:15:39 +03:00
}
2024-01-02 15:45:06 -06:00
}
Write-Progress -Activity "Removing Provisioned Apps" -Status "Ready" -Completed
}
else
{
Write-Host "Could not get Provisioned App information. Skipping process..."
}
2023-11-28 16:11:11 -06:00
}
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 / 1 MB), ( $totalSize / 1 MB))
}
2024-03-28 12:39:23 -07:00
Write-Host "File copied to Ventoy drive $( $volume . DriveLetter ) "
2023-11-28 16:11:11 -06:00
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
2023-12-19 13:55:55 -06:00
Write-Host "[INFO] In Your local takeown expects ' $( $yesNo [ 0 ]) ' as a Yes answer."
2023-11-28 16:11:11 -06:00
# 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
2024-06-29 01:15:39 +03:00
# $directoryPath = "$($scratchDir)\Windows\System32\WebThreatDefSvc"
2023-11-28 16:11:11 -06:00
# 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
2024-06-29 01:15:39 +03:00
2023-11-28 16:11:11 -06:00
$itemsToDelete = [ System.Collections.ArrayList ]:: new ()
if ( $mask -eq "" )
{
Write-Debug "Adding $( $pathToDelete ) to array."
[ void ] $itemsToDelete . Add ( $pathToDelete )
}
2024-06-29 01:15:39 +03:00
else
2023-11-28 16:11:11 -06:00
{
2024-06-29 01:15:39 +03:00
Write-Debug "Adding $( $pathToDelete ) to array and mask is $( $mask ) "
2023-11-28 16:11:11 -06:00
if ( $Directory ) { $itemsToDelete = Get-ChildItem $pathToDelete -Include $mask -Recurse -Directory }
else { $itemsToDelete = Get-ChildItem $pathToDelete -Include $mask -Recurse }
}
foreach ( $itemToDelete in $itemsToDelete )
{
2024-03-21 16:23:24 -07:00
$status = "Deleting $( $itemToDelete ) "
2023-11-28 16:11:11 -06:00
Write-Progress -Activity "Removing Items" -Status $status -PercentComplete ( $counter ++/ $itemsToDelete . Count * 100 )
2024-06-29 01:15:39 +03:00
if ( Test-Path -Path " $( $itemToDelete ) " -PathType Container )
2023-11-28 16:11:11 -06:00
{
$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>
2024-01-15 11:32:19 -06:00
# 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>
2023-11-28 16:11:11 -06:00
$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">
2024-03-21 16:23:24 -07:00
<#REPLACEME#>
2023-11-28 16:11:11 -06:00
<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>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>c:\windows\csup.txt</CommandLine>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>2</Order>
<CommandLine>CMD /C echo GG>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>
'@
2024-03-21 16:23:24 -07:00
$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 ()
}
2024-03-28 12:39:23 -07:00
$unattend | Out-File -FilePath " $env:temp \unattend.xml" -Force -Encoding utf8
2023-11-28 16:11:11 -06:00
}
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,
2024-06-29 01:15:39 +03:00
2023-11-28 16:11:11 -06:00
[Parameter(Mandatory = $true)]
[string]$ValueName
)
2024-06-29 01:15:39 +03:00
2023-11-28 16:11:11 -06:00
# Check if the registry path exists
if (Test-Path -Path $RegistryPath)
{
$registryValue = Get-ItemProperty -Path $RegistryPath -Name $ValueName -ErrorAction SilentlyContinue
2024-06-29 01:15:39 +03:00
2023-11-28 16:11:11 -06:00
# 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."
}
}
2024-06-29 01:15:39 +03:00
2023-11-28 16:11:11 -06:00
function Stop-UnnecessaryServices
{
2024-01-12 00:34:41 -06:00
$servicesToExclude = @(
2023-11-28 16:11:11 -06:00
"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"
2024-06-29 01:15:39 +03:00
)
2024-01-12 00:34:41 -06:00
$runningServices = Get-Service | Where-Object { $servicesToExclude -notcontains $_.Name }
foreach($service in $runningServices)
2023-11-28 16:11:11 -06:00
{
2024-01-12 00:34:41 -06:00
Stop-Service -Name $service.Name -PassThru
2023-11-28 16:11:11 -06:00
Set-Service $service.Name -StartupType Manual
"Stopping service $($service.Name)" | Out-File -FilePath c:\windows\LogFirstRun.txt -Append -NoClobber
}
}
2024-06-29 01:15:39 +03:00
2023-11-28 16:11:11 -06:00
"FirstStartup has worked" | Out-File -FilePath c:\windows\LogFirstRun.txt -Append -NoClobber
2024-06-29 01:15:39 +03:00
2023-11-28 16:11:11 -06:00
$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
2024-06-29 01:15:39 +03:00
#Import-Module -Name PSWindowsUpdate;
2023-11-28 16:11:11 -06:00
#Stop-Service -Name wuauserv
#Set-WUSettings -MicrosoftUpdateEnabled -AutoUpdateOption 'Never'
#Start-Service -Name wuauserv
2024-06-29 01:15:39 +03:00
2023-11-28 16:11:11 -06:00
Stop-UnnecessaryServices
2024-06-29 01:15:39 +03:00
2023-11-28 16:11:11 -06:00
$taskbarPath = "$env:AppData\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar"
2024-06-29 01:15:39 +03:00
# Delete all files on the Taskbar
2023-11-28 16:11:11 -06:00
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"
2024-06-29 01:15:39 +03:00
2023-11-28 16:11:11 -06:00
# 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
2024-06-29 01:15:39 +03:00
if ($edgeShortcutFiles)
2023-11-28 16:11:11 -06:00
{
2024-06-29 01:15:39 +03:00
foreach ($shortcutFile in $edgeShortcutFiles)
2023-11-28 16:11:11 -06:00
{
# 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
2024-06-29 01:15:39 +03:00
2023-11-28 16:11:11 -06:00
# Create a shortcut object
$shortcut = $shell.CreateShortcut($shortcutPath)
if (Test-Path -Path "c:\Windows\cttlogo.png")
{
$shortcut.IconLocation = "c:\Windows\cttlogo.png"
}
2024-06-29 01:15:39 +03:00
2023-11-28 16:11:11 -06:00
# Set properties of the shortcut
$shortcut.TargetPath = "powershell.exe"
$shortcut.Arguments = "-NoProfile -ExecutionPolicy Bypass -Command `"$command`""
# Save the shortcut
$shortcut.Save()
2024-06-29 01:15:39 +03:00
2024-03-21 16:23:24 -07:00
# 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)
2024-06-29 01:15:39 +03:00
2023-11-28 16:11:11 -06:00
Write-Host "Shortcut created at: $shortcutPath"
2024-06-29 01:15:39 +03:00
#
2023-11-28 16:11:11 -06:00
# Done create WinUtil shortcut on the desktop
# ************************************************
Start-Process explorer
2024-06-29 01:15:39 +03:00
2023-11-28 16:11:11 -06:00
'@
2024-06-29 01:15:39 +03:00
$firstRun | Out-File -FilePath " $env:temp \FirstStartup.ps1" -Force
2024-03-21 16:23:24 -07:00
}