<# .SYNOPSIS Sophia Script is a PowerShell module for Windows 10 & Windows 11 fine-tuning and automating the routine tasks Version: v5.17.1 Date: 03.06.2023 Copyright (c) 2014—2023 farag Copyright (c) 2019—2023 farag & Inestic Thanks to all https://forum.ru-board.com members involved .NOTES Supported Windows 10 version Version: 21H2 Build: 19044.2965+ Edition: Enterprise LTSC 2021 Architecture: x64 .LINK GitHub https://github.com/farag2/Sophia-Script-for-Windows .LINK Telegram https://t.me/sophianews https://t.me/sophia_chat .LINK Discord https://discord.gg/sSryhaEv79 .NOTES https://forum.ru-board.com/topic.cgi?forum=62&topic=30617#15 https://habr.com/company/skillfactory/blog/553800/ https://forums.mydigitallife.net/threads/powershell-windows-10-sophia-script.81675/ https://www.reddit.com/r/PowerShell/comments/go2n5v/powershell_script_setup_windows_10/ .LINK Authors https://github.com/farag2 https://github.com/Inestic #> #region Checks function Checks { param ( [Parameter(Mandatory = $false)] [switch] $Warning ) Set-StrictMode -Version Latest # Сlear the $Error variable $Global:Error.Clear() # Unblock all files in the script folder by removing the Zone.Identifier alternate data stream with a value of "3" Get-ChildItem -Path $PSScriptRoot\..\ -File -Recurse -Force | Unblock-File [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 # Progress bar can significantly impact cmdlet performance # https://github.com/PowerShell/PowerShell/issues/2138 $ProgressPreference = "SilentlyContinue" # Extract strings from %SystemRoot%\System32\shell32.dll using its' number $Signature = @{ Namespace = "WinAPI" Name = "GetStr" Language = "CSharp" UsingNamespace = "System.Text" MemberDefinition = @" [DllImport("kernel32.dll", CharSet = CharSet.Auto)] public static extern IntPtr GetModuleHandle(string lpModuleName); [DllImport("user32.dll", CharSet = CharSet.Auto)] internal static extern int LoadString(IntPtr hInstance, uint uID, StringBuilder lpBuffer, int nBufferMax); public static string GetString(uint strId) { IntPtr intPtr = GetModuleHandle("shell32.dll"); StringBuilder sb = new StringBuilder(255); LoadString(intPtr, strId, sb, sb.Capacity); return sb.ToString(); } "@ } if (-not ("WinAPI.GetStr" -as [type])) { Add-Type @Signature } # Detect the OS bitness if (-not [System.Environment]::Is64BitOperatingSystem) { Write-Warning -Message $Localization.UnsupportedOSBitness Start-Process -FilePath "https://t.me/sophia_chat" Start-Process -FilePath "https://discord.gg/sSryhaEv79" exit } # Detect the OS build version switch (((Get-CimInstance -ClassName CIM_OperatingSystem).BuildNumber -eq 19044) -and ((Get-WindowsEdition -Online).Edition -match "EnterpriseS")) { $true { if ((Get-ItemPropertyValue -Path "HKLM:\SOFTWARE\Microsoft\Windows nt\CurrentVersion" -Name UBR) -lt 2965) { # Check whether the OS minor build version is 2965 minimum # https://support.microsoft.com/en-us/help/5018682 $CurrentBuild = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows nt\CurrentVersion" -Name CurrentBuild $UBR = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows nt\CurrentVersion" -Name UBR Write-Warning -Message ($Localization.UpdateWarning -f $CurrentBuild.CurrentBuild, $UBR.UBR) Start-Process -FilePath "https://t.me/sophia_chat" Start-Process -FilePath "https://discord.gg/sSryhaEv79" Start-Process -FilePath "https://github.com/farag2/Sophia-Script-for-Windows#system-requirements" # Enable receiving updates for other Microsoft products when you update Windows (New-Object -ComObject Microsoft.Update.ServiceManager).AddService2("7971f918-a847-4430-9279-4a52d1efe18d", 7, "") Start-Sleep -Seconds 1 # Open the "Windows Update" page Start-Process -FilePath "ms-settings:windowsupdate" # Check for updates Start-Process -FilePath "ms-settings:windowsupdate-action" Start-Sleep -Seconds 1 # Trigger Windows Update for detecting new updates (New-Object -ComObject Microsoft.Update.AutoUpdate).DetectNow() exit } } $false { Write-Warning -Message $Localization.UnsupportedOSBuild Start-Process -FilePath "https://t.me/sophia_chat" Start-Process -FilePath "https://discord.gg/sSryhaEv79" Start-Process -FilePath "https://github.com/farag2/Sophia-Script-for-Windows#system-requirements" exit } } # Check the language mode if ($ExecutionContext.SessionState.LanguageMode -ne "FullLanguage") { Write-Warning -Message $Localization.UnsupportedLanguageMode Start-Process -FilePath "https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_language_modes" Start-Process -FilePath "https://t.me/sophia_chat" Start-Process -FilePath "https://discord.gg/sSryhaEv79" exit } # Check whether the logged-in user is an admin $CurrentUserName = (Get-Process -Id $PID -IncludeUserName).UserName | Split-Path -Leaf $CurrentSessionId = (Get-Process -Id $PID -IncludeUserName).SessionId $LoginUserName = (Get-Process -IncludeUserName | Where-Object -FilterScript {($_.ProcessName -eq "explorer") -and ($_.SessionId -eq $CurrentSessionId)}).UserName | Select-Object -First 1 | Split-Path -Leaf if ($CurrentUserName -ne $LoginUserName) { Write-Warning -Message $Localization.LoggedInUserNotAdmin Start-Process -FilePath "https://t.me/sophia_chat" Start-Process -FilePath "https://discord.gg/sSryhaEv79" exit } # Check whether the script was run via PowerShell 5.1 if ($PSVersionTable.PSVersion.Major -ne 5) { Write-Warning -Message ($Localization.UnsupportedPowerShell -f $PSVersionTable.PSVersion.Major, $PSVersionTable.PSVersion.Minor) Start-Process -FilePath "https://t.me/sophia_chat" Start-Process -FilePath "https://discord.gg/sSryhaEv79" exit } # Check whether the script was run in PowerShell ISE or VS Code if (($Host.Name -match "ISE") -or ($env:TERM_PROGRAM -eq "vscode")) { Write-Warning -Message ($Localization.UnsupportedHost -f $Host.Name.replace("Host", "")) Start-Process -FilePath "https://t.me/sophia_chat" Start-Process -FilePath "https://discord.gg/sSryhaEv79" exit } # Check whether Windows was broken by 3rd party harmful tweakers and trojans $Tweakers = @{ # https://github.com/Sycnex/Windows10Debloater Windows10Debloater = "$env:SystemDrive\Temp\Windows10Debloater" # https://github.com/Fs00/Win10BloatRemover Win10BloatRemover = "$env:TEMP\.net\Win10BloatRemover" # https://github.com/arcadesdude/BRU "Bloatware Removal" = "$env:SystemDrive\BRU\Bloatware-Removal*.log" # https://www.youtube.com/GHOSTSPECTRE "Ghost Toolbox" = "$env:SystemRoot\System32\migwiz\dlmanifests\run.ghost.cmd" # https://github.com/hellzerg/optimizer Optimizer = "$(Get-ItemPropertyValue -Path `"HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders`" -Name `"{374DE290-123F-4565-9164-39C4925E467B}`")\OptimizerDownloads" # https://win10tweaker.ru "Win 10 Tweaker" = "HKCU:\Software\Win 10 Tweaker" # https://forum.ru-board.com/topic.cgi?forum=5&topic=50519 "Modern Tweaker" = "Registry::HKEY_CLASSES_ROOT\CLSID\{645FF040-5081-101B-9F08-00AA002F954E}\shell\Modern Cleaner" # https://boosterx.ru BoosterX = "$env:ProgramFiles\GameModeX\GameModeX.exe" # https://forum.ru-board.com/topic.cgi?forum=5&topic=14285&start=400#11 "Defender Control" = "$env:APPDATA\Defender Control" # https://forum.ru-board.com/topic.cgi?forum=5&topic=14285&start=260#12 "Defender Switch" = "$env:ProgramData\DSW" # https://revi.cc/revios/download "Revision Tool" = "${env:ProgramFiles(x86)}\Revision Tool" # https://www.youtube.com/watch?v=L0cj_I6OF2o "WinterOS Tweaker" = "$env:SystemRoot\WinterOS*" # https://github.com/ThePCDuke/WinCry WinCry = "$env:SystemRoot\TempCleaner.exe" } foreach ($Tweaker in $Tweakers.Keys) { if (Test-Path -Path $Tweakers[$Tweaker]) { if ($Tweakers[$Tweaker] -eq "HKCU:\Software\Win 10 Tweaker") { Write-Warning -Message $Localization.Win10TweakerWarning Start-Process -FilePath "https://youtu.be/na93MS-1EkM" Start-Process -FilePath "https://pikabu.ru/story/byekdor_v_win_10_tweaker_ili_sovremennyie_metodyi_borbyi_s_piratstvom_8227558" Start-Process -FilePath "https://t.me/sophia_chat" Start-Process -FilePath "https://discord.gg/sSryhaEv79" exit } Write-Warning -Message ($Localization.TweakerWarning -f $Tweaker) Start-Process -FilePath "https://t.me/sophia_chat" Start-Process -FilePath "https://discord.gg/sSryhaEv79" exit } } # Flibustier custom Windows image if (Get-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\.NETFramework\Performance -Name *flibustier) { Write-Warning -Message ($Localization.TweakerWarning -f "flblauncher") Start-Process -FilePath "https://t.me/sophia_chat" Start-Process -FilePath "https://discord.gg/sSryhaEv79" exit } # Check whether LGPO.exe exists in the bin folder if (-not (Test-Path -Path "$PSScriptRoot\..\bin\LGPO.exe")) { Write-Warning -Message $Localization.Bin Start-Process -FilePath "https://github.com/farag2/Sophia-Script-for-Windows/releases/latest" Start-Process -FilePath "https://t.me/sophia_chat" Start-Process -FilePath "https://discord.gg/sSryhaEv79" exit } # Check for a pending reboot $PendingActions = @( # CBS pending "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending", "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootInProgress", "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\PackagesPending", # Windows Update pending "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\PostRebootReporting", "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired" ) if (($PendingActions | Test-Path) -contains $true) { Write-Warning -Message $Localization.RebootPending Start-Process -FilePath "https://t.me/sophia_chat" Start-Process -FilePath "https://discord.gg/sSryhaEv79" exit } # Check if the current module version is the latest one try { # Check the internet connection $Parameters = @{ Uri = "https://www.google.com" Method = "Head" DisableKeepAlive = $true UseBasicParsing = $true } if (-not (Invoke-WebRequest @Parameters).StatusDescription) { return } try { # https://github.com/farag2/Sophia-Script-for-Windows/blob/master/sophia_script_versions.json $Parameters = @{ Uri = "https://raw.githubusercontent.com/farag2/Sophia-Script-for-Windows/master/sophia_script_versions.json" Verbose = $true UseBasicParsing = $true } $LatestRelease = (Invoke-RestMethod @Parameters).Sophia_Script_Windows_10_LTSC2021 $CurrentRelease = (Get-Module -Name Sophia).Version.ToString() if ([System.Version]$LatestRelease -gt [System.Version]$CurrentRelease) { Write-Warning -Message $Localization.UnsupportedRelease Start-Process -FilePath "https://github.com/farag2/Sophia-Script-for-Windows/releases/latest" Start-Process -FilePath "https://t.me/sophia_chat" Start-Process -FilePath "https://discord.gg/sSryhaEv79" exit } } catch [System.Net.WebException] { Write-Warning -Message ($Localization.NoResponse -f "https://github.com") Write-Error -Message ($Localization.NoResponse -f "https://github.com") -ErrorAction SilentlyContinue } } catch [System.Net.WebException] { Write-Warning -Message $Localization.NoInternetConnection Write-Error -Message $Localization.NoInternetConnection -ErrorAction SilentlyContinue } #region Defender checks # Check whether necessary Microsoft Defender components exists $Files = @( "$env:SystemRoot\system32\smartscreen.exe", "$env:SystemRoot\system32\SecurityHealthSystray.exe" ) foreach ($File in $Files) { if (-not (Test-Path -Path $File)) { Write-Warning -Message ($Localization.WindowsComponentBroken -f $File) Start-Process -FilePath "https://github.com/farag2/Sophia-Script-for-Windows/releases/latest" Start-Process -FilePath "https://t.me/sophia_chat" Start-Process -FilePath "https://discord.gg/sSryhaEv79" exit } } # Checking whether WMI is corrupted try { Get-CimInstance -ClassName MSFT_MpComputerStatus -Namespace root/Microsoft/Windows/Defender -ErrorAction Stop | Out-Null } catch [Microsoft.Management.Infrastructure.CimException] { # Provider Load Failure exception Write-Warning -Message $Global:Error.Exception.Message | Select-Object -First 1 Write-Warning -Message ($Localization.WindowsComponentBroken -f "Microsoft Defender") Start-Process -FilePath "https://t.me/sophia_chat" Start-Process -FilePath "https://discord.gg/sSryhaEv79" exit } # Check Microsoft Defender state if ($null -eq (Get-CimInstance -Namespace root/SecurityCenter2 -ClassName AntiVirusProduct -ErrorAction Ignore)) { Write-Warning -Message ($Localization.WindowsComponentBroken -f "Microsoft Defender") Start-Process -FilePath "https://t.me/sophia_chat" Start-Process -FilePath "https://discord.gg/sSryhaEv79" exit } # Check Microsoft Defender state $productState = (Get-CimInstance -Namespace root/SecurityCenter2 -ClassName Antivirusproduct | Where-Object -FilterScript {$_.instanceGuid -eq "{D68DDC3A-831F-4fae-9E44-DA132C1ACF46}"}).productState $DefenderState = ('0x{0:x}' -f $productState).Substring(3, 2) if ($DefenderState -notmatch "00|01") { $Script:DefenderproductState = $true } else { $Script:DefenderproductState = $false } # Checking services try { $Services = Get-Service -Name Windefend, SecurityHealthService, wscsvc -ErrorAction Stop } catch [Microsoft.PowerShell.Commands.ServiceCommandException] { Write-Warning -Message ($Localization.WindowsComponentBroken -f "Microsoft Defender") Start-Process -FilePath "https://t.me/sophia_chat" Start-Process -FilePath "https://discord.gg/sSryhaEv79" exit } $Script:DefenderServices = ($Services | Where-Object -FilterScript {$_.Status -ne "running"} | Measure-Object).Count -lt $Services.Count # Specify whether Antispyware protection is enabled if ((Get-CimInstance -ClassName MSFT_MpComputerStatus -Namespace root/Microsoft/Windows/Defender).AntispywareEnabled) { $Script:DefenderAntispywareEnabled = $true } else { $Script:DefenderAntispywareEnabled = $false } # https://docs.microsoft.com/en-us/graph/api/resources/intune-devices-windowsdefenderproductstatus?view=graph-rest-beta try { if ($Script:DefenderproductState) { if ((Get-CimInstance -ClassName MSFT_MpComputerStatus -Namespace root/Microsoft/Windows/Defender).ProductStatus -eq 1) { $Script:DefenderProductStatus = $false } else { $Script:DefenderProductStatus = $true } } else { $Script:DefenderProductStatus = $false } } catch [System.Management.Automation.PropertyNotFoundException] { Write-Warning -Message $Localization.UpdateDefender Start-Process -FilePath "https://t.me/sophia_chat" Start-Process -FilePath "https://discord.gg/sSryhaEv79" # Enable receiving updates for other Microsoft products when you update Windows (New-Object -ComObject Microsoft.Update.ServiceManager).AddService2("7971f918-a847-4430-9279-4a52d1efe18d", 7, "") Start-Sleep -Seconds 1 # Open the "Windows Update" page Start-Process -FilePath "ms-settings:windowsupdate" # Check for updates Start-Process -FilePath "ms-settings:windowsupdate-action" Start-Sleep -Seconds 1 # Trigger Windows Update for detecting new updates (New-Object -ComObject Microsoft.Update.AutoUpdate).DetectNow() exit } # https://docs.microsoft.com/en-us/graph/api/resources/intune-devices-windowsdefenderproductstatus?view=graph-rest-beta if ((Get-CimInstance -ClassName MSFT_MpComputerStatus -Namespace root/Microsoft/Windows/Defender).AMEngineVersion -eq "0.0.0.0") { $Script:DefenderAMEngineVersion = $false } else { $Script:DefenderAMEngineVersion = $true } # Check whether Microsoft Defender was turned off # Due to "Set-StrictMode -Version Latest" we have to use GetValue() if ([Microsoft.Win32.Registry]::GetValue("HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender", "DisableAntiSpyware", $false) -eq 1) { $Script:DisableAntiSpyware = $true } else { $Script:DisableAntiSpyware = $false } # Check whether real-time protection prompts for known malware detection # Due to "Set-StrictMode -Version Latest" we have to use GetValue() if ([Microsoft.Win32.Registry]::GetValue("HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection", "DisableRealtimeMonitoring", $false) -eq 1) { $Script:DisableRealtimeMonitoring = $true } else { $Script:DisableRealtimeMonitoring = $false } # Check whether behavior monitoring was disabled # Due to "Set-StrictMode -Version Latest" we have to use GetValue() if ([Microsoft.Win32.Registry]::GetValue("HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection", "DisableBehaviorMonitoring", $false) -eq 1) { $Script:DisableBehaviorMonitoring = $true } else { $Script:DisableBehaviorMonitoring = $false } if ($Script:DefenderproductState -and $Script:DefenderServices -and $Script:DefenderAntispywareEnabled -and $Script:DefenderAMEngineVersion -and (-not $Script:DisableAntiSpyware) -and (-not $Script:DisableRealtimeMonitoring) -and (-not $Script:DisableBehaviorMonitoring)) { # Defender is enabled $Script:DefenderEnabled = $true switch ((Get-MpPreference).EnableControlledFolderAccess) { "1" { Write-Warning -Message $Localization.ControlledFolderAccessDisabled # Turn off Controlled folder access to let the script proceed $Script:ControlledFolderAccess = $true Set-MpPreference -EnableControlledFolderAccess Disabled # Open "Ransomware protection" page Start-Process -FilePath windowsdefender://RansomwareProtection } "0" { $Script:ControlledFolderAccess = $false } } } #endregion Defender checks # Enable back the SysMain service if it was disabled by harmful tweakers if ((Get-Service -Name SysMain).Status -eq "Stopped") { Get-Service -Name SysMain | Set-Service -StartupType Automatic Get-Service -Name SysMain | Start-Service Start-Process -FilePath "https://www.outsidethebox.ms/19318/" } # Automatically manage paging file size for all drives if (-not (Get-CimInstance -ClassName CIM_ComputerSystem).AutomaticManagedPageFile) { Get-CimInstance -ClassName CIM_ComputerSystem | Set-CimInstance -Property @{AutomaticManagedPageFile = $true} } # Remove firewalled IP addresses that block Microsoft recourses added by harmful tweakers # https://wpd.app Get-NetFirewallRule | Where-Object -FilterScript {($_.DisplayName -match "Blocker MicrosoftTelemetry") -or ($_.DisplayName -match "Blocker MicrosoftExtra") -or ($_.DisplayName -match "windowsSpyBlocker")} | Remove-NetFirewallRule Write-Information -MessageData "" -InformationAction Continue # Extract the localized "Please wait..." string from shell32.dll Write-Verbose -Message ([WinAPI.GetStr]::GetString(12612)) -Verbose # Remove IP addresses from hosts file that block Microsoft recourses added by WindowsSpyBlocker # https://github.com/crazy-max/WindowsSpyBlocker try { # Check the internet connection $Parameters = @{ Uri = "https://www.google.com" Method = "Head" DisableKeepAlive = $true UseBasicParsing = $true } if (-not (Invoke-WebRequest @Parameters).StatusDescription) { return } try { # Check whether https://github.com is alive $Parameters = @{ Uri = "https://github.com" Method = "Head" DisableKeepAlive = $true UseBasicParsing = $true } if (-not (Invoke-WebRequest @Parameters).StatusDescription) { return } Clear-Variable -Name IPArray -ErrorAction Ignore # https://github.com/crazy-max/WindowsSpyBlocker/tree/master/data/hosts $Parameters = @{ Uri = "https://raw.githubusercontent.com/crazy-max/WindowsSpyBlocker/master/data/hosts/extra.txt" UseBasicParsing = $true Verbose = $true } $extra = (Invoke-WebRequest @Parameters).Content $Parameters = @{ Uri = "https://raw.githubusercontent.com/crazy-max/WindowsSpyBlocker/master/data/hosts/extra_v6.txt" UseBasicParsing = $true Verbose = $true } $extra_v6 = (Invoke-WebRequest @Parameters).Content $Parameters = @{ Uri = "https://raw.githubusercontent.com/crazy-max/WindowsSpyBlocker/master/data/hosts/spy.txt" UseBasicParsing = $true Verbose = $true } $spy = (Invoke-WebRequest @Parameters).Content $Parameters = @{ Uri = "https://raw.githubusercontent.com/crazy-max/WindowsSpyBlocker/master/data/hosts/spy_v6.txt" UseBasicParsing = $true Verbose = $true } $spy_v6 = (Invoke-WebRequest @Parameters).Content $Parameters = @{ Uri = "https://raw.githubusercontent.com/crazy-max/WindowsSpyBlocker/master/data/hosts/update.txt" UseBasicParsing = $true Verbose = $true } $update =(Invoke-WebRequest @Parameters).Content $Parameters = @{ Uri = "https://raw.githubusercontent.com/crazy-max/WindowsSpyBlocker/master/data/hosts/update_v6.txt" UseBasicParsing = $true Verbose = $true } $update_v6 = (Invoke-WebRequest @Parameters).Content $IPArray += $extra, $extra_v6, $spy, $spy_v6, $update, $update_v6 # Split the Array variable content $IPArray = $IPArray -split "`r?`n" | Where-Object -FilterScript {$_ -notmatch "#"} # Extract the localized "Please wait..." string from shell32.dll Write-Verbose -Message ([WinAPI.GetStr]::GetString(12612)) -Verbose # Check if hosts contains any of string from $IPArray array if ((Get-Content -Path "$env:SystemRoot\System32\drivers\etc\hosts" -Encoding Default -Force | ForEach-Object -Process { ($_ -ne "") -and (-not $_.StartsWith("#")) -and ($IPArray -split "`r?`n" | Select-String -Pattern $_.Trim()) }) -contains $true) { Write-Warning -Message ($Localization.TweakerWarning -f "WindowsSpyBlocker") # Clear hosts file $hosts = Get-Content -Path "$env:SystemRoot\System32\drivers\etc\hosts" -Encoding Default -Force $hosts | ForEach-Object -Process { if (($_ -ne "") -and (-not $_.StartsWith("#")) -and ($IPArray -split "`r?`n" | Select-String -Pattern $_.Trim())) { $hostsData = $_ $hosts = $hosts | Where-Object -FilterScript {$_ -notmatch $hostsData} } } $hosts | Set-Content -Path "$env:SystemRoot\System32\drivers\etc\hosts" -Encoding Default -Force Start-Process -FilePath notepad.exe "$env:SystemRoot\System32\drivers\etc\hosts" } } catch [System.Net.WebException] { Write-Warning -Message ($Localization.NoResponse -f "https://github.com") Write-Error -Message ($Localization.NoResponse -f "https://github.com") -ErrorAction SilentlyContinue Write-Error -Message ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -ErrorAction SilentlyContinue } } catch [System.Net.WebException] { Write-Warning -Message $Localization.NoInternetConnection Write-Error -Message $Localization.NoInternetConnection -ErrorAction SilentlyContinue Write-Error -Message ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -ErrorAction SilentlyContinue } # PowerShell 5.1 (7.3 too) interprets 8.3 file name literally, if an environment variable contains a non-latin word Get-ChildItem -Path "$env:TEMP\Computer.txt", "$env:TEMP\User.txt" -Force -ErrorAction Ignore | Remove-Item -Recurse -Force -ErrorAction Ignore # Save all opened folders in order to restore them after File Explorer restart $Script:OpenedFolders = {(New-Object -ComObject Shell.Application).Windows() | ForEach-Object -Process {$_.Document.Folder.Self.Path}}.Invoke() # Display a warning message about whether a user has customized the preset file if ($Warning) { # Get the name of a preset (e.g Sophia.ps1) regardless it was named $PresetName = Split-Path -Path ((Get-PSCallStack).Position | Where-Object -FilterScript {$_.File -match ".ps1"}).File -Leaf $Title = "" $Message = $Localization.CustomizationWarning -f $PresetName # Extract the localized "&Yes" string from shell32.dll $Yes = [WinAPI.GetStr]::GetString(33224) # Extract the localized "&No" string from shell32.dll $No = [WinAPI.GetStr]::GetString(33232) $Options = $No, $Yes $DefaultChoice = 0 $Result = $Host.UI.PromptForChoice($Title, $Message, $Options, $DefaultChoice) switch ($Result) { "0" { Invoke-Item -Path $PSScriptRoot\..\$PresetName Start-Sleep -Seconds 5 Start-Process -FilePath "https://github.com/farag2/Sophia-Script-for-Windows#how-to-use" Start-Process -FilePath "https://t.me/sophia_chat" Start-Process -FilePath "https://discord.gg/sSryhaEv79" exit } "1" { continue } } } } #endregion Checks #region Protection # Enable script logging. The log will be being recorded into the script root folder # To stop logging just close the console or type "Stop-Transcript" function Logging { $TranscriptFilename = "Log-$((Get-Date).ToString("dd.MM.yyyy-HH-mm"))" Start-Transcript -Path $PSScriptRoot\..\$TranscriptFilename.txt -Force } # Create a restore point for the system drive function CreateRestorePoint { $SystemDriveUniqueID = (Get-Volume | Where-Object -FilterScript {$_.DriveLetter -eq "$($env:SystemDrive[0])"}).UniqueID $SystemProtection = ((Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SPP\Clients" -ErrorAction Ignore)."{09F7EDC5-294E-4180-AF6A-FB0E6A0E9513}") | Where-Object -FilterScript {$_ -match [regex]::Escape($SystemDriveUniqueID)} $Script:ComputerRestorePoint = $false if ($null -eq $SystemProtection) { $ComputerRestorePoint = $true Enable-ComputerRestore -Drive $env:SystemDrive } # Never skip creating a restore point New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SystemRestore" -Name SystemRestorePointCreationFrequency -PropertyType DWord -Value 0 -Force Checkpoint-Computer -Description "Sophia Script for Windows 10" -RestorePointType MODIFY_SETTINGS # Revert the System Restore checkpoint creation frequency to 1440 minutes New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SystemRestore" -Name SystemRestorePointCreationFrequency -PropertyType DWord -Value 1440 -Force # Turn off System Protection for the system drive if it was turned off before without deleting the existing restore points if ($Script:ComputerRestorePoint) { Disable-ComputerRestore -Drive $env:SystemDrive } } #endregion Protection #region Additional functions <# .SYNOPSIS Create pre-configured text files for LGPO.exe tool .EXAMPLE Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\DataCollection -Name AllowTelemetry -Type DWORD -Value 0 .NOTES https://techcommunity.microsoft.com/t5/microsoft-security-baselines/lgpo-exe-local-group-policy-object-utility-v1-0/ba-p/701045 .NOTES Machine-wide user #> function script:Set-Policy { [CmdletBinding()] param ( [Parameter( Mandatory = $true, Position = 1 )] [string] [ValidateSet("Computer", "User")] $Scope, [Parameter( Mandatory = $true, Position = 2 )] [string] $Path, [Parameter( Mandatory = $true, Position = 3 )] [string] $Name, [Parameter( Mandatory = $true, Position = 4 )] [ValidateSet("DWORD", "SZ", "EXSZ", "CLEAR")] [string] $Type, [Parameter( Mandatory = $false, Position = 5 )] $Value ) if (-not (Test-Path -Path "$env:SystemRoot\System32\gpedit.msc")) { return } switch ($Type) { "CLEAR" { $Policy = @" $Scope $($Path) $($Name) $($Type)`n "@ } default { $Policy = @" $Scope $($Path) $($Name) $($Type):$($Value)`n "@ } } if ($Scope -eq "Computer") { $Path = "$env:TEMP\Computer.txt" } else { $Path = "$env:TEMP\User.txt" } Add-Content -Path $Path -Value $Policy -Encoding Default -Force } # Revert back removed or commented out "Checks" functions function script:AdditionalChecks { # Get the name of a preset (e.g Sophia.ps1) regardless it was named $PresetName = ((Get-PSCallStack).Position | Where-Object -FilterScript {$_.File -match ".ps1"}).File if (Select-String -Path $PresetName -Pattern Checks | Select-String -Pattern "{Checks}", "The mandatory checks" -NotMatch) { # The string exists and is commented if ((Select-String -Path $PresetName -Pattern Checks | Select-String -Pattern "{Checks}", "The mandatory checks" -NotMatch).Line.StartsWith("#") -eq $true) { $Host.UI.RawUI.WindowTitle = "Checks | $($PresetName)" $ReadFile = Get-Content -Path $PresetName -Encoding UTF8 # Calculate the string number to uncomment "Checks -Warning" $LineNumber = (Select-String -Path $PresetName -Pattern Checks | Select-String -Pattern "{Checks}", "The mandatory checks" -NotMatch).LineNumber # Get date from the required line to replace it with "Checks -Warning" $RequiredLine = (Get-Content -Path $PresetName -Encoding UTF8) | Where-Object -FilterScript {$_.ReadCount -eq $LineNumber} (Get-Content -Path $PresetName -Encoding UTF8).Replace($RequiredLine, "Checks -Warning") | Set-Content -Path $PresetName -Encoding UTF8 -Force Start-Process -FilePath "https://t.me/sophia_chat" Start-Process -FilePath "https://discord.gg/sSryhaEv79" exit } } else { $Host.UI.RawUI.WindowTitle = "Checks | $($PresetName)" $ReadFile = Get-Content -Path $PresetName -Encoding UTF8 # Calculate the string number to add after "Checks -Warning" $LineNumber = (Select-String -Path $PresetName -Pattern Import-LocalizedData).LineNumber # Array of a new file: content before $LineNumber (including $LineNumber), new added string, the rest data of file $UpdatedFile = @($ReadFile[0..($LineNumber - 1)], "`nChecks -Warning", $ReadFile[$LineNumber..($ReadFile.Length + 1)]) Set-Content -Path $PresetName -Value $UpdatedFile -Encoding UTF8 -Force Start-Process -FilePath "https://t.me/sophia_chat" Start-Process -FilePath "https://discord.gg/sSryhaEv79" exit } } #endregion Additional functions #region Privacy & Telemetry <# .SYNOPSIS The Connected User Experiences and Telemetry (DiagTrack) service .PARAMETER Disable Disable the Connected User Experiences and Telemetry (DiagTrack) service, and block connection for the Unified Telemetry Client Outbound Traffic .PARAMETER Enable Enable the Connected User Experiences and Telemetry (DiagTrack) service, and allow connection for the Unified Telemetry Client Outbound Traffic .EXAMPLE DiagTrackService -Disable .EXAMPLE DiagTrackService -Enable .NOTES Current user #> function DiagTrackService { param ( [Parameter( Mandatory = $true, ParameterSetName = "Disable" )] [switch] $Disable, [Parameter( Mandatory = $true, ParameterSetName = "Enable" )] [switch] $Enable ) # Revert back removed or commented out "Checks" functions AdditionalChecks switch ($PSCmdlet.ParameterSetName) { "Disable" { # Connected User Experiences and Telemetry Get-Service -Name DiagTrack | Stop-Service -Force Get-Service -Name DiagTrack | Set-Service -StartupType Disabled # Block connection for the Unified Telemetry Client Outbound Traffic Get-NetFirewallRule -Group DiagTrack | Set-NetFirewallRule -Enabled False -Action Block } "Enable" { # Connected User Experiences and Telemetry Get-Service -Name DiagTrack | Set-Service -StartupType Automatic Get-Service -Name DiagTrack | Start-Service # Allow connection for the Unified Telemetry Client Outbound Traffic Get-NetFirewallRule -Group DiagTrack | Set-NetFirewallRule -Enabled True -Action Allow } } } <# .SYNOPSIS Diagnostic data .PARAMETER Minimal Set the diagnostic data collection to minimum .PARAMETER Default Set the diagnostic data collection to default .EXAMPLE DiagnosticDataLevel -Minimal .EXAMPLE DiagnosticDataLevel -Default .NOTES Machine-wide #> function DiagnosticDataLevel { param ( [Parameter( Mandatory = $true, ParameterSetName = "Minimal" )] [switch] $Minimal, [Parameter( Mandatory = $true, ParameterSetName = "Default" )] [switch] $Default ) switch ($PSCmdlet.ParameterSetName) { "Minimal" { # Security level if (-not (Test-Path -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection)) { New-Item -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection -Force } if (-not (Test-Path -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Diagnostics\DiagTrack)) { New-Item -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Diagnostics\DiagTrack -Force } New-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection -Name AllowTelemetry -PropertyType DWord -Value 0 -Force New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\DataCollection -Name MaxTelemetryAllowed -PropertyType DWord -Value 1 -Force New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Diagnostics\DiagTrack -Name ShowedToastAtLevel -PropertyType DWord -Value 1 -Force } "Default" { # Optional diagnostic data Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection -Name AllowTelemetry -Force -ErrorAction Ignore Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\DataCollection -Name AllowTelemetry -Type CLEAR if (-not (Test-Path -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Diagnostics\DiagTrack)) { New-Item -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Diagnostics\DiagTrack -Force } New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\DataCollection -Name MaxTelemetryAllowed -PropertyType DWord -Value 3 -Force New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Diagnostics\DiagTrack -Name ShowedToastAtLevel -PropertyType DWord -Value 3 -Force } } } <# .SYNOPSIS Windows Error Reporting .PARAMETER Disable Turn off Windows Error Reporting .PARAMETER Enable Turn on Windows Error Reporting .EXAMPLE ErrorReporting -Disable .EXAMPLE ErrorReporting -Enable .NOTES Current user #> function ErrorReporting { param ( [Parameter( Mandatory = $true, ParameterSetName = "Disable" )] [switch] $Disable, [Parameter( Mandatory = $true, ParameterSetName = "Enable" )] [switch] $Enable ) switch ($PSCmdlet.ParameterSetName) { "Disable" { if ((Get-WindowsEdition -Online).Edition -notmatch "Core") { Get-ScheduledTask -TaskName QueueReporting | Disable-ScheduledTask New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Windows Error Reporting" -Name Disabled -PropertyType DWord -Value 1 -Force } Get-Service -Name WerSvc | Stop-Service -Force Get-Service -Name WerSvc | Set-Service -StartupType Disabled } "Enable" { Get-ScheduledTask -TaskName QueueReporting | Enable-ScheduledTask Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Windows Error Reporting" -Name Disabled -Force -ErrorAction Ignore Get-Service -Name WerSvc | Set-Service -StartupType Manual Get-Service -Name WerSvc | Start-Service } } } <# .SYNOPSIS The feedback frequency .PARAMETER Never Change the feedback frequency to "Never" .PARAMETER Automatically Change feedback frequency to "Automatically" .EXAMPLE FeedbackFrequency -Never .EXAMPLE FeedbackFrequency -Automatically .NOTES Current user #> function FeedbackFrequency { param ( [Parameter( Mandatory = $true, ParameterSetName = "Never" )] [switch] $Never, [Parameter( Mandatory = $true, ParameterSetName = "Automatically" )] [switch] $Automatically ) switch ($PSCmdlet.ParameterSetName) { "Never" { if (-not (Test-Path -Path HKCU:\Software\Microsoft\Siuf\Rules)) { New-Item -Path HKCU:\Software\Microsoft\Siuf\Rules -Force } New-ItemProperty -Path HKCU:\Software\Microsoft\Siuf\Rules -Name NumberOfSIUFInPeriod -PropertyType DWord -Value 0 -Force } "Automatically" { Remove-Item -Path HKCU:\Software\Microsoft\Siuf\Rules -Force -ErrorAction Ignore } } } <# .SYNOPSIS The diagnostics tracking scheduled tasks .PARAMETER Disable Turn off the diagnostics tracking scheduled tasks .PARAMETER Enable Turn on the diagnostics tracking scheduled tasks .EXAMPLE ScheduledTasks -Disable .EXAMPLE ScheduledTasks -Enable .NOTES A pop-up dialog box lets a user select tasks .NOTES Current user #> function ScheduledTasks { param ( [Parameter( Mandatory = $true, ParameterSetName = "Disable" )] [switch] $Disable, [Parameter( Mandatory = $true, ParameterSetName = "Enable" )] [switch] $Enable ) Add-Type -AssemblyName PresentationCore, PresentationFramework #region Variables # Initialize an array list to store the selected scheduled tasks $SelectedTasks = New-Object -TypeName System.Collections.ArrayList($null) # The following tasks will have their checkboxes checked [string[]]$CheckedScheduledTasks = @( # Collects program telemetry information if opted-in to the Microsoft Customer Experience Improvement Program "ProgramDataUpdater", # This task collects and uploads autochk SQM data if opted-in to the Microsoft Customer Experience Improvement Program "Proxy", # If the user has consented to participate in the Windows Customer Experience Improvement Program, this job collects and sends usage data to Microsoft "Consolidator", # The USB CEIP (Customer Experience Improvement Program) task collects Universal Serial Bus related statistics and information about your machine and sends it to the Windows Device Connectivity engineering group at Microsoft "UsbCeip", # The Windows Disk Diagnostic reports general disk and system information to Microsoft for users participating in the Customer Experience Program "Microsoft-Windows-DiskDiagnosticDataCollector", # This task shows various Map related toasts "MapsToastTask", # This task checks for updates to maps which you have downloaded for offline use "MapsUpdateTask", # Initializes Family Safety monitoring and enforcement "FamilySafetyMonitor", # Synchronizes the latest settings with the Microsoft family features service "FamilySafetyRefreshTask", # XblGameSave Standby Task "XblGameSaveTask" ) # Check if device has a camera $DeviceHasCamera = Get-CimInstance -ClassName Win32_PnPEntity | Where-Object -FilterScript {(($_.PNPClass -eq "Camera") -or ($_.PNPClass -eq "Image")) -and ($_.Service -ne "StillCam")} if (-not $DeviceHasCamera) { # Windows Hello $CheckedScheduledTasks += "FODCleanupTask" } #endregion Variables #region XAML Markup # The section defines the design of the upcoming dialog box [xml]$XAML = @"