Files
DevOps/Powershell/Sophia Script/SophiaScriptForWindows11/Module/Sophia.psm1
2026-03-10 19:07:03 +01:00

11903 lines
354 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<#
.SYNOPSIS
Sophia Script is a PowerShell module for fine-tuning Windows and automating routine tasks
.VERSION
7.1.4
.DATE
24.02.2026
.COPYRIGHT
(c) 2014—2026 Team Sophia
.NOTES
Supports Windows 11 24H2+ Home/Pro/Enterprise
.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
.DONATE
https://ko-fi.com/farag
https://boosty.to/teamsophia
.NOTES
https://forum.ru-board.com/topic.cgi?forum=62&topic=30617#15
https://habr.com/companies/skillfactory/articles/553800/
https://forums.mydigitallife.net/threads/powershell-sophia-script-for-windows-6-0-4-7-0-4-2026.81675/page-21
https://www.reddit.com/r/PowerShell/comments/go2n5v/powershell_script_setup_windows_10/
.LINK
https://github.com/farag2
https://github.com/Inestic
https://github.com/lowl1f3
#>
#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
{
# Check if system protection is turned on
$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)}
$Global:ComputerRestorePoint = $false
# System protection is turned off
if (-not $SystemProtection)
{
# Turn it on for a while
$Global: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 11" -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 ($Global:ComputerRestorePoint)
{
Disable-ComputerRestore -Drive $env:SystemDrive
}
}
#endregion Protection
#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
Disabling the "Connected User Experiences and Telemetry" service (DiagTrack) can cause you not being able to get Xbox achievements anymore and affects Feedback Hub
.NOTES
Current user
#>
function DiagTrackService
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
# Connected User Experiences and Telemetry
# Disabling the "Connected User Experiences and Telemetry" service (DiagTrack) can cause you not being able to get Xbox achievements anymore and affects Feedback Hub
Get-Service -Name DiagTrack -ErrorAction Ignore | Stop-Service -Force
Get-Service -Name DiagTrack -ErrorAction Ignore | Set-Service -StartupType Disabled
# Block connection for the Unified Telemetry Client Outbound Traffic
Get-NetFirewallRule -Group DiagTrack -ErrorAction Ignore | Set-NetFirewallRule -Enabled True -Action Block
}
"Enable"
{
# Connected User Experiences and Telemetry
Get-Service -Name DiagTrack -ErrorAction Ignore | Set-Service -StartupType Automatic
Get-Service -Name DiagTrack -ErrorAction Ignore | Start-Service
# Allow connection for the Unified Telemetry Client Outbound Traffic
Get-NetFirewallRule -Group DiagTrack -ErrorAction Ignore | 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
)
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
}
switch ($PSCmdlet.ParameterSetName)
{
"Minimal"
{
$EditionID = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").EditionID
if (($EditionID -match "Enterprise") -or ($EditionID -match "Education"))
{
# Diagnostic data off
New-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection -Name AllowTelemetry -PropertyType DWord -Value 0 -Force
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\DataCollection -Name AllowTelemetry -Type DWORD -Value 0
}
else
{
# Send required diagnostic data
New-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection -Name AllowTelemetry -PropertyType DWord -Value 1 -Force
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\DataCollection -Name AllowTelemetry -Type DWORD -Value 1
}
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
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
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
}
}
}
<#
.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
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting", "HKCU:\Software\Policies\Microsoft\Windows\Windows Error Reporting" -Name Disabled -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path "SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting" -Name Disabled -Type CLEAR
Set-Policy -Scope User -Path "Software\Policies\Microsoft\Windows\Windows Error Reporting" -Name Disabled -Type CLEAR
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
Get-ScheduledTask -TaskName QueueReporting -ErrorAction Ignore | 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 -ErrorAction Ignore | 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
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection -Name DoNotShowFeedbackNotifications -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\DataCollection -Name DoNotShowFeedbackNotifications -Type CLEAR
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Siuf\Rules -Name PeriodInNanoSeconds -Force -ErrorAction Ignore
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-ItemProperty -Path HKCU:\Software\Microsoft\Siuf\Rules -Name NumberOfSIUFInPeriod -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
Current user
#>
function ScheduledTasks
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
Add-Type -AssemblyName PresentationCore, PresentationFramework
# 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 = @(
# Gathers Win32 application data for App Backup scenario
"MareBackup",
# Collects program telemetry information if opted-in to the Microsoft Customer Experience Improvement Program
"Microsoft Compatibility Appraiser",
# Collects program telemetry information if opted-in to the Microsoft Customer Experience Improvement Program
"Microsoft Compatibility Appraiser Exp",
# Scans startup entries and raises notification to the user if there are too many startup entries.
"StartupAppTask",
# 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
# The information received is used to help improve the reliability, stability, and overall functionality of USB in Windows
# If the user has not consented to participate in Windows CEIP, this task does not do anything
"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
# Disabling this task will prevent Windows from notifying you of updated maps
"MapsUpdateTask"
)
#region XAML Markup
# The section defines the design of the upcoming dialog box
[xml]$XAML = @"
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Name="Window"
MinHeight="450" MinWidth="400"
SizeToContent="WidthAndHeight" WindowStartupLocation="CenterScreen"
TextOptions.TextFormattingMode="Display" SnapsToDevicePixels="True"
FontFamily="Candara" FontSize="16" ShowInTaskbar="True"
Background="#F1F1F1" Foreground="#262626">
<Window.Resources>
<Style TargetType="StackPanel">
<Setter Property="Orientation" Value="Horizontal"/>
<Setter Property="VerticalAlignment" Value="Top"/>
</Style>
<Style TargetType="CheckBox">
<Setter Property="Margin" Value="10, 10, 5, 10"/>
<Setter Property="IsChecked" Value="True"/>
</Style>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="5, 10, 10, 10"/>
</Style>
<Style TargetType="Button">
<Setter Property="Margin" Value="20"/>
<Setter Property="Padding" Value="10"/>
</Style>
<Style TargetType="Border">
<Setter Property="Grid.Row" Value="1"/>
<Setter Property="CornerRadius" Value="0"/>
<Setter Property="BorderThickness" Value="0, 1, 0, 1"/>
<Setter Property="BorderBrush" Value="#000000"/>
</Style>
<Style TargetType="ScrollViewer">
<Setter Property="HorizontalScrollBarVisibility" Value="Disabled"/>
<Setter Property="BorderBrush" Value="#000000"/>
<Setter Property="BorderThickness" Value="0, 1, 0, 1"/>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ScrollViewer Name="Scroll" Grid.Row="0"
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto">
<StackPanel Name="PanelContainer" Orientation="Vertical"/>
</ScrollViewer>
<Button Name="Button" Grid.Row="2"/>
</Grid>
</Window>
"@
#endregion XAML Markup
$Form = [Windows.Markup.XamlReader]::Load((New-Object -TypeName System.Xml.XmlNodeReader -ArgumentList $XAML))
$XAML.SelectNodes("//*[@*[contains(translate(name(.),'n','N'),'Name')]]") | ForEach-Object -Process {
Set-Variable -Name $_.Name -Value $Form.FindName($_.Name)
}
#region Functions
function Get-CheckboxClicked
{
[CmdletBinding()]
param
(
[Parameter(
Mandatory = $true,
ValueFromPipeline = $true
)]
[ValidateNotNull()]
$CheckBox
)
$Task = $Tasks | Where-Object -FilterScript {$_.TaskName -eq $CheckBox.Parent.Children[1].Text}
if ($CheckBox.IsChecked)
{
[void]$SelectedTasks.Add($Task)
}
else
{
[void]$SelectedTasks.Remove($Task)
}
if ($SelectedTasks.Count -gt 0)
{
$Button.IsEnabled = $true
}
else
{
$Button.IsEnabled = $false
}
}
function DisableButton
{
Write-Information -MessageData "" -InformationAction Continue
# Extract the localized "Please wait..." string from %SystemRoot%\System32\shell32.dll
Write-Verbose -Message ([WinAPI.GetStrings]::GetString(12612)) -Verbose
[void]$Window.Close()
$SelectedTasks | ForEach-Object -Process {Write-Verbose -Message $_.TaskName -Verbose}
$SelectedTasks | Disable-ScheduledTask
}
function EnableButton
{
Write-Information -MessageData "" -InformationAction Continue
# Extract the localized "Please wait..." string from %SystemRoot%\System32\shell32.dll
Write-Verbose -Message ([WinAPI.GetStrings]::GetString(12612)) -Verbose
[void]$Window.Close()
$SelectedTasks | ForEach-Object -Process {Write-Verbose -Message $_.TaskName -Verbose}
$SelectedTasks | Enable-ScheduledTask
}
function Add-TaskControl
{
[CmdletBinding()]
param
(
[Parameter(
Mandatory = $true,
ValueFromPipeline = $true
)]
[ValidateNotNull()]
$Task
)
process
{
$CheckBox = New-Object -TypeName System.Windows.Controls.CheckBox
$CheckBox.Add_Click({Get-CheckboxClicked -CheckBox $_.Source})
$TextBlock = New-Object -TypeName System.Windows.Controls.TextBlock
$TextBlock.Text = $Task.TaskName
$StackPanel = New-Object -TypeName System.Windows.Controls.StackPanel
[void]$StackPanel.Children.Add($CheckBox)
[void]$StackPanel.Children.Add($TextBlock)
[void]$PanelContainer.Children.Add($StackPanel)
# If task checked add to the array list
if ($CheckedScheduledTasks | Where-Object -FilterScript {$Task.TaskName -match $_})
{
[void]$SelectedTasks.Add($Task)
}
else
{
$CheckBox.IsChecked = $false
}
}
}
#endregion Functions
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
$State = "Disabled"
# Extract the localized "Enable" string from %SystemRoot%\System32\shell32.dll
$ButtonContent = [WinAPI.GetStrings]::GetString(51472)
$ButtonAdd_Click = {EnableButton}
}
"Disable"
{
$State = "Ready"
$ButtonContent = $Localization.Disable
$ButtonAdd_Click = {DisableButton}
}
}
Write-Information -MessageData "" -InformationAction Continue
# Extract the localized "Please wait..." string from %SystemRoot%\System32\shell32.dll
Write-Verbose -Message ([WinAPI.GetStrings]::GetString(12612)) -Verbose
# Getting list of all scheduled tasks according to the conditions
$Tasks = Get-ScheduledTask | Where-Object -FilterScript {($_.State -eq $State) -and ($_.TaskName -in $CheckedScheduledTasks)}
if (-not $Tasks)
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.NoScheduledTasks, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.NoScheduledTasks, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
#region Sendkey function
# Emulate the Backspace key sending to prevent the console window to freeze
Start-Sleep -Milliseconds 500
Add-Type -AssemblyName System.Windows.Forms
# We cannot use Get-Process -Id $PID as script might be invoked via Terminal with different $PID
Get-Process -Name powershell, WindowsTerminal -ErrorAction Ignore | Where-Object -FilterScript {$_.MainWindowTitle -match "Sophia Script for Windows 11"} | ForEach-Object -Process {
# Show window, if minimized
[WinAPI.ForegroundWindow]::ShowWindowAsync($_.MainWindowHandle, 10)
Start-Sleep -Seconds 1
# Force move the console window to the foreground
[WinAPI.ForegroundWindow]::SetForegroundWindow($_.MainWindowHandle)
Start-Sleep -Seconds 1
# Emulate the Backspace key sending
[System.Windows.Forms.SendKeys]::SendWait("{BACKSPACE 1}")
}
#endregion Sendkey function
$Window.Add_Loaded({$Tasks | Add-TaskControl})
$Button.Content = $ButtonContent
$Button.Add_Click({& $ButtonAdd_Click})
$Window.Title = $Localization.ScheduledTasks
# Force move the WPF form to the foreground
$Window.Add_Loaded({$Window.Activate()})
$Form.ShowDialog() | Out-Null
}
<#
.SYNOPSIS
The sign-in info to automatically finish setting up device after an update
.PARAMETER Disable
Do not use sign-in info to automatically finish setting up device after an update
.PARAMETER Enable
Use sign-in info to automatically finish setting up device after an update
.EXAMPLE
SigninInfo -Disable
.EXAMPLE
SigninInfo -Enable
.NOTES
Current user
#>
function SigninInfo
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -Name DisableAutomaticRestartSignOn -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -Name DisableAutomaticRestartSignOn -Type CLEAR
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
$SID = (Get-CimInstance -ClassName Win32_UserAccount | Where-Object -FilterScript {$_.Name -eq $env:USERNAME}).SID
if (-not (Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\UserARSO\$SID"))
{
New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\UserARSO\$SID" -Force
}
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\UserARSO\$SID" -Name OptOut -PropertyType DWord -Value 1 -Force
}
"Enable"
{
$SID = (Get-CimInstance -ClassName Win32_UserAccount | Where-Object -FilterScript {$_.Name -eq $env:USERNAME}).SID
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\UserARSO\$SID" -Name OptOut -Force -ErrorAction Ignore
}
}
}
<#
.SYNOPSIS
The provision to websites a locally relevant content by accessing my language list
.PARAMETER Disable
Do not let websites show me locally relevant content by accessing my language list
.PARAMETER Enable
Let websites show me locally relevant content by accessing language my list
.EXAMPLE
LanguageListAccess -Disable
.EXAMPLE
LanguageListAccess -Enable
.NOTES
Current user
#>
function LanguageListAccess
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
New-ItemProperty -Path "HKCU:\Control Panel\International\User Profile" -Name HttpAcceptLanguageOptOut -PropertyType DWord -Value 1 -Force
}
"Enable"
{
Remove-ItemProperty -Path "HKCU:\Control Panel\International\User Profile" -Name HttpAcceptLanguageOptOut -Force -ErrorAction Ignore
}
}
}
<#
.SYNOPSIS
The permission for apps to show me personalized ads by using my advertising ID
.PARAMETER Disable
Do not let apps show me personalized ads by using my advertising ID
.PARAMETER Enable
Let apps show me personalized ads by using my advertising ID
.EXAMPLE
AdvertisingID -Disable
.EXAMPLE
AdvertisingID -Enable
.NOTES
Current user
#>
function AdvertisingID
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo -Name DisabledByGroupPolicy -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo -Name DisabledByGroupPolicy -Type CLEAR
if (-not (Test-Path -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\AdvertisingInfo))
{
New-Item -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\AdvertisingInfo -Force
}
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\AdvertisingInfo -Name Enabled -PropertyType DWord -Value 0 -Force
}
"Enable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\AdvertisingInfo -Name Enabled -PropertyType DWord -Value 1 -Force
}
}
}
<#
.SYNOPSIS
The Windows welcome experiences after updates and occasionally when I sign in to highlight what's new and suggested
.PARAMETER Hide
Hide the Windows welcome experiences after updates and occasionally when I sign in to highlight what's new and suggested
.PARAMETER Show
Show the Windows welcome experiences after updates and occasionally when I sign in to highlight what's new and suggested
.EXAMPLE
WindowsWelcomeExperience -Hide
.EXAMPLE
WindowsWelcomeExperience -Show
.NOTES
Current user
#>
function WindowsWelcomeExperience
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Show"
)]
[switch]
$Show,
[Parameter(
Mandatory = $true,
ParameterSetName = "Hide"
)]
[switch]
$Hide
)
switch ($PSCmdlet.ParameterSetName)
{
"Show"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager -Name SubscribedContent-310093Enabled -PropertyType DWord -Value 1 -Force
}
"Hide"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager -Name SubscribedContent-310093Enabled -PropertyType DWord -Value 0 -Force
}
}
}
<#
.SYNOPSIS
Getting tip and suggestions when I use Windows
.PARAMETER Enable
Get tip and suggestions when using Windows
.PARAMETER Disable
Do not get tip and suggestions when I use Windows
.EXAMPLE
WindowsTips -Disable
.EXAMPLE
WindowsTips -Enable
.NOTES
Current user
#>
function WindowsTips
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\CloudContent -Name DisableSoftLanding -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\CloudContent -Name DisableSoftLanding -Type CLEAR
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager -Name SubscribedContent-338389Enabled -PropertyType DWord -Value 0 -Force
}
"Enable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager -Name SubscribedContent-338389Enabled -PropertyType DWord -Value 1 -Force
}
}
}
<#
.SYNOPSIS
Show me suggested content in the Settings app
.PARAMETER Hide
Hide from me suggested content in the Settings app
.PARAMETER Show
Show me suggested content in the Settings app
.EXAMPLE
SettingsSuggestedContent -Hide
.EXAMPLE
SettingsSuggestedContent -Show
.NOTES
Current user
#>
function SettingsSuggestedContent
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Hide"
)]
[switch]
$Hide,
[Parameter(
Mandatory = $true,
ParameterSetName = "Show"
)]
[switch]
$Show
)
switch ($PSCmdlet.ParameterSetName)
{
"Hide"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager -Name SubscribedContent-338393Enabled -PropertyType DWord -Value 0 -Force
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager -Name SubscribedContent-353694Enabled -PropertyType DWord -Value 0 -Force
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager -Name SubscribedContent-353696Enabled -PropertyType DWord -Value 0 -Force
}
"Show"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager -Name SubscribedContent-338393Enabled -PropertyType DWord -Value 1 -Force
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager -Name SubscribedContent-353694Enabled -PropertyType DWord -Value 1 -Force
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager -Name SubscribedContent-353696Enabled -PropertyType DWord -Value 1 -Force
}
}
}
<#
.SYNOPSIS
Automatic installing suggested apps
.PARAMETER Disable
Turn off automatic installing suggested apps
.PARAMETER Enable
Turn on automatic installing suggested apps
.EXAMPLE
AppsSilentInstalling -Disable
.EXAMPLE
AppsSilentInstalling -Enable
.NOTES
Current user
#>
function AppsSilentInstalling
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\CloudContent -Name DisableWindowsConsumerFeatures -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\CloudContent -Name DisableWindowsConsumerFeatures -Type CLEAR
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager -Name SilentInstalledAppsEnabled -PropertyType DWord -Value 0 -Force
}
"Enable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager -Name SilentInstalledAppsEnabled -PropertyType DWord -Value 1 -Force
}
}
}
<#
.SYNOPSIS
Ways to get the most out of Windows and finish setting up this device
.PARAMETER Disable
Do not suggest ways to get the most out of Windows and finish setting up this device
.PARAMETER Enable
Suggest ways to get the most out of Windows and finish setting up this device
.EXAMPLE
WhatsNewInWindows -Disable
.EXAMPLE
WhatsNewInWindows -Enable
.NOTES
Current user
#>
function WhatsNewInWindows
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
if (-not (Test-Path -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\UserProfileEngagement))
{
New-Item -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\UserProfileEngagement -Force
}
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\UserProfileEngagement -Name ScoobeSystemSettingEnabled -PropertyType DWord -Value 0 -Force
}
"Enable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\UserProfileEngagement -Name ScoobeSystemSettingEnabled -PropertyType DWord -Value 1 -Force
}
}
}
<#
.SYNOPSIS
Tailored experiences
.PARAMETER Disable
Do not let Microsoft use your diagnostic data for personalized tips, ads, and recommendations
.PARAMETER Enable
Let Microsoft use your diagnostic data for personalized tips, ads, and recommendations
.EXAMPLE
TailoredExperiences -Disable
.EXAMPLE
TailoredExperiences -Enable
.NOTES
Current user
#>
function TailoredExperiences
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKCU:\Software\Policies\Microsoft\Windows\CloudContent -Name DisableTailoredExperiencesWithDiagnosticData -Force -ErrorAction Ignore
Set-Policy -Scope User -Path Software\Policies\Microsoft\Windows\CloudContent -Name DisableTailoredExperiencesWithDiagnosticData -Type CLEAR
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Privacy -Name TailoredExperiencesWithDiagnosticDataEnabled -PropertyType DWord -Value 0 -Force
}
"Enable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Privacy -Name TailoredExperiencesWithDiagnosticDataEnabled -PropertyType DWord -Value 1 -Force
}
}
}
<#
.SYNOPSIS
Bing search in Start Menu
.PARAMETER Disable
Disable Bing search in Start Menu
.PARAMETER Enable
Enable Bing search in Start Menu
.EXAMPLE
BingSearch -Disable
.EXAMPLE
BingSearch -Enable
.NOTES
Current user
#>
function BingSearch
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
if (-not (Test-Path -Path HKCU:\Software\Policies\Microsoft\Windows\Explorer))
{
New-Item -Path HKCU:\Software\Policies\Microsoft\Windows\Explorer -Force
}
New-ItemProperty -Path HKCU:\Software\Policies\Microsoft\Windows\Explorer -Name DisableSearchBoxSuggestions -PropertyType DWord -Value 1 -Force
Set-Policy -Scope User -Path Software\Policies\Microsoft\Windows\Explorer -Name DisableSearchBoxSuggestions -Type DWORD -Value 1
}
"Enable"
{
Remove-ItemProperty -Path HKCU:\Software\Policies\Microsoft\Windows\Explorer -Name DisableSearchBoxSuggestions -Force -ErrorAction Ignore
Set-Policy -Scope User -Path Software\Policies\Microsoft\Windows\Explorer -Name DisableSearchBoxSuggestions -Type CLEAR
}
}
}
#endregion Privacy & Telemetry
#region UI & Personalization
<#
.SYNOPSIS
"This PC" icon on Desktop
.PARAMETER Show
Show "This PC" icon on Desktop
.PARAMETER Hide
Hide "This PC" icon on Desktop
.EXAMPLE
ThisPC -Show
.EXAMPLE
ThisPC -Hide
.NOTES
Current user
#>
function ThisPC
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Show"
)]
[switch]
$Show,
[Parameter(
Mandatory = $true,
ParameterSetName = "Hide"
)]
[switch]
$Hide
)
switch ($PSCmdlet.ParameterSetName)
{
"Show"
{
if (-not (Test-Path -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\NewStartPanel))
{
New-Item -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\NewStartPanel -Force
}
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\NewStartPanel -Name "{20D04FE0-3AEA-1069-A2D8-08002B30309D}" -PropertyType DWord -Value 0 -Force
}
"Hide"
{
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\NewStartPanel -Name "{20D04FE0-3AEA-1069-A2D8-08002B30309D}" -Force -ErrorAction Ignore
}
}
}
<#
.SYNOPSIS
Item check boxes
.PARAMETER Disable
Do not use item check boxes
.PARAMETER Enable
Use check item check boxes
.EXAMPLE
CheckBoxes -Disable
.EXAMPLE
CheckBoxes -Enable
.NOTES
Current user
#>
function CheckBoxes
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name AutoCheckSelect -PropertyType DWord -Value 1 -Force
}
"Disable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name AutoCheckSelect -PropertyType DWord -Value 0 -Force
}
}
}
<#
.SYNOPSIS
Hidden files, folders, and drives
.PARAMETER Enable
Show hidden files, folders, and drives
.PARAMETER Disable
Do not show hidden files, folders, and drives
.EXAMPLE
HiddenItems -Enable
.EXAMPLE
HiddenItems -Disable
.NOTES
Current user
#>
function HiddenItems
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name Hidden -PropertyType DWord -Value 1 -Force
}
"Disable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name Hidden -PropertyType DWord -Value 2 -Force
}
}
}
<#
.SYNOPSIS
File name extensions
.PARAMETER Show
Show file name extensions
.PARAMETER Hide
Hide file name extensions
.EXAMPLE
FileExtensions -Show
.EXAMPLE
FileExtensions -Hide
.NOTES
Current user
#>
function FileExtensions
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Show"
)]
[switch]
$Show,
[Parameter(
Mandatory = $true,
ParameterSetName = "Hide"
)]
[switch]
$Hide
)
switch ($PSCmdlet.ParameterSetName)
{
"Show"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name HideFileExt -PropertyType DWord -Value 0 -Force
}
"Hide"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name HideFileExt -PropertyType DWord -Value 1 -Force
}
}
}
<#
.SYNOPSIS
Folder merge conflicts
.PARAMETER Show
Show folder merge conflicts
.PARAMETER Hide
Hide folder merge conflicts
.EXAMPLE
MergeConflicts -Show
.EXAMPLE
MergeConflicts -Hide
.NOTES
Current user
#>
function MergeConflicts
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Show"
)]
[switch]
$Show,
[Parameter(
Mandatory = $true,
ParameterSetName = "Hide"
)]
[switch]
$Hide
)
switch ($PSCmdlet.ParameterSetName)
{
"Show"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name HideMergeConflicts -PropertyType DWord -Value 0 -Force
}
"Hide"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name HideMergeConflicts -PropertyType DWord -Value 1 -Force
}
}
}
<#
.SYNOPSIS
Configure how to open File Explorer
.PARAMETER ThisPC
Open File Explorer to "This PC"
.PARAMETER QuickAccess
Open File Explorer to Quick access
.EXAMPLE
OpenFileExplorerTo -ThisPC
.EXAMPLE
OpenFileExplorerTo -QuickAccess
.NOTES
Current user
#>
function OpenFileExplorerTo
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "ThisPC"
)]
[switch]
$ThisPC,
[Parameter(
Mandatory = $true,
ParameterSetName = "QuickAccess"
)]
[switch]
$QuickAccess
)
switch ($PSCmdlet.ParameterSetName)
{
"ThisPC"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name LaunchTo -PropertyType DWord -Value 1 -Force
}
"QuickAccess"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name LaunchTo -PropertyType DWord -Value 2 -Force
}
}
}
<#
.SYNOPSIS
File Explorer mode
.PARAMETER Disable
Disable File Explorer compact mode
.PARAMETER Enable
Enable File Explorer compact mode
.EXAMPLE
FileExplorerCompactMode -Disable
.EXAMPLE
FileExplorerCompactMode -Enable
.NOTES
Current user
#>
function FileExplorerCompactMode
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name UseCompactMode -PropertyType DWord -Value 0 -Force
}
"Enable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name UseCompactMode -PropertyType DWord -Value 1 -Force
}
}
}
<#
.SYNOPSIS
Sync provider notification in File Explorer
.PARAMETER Hide
Hide sync provider notification within File Explorer
.PARAMETER Show
Show sync provider notification within File Explorer
.EXAMPLE
OneDriveFileExplorerAd -Hide
.EXAMPLE
OneDriveFileExplorerAd -Show
.NOTES
Current user
#>
function OneDriveFileExplorerAd
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Hide"
)]
[switch]
$Hide,
[Parameter(
Mandatory = $true,
ParameterSetName = "Show"
)]
[switch]
$Show
)
switch ($PSCmdlet.ParameterSetName)
{
"Hide"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name ShowSyncProviderNotifications -PropertyType DWord -Value 0 -Force
}
"Show"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name ShowSyncProviderNotifications -PropertyType DWord -Value 1 -Force
}
}
}
<#
.SYNOPSIS
Windows snapping
.PARAMETER Disable
When I snap a window, do not show what I can snap next to it
.PARAMETER Enable
When I snap a window, show what I can snap next to it
.EXAMPLE
SnapAssist -Disable
.EXAMPLE
SnapAssist -Enable
.NOTES
Current user
#>
function SnapAssist
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
# Property type is string
New-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name WindowArrangementActive -PropertyType String -Value 1 -Force
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name SnapAssist -PropertyType DWord -Value 0 -Force
}
"Enable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name SnapAssist -PropertyType DWord -Value 1 -Force
}
}
}
<#
.SYNOPSIS
The file transfer dialog box mode
.PARAMETER Detailed
Show the file transfer dialog box in the detailed mode
.PARAMETER Compact
Show the file transfer dialog box in the compact mode
.EXAMPLE
FileTransferDialog -Detailed
.EXAMPLE
FileTransferDialog -Compact
.NOTES
Current user
#>
function FileTransferDialog
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Detailed"
)]
[switch]
$Detailed,
[Parameter(
Mandatory = $true,
ParameterSetName = "Compact"
)]
[switch]
$Compact
)
if (-not (Test-Path -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\OperationStatusManager))
{
New-Item -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\OperationStatusManager -Force
}
switch ($PSCmdlet.ParameterSetName)
{
"Detailed"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\OperationStatusManager -Name EnthusiastMode -PropertyType DWord -Value 1 -Force
}
"Compact"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\OperationStatusManager -Name EnthusiastMode -PropertyType DWord -Value 0 -Force
}
}
}
<#
.SYNOPSIS
The recycle bin files delete confirmation dialog
.PARAMETER Enable
Display the recycle bin files delete confirmation dialog
.PARAMETER Disable
Do not display the recycle bin files delete confirmation dialog
.EXAMPLE
RecycleBinDeleteConfirmation -Enable
.EXAMPLE
RecycleBinDeleteConfirmation -Disable
.NOTES
Current user
#>
function RecycleBinDeleteConfirmation
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer, HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer -Name ConfirmFileDelete -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\Explorer -Name ConfirmFileDelete -Type CLEAR
Set-Policy -Scope User -Path Software\Policies\Microsoft\Windows\Explorer -Name ConfirmFileDelete -Type CLEAR
$ShellState = Get-ItemPropertyValue -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer -Name ShellState
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
$ShellState[4] = $ShellState[4] -band -bnot 0x00000004
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer -Name ShellState -PropertyType Binary -Value $ShellState -Force
}
"Disable"
{
$ShellState[4] = $ShellState[4] -bor 0x00000004
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer -Name ShellState -PropertyType Binary -Value $ShellState -Force
}
}
}
<#
.SYNOPSIS
Recently used files in Quick access
.PARAMETER Hide
Hide recently used files in Quick access
.PARAMETER Show
Show recently used files in Quick access
.EXAMPLE
QuickAccessRecentFiles -Hide
.EXAMPLE
QuickAccessRecentFiles -Show
.NOTES
Current user
#>
function QuickAccessRecentFiles
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Hide"
)]
[switch]
$Hide,
[Parameter(
Mandatory = $true,
ParameterSetName = "Show"
)]
[switch]
$Show
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer, HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer -Name NoRecentDocsHistory -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\Explorer -Name NoRecentDocsHistory -Type CLEAR
Set-Policy -Scope User -Path Software\Policies\Microsoft\Windows\Explorer -Name NoRecentDocsHistory -Type CLEAR
switch ($PSCmdlet.ParameterSetName)
{
"Hide"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer -Name ShowRecent -PropertyType DWord -Value 0 -Force
}
"Show"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer -Name ShowRecent -PropertyType DWord -Value 1 -Force
}
}
}
<#
.SYNOPSIS
Frequently used folders in Quick access
.PARAMETER Hide
Hide frequently used folders in Quick access
.PARAMETER Show
Show frequently used folders in Quick access
.EXAMPLE
QuickAccessFrequentFolders -Hide
.EXAMPLE
QuickAccessFrequentFolders -Show
.NOTES
Current user
#>
function QuickAccessFrequentFolders
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Hide"
)]
[switch]
$Hide,
[Parameter(
Mandatory = $true,
ParameterSetName = "Show"
)]
[switch]
$Show
)
switch ($PSCmdlet.ParameterSetName)
{
"Hide"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer -Name ShowFrequent -PropertyType DWord -Value 0 -Force
}
"Show"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer -Name ShowFrequent -PropertyType DWord -Value 1 -Force
}
}
}
<#
.SYNOPSIS
Taskbar alignment
.PARAMETER Left
Set the taskbar alignment to the left
.PARAMETER Center
Set the taskbar alignment to the center
.EXAMPLE
TaskbarAlignment -Center
.EXAMPLE
TaskbarAlignment -Left
.NOTES
Current user
#>
function TaskbarAlignment
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Left"
)]
[switch]
$Left,
[Parameter(
Mandatory = $true,
ParameterSetName = "Center"
)]
[switch]
$Center
)
switch ($PSCmdlet.ParameterSetName)
{
"Center"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name TaskbarAl -PropertyType DWord -Value 1 -Force
}
"Left"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name TaskbarAl -PropertyType DWord -Value 0 -Force
}
}
}
<#
.SYNOPSIS
The widgets icon on the taskbar
.PARAMETER Hide
Hide the widgets icon on the taskbar
.PARAMETER Show
Show the widgets icon on the taskbar
.EXAMPLE
TaskbarWidgets -Hide
.EXAMPLE
TaskbarWidgets -Show
.NOTES
Current user
#>
function TaskbarWidgets
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Hide"
)]
[switch]
$Hide,
[Parameter(
Mandatory = $true,
ParameterSetName = "Show"
)]
[switch]
$Show
)
if (-not (Get-AppxPackage -Name MicrosoftWindows.Client.WebExperience))
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.WidgetNotInstalled, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.WidgetNotInstalled, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\PolicyManager\default\NewsAndInterests\AllowNewsAndInterests -Name value -Force -ErrorAction Ignore
Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Dsh -Name AllowNewsAndInterests -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Dsh -Name AllowNewsAndInterests -Type CLEAR
# We cannot set a value to TaskbarDa, having called any of APIs, except of copying powershell.exe (or any other tricks) with a different name, due to a UCPD driver tracks all executables to block the access to the registry
Copy-Item -Path "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe" -Destination "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell_temp.exe" -Force
switch ($PSCmdlet.ParameterSetName)
{
"Hide"
{
& "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell_temp.exe" -Command {New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name TaskbarDa -PropertyType DWord -Value 0 -Force}
}
"Show"
{
& "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell_temp.exe" -Command {New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name TaskbarDa -PropertyType DWord -Value 1 -Force}
}
}
Remove-Item -Path "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell_temp.exe" -Force
}
<#
.SYNOPSIS
Search on the taskbar
.PARAMETER Hide
Hide the search on the taskbar
.PARAMETER SearchIcon
Show the search icon on the taskbar
.PARAMETER SearchBox
Show the search box on the taskbar
.EXAMPLE
TaskbarSearch -Hide
.EXAMPLE
TaskbarSearch -SearchIcon
.EXAMPLE
TaskbarSearch -SearchIconLabel
.EXAMPLE
TaskbarSearch -SearchBox
.NOTES
Current user
#>
function TaskbarSearch
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Hide"
)]
[switch]
$Hide,
[Parameter(
Mandatory = $true,
ParameterSetName = "SearchIcon"
)]
[switch]
$SearchIcon,
[Parameter(
Mandatory = $true,
ParameterSetName = "SearchIconLabel"
)]
[switch]
$SearchIconLabel,
[Parameter(
Mandatory = $true,
ParameterSetName = "SearchBox"
)]
[switch]
$SearchBox
)
# Remove all policies in order to make changes visible in UI
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\PolicyManager\default\Search\DisableSearch -Name value -PropertyType DWord -Value 0 -Force
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search" -Name DisableSearch, SearchOnTaskbarMode -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path "SOFTWARE\Policies\Microsoft\Windows\Windows Search" -Name DisableSearch -Type CLEAR
Set-Policy -Scope Computer -Path "SOFTWARE\Policies\Microsoft\Windows\Windows Search" -Name SearchOnTaskbarMode -Type CLEAR
switch ($PSCmdlet.ParameterSetName)
{
"Hide"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Search -Name SearchboxTaskbarMode -PropertyType DWord -Value 0 -Force
}
"SearchIcon"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Search -Name SearchboxTaskbarMode -PropertyType DWord -Value 1 -Force
}
"SearchIconLabel"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Search -Name SearchboxTaskbarMode -PropertyType DWord -Value 3 -Force
}
"SearchBox"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Search -Name SearchboxTaskbarMode -PropertyType DWord -Value 2 -Force
}
}
}
<#
.SYNOPSIS
Search highlights
.PARAMETER Hide
Hide search highlights
.PARAMETER Show
Show search highlights
.EXAMPLE
SearchHighlights -Hide
.EXAMPLE
SearchHighlights -Show
.NOTES
Current user
#>
function SearchHighlights
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Hide"
)]
[switch]
$Hide,
[Parameter(
Mandatory = $true,
ParameterSetName = "Show"
)]
[switch]
$Show
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search" -Name EnableDynamicContentInWSB -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path "SOFTWARE\Policies\Microsoft\Windows\Windows Search" -Name EnableDynamicContentInWSB -Type CLEAR
switch ($PSCmdlet.ParameterSetName)
{
"Hide"
{
# Checking whether "Ask Copilot" and "Find results in Web" were disabled. They also disable Search Highlights automatically
# We have to use GetValue() due to "Set-StrictMode -Version Latest"
$BingSearchEnabled = ([Microsoft.Win32.Registry]::GetValue("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Search", "BingSearchEnabled", $null))
$DisableSearchBoxSuggestions = ([Microsoft.Win32.Registry]::GetValue("HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Explorer", "DisableSearchBoxSuggestions", $null))
if (($BingSearchEnabled -eq 1) -or ($DisableSearchBoxSuggestions -eq 1))
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.SearchHighlightsDisabled, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.SearchHighlightsDisabled, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
else
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\SearchSettings -Name IsDynamicSearchBoxEnabled -PropertyType DWord -Value 0 -Force
}
}
"Show"
{
# Enable "Ask Copilot" and "Find results in Web" icons in Windows Search in order to enable Search Highlights
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Search -Name BingSearchEnabled -Force -ErrorAction Ignore
Remove-ItemProperty -Path HKCU:\Software\Policies\Microsoft\Windows\Explorer -Name DisableSearchBoxSuggestions -Force -ErrorAction Ignore
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\SearchSettings -Name IsDynamicSearchBoxEnabled -PropertyType DWord -Value 1 -Force
}
}
}
<#
.SYNOPSIS
Task view button on the taskbar
.PARAMETER Hide
Hide the Task view button on the taskbar
.PARAMETER Show
Show the Task View button on the taskbar
.EXAMPLE
TaskViewButton -Hide
.EXAMPLE
TaskViewButton -Show
.NOTES
Current user
#>
function TaskViewButton
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Hide"
)]
[switch]
$Hide,
[Parameter(
Mandatory = $true,
ParameterSetName = "Show"
)]
[switch]
$Show
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKCU:\Software\Policies\Microsoft\Windows\Explorer, HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer -Name HideTaskViewButton -Force -ErrorAction Ignore
Set-Policy -Scope User -Path Software\Policies\Microsoft\Windows\Explorer -Name HideTaskViewButton -Type CLEAR
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\Explorer -Name HideTaskViewButton -Type CLEAR
switch ($PSCmdlet.ParameterSetName)
{
"Hide"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name ShowTaskViewButton -PropertyType DWord -Value 0 -Force
}
"Show"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name ShowTaskViewButton -PropertyType DWord -Value 1 -Force
}
}
}
<#
.SYNOPSIS
Seconds on the taskbar clock
.PARAMETER Show
Show seconds on the taskbar clock
.PARAMETER Hide
Hide seconds on the taskbar clock
.EXAMPLE
SecondsInSystemClock -Show
.EXAMPLE
SecondsInSystemClock -Hide
.NOTES
Current user
#>
function SecondsInSystemClock
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Show"
)]
[switch]
$Show,
[Parameter(
Mandatory = $true,
ParameterSetName = "Hide"
)]
[switch]
$Hide
)
switch ($PSCmdlet.ParameterSetName)
{
"Show"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name ShowSecondsInSystemClock -PropertyType DWord -Value 1 -Force
}
"Hide"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name ShowSecondsInSystemClock -PropertyType DWord -Value 0 -Force
}
}
}
<#
.SYNOPSIS
Time in Notification Center
.PARAMETER Show
Show time in Notification Center
.PARAMETER Hide
Hide time in Notification Center
.EXAMPLE
ClockInNotificationCenter -Show
.EXAMPLE
ClockInNotificationCenter -Hide
.NOTES
Current user
#>
function ClockInNotificationCenter
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Show"
)]
[switch]
$Show,
[Parameter(
Mandatory = $true,
ParameterSetName = "Hide"
)]
[switch]
$Hide
)
switch ($PSCmdlet.ParameterSetName)
{
"Show"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name ShowClockInNotificationCenter -PropertyType DWord -Value 1 -Force
}
"Hide"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name ShowClockInNotificationCenter -PropertyType DWord -Value 0 -Force
}
}
}
<#
.SYNOPSIS
Combine taskbar buttons and hide labels
.PARAMETER Always
Combine taskbar buttons and always hide labels
.PARAMETER Full
Combine taskbar buttons and hide labels when taskbar is full
.PARAMETER Never
Combine taskbar buttons and never hide labels
.EXAMPLE
TaskbarCombine -Always
.EXAMPLE
TaskbarCombine -Full
.EXAMPLE
TaskbarCombine -Never
.NOTES
Current user
#>
function TaskbarCombine
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Always"
)]
[switch]
$Always,
[Parameter(
Mandatory = $true,
ParameterSetName = "Full"
)]
[switch]
$Full,
[Parameter(
Mandatory = $true,
ParameterSetName = "Never"
)]
[switch]
$Never
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer, HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer -Name NoTaskGrouping -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -Name NoTaskGrouping -Type CLEAR
Set-Policy -Scope User -Path Software\Microsoft\Windows\CurrentVersion\Policies\Explorer -Name NoTaskGrouping -Type CLEAR
switch ($PSCmdlet.ParameterSetName)
{
"Always"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name TaskbarGlomLevel -PropertyType DWord -Value 0 -Force
}
"Full"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name TaskbarGlomLevel -PropertyType DWord -Value 1 -Force
}
"Never"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name TaskbarGlomLevel -PropertyType DWord -Value 2 -Force
}
}
}
<#
.SYNOPSIS
Unpin shortcuts from the taskbar
.PARAMETER Edge
Unpin Microsoft Edge shortcut from the taskbar
.PARAMETER Store
Unpin Microsoft Store from the taskbar
.PARAMETER Outlook
Unpin Outlook shortcut from the taskbar
.EXAMPLE
UnpinTaskbarShortcuts -Shortcuts Edge, Store, Outlook
.NOTES
Current user
#>
function UnpinTaskbarShortcuts
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[ValidateSet("Edge", "Store", "Outlook")]
[string[]]
$Shortcuts
)
# Extract the localized "Unpin from taskbar" string from %SystemRoot%\System32\shell32.dll
$LocalizedString = [WinAPI.GetStrings]::GetString(5387)
foreach ($Shortcut in $Shortcuts)
{
switch ($Shortcut)
{
Edge
{
if (Test-Path -Path "$env:AppData\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\Microsoft Edge.lnk")
{
# Call the shortcut context menu item
$Shell = (New-Object -ComObject Shell.Application).NameSpace("$env:AppData\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar")
$Shortcut = $Shell.ParseName("Microsoft Edge.lnk")
# Extract the localized "Unpin from taskbar" string from %SystemRoot%\System32\shell32.dll
$Shortcut.Verbs() | Where-Object -FilterScript {$_.Name -eq $LocalizedString} | ForEach-Object -Process {$_.DoIt()}
}
}
Store
{
if ((New-Object -ComObject Shell.Application).NameSpace("shell:::{4234d49b-0245-4df3-b780-3893943456e1}").Items() | Where-Object -FilterScript {$_.Name -eq "Microsoft Store"})
{
# Extract the localized "Unpin from taskbar" string from %SystemRoot%\System32\shell32.dll
((New-Object -ComObject Shell.Application).NameSpace("shell:::{4234d49b-0245-4df3-b780-3893943456e1}").Items() | Where-Object -FilterScript {
$_.Name -eq "Microsoft Store"
}).Verbs() | Where-Object -FilterScript {$_.Name -eq $LocalizedString} | ForEach-Object -Process {$_.DoIt()}
}
}
Outlook
{
if ((New-Object -ComObject Shell.Application).NameSpace("shell:::{4234d49b-0245-4df3-b780-3893943456e1}").Items() | Where-Object -FilterScript {$_.Name -match "Outlook"})
{
# Extract the localized "Unpin from taskbar" string from %SystemRoot%\System32\shell32.dll
((New-Object -ComObject Shell.Application).NameSpace("shell:::{4234d49b-0245-4df3-b780-3893943456e1}").Items() | Where-Object -FilterScript {
$_.Name -match "Outlook"
}).Verbs() | Where-Object -FilterScript {$_.Name -eq $LocalizedString} | ForEach-Object -Process {$_.DoIt()}
}
}
}
}
}
<#
.SYNOPSIS
End task in taskbar by right click
.PARAMETER Enable
Enable end task in taskbar by right click
.PARAMETER Disable
Disable end task in taskbar by right click
.EXAMPLE
TaskbarEndTask -Enable
.EXAMPLE
TaskbarEndTask -Disable
.NOTES
Current user
#>
function TaskbarEndTask
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
if (-not (Test-Path -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\TaskbarDeveloperSettings))
{
New-Item -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\TaskbarDeveloperSettings -Force
}
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\TaskbarDeveloperSettings -Name TaskbarEndTask -PropertyType DWord -Value 1 -Force
}
"Disable"
{
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\TaskbarDeveloperSettings -Name TaskbarEndTask -Force -ErrorAction Ignore
}
}
}
<#
.SYNOPSIS
The Control Panel icons view
.PARAMETER Category
View the Control Panel icons by category
.PARAMETER LargeIcons
View the Control Panel icons by large icons
.PARAMETER SmallIcons
View the Control Panel icons by Small icons
.EXAMPLE
ControlPanelView -Category
.EXAMPLE
ControlPanelView -LargeIcons
.EXAMPLE
ControlPanelView -SmallIcons
.NOTES
Current user
#>
function ControlPanelView
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Category"
)]
[switch]
$Category,
[Parameter(
Mandatory = $true,
ParameterSetName = "LargeIcons"
)]
[switch]
$LargeIcons,
[Parameter(
Mandatory = $true,
ParameterSetName = "SmallIcons"
)]
[switch]
$SmallIcons
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer -Name ForceClassicControlPanel -Force -ErrorAction Ignore
Set-Policy -Scope User -Path Software\Microsoft\Windows\CurrentVersion\Policies\Explorer -Name ForceClassicControlPanel -Type CLEAR
if (-not (Test-Path -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\ControlPanel))
{
New-Item -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\ControlPanel -Force
}
switch ($PSCmdlet.ParameterSetName)
{
"Category"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\ControlPanel -Name AllItemsIconView -PropertyType DWord -Value 0 -Force
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\ControlPanel -Name StartupPage -PropertyType DWord -Value 0 -Force
}
"LargeIcons"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\ControlPanel -Name AllItemsIconView -PropertyType DWord -Value 0 -Force
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\ControlPanel -Name StartupPage -PropertyType DWord -Value 1 -Force
}
"SmallIcons"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\ControlPanel -Name AllItemsIconView -PropertyType DWord -Value 1 -Force
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\ControlPanel -Name StartupPage -PropertyType DWord -Value 1 -Force
}
}
}
<#
.SYNOPSIS
The default Windows mode
.PARAMETER Dark
Set the default Windows mode to dark
.PARAMETER Light
Set the default Windows mode to light
.EXAMPLE
WindowsColorScheme -Dark
.EXAMPLE
WindowsColorScheme -Light
.NOTES
Current user
#>
function WindowsColorMode
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Dark"
)]
[switch]
$Dark,
[Parameter(
Mandatory = $true,
ParameterSetName = "Light"
)]
[switch]
$Light
)
switch ($PSCmdlet.ParameterSetName)
{
"Dark"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize -Name SystemUsesLightTheme -PropertyType DWord -Value 0 -Force
}
"Light"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize -Name SystemUsesLightTheme -PropertyType DWord -Value 1 -Force
}
}
}
<#
.SYNOPSIS
The default app mode
.PARAMETER Dark
Set the default app mode to dark
.PARAMETER Light
Set the default app mode to light
.EXAMPLE
AppColorMode -Dark
.EXAMPLE
AppColorMode -Light
.NOTES
Current user
#>
function AppColorMode
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Dark"
)]
[switch]
$Dark,
[Parameter(
Mandatory = $true,
ParameterSetName = "Light"
)]
[switch]
$Light
)
switch ($PSCmdlet.ParameterSetName)
{
"Dark"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize -Name AppsUseLightTheme -PropertyType DWord -Value 0 -Force
}
"Light"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize -Name AppsUseLightTheme -PropertyType DWord -Value 1 -Force
}
}
}
<#
.SYNOPSIS
First sign-in animation after the upgrade
.PARAMETER Disable
Disable first sign-in animation after the upgrade
.PARAMETER Enable
Enable first sign-in animation after the upgrade
.EXAMPLE
FirstLogonAnimation -Disable
.EXAMPLE
FirstLogonAnimation -Enable
.NOTES
Current user
#>
function FirstLogonAnimation
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -Name EnableFirstLogonAnimation -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -Name EnableFirstLogonAnimation -Type CLEAR
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name EnableFirstLogonAnimation -PropertyType DWord -Value 0 -Force
}
"Enable"
{
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name EnableFirstLogonAnimation -PropertyType DWord -Value 1 -Force
}
}
}
<#
.SYNOPSIS
The quality factor of the JPEG desktop wallpapers
.PARAMETER Max
Set the quality factor of the JPEG desktop wallpapers to maximum
.PARAMETER Default
Set the quality factor of the JPEG desktop wallpapers to default
.EXAMPLE
JPEGWallpapersQuality -Max
.EXAMPLE
JPEGWallpapersQuality -Default
.NOTES
Current user
#>
function JPEGWallpapersQuality
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Max"
)]
[switch]
$Max,
[Parameter(
Mandatory = $true,
ParameterSetName = "Default"
)]
[switch]
$Default
)
switch ($PSCmdlet.ParameterSetName)
{
"Max"
{
New-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name JPEGImportQuality -PropertyType DWord -Value 100 -Force
}
"Default"
{
Remove-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name JPEGImportQuality -Force -ErrorAction Ignore
}
}
}
<#
.SYNOPSIS
The "- Shortcut" suffix adding to the name of the created shortcuts
.PARAMETER Disable
Do not add the "- Shortcut" suffix to the file name of created shortcuts
.PARAMETER Enable
Add the "- Shortcut" suffix to the file name of created shortcuts
.EXAMPLE
ShortcutsSuffix -Disable
.EXAMPLE
ShortcutsSuffix -Enable
.NOTES
Current user
#>
function ShortcutsSuffix
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer -Name link -Force -ErrorAction Ignore
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
if (-not (Test-Path -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\NamingTemplates))
{
New-Item -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\NamingTemplates -Force
}
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\NamingTemplates -Name ShortcutNameTemplate -PropertyType String -Value "%s.lnk" -Force
}
"Enable"
{
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\NamingTemplates -Name ShortcutNameTemplate -Force -ErrorAction Ignore
}
}
}
<#
.SYNOPSIS
The Print screen button usage
.PARAMETER Enable
Use the Print screen button to open screen snipping
.PARAMETER Disable
Do not use the Print screen button to open screen snipping
.EXAMPLE
PrtScnSnippingTool -Enable
.EXAMPLE
PrtScnSnippingTool -Disable
.NOTES
Current user
#>
function PrtScnSnippingTool
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
New-ItemProperty -Path "HKCU:\Control Panel\Keyboard" -Name PrintScreenKeyForSnippingEnabled -PropertyType DWord -Value 1 -Force
}
"Disable"
{
New-ItemProperty -Path "HKCU:\Control Panel\Keyboard" -Name PrintScreenKeyForSnippingEnabled -PropertyType DWord -Value 0 -Force
}
}
}
<#
.SYNOPSIS
A different input method for each app window
.PARAMETER Enable
Let me use a different input method for each app window
.PARAMETER Disable
Do not use a different input method for each app window
.EXAMPLE
AppsLanguageSwitch -Enable
.EXAMPLE
AppsLanguageSwitch -Disable
.NOTES
Current user
#>
function AppsLanguageSwitch
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
Set-WinLanguageBarOption -UseLegacySwitchMode
}
"Disable"
{
Set-WinLanguageBarOption
}
}
}
<#
.SYNOPSIS
Title bar window shake
.PARAMETER Enable
When I grab a windows's title bar and shake it, minimize all other windows
.PARAMETER Disable
When I grab a windows's title bar and shake it, don't minimize all other windows
.EXAMPLE
AeroShaking -Enable
.EXAMPLE
AeroShaking -Disable
.NOTES
Current user
#>
function AeroShaking
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKCU:\Software\Policies\Microsoft\Windows\Explorer, HKLM:\Software\Policies\Microsoft\Windows\Explorer -Name NoWindowMinimizingShortcuts -Force -ErrorAction Ignore
Set-Policy -Scope User -Path Software\Policies\Microsoft\Windows\Explorer -Name NoWindowMinimizingShortcuts -Type CLEAR
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\Explorer -Name NoWindowMinimizingShortcuts -Type CLEAR
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name DisallowShaking -PropertyType DWord -Value 0 -Force
}
"Disable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name DisallowShaking -PropertyType DWord -Value 1 -Force
}
}
}
<#
.SYNOPSIS
Free "Windows 11 Cursors Concept" cursors from Jepri Creations
.PARAMETER Dark
Download and install free dark "Windows 11 Cursors Concept" cursors from Jepri Creations
.PARAMETER Light
Download and install free light "Windows 11 Cursors Concept" cursors from Jepri Creations
.PARAMETER Default
Set default cursors
.EXAMPLE
Install-Cursors -Dark
.EXAMPLE
Install-Cursors -Light
.EXAMPLE
Install-Cursors -Default
.LINK
https://www.deviantart.com/jepricreations/art/Windows-11-Cursors-Concept-886489356
.NOTES
The 14/12/24 version
.NOTES
Current user
#>
function Install-Cursors
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Dark"
)]
[switch]
$Dark,
[Parameter(
Mandatory = $true,
ParameterSetName = "Light"
)]
[switch]
$Light,
[Parameter(
Mandatory = $true,
ParameterSetName = "Default"
)]
[switch]
$Default
)
if (-not $Default)
{
$DownloadsFolder = Get-ItemPropertyValue -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" -Name "{374DE290-123F-4565-9164-39C4925E467B}"
try
{
# Download cursors
# The archive was saved in the "Cursors" folder using DeviantArt API via GitHub CI/CD
# https://github.com/farag2/Sophia-Script-for-Windows/tree/master/Cursors
# https://github.com/farag2/Sophia-Script-for-Windows/blob/master/.github/workflows/Cursors.yml
$Parameters = @{
Uri = "https://raw.githubusercontent.com/farag2/Sophia-Script-for-Windows/refs/heads/master/Cursors/Windows11Cursors.zip"
OutFile = "$DownloadsFolder\Windows11Cursors.zip"
UseBasicParsing = $true
Verbose = $true
}
Invoke-WebRequest @Parameters
}
catch [System.Net.WebException]
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.NoResponse -f "https://raw.githubusercontent.com"), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.NoResponse -f "https://raw.githubusercontent.com"), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
}
switch ($PSCmdlet.ParameterSetName)
{
"Dark"
{
if (-not (Test-Path -Path "$env:SystemRoot\Cursors\W11 Cursor Dark Free"))
{
New-Item -Path "$env:SystemRoot\Cursors\W11 Cursor Dark Free" -ItemType Directory -Force
}
# Extract archive from "dark" folder only
& "$env:SystemRoot\System32\tar.exe" -xvf "$DownloadsFolder\Windows11Cursors.zip" -C "$env:SystemRoot\Cursors\W11 Cursor Dark Free" --strip-components=1 dark/
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name "(default)" -PropertyType String -Value "W11 Cursor Dark Free by Jepri Creations" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name AppStarting -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Dark Free\appstarting.ani" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name Arrow -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Dark Free\arrow.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name Crosshair -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Dark Free\crosshair.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name Hand -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Dark Free\hand.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name Help -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Dark Free\help.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name IBeam -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Dark Free\ibeam.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name No -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Dark Free\no.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name NWPen -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Dark Free\nwpen.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name Person -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Dark Free\person.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name Pin -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Dark Free\pin.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name "Scheme Source" -PropertyType DWord -Value 1 -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name SizeAll -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Dark Free\sizeall.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name SizeNESW -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Dark Free\sizenesw.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name SizeNS -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Dark Free\sizens.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name SizeNWSE -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Dark Free\sizenwse.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name SizeWE -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Dark Free\sizewe.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name UpArrow -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Dark Free\uparrow.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name Wait -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Dark Free\wait.ani" -Force
if (-not (Test-Path -Path "HKCU:\Control Panel\Cursors\Schemes"))
{
New-Item -Path "HKCU:\Control Panel\Cursors\Schemes" -Force
}
[string[]]$Schemes = (
"%SystemRoot%\Cursors\W11 Cursor Dark Free\arrow.cur",
"%SystemRoot%\Cursors\W11 Cursor Dark Free\help.cur",
"%SystemRoot%\Cursors\W11 Cursor Dark Free\appstarting.ani",
"%SystemRoot%\Cursors\W11 Cursor Dark Free\wait.ani",
"%SystemRoot%\Cursors\W11 Cursor Dark Free\crosshair.cur",
"%SystemRoot%\Cursors\W11 Cursor Dark Free\ibeam.cur",
"%SystemRoot%\Cursors\W11 Cursor Dark Free\nwpen.cur",
"%SystemRoot%\Cursors\W11 Cursor Dark Free\no.cur",
"%SystemRoot%\Cursors\W11 Cursor Dark Free\sizens.cur",
"%SystemRoot%\Cursors\W11 Cursor Dark Free\sizewe.cur",
"%SystemRoot%\Cursors\W11 Cursor Dark Free\sizenwse.cur",
"%SystemRoot%\Cursors\W11 Cursor Dark Free\sizenesw.cur",
"%SystemRoot%\Cursors\W11 Cursor Dark Free\sizeall.cur",
"%SystemRoot%\Cursors\W11 Cursor Dark Free\uparrow.cur",
"%SystemRoot%\Cursors\W11 Cursor Dark Free\hand.cur",
"%SystemRoot%\Cursors\W11 Cursor Dark Free\person.cur",
"%SystemRoot%\Cursors\W11 Cursor Dark Free\pin.cur"
) -join ","
New-ItemProperty -Path "HKCU:\Control Panel\Cursors\Schemes" -Name "W11 Cursor Dark Free by Jepri Creations" -PropertyType String -Value $Schemes -Force
Start-Sleep -Seconds 1
Remove-Item -Path "$DownloadsFolder\Windows11Cursors.zip", "$env:SystemRoot\Cursors\W11 Cursor Dark Free\Install.inf" -Force -ErrorAction Ignore
}
"Light"
{
if (-not (Test-Path -Path "$env:SystemRoot\Cursors\W11 Cursor Light Free"))
{
New-Item -Path "$env:SystemRoot\Cursors\W11 Cursor Light Free" -ItemType Directory -Force
}
# Extract archive from "light" folder only
& "$env:SystemRoot\System32\tar.exe" -xvf "$DownloadsFolder\Windows11Cursors.zip" -C "$env:SystemRoot\Cursors\W11 Cursor Light Free" --strip-components=1 light/
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name "(default)" -PropertyType String -Value "W11 Cursor Light Free by Jepri Creations" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name AppStarting -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Light Free\appstarting.ani" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name Arrow -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Light Free\arrow.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name Crosshair -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Light Free\crosshair.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name Hand -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Light Free\hand.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name Help -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Light Free\help.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name IBeam -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Light Free\ibeam.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name No -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Light Free\no.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name NWPen -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Light Free\nwpen.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name Person -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Light Free\person.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name Pin -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Light Free\pin.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name "Scheme Source" -PropertyType DWord -Value 1 -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name SizeAll -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Light Free\sizeall.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name SizeNESW -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Light Free\sizenesw.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name SizeNS -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Light Free\sizens.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name SizeNWSE -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Light Free\sizenwse.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name SizeWE -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Light Free\sizewe.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name UpArrow -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Light Free\uparrow.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name Wait -PropertyType ExpandString -Value "%SystemRoot%\Cursors\W11 Cursor Light Free\wait.ani" -Force
if (-not (Test-Path -Path "HKCU:\Control Panel\Cursors\Schemes"))
{
New-Item -Path "HKCU:\Control Panel\Cursors\Schemes" -Force
}
[string[]]$Schemes = (
"%SystemRoot%\Cursors\W11 Cursor Light Free\arrow.cur",
"%SystemRoot%\Cursors\W11 Cursor Light Free\help.cur",
"%SystemRoot%\Cursors\W11 Cursor Light Free\appstarting.ani",
"%SystemRoot%\Cursors\W11 Cursor Light Free\wait.ani",
"%SystemRoot%\Cursors\W11 Cursor Light Free\crosshair.cur",
"%SystemRoot%\Cursors\W11 Cursor Light Free\ibeam.cur",
"%SystemRoot%\Cursors\W11 Cursor Light Free\nwpen.cur",
"%SystemRoot%\Cursors\W11 Cursor Light Free\no.cur",
"%SystemRoot%\Cursors\W11 Cursor Light Free\sizens.cur",
"%SystemRoot%\Cursors\W11 Cursor Light Free\sizewe.cur",
"%SystemRoot%\Cursors\W11 Cursor Light Free\sizenwse.cur",
"%SystemRoot%\Cursors\W11 Cursor Light Free\sizenesw.cur",
"%SystemRoot%\Cursors\W11 Cursor Light Free\sizeall.cur",
"%SystemRoot%\Cursors\W11 Cursor Light Free\uparrow.cur",
"%SystemRoot%\Cursors\W11 Cursor Light Free\hand.cur",
"%SystemRoot%\Cursors\W11 Cursor Light Free\person.cur",
"%SystemRoot%\Cursors\W11 Cursor Light Free\pin.cur"
) -join ","
New-ItemProperty -Path "HKCU:\Control Panel\Cursors\Schemes" -Name "W11 Cursor Light Free by Jepri Creations" -PropertyType String -Value $Schemes -Force
Start-Sleep -Seconds 1
Remove-Item -Path "$DownloadsFolder\Windows11Cursors.zip", "$env:SystemRoot\Cursors\W11 Cursor Light Free\Install.inf" -Force
}
"Default"
{
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name "(default)" -PropertyType String -Value "" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name AppStarting -PropertyType ExpandString -Value "%SystemRoot%\cursors\aero_working.ani" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name Arrow -PropertyType ExpandString -Value "%SystemRoot%\cursors\aero_arrow.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name Crosshair -PropertyType ExpandString -Value "" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name Hand -PropertyType ExpandString -Value "%SystemRoot%\cursors\aero_link.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name Help -PropertyType ExpandString -Value "%SystemRoot%\cursors\aero_helpsel.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name IBeam -PropertyType ExpandString -Value "" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name No -PropertyType ExpandString -Value "%SystemRoot%\cursors\aero_unavail.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name NWPen -PropertyType ExpandString -Value "%SystemRoot%\cursors\aero_pen.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name Person -PropertyType ExpandString -Value "%SystemRoot%\cursors\aero_person.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name Pin -PropertyType ExpandString -Value "%SystemRoot%\cursors\aero_pin.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name "Scheme Source" -PropertyType DWord -Value 2 -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name SizeAll -PropertyType ExpandString -Value "%SystemRoot%\cursors\aero_move.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name SizeNESW -PropertyType ExpandString -Value "%SystemRoot%\cursors\aero_nesw.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name SizeNS -PropertyType ExpandString -Value "%SystemRoot%\cursors\aero_ns.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name SizeNWSE -PropertyType ExpandString -Value "%SystemRoot%\cursors\aero_nwse.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name SizeWE -PropertyType ExpandString -Value "%SystemRoot%\cursors\aero_ew.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name UpArrow -PropertyType ExpandString -Value "%SystemRoot%\cursors\aero_up.cur" -Force
New-ItemProperty -Path "HKCU:\Control Panel\Cursors" -Name Wait -PropertyType ExpandString -Value "%SystemRoot%\cursors\aero_up.cur" -Force
}
}
# Reload cursor on-the-fly
$Signature = @{
Namespace = "WinAPI"
Name = "Cursor"
Language = "CSharp"
CompilerParameters = $CompilerParameters
MemberDefinition = @"
[DllImport("user32.dll", EntryPoint = "SystemParametersInfo")]
public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, uint pvParam, uint fWinIni);
"@
}
if (-not ("WinAPI.Cursor" -as [type]))
{
Add-Type @Signature
}
[WinAPI.Cursor]::SystemParametersInfo(0x0057, 0, $null, 0)
}
<#
.SYNOPSIS
Files and folders grouping in the Downloads folder
.PARAMETER None
Do not group files and folder in the Downloads folder
.PARAMETER Default
Group files and folder by date modified in the Downloads folder
.EXAMPLE
FolderGroupBy -None
.EXAMPLE
FolderGroupBy -Default
.NOTES
Current user
#>
function FolderGroupBy
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "None"
)]
[switch]
$None,
[Parameter(
Mandatory = $true,
ParameterSetName = "Default"
)]
[switch]
$Default
)
switch ($PSCmdlet.ParameterSetName)
{
"None"
{
# Clear any Common Dialog views
Get-ChildItem -Path "HKCU:\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags\*\Shell" -Recurse | Where-Object -FilterScript {$_.PSChildName -eq "{885A186E-A440-4ADA-812B-DB871B942259}"} | Remove-Item -Force
# https://learn.microsoft.com/en-us/windows/win32/properties/props-system-null
if (-not (Test-Path -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FolderTypes\{885a186e-a440-4ada-812b-db871b942259}\TopViews\{00000000-0000-0000-0000-000000000000}"))
{
New-Item -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FolderTypes\{885a186e-a440-4ada-812b-db871b942259}\TopViews\{00000000-0000-0000-0000-000000000000}" -Force
}
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FolderTypes\{885a186e-a440-4ada-812b-db871b942259}\TopViews\{00000000-0000-0000-0000-000000000000}" -Name ColumnList -PropertyType String -Value "System.Null" -Force
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FolderTypes\{885a186e-a440-4ada-812b-db871b942259}\TopViews\{00000000-0000-0000-0000-000000000000}" -Name GroupBy -PropertyType String -Value "System.Null" -Force
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FolderTypes\{885a186e-a440-4ada-812b-db871b942259}\TopViews\{00000000-0000-0000-0000-000000000000}" -Name LogicalViewMode -PropertyType DWord -Value 1 -Force
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FolderTypes\{885a186e-a440-4ada-812b-db871b942259}\TopViews\{00000000-0000-0000-0000-000000000000}" -Name Name -PropertyType String -Value NoName -Force
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FolderTypes\{885a186e-a440-4ada-812b-db871b942259}\TopViews\{00000000-0000-0000-0000-000000000000}" -Name Order -PropertyType DWord -Value 0 -Force
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FolderTypes\{885a186e-a440-4ada-812b-db871b942259}\TopViews\{00000000-0000-0000-0000-000000000000}" -Name PrimaryProperty -PropertyType String -Value "System.ItemNameDisplay" -Force
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FolderTypes\{885a186e-a440-4ada-812b-db871b942259}\TopViews\{00000000-0000-0000-0000-000000000000}" -Name SortByList -PropertyType String -Value "prop:System.ItemNameDisplay" -Force
}
"Default"
{
Remove-Item -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FolderTypes\{885a186e-a440-4ada-812b-db871b942259}" -Recurse -Force -ErrorAction Ignore
}
}
}
<#
.SYNOPSIS
Expand to current folder in navigation pane
.PARAMETER Disable
Do not expand to open folder on navigation pane
.PARAMETER Enable
Expand to open folder on navigation pane
.EXAMPLE
NavigationPaneExpand -Disable
.EXAMPLE
NavigationPaneExpand -Enable
.NOTES
Current user
#>
function NavigationPaneExpand
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name NavPaneExpandToCurrentFolder -PropertyType DWord -Value 0 -Force
}
"Enable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name NavPaneExpandToCurrentFolder -PropertyType DWord -Value 1 -Force
}
}
}
<#
.SYNOPSIS
Recently added apps on Start
.PARAMETER Hide
Hide recently added apps on Start
.PARAMETER Show
Show recently added apps in Start
.EXAMPLE
RecentlyAddedStartApps -Hide
.EXAMPLE
RecentlyAddedStartApps -Show
.NOTES
Current user
#>
function RecentlyAddedStartApps
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Hide"
)]
[switch]
$Hide,
[Parameter(
Mandatory = $true,
ParameterSetName = "Show"
)]
[switch]
$Show
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKCU:\Software\Policies\Microsoft\Windows\Explorer, HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer -Name HideRecentlyAddedApps -Force -ErrorAction Ignore
Set-Policy -Scope User -Path Software\Policies\Microsoft\Windows\Explorer -Name HideRecentlyAddedApps -Type CLEAR
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\Explorer -Name HideRecentlyAddedApps -Type CLEAR
if (Get-Process -Name Start11Srv, StartAllBackCfg, StartMenu -ErrorAction Ignore)
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.CustomStartMenu, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.CustomStartMenu, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
switch ($PSCmdlet.ParameterSetName)
{
"Hide"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Start -Name ShowRecentList -PropertyType DWord -Value 0 -Force
}
"Show"
{
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Start -Name ShowRecentList -Force -ErrorAction Ignore
}
}
}
<#
.SYNOPSIS
Most used apps in Start
.PARAMETER Hide
Hide most used Apps in Start
.PARAMETER Show
Show most used Apps in Start
.EXAMPLE
MostUsedStartApps -Hide
.EXAMPLE
MostUsedStartApps -Show
.NOTES
Current user
#>
function MostUsedStartApps
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Hide"
)]
[switch]
$Hide,
[Parameter(
Mandatory = $true,
ParameterSetName = "Show"
)]
[switch]
$Show
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKCU:\Software\Policies\Microsoft\Windows\Explorer, HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer -Name ShowOrHideMostUsedApps -Force -ErrorAction Ignore
Set-Policy -Scope User -Path Software\Policies\Microsoft\Windows\Explorer -Name ShowOrHideMostUsedApps -Type CLEAR
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\Explorer -Name ShowOrHideMostUsedApps -Type CLEAR
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer, HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -Name NoStartMenuMFUprogramsList, NoInstrumentation -Force -ErrorAction Ignore
Set-Policy -Scope User -Path Software\Microsoft\Windows\CurrentVersion\Policies\Explorer -Name NoStartMenuMFUprogramsList -Type CLEAR
Set-Policy -Scope User -Path Software\Microsoft\Windows\CurrentVersion\Policies\Explorer -Name NoInstrumentation -Type CLEAR
Set-Policy -Scope Computer -Path SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -Name NoStartMenuMFUprogramsList -Type CLEAR
Set-Policy -Scope Computer -Path SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -Name NoInstrumentation -Type CLEAR
if (Get-Process -Name Start11Srv, StartAllBackCfg, StartMenu -ErrorAction Ignore)
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.CustomStartMenu, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.CustomStartMenu, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
switch ($PSCmdlet.ParameterSetName)
{
"Hide"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Start -Name ShowFrequentList -PropertyType DWord -Value 0 -Force
}
"Show"
{
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Start -Name ShowFrequentList -Force -ErrorAction Ignore
}
}
}
<#
.SYNOPSIS
Recommended section in Start
.PARAMETER Hide
Hide recommended section in Start
.PARAMETER Show
Show remove recommended section in Start
.EXAMPLE
StartRecommendedSection -Hide
.EXAMPLE
StartRecommendedSection -Show
.NOTES
Current user
#>
function StartRecommendedSection
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Hide"
)]
[switch]
$Hide,
[Parameter(
Mandatory = $true,
ParameterSetName = "Show"
)]
[switch]
$Show
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKCU:\Software\Policies\Microsoft\Windows\Explorer, HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer -Name HideRecommendedSection -Force -ErrorAction Ignore
Set-Policy -Scope User -Path Software\Policies\Microsoft\Windows\Explorer -Name HideRecommendedSection -Type CLEAR
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\Explorer -Name HideRecommendedSection -Type CLEAR
Remove-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\PolicyManager\current\device\Education -Name IsEducationEnvironment -Force -ErrorAction Ignore
Remove-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\PolicyManager\current\device\Start -Name HideRecommendedSection -Force -ErrorAction Ignore
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer, HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -Name NoRecentDocsHistory -Force -ErrorAction Ignore
Set-Policy -Scope User -Path Software\Microsoft\Windows\CurrentVersion\Policies\Explorer -Name NoRecentDocsHistory -Type CLEAR
Set-Policy -Scope Computer -Path SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -Name NoRecentDocsHistory -Type CLEAR
Remove-ItemProperty -Path HKCU:\Software\Policies\Microsoft\Windows\Explorer, HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer -Name HideRecentlyAddedApps -Force -ErrorAction Ignore
Set-Policy -Scope User -Path Software\Policies\Microsoft\Windows\Explorer -Name HideRecentlyAddedApps -Type CLEAR
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\Explorer -Name HideRecentlyAddedApps -Type CLEAR
Remove-ItemProperty -Path HKCU:\Software\Policies\Microsoft\Windows\Explorer, HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer -Name ShowOrHideMostUsedApps -Force -ErrorAction Ignore
Set-Policy -Scope User -Path Software\Policies\Microsoft\Windows\Explorer -Name ShowOrHideMostUsedApps -Type CLEAR
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\Explorer -Name ShowOrHideMostUsedApps -Type CLEAR
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer, HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -Name NoStartMenuMFUprogramsList, NoInstrumentation -Force -ErrorAction Ignore
Set-Policy -Scope User -Path Software\Microsoft\Windows\CurrentVersion\Policies\Explorer -Name NoStartMenuMFUprogramsList -Type CLEAR
Set-Policy -Scope User -Path Software\Microsoft\Windows\CurrentVersion\Policies\Explorer -Name NoInstrumentation -Type CLEAR
Set-Policy -Scope Computer -Path SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -Name NoStartMenuMFUprogramsList -Type CLEAR
Set-Policy -Scope Computer -Path SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -Name NoInstrumentation -Type CLEAR
if (Get-Process -Name Start11Srv, StartAllBackCfg, StartMenu -ErrorAction Ignore)
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.CustomStartMenu, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.CustomStartMenu, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
switch ($PSCmdlet.ParameterSetName)
{
"Hide"
{
# Hide recently added apps in Start
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Start -Name ShowRecentList -PropertyType DWord -Value 0 -Force
# Hide most used Apps in Start
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Start -Name ShowFrequentList -PropertyType DWord -Value 0 -Force
# Hide recommendations for tips, shortcuts, new apps, and more in Start
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name Start_IrisRecommendations -PropertyType DWord -Value 0 -Force
# Hide recommended files in Start, recent files in File Explorer, and items in jump lists
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name Start_TrackDocs -PropertyType DWord -Value 0 -Force
}
"Show"
{
# Show recently added apps in Start
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Start -Name ShowRecentList -Force -ErrorAction Ignore
# Show most used Apps in Start
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Start -Name ShowFrequentList -Force -ErrorAction Ignore
# Show recommendations for tips, shortcuts, new apps, and more in Start
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name Start_IrisRecommendations -Force -ErrorAction Ignore
# Show recommended files in Start, recent files in File Explorer, and items in jump lists
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name Start_TrackDocs -Force -ErrorAction Ignore
}
}
}
<#
.SYNOPSIS
Recommendations for tips, shortcuts, new apps, and more in Start
.PARAMETER Hide
Hide recommendations for tips, shortcuts, new apps, and more in Start
.PARAMETER Show
Show recommendations for tips, shortcuts, new apps, and more in Start
.EXAMPLE
StartRecommendationsTips -Hide
.EXAMPLE
StartRecommendationsTips -Show
.NOTES
Current user
#>
function StartRecommendationsTips
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Hide"
)]
[switch]
$Hide,
[Parameter(
Mandatory = $true,
ParameterSetName = "Show"
)]
[switch]
$Show
)
if (Get-Process -Name Start11Srv, StartAllBackCfg, StartMenu -ErrorAction Ignore)
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.CustomStartMenu, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.CustomStartMenu, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
switch ($PSCmdlet.ParameterSetName)
{
"Hide"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name Start_IrisRecommendations -PropertyType DWord -Value 0 -Force
}
"Show"
{
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name Start_IrisRecommendations -Force -ErrorAction Ignore
}
}
}
<#
.SYNOPSIS
Microsoft account-related notifications in Start
.PARAMETER Hide
Hide Microsoft account-related notifications in Start
.PARAMETER Show
Show Microsoft account-related notifications in Start
.EXAMPLE
StartAccountNotifications -Hide
.EXAMPLE
StartAccountNotifications -Show
.NOTES
Current user
#>
function StartAccountNotifications
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Hide"
)]
[switch]
$Hide,
[Parameter(
Mandatory = $true,
ParameterSetName = "Show"
)]
[switch]
$Show
)
if (Get-Process -Name Start11Srv, StartAllBackCfg, StartMenu -ErrorAction Ignore)
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.CustomStartMenu, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.CustomStartMenu, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
switch ($PSCmdlet.ParameterSetName)
{
"Hide"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name Start_AccountNotifications -PropertyType DWord -Value 0 -Force
}
"Show"
{
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name Start_AccountNotifications -Force -ErrorAction Ignore
}
}
}
<#
.SYNOPSIS
Configure Start layout
.PARAMETER Default
Show default Start layout
.PARAMETER ShowMorePins
Show more pins on Start
.PARAMETER ShowMoreRecommendations
Show more recommendations on Start
.EXAMPLE
StartLayout -Default
.EXAMPLE
StartLayout -ShowMorePins
.EXAMPLE
StartLayout -ShowMoreRecommendations
.NOTES
Current user
#>
function StartLayout
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Default"
)]
[switch]
$Default,
[Parameter(
Mandatory = $true,
ParameterSetName = "ShowMorePins"
)]
[switch]
$ShowMorePins,
[Parameter(
Mandatory = $true,
ParameterSetName = "ShowMoreRecommendations"
)]
[switch]
$ShowMoreRecommendations
)
if (Get-Process -Name Start11Srv, StartAllBackCfg, StartMenu -ErrorAction Ignore)
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.CustomStartMenu, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.CustomStartMenu, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
switch ($PSCmdlet.ParameterSetName)
{
"Default"
{
# Default
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name Start_Layout -PropertyType DWord -Value 0 -Force
}
"ShowMorePins"
{
# Show More Pins
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name Start_Layout -PropertyType DWord -Value 1 -Force
}
"ShowMoreRecommendations"
{
# Show More Recommendations
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name Start_Layout -PropertyType DWord -Value 2 -Force
}
}
}
#endregion UI & Personalization
#region OneDrive
<#
.SYNOPSIS
OneDrive
.PARAMETER Uninstall
Uninstall OneDrive
.PARAMETER Install
Install OneDrive depending which installer is triggered
.PARAMETER Install -AllUsers
Install OneDrive for all users to %ProgramFiles% depending which installer is triggered
.EXAMPLE
OneDrive -Uninstall
.EXAMPLE
OneDrive -Install
.EXAMPLE
OneDrive -Install -AllUsers
.NOTES
OneDrive user folder won't be removed if any file found there
.NOTES
Machine-wide
#>
function OneDrive
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Uninstall"
)]
[switch]
$Uninstall,
[Parameter(
Mandatory = $true,
ParameterSetName = "Install"
)]
[switch]
$Install,
[switch]
$AllUsers
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKLM:\Policies\Microsoft\Windows\OneDrive -Name DisableFileSyncNGSC -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\OneDrive -Name DisableFileSyncNGSC -Type CLEAR
switch ($PSCmdlet.ParameterSetName)
{
"Uninstall"
{
# {$_.Meta.Attributes["UninstallString"]} is broken
[xml]$UninstallString = Get-Package -Name "Microsoft OneDrive" -ErrorAction Ignore | ForEach-Object -Process {$_.SwidTagText}
[string]$UninstallString = $UninstallString.SoftwareIdentity.Meta.UninstallString
if (-not $UninstallString)
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.OneDriveNotInstalled, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.OneDriveNotInstalled, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
# Checking whether user is logged into OneDrive (Microsoft account)
$UserEmailPersonal = Get-ItemProperty -Path HKCU:\Software\Microsoft\OneDrive\Accounts\Personal -Name UserEmail -ErrorAction Ignore
$UserEmailBusiness = Get-ItemProperty -Path HKCU:\Software\Microsoft\OneDrive\Accounts\Business1 -Name UserEmail -ErrorAction Ignore
if ($UserEmailPersonal -or $UserEmailBusiness)
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.OneDriveAccountWarning, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.OneDriveAccountWarning, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.UninstallNotification -f "OneDrive") -Verbose
Write-Information -MessageData "" -InformationAction Continue
Stop-Process -Name OneDrive, OneDriveSetup, FileCoAuth -Force -ErrorAction Ignore
# Getting link to the OneDriveSetup.exe and its argument(s)
[string[]]$OneDriveSetup = ($UninstallString -replace("\s*/", ",/")).Split(",").Trim()
Start-Process -FilePath $OneDriveSetup[0] -ArgumentList $OneDriveSetup[1..$OneDriveSetup.Count] -Wait
# Get the OneDrive user folder path and remove it if it doesn't contain any user files
if (Test-Path -Path $env:OneDrive)
{
if ((Get-ChildItem -Path $env:OneDrive -ErrorAction Ignore | Measure-Object).Count -eq 0)
{
Remove-Item -Path $env:OneDrive -Recurse -Force -ErrorAction Ignore
}
else
{
# That means that some files are left
Start-Process -FilePath "$env:SystemRoot\explorer.exe" -ArgumentList $env:OneDrive
}
}
# Do not restart File Explorer process automatically if it stops in order to unload libraries
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name AutoRestartShell -PropertyType DWord -Value 0 -Force
# Kill all explorer instances in case "launch folder windows in a separate process" enabled
Get-Process -Name explorer | Stop-Process -Force
Write-Information -MessageData "" -InformationAction Continue
# Extract the localized "Please wait..." string from %SystemRoot%\System32\shell32.dll
Write-Verbose -Message ([WinAPI.GetStrings]::GetString(12612)) -Verbose
Start-Sleep -Seconds 3
# Restart File Explorer process automatically if it stops in order to unload libraries
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name AutoRestartShell -PropertyType DWord -Value 1 -Force
Get-Process -Name UserOOBEBroker -ErrorAction Ignore | Stop-Process -Force
Get-ChildItem -Path "$OneDriveFolder\*\FileSyncShell64.dll" -Force | Foreach-Object -Process {
Start-Process -FilePath "$env:SystemRoot\System32\regsvr32.exe" -ArgumentList "/u /s $FileSyncShell64dll" -Wait
}
# Getting OneDrive folder path
$OneDriveFolder = (Split-Path -Path (Split-Path -Path $OneDriveSetup[0] -Parent)) -replace '"', ""
Remove-Item -Path $OneDriveFolder -Force -Recurse -ErrorAction Ignore
# We need to wait for a few seconds to let explore launch unless it will fail to do so
Start-Process -FilePath "$env:SystemRoot\explorer.exe"
Write-Information -MessageData "" -InformationAction Continue
# Extract the localized "Please wait..." string from %SystemRoot%\System32\shell32.dll
Write-Verbose -Message ([WinAPI.GetStrings]::GetString(12612)) -Verbose
Start-Sleep -Seconds 3
Remove-ItemProperty -Path HKCU:\Environment -Name OneDrive, OneDriveConsumer -Force -ErrorAction Ignore
Unregister-ScheduledTask -TaskName *OneDrive* -Confirm:$false -ErrorAction Ignore
$Path = @(
"$env:LOCALAPPDATA\OneDrive",
"$env:LOCALAPPDATA\Microsoft\OneDrive",
"$env:LOCALAPPDATA\Microsoft\OneAuth",
"$env:APPDATA\Microsoft\Windows\Start Menu\Programs\OneDrive.lnk",
"$env:ProgramData\Microsoft OneDrive",
"$env:ProgramFiles\Microsoft OneDrive",
"$env:SystemDrive\OneDriveTemp",
"HKCU:\Software\Microsoft\OneDrive"
)
Remove-Item -Path $Path -Recurse -Force -ErrorAction Ignore
}
"Install"
{
$OneDrive = Get-Package -Name "Microsoft OneDrive" -Force -ErrorAction Ignore
if ($OneDrive)
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.OneDriveInstalled, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.OneDriveInstalled, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.InstallNotification -f "OneDrive") -Verbose
Write-Information -MessageData "" -InformationAction Continue
if (Test-Path -Path $env:SystemRoot\System32\OneDriveSetup.exe)
{
if ($AllUsers)
{
# Install OneDrive for all users to %ProgramFiles%
& $env:SystemRoot\System32\OneDriveSetup.exe /allusers
}
else
{
Start-Process -FilePath $env:SystemRoot\System32\OneDriveSetup.exe
}
}
else
{
try
{
# Downloading the latest OneDrive installer 64-bit
# https://go.microsoft.com/fwlink/p/?LinkID=844652
$Parameters = @{
Uri = "https://g.live.com/1rewlive5skydrive/OneDriveProductionV2"
UseBasicParsing = $true
Verbose = $true
}
$Content = Invoke-RestMethod @Parameters
# Remove invalid chars
[xml]$OneDriveXML = $Content -replace "ï¿", ""
$OneDriveURL = $OneDriveXML.root.update.amd64binary.url | Select-Object -Index 1
$DownloadsFolder = Get-ItemPropertyValue -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" -Name "{374DE290-123F-4565-9164-39C4925E467B}"
$Parameters = @{
Uri = $OneDriveURL
OutFile = "$DownloadsFolder\OneDriveSetup.exe"
UseBasicParsing = $true
Verbose = $true
}
Invoke-WebRequest @Parameters
if ($AllUsers)
{
# Install OneDrive for all users to %ProgramFiles%
& "$DownloadsFolder\OneDriveSetup.exe" /allusers
}
else
{
Start-Process -FilePath "$DownloadsFolder\OneDriveSetup.exe"
}
Start-Sleep -Seconds 3
Get-Process -Name OneDriveSetup -ErrorAction Ignore | Stop-Process -Force
Remove-Item -Path "$DownloadsFolder\OneDriveSetup.exe" -Force
}
catch [System.Net.WebException]
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.NoResponse -f "https://oneclient.sfx.ms"), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.NoResponse -f "https://oneclient.sfx.ms"), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
}
# Save screenshots in the Pictures folder when pressing Windows+PrtScr or using Windows+Shift+S
Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" -Name "{B7BEDE81-DF94-4682-A7D8-57A52620B86F}" -Force -ErrorAction Ignore
Get-ScheduledTask -TaskName "Onedrive* Update*" | Enable-ScheduledTask
Get-ScheduledTask -TaskName "Onedrive* Update*" | Start-ScheduledTask
}
}
}
#endregion OneDrive
#region System
<#
.SYNOPSIS
Storage Sense
.PARAMETER Enable
Turn on Storage Sense
.PARAMETER Disable
Turn off Storage Sense
.EXAMPLE
StorageSense -Enable
.EXAMPLE
StorageSense -Disable
.NOTES
Current user
#>
function StorageSense
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\StorageSense -Name AllowStorageSenseGlobal -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\StorageSense -Name AllowStorageSenseGlobal -Type CLEAR
if (-not (Test-Path -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\StorageSense\Parameters\StoragePolicy))
{
New-Item -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\StorageSense\Parameters\StoragePolicy -ItemType Directory -Force
}
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
# Turn on Storage Sense
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\StorageSense\Parameters\StoragePolicy -Name 01 -PropertyType DWord -Value 1 -Force
# Turn on automatic cleaning up temporary system and app files
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\StorageSense\Parameters\StoragePolicy -Name 04 -PropertyType DWord -Value 1 -Force
# Run Storage Sense every month
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\StorageSense\Parameters\StoragePolicy -Name 2048 -PropertyType DWord -Value 30 -Force
}
"Disable"
{
# Turn off Storage Sense
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\StorageSense\Parameters\StoragePolicy -Name 01 -PropertyType DWord -Value 0 -Force
# Turn off automatic cleaning up temporary system and app files
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\StorageSense\Parameters\StoragePolicy -Name 04 -PropertyType DWord -Value 0 -Force
# Run Storage Sense during low free disk space
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\StorageSense\Parameters\StoragePolicy -Name 2048 -PropertyType DWord -Value 0 -Force
}
}
}
<#
.SYNOPSIS
Hibernation
.PARAMETER Disable
Disable hibernation
.PARAMETER Enable
Enable hibernation
.EXAMPLE
Hibernation -Enable
.EXAMPLE
Hibernation -Disable
.NOTES
Not recommended to turn off for laptops
.NOTES
Current user
#>
function Hibernation
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
& "$env:SystemRoot\System32\powercfg.exe" /HIBERNATE OFF
}
"Enable"
{
& "$env:SystemRoot\System32\powercfg.exe" /HIBERNATE ON
}
}
}
<#
.SYNOPSIS
Windows 260 character paths support limit
.PARAMETER Enable
Enable Windows long paths support which is limited for 260 characters by default
.PARAMETER Disable
Disable Windows long paths support which is limited for 260 characters by default
.EXAMPLE
Win32LongPathsSupport -Enable
.EXAMPLE
Win32LongPathsSupport -Disable
.NOTES
Machine-wide
#>
function Win32LongPathsSupport
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem -Name LongPathsEnabled -PropertyType DWord -Value 1 -Force
Set-Policy -Scope Computer -Path SYSTEM\CurrentControlSet\Control\FileSystem -Name LongPathsEnabled -Type DWORD -Value 1
}
"Disable"
{
New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem -Name LongPathsEnabled -PropertyType DWord -Value 0 -Force
Set-Policy -Scope Computer -Path SYSTEM\CurrentControlSet\Control\FileSystem -Name LongPathsEnabled -Type DWORD -Value 0
}
}
}
<#
.SYNOPSIS
Stop error code when BSoD occurs
.PARAMETER Enable
Display Stop error code when BSoD occurs
.PARAMETER Disable
Do not display stop error code when BSoD occurs
.EXAMPLE
BSoDStopError -Enable
.EXAMPLE
BSoDStopError -Disable
.NOTES
Machine-wide
#>
function BSoDStopError
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl -Name DisplayParameters -PropertyType DWord -Value 1 -Force
}
"Disable"
{
New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl -Name DisplayParameters -PropertyType DWord -Value 0 -Force
}
}
}
<#
.SYNOPSIS
The User Account Control (UAC) behavior
.PARAMETER Never
Never notify
.PARAMETER Default
Notify me only when apps try to make changes to my computer
.EXAMPLE
AdminApprovalMode -Never
.EXAMPLE
AdminApprovalMode -Default
.NOTES
Machine-wide
#>
function AdminApprovalMode
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Never"
)]
[switch]
$Never,
[Parameter(
Mandatory = $true,
ParameterSetName = "Default"
)]
[switch]
$Default
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -Name FilterAdministratorToken -Force -ErrorAction Ignore
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -Name ConsentPromptBehaviorUser -PropertyType DWord -Value 3 -Force
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -Name EnableInstallerDetection -PropertyType DWord -Value 1 -Force
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -Name ValidateAdminCodeSignatures -PropertyType DWord -Value 0 -Force
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -Name EnableSecureUIAPaths -PropertyType DWord -Value 1 -Force
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -Name EnableLUA -PropertyType DWord -Value 1 -Force
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -Name PromptOnSecureDesktop -PropertyType DWord -Value 1 -Force
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -Name EnableVirtualization -PropertyType DWord -Value 1 -Force
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -Name EnableUIADesktopToggle -PropertyType DWord -Value 1 -Force
switch ($PSCmdlet.ParameterSetName)
{
"Never"
{
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -Name ConsentPromptBehaviorAdmin -PropertyType DWord -Value 0 -Force
}
"Default"
{
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -Name ConsentPromptBehaviorAdmin -PropertyType DWord -Value 5 -Force
}
}
}
<#
.SYNOPSIS
Delivery Optimization
.PARAMETER Disable
Turn off Delivery Optimization
.PARAMETER Enable
Turn on Delivery Optimization
.EXAMPLE
DeliveryOptimization -Disable
.EXAMPLE
DeliveryOptimization -Enable
.NOTES
Current user
#>
function DeliveryOptimization
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeliveryOptimization -Name DODownloadMode -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\DeliveryOptimization -Name DODownloadMode -Type CLEAR
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
New-ItemProperty -Path Registry::HKEY_USERS\S-1-5-20\SOFTWARE\Microsoft\Windows\CurrentVersion\DeliveryOptimization\Settings -Name DownloadMode -PropertyType DWord -Value 0 -Force
Delete-DeliveryOptimizationCache -Force
}
"Enable"
{
New-ItemProperty -Path Registry::HKEY_USERS\S-1-5-20\SOFTWARE\Microsoft\Windows\CurrentVersion\DeliveryOptimization\Settings -Name DownloadMode -PropertyType DWord -Value 1 -Force
}
}
}
<#
.SYNOPSIS
Windows manages my default printer
.PARAMETER Disable
Do not let Windows manage my default printer
.PARAMETER Enable
Let Windows manage my default printer
.EXAMPLE
WindowsManageDefaultPrinter -Disable
.EXAMPLE
WindowsManageDefaultPrinter -Enable
.NOTES
Current user
#>
function WindowsManageDefaultPrinter
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
Set-Policy -Scope User -Path "Software\Microsoft\Windows NT\CurrentVersion\Windows" -Name LegacyDefaultPrinterMode -Type CLEAR
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Windows" -Name LegacyDefaultPrinterMode -PropertyType DWord -Value 1 -Force
}
"Enable"
{
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Windows" -Name LegacyDefaultPrinterMode -PropertyType DWord -Value 0 -Force
}
}
}
<#
.SYNOPSIS
Windows features
.PARAMETER Disable
Disable Windows features
.PARAMETER Enable
Enable Windows features
.EXAMPLE
WindowsFeatures -Disable
.EXAMPLE
WindowsFeatures -Enable
.NOTES
Current user
#>
function WindowsFeatures
{
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 Windows features
$SelectedFeatures = New-Object -TypeName System.Collections.ArrayList($null)
# The following Windows features will have their checkboxes checked
[string[]]$CheckedFeatures = @(
# Legacy Components
"LegacyComponents",
# PowerShell 2.0
"MicrosoftWindowsPowerShellV2",
"MicrosoftWindowsPowershellV2Root",
# Microsoft XPS Document Writer
"Printing-XPSServices-Features",
# Recall
"Recall"
# Work Folders Client
"WorkFolders-Client"
)
# The following Windows features will have their checkboxes unchecked
[string[]]$UncheckedFeatures = @(
# Media Features
# If you want to leave "Multimedia settings" in the advanced settings of Power Options do not disable this feature
"MediaPlayback"
)
#endregion Variables
#region XAML Markup
# The section defines the design of the upcoming dialog box
[xml]$XAML = @"
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Name="Window"
MinHeight="450" MinWidth="400"
SizeToContent="WidthAndHeight" WindowStartupLocation="CenterScreen"
TextOptions.TextFormattingMode="Display" SnapsToDevicePixels="True"
FontFamily="Candara" FontSize="16" ShowInTaskbar="True"
Background="#F1F1F1" Foreground="#262626">
<Window.Resources>
<Style TargetType="StackPanel">
<Setter Property="Orientation" Value="Horizontal"/>
<Setter Property="VerticalAlignment" Value="Top"/>
</Style>
<Style TargetType="CheckBox">
<Setter Property="Margin" Value="10, 10, 5, 10"/>
<Setter Property="IsChecked" Value="True"/>
</Style>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="5, 10, 10, 10"/>
</Style>
<Style TargetType="Button">
<Setter Property="Margin" Value="20"/>
<Setter Property="Padding" Value="10"/>
</Style>
<Style TargetType="Border">
<Setter Property="Grid.Row" Value="1"/>
<Setter Property="CornerRadius" Value="0"/>
<Setter Property="BorderThickness" Value="0, 1, 0, 1"/>
<Setter Property="BorderBrush" Value="#000000"/>
</Style>
<Style TargetType="ScrollViewer">
<Setter Property="HorizontalScrollBarVisibility" Value="Disabled"/>
<Setter Property="BorderBrush" Value="#000000"/>
<Setter Property="BorderThickness" Value="0, 1, 0, 1"/>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ScrollViewer Name="Scroll" Grid.Row="0"
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto">
<StackPanel Name="PanelContainer" Orientation="Vertical"/>
</ScrollViewer>
<Button Name="Button" Grid.Row="2"/>
</Grid>
</Window>
"@
#endregion XAML Markup
$Form = [Windows.Markup.XamlReader]::Load((New-Object -TypeName System.Xml.XmlNodeReader -ArgumentList $XAML))
$XAML.SelectNodes("//*[@*[contains(translate(name(.),'n','N'),'Name')]]") | ForEach-Object -Process {
Set-Variable -Name $_.Name -Value $Form.FindName($_.Name)
}
#region Functions
function Get-CheckboxClicked
{
[CmdletBinding()]
param
(
[Parameter(
Mandatory = $true,
ValueFromPipeline = $true
)]
[ValidateNotNull()]
$CheckBox
)
$Feature = $Features | Where-Object -FilterScript {$_.DisplayName -eq $CheckBox.Parent.Children[1].Text}
if ($CheckBox.IsChecked)
{
[void]$SelectedFeatures.Add($Feature)
}
else
{
[void]$SelectedFeatures.Remove($Feature)
}
if ($SelectedFeatures.Count -gt 0)
{
$Button.IsEnabled = $true
}
else
{
$Button.IsEnabled = $false
}
}
function DisableButton
{
Write-Information -MessageData "" -InformationAction Continue
# Extract the localized "Please wait..." string from %SystemRoot%\System32\shell32.dll
Write-Verbose -Message ([WinAPI.GetStrings]::GetString(12612)) -Verbose
[void]$Window.Close()
$SelectedFeatures | ForEach-Object -Process {Write-Verbose -Message $_.DisplayName -Verbose}
$SelectedFeatures | Disable-WindowsOptionalFeature -Online -NoRestart
}
function EnableButton
{
Write-Information -MessageData "" -InformationAction Continue
# Extract the localized "Please wait..." string from %SystemRoot%\System32\shell32.dll
Write-Verbose -Message ([WinAPI.GetStrings]::GetString(12612)) -Verbose
[void]$Window.Close()
$SelectedFeatures | ForEach-Object -Process {Write-Verbose -Message $_.DisplayName -Verbose}
$SelectedFeatures | Enable-WindowsOptionalFeature -Online -All -NoRestart
}
function Add-FeatureControl
{
[CmdletBinding()]
param
(
[Parameter(
Mandatory = $true,
ValueFromPipeline = $true
)]
[ValidateNotNull()]
$Feature
)
process
{
$CheckBox = New-Object -TypeName System.Windows.Controls.CheckBox
$CheckBox.Add_Click({Get-CheckboxClicked -CheckBox $_.Source})
$CheckBox.ToolTip = $Feature.Description
$TextBlock = New-Object -TypeName System.Windows.Controls.TextBlock
$TextBlock.Text = $Feature.DisplayName
$TextBlock.ToolTip = $Feature.Description
$StackPanel = New-Object -TypeName System.Windows.Controls.StackPanel
[void]$StackPanel.Children.Add($CheckBox)
[void]$StackPanel.Children.Add($TextBlock)
[void]$PanelContainer.Children.Add($StackPanel)
$CheckBox.IsChecked = $true
# If feature checked add to the array list
if ($UnCheckedFeatures | Where-Object -FilterScript {$Feature.FeatureName -like $_})
{
$CheckBox.IsChecked = $false
# Exit function if item is not checked
return
}
# If feature checked add to the array list
[void]$SelectedFeatures.Add($Feature)
}
}
#endregion Functions
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
$State = @("Disabled", "DisablePending")
$ButtonContent = $Localization.Enable
$ButtonAdd_Click = {EnableButton}
}
"Disable"
{
$State = @("Enabled", "EnablePending")
$ButtonContent = $Localization.Disable
$ButtonAdd_Click = {DisableButton}
}
}
Write-Information -MessageData "" -InformationAction Continue
# Extract the localized "Please wait..." string from %SystemRoot%\System32\shell32.dll
Write-Verbose -Message ([WinAPI.GetStrings]::GetString(12612)) -Verbose
# Getting list of all optional features according to the conditions
$OFS = "|"
$Features = Get-WindowsOptionalFeature -Online | Where-Object -FilterScript {
($_.State -in $State) -and (($_.FeatureName -match $UncheckedFeatures) -or ($_.FeatureName -match $CheckedFeatures))
} | ForEach-Object -Process {Get-WindowsOptionalFeature -FeatureName $_.FeatureName -Online}
$OFS = " "
if (-not $Features)
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.NoWindowsFeatures, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.NoWindowsFeatures, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
#region Sendkey function
# Emulate the Backspace key sending to prevent the console window to freeze
Start-Sleep -Milliseconds 500
Add-Type -AssemblyName System.Windows.Forms
# We cannot use Get-Process -Id $PID as script might be invoked via Terminal with different $PID
Get-Process -Name powershell, WindowsTerminal -ErrorAction Ignore | Where-Object -FilterScript {$_.MainWindowTitle -match "Sophia Script for Windows 11"} | ForEach-Object -Process {
# Show window, if minimized
[WinAPI.ForegroundWindow]::ShowWindowAsync($_.MainWindowHandle, 10)
Start-Sleep -Seconds 1
# Force move the console window to the foreground
[WinAPI.ForegroundWindow]::SetForegroundWindow($_.MainWindowHandle)
Start-Sleep -Seconds 1
# Emulate the Backspace key sending
[System.Windows.Forms.SendKeys]::SendWait("{BACKSPACE 1}")
}
#endregion Sendkey function
$Window.Add_Loaded({$Features | Add-FeatureControl})
$Button.Content = $ButtonContent
$Button.Add_Click({& $ButtonAdd_Click})
$Window.Title = $Localization.WindowsFeaturesTitle
# Force move the WPF form to the foreground
$Window.Add_Loaded({$Window.Activate()})
$Form.ShowDialog() | Out-Null
}
<#
.SYNOPSIS
Optional features
.PARAMETER Uninstall
Uninstall optional features
.PARAMETER Install
Install optional features
.EXAMPLE
WindowsCapabilities -Uninstall
.EXAMPLE
WindowsCapabilities -Install
.NOTES
Current user
#>
function WindowsCapabilities
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Uninstall"
)]
[switch]
$Uninstall,
[Parameter(
Mandatory = $true,
ParameterSetName = "Install"
)]
[switch]
$Install
)
Add-Type -AssemblyName PresentationCore, PresentationFramework
#region Variables
# Initialize an array list to store the selected optional features
$SelectedCapabilities = New-Object -TypeName System.Collections.ArrayList($null)
# The following optional features will have their checkboxes checked
[string[]]$CheckedCapabilities = @(
# Steps Recorder
"App.StepsRecorder*"
)
# The following optional features will have their checkboxes unchecked
[string[]]$UncheckedCapabilities = @(
# Internet Explorer mode
"Browser.InternetExplorer*",
# Windows Media Player
# If you want to leave "Multimedia settings" element in the advanced settings of Power Options do not uninstall this feature
"Media.WindowsMediaPlayer*"
)
# The following optional features will be excluded from the display
[string[]]$ExcludedCapabilities = @(
# The DirectX Database to configure and optimize apps when multiple Graphics Adapters are present
"DirectX.Configuration.Database*",
# Language components
"Language.*",
# Notepad
"Microsoft.Windows.Notepad*",
# Mail, contacts, and calendar sync component
"OneCoreUAP.OneSync*",
# Windows PowerShell Intergrated Scripting Enviroment
"Microsoft.Windows.PowerShell.ISE*",
# Management of printers, printer drivers, and printer servers
"Print.Management.Console*",
# Features critical to Windows functionality
"Windows.Client.ShellComponents*"
)
#endregion Variables
#region XAML Markup
# The section defines the design of the upcoming dialog box
[xml]$XAML = @"
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Name="Window"
MinHeight="450" MinWidth="400"
SizeToContent="WidthAndHeight" WindowStartupLocation="CenterScreen"
TextOptions.TextFormattingMode="Display" SnapsToDevicePixels="True"
FontFamily="Candara" FontSize="16" ShowInTaskbar="True"
Background="#F1F1F1" Foreground="#262626">
<Window.Resources>
<Style TargetType="StackPanel">
<Setter Property="Orientation" Value="Horizontal"/>
<Setter Property="VerticalAlignment" Value="Top"/>
</Style>
<Style TargetType="CheckBox">
<Setter Property="Margin" Value="10, 10, 5, 10"/>
<Setter Property="IsChecked" Value="True"/>
</Style>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="5, 10, 10, 10"/>
</Style>
<Style TargetType="Button">
<Setter Property="Margin" Value="20"/>
<Setter Property="Padding" Value="10"/>
</Style>
<Style TargetType="Border">
<Setter Property="Grid.Row" Value="1"/>
<Setter Property="CornerRadius" Value="0"/>
<Setter Property="BorderThickness" Value="0, 1, 0, 1"/>
<Setter Property="BorderBrush" Value="#000000"/>
</Style>
<Style TargetType="ScrollViewer">
<Setter Property="HorizontalScrollBarVisibility" Value="Disabled"/>
<Setter Property="BorderBrush" Value="#000000"/>
<Setter Property="BorderThickness" Value="0, 1, 0, 1"/>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ScrollViewer Name="Scroll" Grid.Row="0"
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto">
<StackPanel Name="PanelContainer" Orientation="Vertical"/>
</ScrollViewer>
<Button Name="Button" Grid.Row="2"/>
</Grid>
</Window>
"@
#endregion XAML Markup
$Form = [Windows.Markup.XamlReader]::Load((New-Object -TypeName System.Xml.XmlNodeReader -ArgumentList $XAML))
$XAML.SelectNodes("//*[@*[contains(translate(name(.),'n','N'),'Name')]]") | ForEach-Object -Process {
Set-Variable -Name $_.Name -Value $Form.FindName($_.Name)
}
#region Functions
function Get-CheckboxClicked
{
[CmdletBinding()]
param
(
[Parameter(
Mandatory = $true,
ValueFromPipeline = $true
)]
[ValidateNotNull()]
$CheckBox
)
$Capability = $Capabilities | Where-Object -FilterScript {$_.DisplayName -eq $CheckBox.Parent.Children[1].Text}
if ($CheckBox.IsChecked)
{
[void]$SelectedCapabilities.Add($Capability)
}
else
{
[void]$SelectedCapabilities.Remove($Capability)
}
if ($SelectedCapabilities.Count -gt 0)
{
$Button.IsEnabled = $true
}
else
{
$Button.IsEnabled = $false
}
}
function UninstallButton
{
Write-Information -MessageData "" -InformationAction Continue
# Extract the localized "Please wait..." string from %SystemRoot%\System32\shell32.dll
Write-Verbose -Message ([WinAPI.GetStrings]::GetString(12612)) -Verbose
[void]$Window.Close()
$SelectedCapabilities | ForEach-Object -Process {Write-Verbose -Message $_.DisplayName -Verbose}
$SelectedCapabilities | Where-Object -FilterScript {$_.Name -in (Get-WindowsCapability -Online).Name} | Remove-WindowsCapability -Online
}
function InstallButton
{
try
{
Write-Information -MessageData "" -InformationAction Continue
# Extract the localized "Please wait..." string from %SystemRoot%\System32\shell32.dll
Write-Verbose -Message ([WinAPI.GetStrings]::GetString(12612)) -Verbose
[void]$Window.Close()
$SelectedCapabilities | ForEach-Object -Process {Write-Verbose -Message $_.DisplayName -Verbose}
$SelectedCapabilities | Where-Object -FilterScript {$_.Name -in ((Get-WindowsCapability -Online).Name)} | Add-WindowsCapability -Online
}
catch [System.Runtime.InteropServices.COMException]
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.NoResponse -f "http://tlu.dl.delivery.mp.microsoft.com"), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.NoResponse -f "http://tlu.dl.delivery.mp.microsoft.com"), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
}
}
function Add-CapabilityControl
{
[CmdletBinding()]
param
(
[Parameter(
Mandatory = $true,
ValueFromPipeline = $true
)]
[ValidateNotNull()]
$Capability
)
process
{
$CheckBox = New-Object -TypeName System.Windows.Controls.CheckBox
$CheckBox.Add_Click({Get-CheckboxClicked -CheckBox $_.Source})
$CheckBox.ToolTip = $Capability.Description
$TextBlock = New-Object -TypeName System.Windows.Controls.TextBlock
$TextBlock.Text = $Capability.DisplayName
$TextBlock.ToolTip = $Capability.Description
$StackPanel = New-Object -TypeName System.Windows.Controls.StackPanel
[void]$StackPanel.Children.Add($CheckBox)
[void]$StackPanel.Children.Add($TextBlock)
[void]$PanelContainer.Children.Add($StackPanel)
# If capability checked add to the array list
if ($UnCheckedCapabilities | Where-Object -FilterScript {$Capability.Name -like $_})
{
$CheckBox.IsChecked = $false
# Exit function if item is not checked
return
}
# If capability checked add to the array list
[void]$SelectedCapabilities.Add($Capability)
}
}
#endregion Functions
switch ($PSCmdlet.ParameterSetName)
{
"Install"
{
try
{
$State = "NotPresent"
$ButtonContent = $Localization.Install
$ButtonAdd_Click = {InstallButton}
}
catch [System.ComponentModel.Win32Exception]
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.NoResponse -f "http://tlu.dl.delivery.mp.microsoft.com"), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.NoResponse -f "http://tlu.dl.delivery.mp.microsoft.com"), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
}
"Uninstall"
{
$State = "Installed"
$ButtonContent = $Localization.Uninstall
$ButtonAdd_Click = {UninstallButton}
}
}
Write-Information -MessageData "" -InformationAction Continue
# Extract the localized "Please wait..." string from %SystemRoot%\System32\shell32.dll
Write-Verbose -Message ([WinAPI.GetStrings]::GetString(12612)) -Verbose
# Getting list of all capabilities according to the conditions
$OFS = "|"
$Capabilities = Get-WindowsCapability -Online | Where-Object -FilterScript {
($_.State -eq $State) -and (($_.Name -match $UncheckedCapabilities) -or ($_.Name -match $CheckedCapabilities) -and ($_.Name -notmatch $ExcludedCapabilities))
} | ForEach-Object -Process {Get-WindowsCapability -Name $_.Name -Online}
$OFS = " "
if (-not $Capabilities)
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.NoOptionalFeatures, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.NoOptionalFeatures, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
#region Sendkey function
# Emulate the Backspace key sending to prevent the console window to freeze
Start-Sleep -Milliseconds 500
Add-Type -AssemblyName System.Windows.Forms
# We cannot use Get-Process -Id $PID as script might be invoked via Terminal with different $PID
Get-Process -Name powershell, WindowsTerminal -ErrorAction Ignore | Where-Object -FilterScript {$_.MainWindowTitle -match "Sophia Script for Windows 11"} | ForEach-Object -Process {
# Show window, if minimized
[WinAPI.ForegroundWindow]::ShowWindowAsync($_.MainWindowHandle, 10)
Start-Sleep -Seconds 1
# Force move the console window to the foreground
[WinAPI.ForegroundWindow]::SetForegroundWindow($_.MainWindowHandle)
Start-Sleep -Seconds 1
# Emulate the Backspace key sending
[System.Windows.Forms.SendKeys]::SendWait("{BACKSPACE 1}")
}
#endregion Sendkey function
$Window.Add_Loaded({$Capabilities | Add-CapabilityControl})
$Button.Content = $ButtonContent
$Button.Add_Click({& $ButtonAdd_Click})
$Window.Title = $Localization.OptionalFeaturesTitle
# Force move the WPF form to the foreground
$Window.Add_Loaded({$Window.Activate()})
$Form.ShowDialog() | Out-Null
}
<#
.SYNOPSIS
Receive updates for other Microsoft products
.PARAMETER Enable
Receive updates for other Microsoft products
.PARAMETER Disable
Do not receive updates for other Microsoft products
.EXAMPLE
UpdateMicrosoftProducts -Enable
.EXAMPLE
UpdateMicrosoftProducts -Disable
.NOTES
Current user
#>
function UpdateMicrosoftProducts
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -Name AllowMUUpdateService -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -Name AllowMUUpdateService -Type CLEAR
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings -Name AllowMUUpdateService -PropertyType DWord -Value 1 -Force
}
"Disable"
{
Remove-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings -Name AllowMUUpdateService -Force -ErrorAction Ignore
}
}
}
<#
.SYNOPSIS
Notification when your PC requires a restart to finish updating
.PARAMETER Show
Notify me when a restart is required to finish updating
.PARAMETER Hide
Do not notify me when a restart is required to finish updating
.EXAMPLE
RestartNotification -Show
.EXAMPLE
RestartNotification -Hide
.NOTES
Machine-wide
#>
function RestartNotification
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Show"
)]
[switch]
$Show,
[Parameter(
Mandatory = $true,
ParameterSetName = "Hide"
)]
[switch]
$Hide
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -Name SetAutoRestartNotificationDisable -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -Name SetAutoRestartNotificationDisable -Type CLEAR
switch ($PSCmdlet.ParameterSetName)
{
"Show"
{
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings -Name RestartNotificationsAllowed2 -PropertyType DWord -Value 1 -Force
}
"Hide"
{
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings -Name RestartNotificationsAllowed2 -PropertyType DWord -Value 0 -Force
}
}
}
<#
.SYNOPSIS
Restart as soon as possible to finish updating
.PARAMETER Enable
Restart as soon as possible to finish updating
.PARAMETER Disable
Don't restart as soon as possible to finish updating
.EXAMPLE
DeviceRestartAfterUpdate -Enable
.EXAMPLE
DeviceRestartAfterUpdate -Disable
.NOTES
Machine-wide
#>
function RestartDeviceAfterUpdate
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -Name ActiveHoursEnd, ActiveHoursStart, SetActiveHours -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -Name ActiveHoursEnd -Type CLEAR
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -Name ActiveHoursStart -Type CLEAR
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -Name SetActiveHours -Type CLEAR
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings -Name IsExpedited -PropertyType DWord -Value 1 -Force
}
"Disable"
{
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings -Name IsExpedited -PropertyType DWord -Value 0 -Force
}
}
}
<#
.SYNOPSIS
Active hours
.PARAMETER Automatically
Automatically adjust active hours for me based on daily usage
.PARAMETER Manually
Manually adjust active hours for me based on daily usage
.EXAMPLE
ActiveHours -Automatically
.EXAMPLE
ActiveHours -Manually
.NOTES
Machine-wide
#>
function ActiveHours
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Automatically"
)]
[switch]
$Automatically,
[Parameter(
Mandatory = $true,
ParameterSetName = "Manually"
)]
[switch]
$Manually
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -Name NoAutoRebootWithLoggedOnUsers, AlwaysAutoRebootAtScheduledTime -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -Name NoAutoRebootWithLoggedOnUsers -Type CLEAR
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -Name AlwaysAutoRebootAtScheduledTime -Type CLEAR
Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -Name ActiveHoursEnd, ActiveHoursStart, SetActiveHours -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -Name ActiveHoursEnd -Type CLEAR
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -Name ActiveHoursStart -Type CLEAR
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -Name SetActiveHours -Type CLEAR
switch ($PSCmdlet.ParameterSetName)
{
"Automatically"
{
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings -Name SmartActiveHoursState -PropertyType DWord -Value 1 -Force
}
"Manually"
{
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings -Name SmartActiveHoursState -PropertyType DWord -Value 0 -Force
}
}
}
<#
.SYNOPSIS
Windows latest updates
.PARAMETER Disable
Do not get the latest updates as soon as they're available
.PARAMETER Enable
Get the latest updates as soon as they're available
.EXAMPLE
WindowsLatestUpdate -Disable
.EXAMPLE
WindowsLatestUpdate -Enable
.NOTES
Machine-wide
#>
function WindowsLatestUpdate
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -Name AllowOptionalContent, SetAllowOptionalContent -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -Name AllowOptionalContent -Type CLEAR
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -Name SetAllowOptionalContent -Type CLEAR
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings -Name IsContinuousInnovationOptedIn -PropertyType DWord -Value 0 -Force
}
"Enable"
{
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings -Name IsContinuousInnovationOptedIn -PropertyType DWord -Value 1 -Force
}
}
}
<#
.SYNOPSIS
Power plan
.PARAMETER High
Set power plan on "High performance"
.PARAMETER Balanced
Set power plan on "Balanced"
.EXAMPLE
PowerPlan -High
.EXAMPLE
PowerPlan -Balanced
.NOTES
Not recommended to turn on for laptops
.NOTES
Current user
#>
function PowerPlan
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "High"
)]
[switch]
$High,
[Parameter(
Mandatory = $true,
ParameterSetName = "Balanced"
)]
[switch]
$Balanced
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings -Name ActivePowerScheme -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Power\PowerSettings -Name ActivePowerScheme -Type CLEAR
switch ($PSCmdlet.ParameterSetName)
{
"High"
{
& "$env:SystemRoot\System32\powercfg.exe" /SETACTIVE SCHEME_MIN
}
"Balanced"
{
& "$env:SystemRoot\System32\powercfg.exe" /SETACTIVE SCHEME_BALANCED
}
}
}
<#
.SYNOPSIS
Network adapters power management
.PARAMETER Disable
Do not allow the computer to turn off the network adapters to save power
.PARAMETER Enable
Allow the computer to turn off the network adapters to save power
.EXAMPLE
NetworkAdaptersSavePower -Disable
.EXAMPLE
NetworkAdaptersSavePower -Enable
.NOTES
Not recommended to turn off for laptops
.NOTES
Current user
#>
function NetworkAdaptersSavePower
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
# Turn On Desktop Apps Access to Location
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\location -Name Value -PropertyType String -Value Allow -Force
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\location -Name Value -PropertyType String -Value Allow -Force
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\location\NonPackaged -Name Value -PropertyType String -Value Allow -Force
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors -Name DisableLocation -Force -ErrorAction Ignore
Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -Name LetAppsAccessLocation -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors -Name DisableLocation -Type CLEAR
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -Name LetAppsAccessLocation -Type CLEAR
# Checking whether there's an adapter that has AllowComputerToTurnOffDevice property to manage
# We need also check for adapter status per some laptops have many equal adapters records in adapters list
$PhysicalAdaptersStatusUp = @(Get-NetAdapter -Physical | Where-Object -FilterScript {$_.Status -eq "Up"})
$Adapters = $PhysicalAdaptersStatusUp | Get-NetAdapterPowerManagement | Where-Object -FilterScript {$_.AllowComputerToTurnOffDevice -ne "Unsupported"}
if (-not $Adapters)
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.NoSupportedNetworkAdapters, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.NoSupportedNetworkAdapters, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
# Checking whether PC is currently connected to a Wi-Fi network
# NetConnectionStatus 2 is Wi-Fi
$InterfaceIndex = (Get-CimInstance -ClassName Win32_NetworkAdapter -Namespace root/CIMV2 | Where-Object -FilterScript {$_.NetConnectionStatus -eq 2}).InterfaceIndex
if (Get-NetAdapter -Physical | Where-Object -FilterScript {($_.Status -eq "Up") -and ($_.PhysicalMediaType -eq "Native 802.11") -and ($_.InterfaceIndex -eq $InterfaceIndex)})
{
# Get currently connected Wi-Fi network SSID
$SSID = (Get-NetConnectionProfile).Name
}
if ($PhysicalAdaptersStatusUp)
{
# If Wi-Fi network was used
if ($SSID)
{
Write-Verbose -Message $SSID -Verbose
# Check whether network shell commands were granted location permission to access WLAN information
# https://learn.microsoft.com/en-us/windows/win32/nativewifi/wi-fi-access-location-changes
try
{
# Connect to it
Start-Process -FilePath "$env:SystemRoot\System32\netsh.exe" -ArgumentList "wlan connect name=$SSID" -Wait -ErrorAction Stop
}
catch
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.LocationServicesDisabled, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.LocationServicesDisabled, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
Start-Process -FilePath ms-settings:privacy-location
return
}
}
# All network adapters are turned into "Disconnected" for few seconds, so we need to wait a bit to let them up
# Otherwise functions below will indicate that there is no the Internet connection
while
(
Get-NetAdapter -Physical -Name $PhysicalAdaptersStatusUp.Name | Where-Object -FilterScript {($_.Status -eq "Disconnected") -and $_.MacAddress}
)
{
Write-Information -MessageData "" -InformationAction Continue
# Extract the localized "Please wait..." string from %SystemRoot%\System32\shell32.dll
Write-Verbose -Message ([WinAPI.GetStrings]::GetString(12612)) -Verbose
Start-Sleep -Seconds 2
}
}
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
foreach ($Adapter in $Adapters)
{
$Adapter.AllowComputerToTurnOffDevice = "Disabled"
$Adapter | Set-NetAdapterPowerManagement
}
}
"Enable"
{
foreach ($Adapter in $Adapters)
{
$Adapter.AllowComputerToTurnOffDevice = "Enabled"
$Adapter | Set-NetAdapterPowerManagement
}
}
}
if ($PhysicalAdaptersStatusUp)
{
# If Wi-Fi network was used
if ($SSID)
{
Write-Verbose -Message $SSID -Verbose
# Connect to it
Start-Process -FilePath "$env:SystemRoot\System32\netsh.exe" -ArgumentList "wlan connect name=$SSID" -Wait
}
# All network adapters are turned into "Disconnected" for few seconds, so we need to wait a bit to let them up
# Otherwise functions below will indicate that there is no the Internet connection
while
(
Get-NetAdapter -Physical -Name $PhysicalAdaptersStatusUp.Name | Where-Object -FilterScript {($_.Status -eq "Disconnected") -and $_.MacAddress}
)
{
Write-Information -MessageData "" -InformationAction Continue
# Extract the localized "Please wait..." string from %SystemRoot%\System32\shell32.dll
Write-Verbose -Message ([WinAPI.GetStrings]::GetString(12612)) -Verbose
Start-Sleep -Seconds 2
}
}
}
<#
.SYNOPSIS
Override for default input method
.PARAMETER English
Override for default input method: English
.PARAMETER Default
Override for default input method: use language list
.EXAMPLE
InputMethod -English
.EXAMPLE
InputMethod -Default
.NOTES
Current user
#>
function InputMethod
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "English"
)]
[switch]
$English,
[Parameter(
Mandatory = $true,
ParameterSetName = "Default"
)]
[switch]
$Default
)
switch ($PSCmdlet.ParameterSetName)
{
"English"
{
Set-WinDefaultInputMethodOverride -InputTip "0409:00000409"
}
"Default"
{
Remove-ItemProperty -Path "HKCU:\Control Panel\International\User Profile" -Name InputMethodOverride -Force -ErrorAction Ignore
}
}
}
<#
.SYNOPSIS
Change User folders location
.PARAMETER Root
Change user folders location to the root of any drive using an interactive menu
.PARAMETER Custom
Select folders for user folders location manually using a folder browser dialog
.PARAMETER Default
Change user folders location to the default values
.EXAMPLE
Set-UserShellFolderLocation -Root
.EXAMPLE
Set-UserShellFolderLocation -Custom
.EXAMPLE
Set-UserShellFolderLocation -Default
.NOTES
User files or folders won't be moved to a new location
.NOTES
Current user
#>
function Set-UserShellFolderLocation
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Root"
)]
[switch]
$Root,
[Parameter(
Mandatory = $true,
ParameterSetName = "Custom"
)]
[switch]
$Custom,
[Parameter(
Mandatory = $true,
ParameterSetName = "Default"
)]
[switch]
$Default
)
# Localized user folder name IDs for "WinAPI.GetStrings" function
$LocalizedUserFolderNameIDs = @{
"Desktop" = "21769"
"Documents" = "21770"
"Downloads" = "21798"
"Music" = "21790"
"Pictures" = "21779"
"Videos" = "21791"
}
# Registry user folder names
$Global:UserFolderRegistry = @{
"Desktop" = "Desktop"
"Documents" = "Personal"
"Downloads" = "{374DE290-123F-4565-9164-39C4925E467B}"
"Music" = "My Music"
"Pictures" = "My Pictures"
"Videos" = "My Video"
}
$Global:UserFolderGUIDs = @{
"Desktop" = "{754AC886-DF64-4CBA-86B5-F7FBF4FBCEF5}"
"Documents" = "{F42EE2D3-909F-4907-8871-4C22FC0BF756}"
"Downloads" = "{7D83EE9B-2244-4E70-B1F5-5404642AF1E4}"
"Music" = "{A0C69A99-21C8-4671-8703-7934162FCF1D}"
"Pictures" = "{0DDD015D-B06C-45D5-8C4C-F59713854639}"
"Videos" = "{35286A68-3C57-41A1-BBB1-0EAE73D76C95}"
}
# Contents of the hidden desktop.ini file for each type of user folders
$Desktop = @"
"",
"[.ShellClassInfo]",
"LocalizedResourceName=@shell32.dll,-21769",
"IconResource=%SystemRoot%\System32\imageres.dll,-183"
"@
$Documents = @"
"",
"[.ShellClassInfo]",
"LocalizedResourceName=@shell32.dll,-21770",
"IconResource=%SystemRoot%\System32\imageres.dll,-112",
"IconFile=%SystemRoot%\System32\shell32.dll",
"IconIndex=-235"
"@
$Downloads = @"
"",
"[.ShellClassInfo]",
"LocalizedResourceName=@shell32.dll,-21798",
"IconResource=%SystemRoot%\System32\imageres.dll,-184"
"@
$Music = @"
"",
"[.ShellClassInfo]",
"LocalizedResourceName=@shell32.dll,-21790",
"InfoTip=@shell32.dll,-12689",
"IconResource=%SystemRoot%\System32\imageres.dll,-108",
"IconFile=%SystemRoot%\System32\shell32.dll","IconIndex=-237"
"@
$Pictures = @"
"",
"[.ShellClassInfo]",
"LocalizedResourceName=@shell32.dll,-21779",
"InfoTip=@shell32.dll,-12688",
"IconResource=%SystemRoot%\System32\imageres.dll,-113",
"IconFile=%SystemRoot%\System32\shell32.dll",
"IconIndex=-236"
"@
$Videos = @"
"",
"[.ShellClassInfo]",
"LocalizedResourceName=@shell32.dll,-21791",
"InfoTip=@shell32.dll,-12690",
"IconResource=%SystemRoot%\System32\imageres.dll,-189",
"IconFile=%SystemRoot%\System32\shell32.dll",
"IconIndex=-238"
"@
$Global:DesktopINI = @{
"Desktop" = $Desktop
"Documents" = $Documents
"Downloads" = $Downloads
"Music" = $Music
"Pictures" = $Pictures
"Videos" = $Videos
}
switch ($PSCmdlet.ParameterSetName)
{
"Root"
{
# Store all fixed disks' letters except C drive to call with Show-Menu function
# https://learn.microsoft.com/en-us/dotnet/api/system.io.drivetype
$DriveLetters = @((Get-CimInstance -ClassName CIM_LogicalDisk | Where-Object -FilterScript {($_.DriveType -eq 3) -and ($_.Name -ne $env:SystemDrive)}).DeviceID | Sort-Object)
if (-not $DriveLetters)
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.UserFolderLocationMove, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.UserFolderLocationMove, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
foreach ($UserFolder in @("Desktop", "Documents", "Downloads", "Music", "Pictures", "Videos"))
{
# Extract the localized user folders strings from %SystemRoot%\System32\shell32.dll
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.DriveSelect -f [WinAPI.GetStrings]::GetString($LocalizedUserFolderNameIDs[$UserFolder])) -Verbose
$CurrentUserFolderLocation = Get-ItemPropertyValue -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" -Name $UserFolderRegistry[$UserFolder]
Write-Verbose -Message ($Localization.CurrentUserFolderLocation -f [WinAPI.GetStrings]::GetString($LocalizedUserFolderNameIDs[$UserFolder]), $CurrentUserFolderLocation) -Verbose
Write-Warning -Message $Localization.FilesWontBeMoved
do
{
$Choice = Show-Menu -Menu $DriveLetters -Default $DriveLetters.Count[-1] -AddSkip
switch ($Choice)
{
{$DriveLetters -contains $Choice}
{
Set-UserShellFolder -UserFolder $UserFolder -Path "$($Choice)\$UserFolder"
}
$Skip
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.UserFolderMoveSkipped -f [WinAPI.GetStrings]::GetString($LocalizedUserFolderNameIDs[$UserFolder])), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.UserFolderMoveSkipped -f [WinAPI.GetStrings]::GetString($LocalizedUserFolderNameIDs[$UserFolder])), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
}
$KeyboardArrows {}
}
}
until ($Choice -ne $KeyboardArrows)
}
}
"Custom"
{
foreach ($UserFolder in @("Desktop", "Documents", "Downloads", "Music", "Pictures", "Videos"))
{
# Extract the localized user folders strings from %SystemRoot%\System32\shell32.dll
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.UserFolderRequest -f [WinAPI.GetStrings]::GetString($LocalizedUserFolderNameIDs[$UserFolder])) -Verbose
$CurrentUserFolderLocation = Get-ItemPropertyValue -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" -Name $UserFolderRegistry[$UserFolder]
Write-Verbose -Message ($Localization.CurrentUserFolderLocation -f [WinAPI.GetStrings]::GetString($LocalizedUserFolderNameIDs[$UserFolder]), $CurrentUserFolderLocation) -Verbose
Write-Warning -Message $Localization.FilesWontBeMoved
do
{
$Choice = Show-Menu -Menu $Browse -Default 1 -AddSkip
switch ($Choice)
{
$Browse
{
Add-Type -AssemblyName System.Windows.Forms
$FolderBrowserDialog = New-Object -TypeName System.Windows.Forms.FolderBrowserDialog
$FolderBrowserDialog.Description = $Localization.FolderSelect
$FolderBrowserDialog.RootFolder = "MyComputer"
# Force move the open file dialog to the foreground
$Focus = New-Object -TypeName System.Windows.Forms.Form -Property @{TopMost = $true}
$FolderBrowserDialog.ShowDialog($Focus)
if ($FolderBrowserDialog.SelectedPath)
{
if ($FolderBrowserDialog.SelectedPath -eq "C:\")
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message $Localization.UserFolderLocationMove -Verbose
continue
}
else
{
Set-UserShellFolder -UserFolder $UserFolder -Path $FolderBrowserDialog.SelectedPath
}
}
}
$Skip
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.UserFolderMoveSkipped -f [WinAPI.GetStrings]::GetString($LocalizedUserFolderNameIDs[$UserFolder])), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.UserFolderMoveSkipped -f [WinAPI.GetStrings]::GetString($LocalizedUserFolderNameIDs[$UserFolder])), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
}
$KeyboardArrows {}
}
}
until ($Choice -ne $KeyboardArrows)
}
}
"Default"
{
foreach ($UserFolder in @("Desktop", "Documents", "Downloads", "Music", "Pictures", "Videos"))
{
# Extract the localized user folders strings from %SystemRoot%\System32\shell32.dll
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.UserDefaultFolder -f [WinAPI.GetStrings]::GetString($LocalizedUserFolderNameIDs[$UserFolder])) -Verbose
$CurrentUserFolderLocation = Get-ItemPropertyValue -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" -Name Desktop
Write-Verbose -Message ($Localization.CurrentUserFolderLocation -f [WinAPI.GetStrings]::GetString($LocalizedUserFolderNameIDs[$UserFolder]), $CurrentUserFolderLocation) -Verbose
Write-Warning -Message $Localization.FilesWontBeMoved
do
{
$Choice = Show-Menu -Menu $Yes -Default 1 -AddSkip
switch ($Choice)
{
$Yes
{
Set-UserShellFolder -UserFolder $UserFolder -Path "$env:USERPROFILE\$UserFolder"
}
$Skip
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.UserFolderMoveSkipped -f [WinAPI.GetStrings]::GetString($LocalizedUserFolderNameIDs[$UserFolder])), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.UserFolderMoveSkipped -f [WinAPI.GetStrings]::GetString($LocalizedUserFolderNameIDs[$UserFolder])), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
}
$KeyboardArrows {}
}
}
until ($Choice -ne $KeyboardArrows)
}
}
}
}
<#
.SYNOPSIS
The location to save screenshots when pressing Windows+PrtScr or using Windows+Shift+S
.PARAMETER Desktop
Save screenshots on the Desktop when pressing Windows+PrtScr or using Windows+Shift+S
.PARAMETER Default
Save screenshots in the Pictures folder when pressing Windows+PrtScr or using Windows+Shift+S
.EXAMPLE
WinPrtScrFolder -Desktop
.EXAMPLE
WinPrtScrFolder -Default
.NOTES
Current user
#>
function WinPrtScrFolder
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Desktop"
)]
[switch]
$Desktop,
[Parameter(
Mandatory = $true,
ParameterSetName = "Default"
)]
[switch]
$Default
)
# Checking whether user is logged into OneDrive (Microsoft account)
$UserEmailPersonal = Get-ItemProperty -Path HKCU:\Software\Microsoft\OneDrive\Accounts\Personal -Name UserEmail -ErrorAction Ignore
$UserEmailBusiness = Get-ItemProperty -Path HKCU:\Software\Microsoft\OneDrive\Accounts\Business1 -Name UserEmail -ErrorAction Ignore
if ($UserEmailPersonal -or $UserEmailBusiness)
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.OneDriveAccountWarning, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.OneDriveAccountWarning, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
switch ($PSCmdlet.ParameterSetName)
{
"Desktop"
{
$DesktopFolder = Get-ItemPropertyValue -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" -Name Desktop
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" -Name "{B7BEDE81-DF94-4682-A7D8-57A52620B86F}" -PropertyType ExpandString -Value $DesktopFolder -Force
}
"Default"
{
Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" -Name "{B7BEDE81-DF94-4682-A7D8-57A52620B86F}" -Force -ErrorAction Ignore
}
}
}
<#
.SYNOPSIS
Recommended troubleshooter preferences
.PARAMETER Automatically
Run troubleshooter automatically, then notify me
.PARAMETER Default
Ask me before running troubleshooter
.EXAMPLE
RecommendedTroubleshooting -Automatically
.EXAMPLE
RecommendedTroubleshooting -Default
.NOTES
In order this feature to work Windows level of diagnostic data gathering will be set to "Optional diagnostic data" and the error reporting feature will be turned on
.NOTES
Machine-wide
#>
function RecommendedTroubleshooting
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Automatically"
)]
[switch]
$Automatically,
[Parameter(
Mandatory = $true,
ParameterSetName = "Default"
)]
[switch]
$Default
)
Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection -Name AllowTelemetry -Force -ErrorAction Ignore
Remove-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\DataCollection -Name MaxTelemetryAllowed -Force -ErrorAction Ignore
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Diagnostics\DiagTrack -Name ShowedToastAtLevel -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\DataCollection -Name AllowTelemetry -Type CLEAR
# Turn on Windows Error Reporting
Get-ScheduledTask -TaskName QueueReporting -ErrorAction Ignore | Enable-ScheduledTask
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting", "HKCU:\Software\Policies\Microsoft\Windows\Windows Error Reporting" -Name Disabled -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path "SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting" -Name Disabled -Type CLEAR
Set-Policy -Scope User -Path "Software\Policies\Microsoft\Windows\Windows Error Reporting" -Name Disabled -Type CLEAR
Get-Service -Name WerSvc | Set-Service -StartupType Manual
Get-Service -Name WerSvc | Start-Service
switch ($PSCmdlet.ParameterSetName)
{
"Automatically"
{
if (-not (Test-Path -Path HKLM:\SOFTWARE\Microsoft\WindowsMitigation))
{
New-Item -Path HKLM:\SOFTWARE\Microsoft\WindowsMitigation -Force
}
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\WindowsMitigation -Name UserPreference -PropertyType DWord -Value 3 -Force
}
"Default"
{
if (-not (Test-Path -Path HKLM:\SOFTWARE\Microsoft\WindowsMitigation))
{
New-Item -Path HKLM:\SOFTWARE\Microsoft\WindowsMitigation -Force
}
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\WindowsMitigation -Name UserPreference -PropertyType DWord -Value 2 -Force
}
}
}
<#
.SYNOPSIS
Reserved storage
.PARAMETER Disable
Disable and delete reserved storage after the next update installation
.PARAMETER Enable
Enable reserved storage after the next update installation
.EXAMPLE
ReservedStorage -Disable
.EXAMPLE
ReservedStorage -Enable
.NOTES
Current user
#>
function ReservedStorage
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
try
{
Set-WindowsReservedStorageState -State Disabled
}
catch [System.Runtime.InteropServices.COMException]
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.ReservedStorageIsInUse, ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.ReservedStorageIsInUse, ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
}
}
"Enable"
{
Set-WindowsReservedStorageState -State Enabled
}
}
}
<#
.SYNOPSIS
Help look up via F1
.PARAMETER Disable
Disable help lookup via F1
.PARAMETER Enable
Enable help lookup via F1
.EXAMPLE
F1HelpPage -Disable
.EXAMPLE
F1HelpPage -Enable
.NOTES
Current user
#>
function F1HelpPage
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
if (-not (Test-Path -Path "HKCU:\Software\Classes\Typelib\{8cec5860-07a1-11d9-b15e-000d56bfe6ee}\1.0\0\win64"))
{
New-Item -Path "HKCU:\Software\Classes\Typelib\{8cec5860-07a1-11d9-b15e-000d56bfe6ee}\1.0\0\win64" -Force
}
New-ItemProperty -Path "HKCU:\Software\Classes\Typelib\{8cec5860-07a1-11d9-b15e-000d56bfe6ee}\1.0\0\win64" -Name "(default)" -PropertyType String -Value "" -Force
}
"Enable"
{
Remove-Item -Path "HKCU:\Software\Classes\Typelib\{8cec5860-07a1-11d9-b15e-000d56bfe6ee}" -Recurse -Force -ErrorAction Ignore
}
}
}
<#
.SYNOPSIS
Num Lock at startup
.PARAMETER Enable
Enable Num Lock at startup
.PARAMETER Disable
Disable Num Lock at startup
.EXAMPLE
NumLock -Enable
.EXAMPLE
NumLock -Disable
.NOTES
Current user
#>
function NumLock
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
New-ItemProperty -Path "Registry::HKEY_USERS\.DEFAULT\Control Panel\Keyboard" -Name InitialKeyboardIndicators -PropertyType String -Value 2147483650 -Force
}
"Disable"
{
New-ItemProperty -Path "Registry::HKEY_USERS\.DEFAULT\Control Panel\Keyboard" -Name InitialKeyboardIndicators -PropertyType String -Value 2147483648 -Force
}
}
}
<#
.SYNOPSIS
Caps Lock
.PARAMETER Disable
Disable Caps Lock
.PARAMETER Enable
Enable Caps Lock
.EXAMPLE
CapsLock -Disable
.EXAMPLE
CapsLock -Enable
.NOTES
Machine-wide
#>
function CapsLock
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
Remove-ItemProperty -Path "HKCU:\Keyboard Layout" -Name Attributes -Force -ErrorAction Ignore
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Keyboard Layout" -Name "Scancode Map" -PropertyType Binary -Value ([byte[]](0,0,0,0,0,0,0,0,2,0,0,0,0,0,58,0,0,0,0,0)) -Force
}
"Enable"
{
Remove-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Keyboard Layout" -Name "Scancode Map" -Force -ErrorAction Ignore
}
}
}
<#
.SYNOPSIS
The shortcut to start Sticky Keys
.PARAMETER Disable
Turn off Sticky keys when pressing the Shift key 5 times
.PARAMETER Enable
Turn on Sticky keys when pressing the Shift key 5 times
.EXAMPLE
StickyShift -Disable
.EXAMPLE
StickyShift -Enable
.NOTES
Current user
#>
function StickyShift
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
New-ItemProperty -Path "HKCU:\Control Panel\Accessibility\StickyKeys" -Name Flags -PropertyType String -Value 506 -Force
}
"Enable"
{
New-ItemProperty -Path "HKCU:\Control Panel\Accessibility\StickyKeys" -Name Flags -PropertyType String -Value 510 -Force
}
}
}
<#
.SYNOPSIS
AutoPlay for all media and devices
.PARAMETER Disable
Don't use AutoPlay for all media and devices
.PARAMETER Enable
Use AutoPlay for all media and devices
.EXAMPLE
Autoplay -Disable
.EXAMPLE
Autoplay -Enable
.NOTES
Current user
#>
function Autoplay
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer, HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer -Name NoDriveTypeAutoRun -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -Name NoDriveTypeAutoRun -Type CLEAR
Set-Policy -Scope User -Path Software\Microsoft\Windows\CurrentVersion\Policies\Explorer -Name NoDriveTypeAutoRun -Type CLEAR
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\AutoplayHandlers -Name DisableAutoplay -PropertyType DWord -Value 1 -Force
}
"Enable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\AutoplayHandlers -Name DisableAutoplay -PropertyType DWord -Value 0 -Force
}
}
}
<#
.SYNOPSIS
Thumbnail cache removal
.PARAMETER Disable
Disable thumbnail cache removal
.PARAMETER Enable
Enable thumbnail cache removal
.EXAMPLE
ThumbnailCacheRemoval -Disable
.EXAMPLE
ThumbnailCacheRemoval -Enable
.NOTES
Machine-wide
#>
function ThumbnailCacheRemoval
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Thumbnail Cache" -Name Autorun -PropertyType DWord -Value 0 -Force
New-ItemProperty -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Thumbnail Cache" -Name Autorun -PropertyType DWord -Value 0 -Force
}
"Enable"
{
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Thumbnail Cache" -Name Autorun -PropertyType DWord -Value 3 -Force
New-ItemProperty -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Thumbnail Cache" -Name Autorun -PropertyType DWord -Value 3 -Force
}
}
}
<#
.SYNOPSIS
Restart apps after signing in
.PARAMETER Enable
Automatically saving my restartable apps and restart them when I sign back in
.PARAMETER Disable
Turn off automatically saving my restartable apps and restart them when I sign back in
.EXAMPLE
SaveRestartableApps -Enable
.EXAMPLE
SaveRestartableApps -Disable
.NOTES
Current user
#>
function SaveRestartableApps
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name RestartApps -PropertyType DWord -Value 1 -Force
}
"Disable"
{
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name RestartApps -PropertyType DWord -Value 0 -Force
}
}
}
<#
.SYNOPSIS
Restore previous folder windows at logon
.PARAMETER Disable
Do not restore previous folder windows at logon
.PARAMETER Enable
Restore previous folder windows at logon
.EXAMPLE
RestorePreviousFolders -Disable
.EXAMPLE
RestorePreviousFolders -Enable
.NOTES
Current user
#>
function RestorePreviousFolders
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name PersistBrowsers -PropertyType DWord -Value 0 -Force
}
"Enable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name PersistBrowsers -PropertyType DWord -Value 1 -Force
}
}
}
<#
.SYNOPSIS
Network Discovery File and Printers Sharing
.PARAMETER Enable
Enable "Network Discovery" and "File and Printers Sharing" for workgroup networks
.PARAMETER Disable
Disable "Network Discovery" and "File and Printers Sharing" for workgroup networks
.EXAMPLE
NetworkDiscovery -Enable
.EXAMPLE
NetworkDiscovery -Disable
.NOTES
Current user
#>
function NetworkDiscovery
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
$FirewallRules = @(
# File and printer sharing
"@FirewallAPI.dll,-32752",
# Network discovery
"@FirewallAPI.dll,-28502"
)
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
Set-NetFirewallRule -Group $FirewallRules -Profile Private -Enabled True
Set-NetFirewallRule -Profile Private -Name FPS-SMB-In-TCP -Enabled True
Set-NetConnectionProfile -NetworkCategory Private
}
"Disable"
{
Set-NetFirewallRule -Group $FirewallRules -Profile Private -Enabled False
}
}
}
<#
.SYNOPSIS
Register app, calculate hash, and associate with an extension with the "How do you want to open this" pop-up hidden
.PARAMETER ProgramPath
Path to program to associate an extension with
.PARAMETER ProgramPath
Protocol (ProgId)
.PARAMETER Extension
Extension type
.PARAMETER Icon
Path to an icon
.EXAMPLE
Set-Association -ProgramPath 'C:\SumatraPDF.exe' -Extension .pdf -Icon '%SystemRoot%\System32\shell32.dll,100'
.EXAMPLE
Set-Association -ProgramPath '%ProgramFiles%\Notepad++\notepad++.exe' -Extension .txt -Icon '%ProgramFiles%\Notepad++\notepad++.exe,0'
.EXAMPLE
Set-Association -ProgramPath MSEdgeHTM -Extension .html
.LINK
https://github.com/DanysysTeam/PS-SFTA
https://github.com/default-username-was-already-taken/set-fileassoc
https://forum.ru-board.com/profile.cgi?action=show&member=westlife
.NOTES
Machine-wide
#>
function Set-Association
{
[CmdletBinding()]
Param
(
[Parameter(
Mandatory = $true,
Position = 0
)]
[string]
$ProgramPath,
[Parameter(
Mandatory = $true,
Position = 1
)]
[string]
$Extension,
[Parameter(
Mandatory = $false,
Position = 2
)]
[string]
$Icon
)
# Microsoft has blocked write access to UserChoice key for .pdf extention and http/https protocols with KB5034765 release, so we have to write values with a copy of powershell.exe to bypass a UCPD driver restrictions
# UCPD driver tracks all executables to block the access to the registry so all registry records will be made within powershell_temp.exe in this function just in case
Copy-Item -Path "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe" -Destination "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell_temp.exe" -Force
$ProgramPath = [System.Environment]::ExpandEnvironmentVariables($ProgramPath)
# If $ProgramPath is a path to an executable
if ($ProgramPath.Contains(":"))
{
if (-not (Test-Path -Path $ProgramPath))
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.ProgramPathNotExists -f $ProgramPath), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.ProgramPathNotExists -f $ProgramPath), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
}
else
{
# ProgId is not registered
if (-not (Test-Path -Path "Registry::HKEY_CLASSES_ROOT\$ProgramPath"))
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.ProgIdNotExists -f $ProgramPath), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.ProgIdNotExists -f $ProgramPath), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
}
if ($Icon)
{
$Icon = [System.Environment]::ExpandEnvironmentVariables($Icon)
}
if (Test-Path -Path $ProgramPath)
{
# Generate ProgId
$ProgId = (Get-Item -Path $ProgramPath).BaseName + $Extension.ToUpper()
}
else
{
$ProgId = $ProgramPath
}
$Signature = @{
Namespace = "WinAPI"
Name = "Action"
Language = "CSharp"
UsingNamespace = "System.Text", "System.Security.AccessControl", "Microsoft.Win32"
CompilerOptions = $CompilerOptions
MemberDefinition = @"
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
private static extern int RegOpenKeyEx(UIntPtr hKey, string subKey, int ulOptions, int samDesired, out UIntPtr hkResult);
[DllImport("advapi32.dll", SetLastError = true)]
private static extern int RegCloseKey(UIntPtr hKey);
[DllImport("advapi32.dll", SetLastError=true, CharSet = CharSet.Unicode)]
private static extern uint RegDeleteKey(UIntPtr hKey, string subKey);
[DllImport("advapi32.dll", EntryPoint = "RegQueryInfoKey", CallingConvention = CallingConvention.Winapi, SetLastError = true)]
private static extern int RegQueryInfoKey(UIntPtr hkey, out StringBuilder lpClass, ref uint lpcbClass, IntPtr lpReserved,
out uint lpcSubKeys, out uint lpcbMaxSubKeyLen, out uint lpcbMaxClassLen, out uint lpcValues, out uint lpcbMaxValueNameLen,
out uint lpcbMaxValueLen, out uint lpcbSecurityDescriptor, ref System.Runtime.InteropServices.ComTypes.FILETIME lpftLastWriteTime);
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);
[DllImport("kernel32.dll", ExactSpelling = true)]
internal static extern IntPtr GetCurrentProcess();
[DllImport("advapi32.dll", SetLastError = true)]
internal static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall, ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int RegLoadKey(uint hKey, string lpSubKey, string lpFile);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int RegUnLoadKey(uint hKey, string lpSubKey);
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct TokPriv1Luid
{
public int Count;
public long Luid;
public int Attr;
}
public static void DeleteKey(RegistryHive registryHive, string subkey)
{
UIntPtr hKey = UIntPtr.Zero;
try
{
var hive = new UIntPtr(unchecked((uint)registryHive));
RegOpenKeyEx(hive, subkey, 0, 0x20019, out hKey);
RegDeleteKey(hive, subkey);
}
finally
{
if (hKey != UIntPtr.Zero)
{
RegCloseKey(hKey);
}
}
}
private static DateTime ToDateTime(System.Runtime.InteropServices.ComTypes.FILETIME ft)
{
IntPtr buf = IntPtr.Zero;
try
{
long[] longArray = new long[1];
int cb = Marshal.SizeOf(ft);
buf = Marshal.AllocHGlobal(cb);
Marshal.StructureToPtr(ft, buf, false);
Marshal.Copy(buf, longArray, 0, 1);
return DateTime.FromFileTime(longArray[0]);
}
finally
{
if (buf != IntPtr.Zero) Marshal.FreeHGlobal(buf);
}
}
public static DateTime? GetLastModified(RegistryHive registryHive, string subKey)
{
var lastModified = new System.Runtime.InteropServices.ComTypes.FILETIME();
var lpcbClass = new uint();
var lpReserved = new IntPtr();
UIntPtr hKey = UIntPtr.Zero;
try
{
try
{
var hive = new UIntPtr(unchecked((uint)registryHive));
if (RegOpenKeyEx(hive, subKey, 0, (int)RegistryRights.ReadKey, out hKey) != 0)
{
return null;
}
uint lpcbSubKeys;
uint lpcbMaxKeyLen;
uint lpcbMaxClassLen;
uint lpcValues;
uint maxValueName;
uint maxValueLen;
uint securityDescriptor;
StringBuilder sb;
if (RegQueryInfoKey(hKey, out sb, ref lpcbClass, lpReserved, out lpcbSubKeys, out lpcbMaxKeyLen, out lpcbMaxClassLen,
out lpcValues, out maxValueName, out maxValueLen, out securityDescriptor, ref lastModified) != 0)
{
return null;
}
var result = ToDateTime(lastModified);
return result;
}
finally
{
if (hKey != UIntPtr.Zero)
{
RegCloseKey(hKey);
}
}
}
catch (Exception)
{
return null;
}
}
internal const int SE_PRIVILEGE_DISABLED = 0x00000000;
internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
internal const int TOKEN_QUERY = 0x00000008;
internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
public enum RegistryHives : uint
{
HKEY_USERS = 0x80000003,
HKEY_LOCAL_MACHINE = 0x80000002
}
public static void AddPrivilege(string privilege)
{
bool retVal;
TokPriv1Luid tp;
IntPtr hproc = GetCurrentProcess();
IntPtr htok = IntPtr.Zero;
retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
tp.Count = 1;
tp.Luid = 0;
tp.Attr = SE_PRIVILEGE_ENABLED;
retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid);
retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
///return retVal;
}
public static int LoadHive(RegistryHives hive, string subKey, string filePath)
{
AddPrivilege("SeRestorePrivilege");
AddPrivilege("SeBackupPrivilege");
uint regHive = (uint)hive;
int result = RegLoadKey(regHive, subKey, filePath);
return result;
}
public static int UnloadHive(RegistryHives hive, string subKey)
{
AddPrivilege("SeRestorePrivilege");
AddPrivilege("SeBackupPrivilege");
uint regHive = (uint)hive;
int result = RegUnLoadKey(regHive, subKey);
return result;
}
"@
}
if (-not ("WinAPI.Action" -as [type]))
{
Add-Type @Signature
}
Clear-Variable -Name RegisteredProgIDs -Force -ErrorAction Ignore
[array]$Global:RegisteredProgIDs = @()
Write-Information -MessageData "" -InformationAction Continue
# Extract the localized "Please wait..." string from %SystemRoot%\System32\shell32.dll
Write-Verbose -Message ([WinAPI.GetStrings]::GetString(12612)) -Verbose
# Register %1 argument if ProgId exists as an executable file
if (Test-Path -Path $ProgramPath)
{
if (-not (Test-Path -Path "HKCU:\Software\Classes\$ProgId\shell\open\command"))
{
New-Item -Path "HKCU:\Software\Classes\$ProgId\shell\open\command" -Force
}
if ($ProgramPath.Contains("%1"))
{
New-ItemProperty -Path "HKCU:\Software\Classes\$ProgId\shell\open\command" -Name "(Default)" -PropertyType String -Value $ProgramPath -Force
}
else
{
New-ItemProperty -Path "HKCU:\Software\Classes\$ProgId\shell\open\command" -Name "(Default)" -PropertyType String -Value "`"$ProgramPath`" `"%1`"" -Force
}
$FileNameEXE = Split-Path -Path $ProgramPath -Leaf
if (-not (Test-Path -Path "HKCU:\Software\Classes\Applications\$FileNameEXE\shell\open\command"))
{
New-Item -Path "HKCU:\Software\Classes\Applications\$FileNameEXE\shell\open\command" -Force
}
New-ItemProperty -Path "HKCU:\Software\Classes\Applications\$FileNameEXE\shell\open\command" -Name "(Default)" -PropertyType String -Value "`"$ProgramPath`" `"%1`"" -Force
}
if ($Icon)
{
if (-not (Test-Path -Path "HKCU:\Software\Classes\$ProgId\DefaultIcon"))
{
New-Item -Path "HKCU:\Software\Classes\$ProgId\DefaultIcon" -Force
}
New-ItemProperty -Path "HKCU:\Software\Classes\$ProgId\DefaultIcon" -Name "(default)" -PropertyType String -Value $Icon -Force
}
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\ApplicationAssociationToasts -Name "$($ProgID)_$($Extension)" -PropertyType DWord -Value 0 -Force
if ($Extension.Contains("."))
{
# If the file extension specified configure the extension
Write-ExtensionKeys -ProgId $ProgId -Extension $Extension
}
else
{
[WinAPI.Action]::DeleteKey([Microsoft.Win32.RegistryHive]::CurrentUser, "Software\Microsoft\Windows\Shell\Associations\UrlAssociations\$Extension\UserChoice")
if (-not (Test-Path -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\$Extension\UserChoice"))
{
New-Item -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\$Extension\UserChoice" -Force
}
$ProgHash = Get-Hash -ProgId $ProgId -Extension $Extension -SubKey "Software\Microsoft\Windows\Shell\Associations\UrlAssociations\$Extension\UserChoice"
# We need to remove DENY permission set for user before setting a value
if (@(".pdf", "http", "https") -contains $Extension)
{
# https://powertoe.wordpress.com/2010/08/28/controlling-registry-acl-permissions-with-powershell/
$Key = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey("Software\Microsoft\Windows\Shell\Associations\UrlAssociations\$Extension\UserChoice",[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,[System.Security.AccessControl.RegistryRights]::ChangePermissions)
$ACL = $key.GetAccessControl()
$Principal = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
# https://learn.microsoft.com/en-us/dotnet/api/system.security.accesscontrol.filesystemrights
$Rule = New-Object -TypeName System.Security.AccessControl.RegistryAccessRule -ArgumentList ($Principal,"FullControl","Deny")
$ACL.RemoveAccessRule($Rule)
$Key.SetAccessControl($ACL)
# We need to use here an approach with "-Command & {}" as there's a variable inside
& "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell_temp.exe" -Command "& {New-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\$Extension\UserChoice' -Name ProgId -PropertyType String -Value $ProgID -Force}"
& "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell_temp.exe" -Command "& {New-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\$Extension\UserChoice' -Name Hash -PropertyType String -Value $ProgHash -Force}"
}
else
{
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\$Extension\UserChoice" -Name ProgId -PropertyType String -Value $ProgId -Force
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\$Extension\UserChoice" -Name Hash -PropertyType String -Value $ProgHash -Force
}
}
# Setting additional parameters to comply with the requirements before configuring the extension
Write-AdditionalKeys -ProgId $ProgId -Extension $Extension
Remove-Item -Path "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell_temp.exe" -Force
}
<#
.SYNOPSIS
Export all Windows associations
.EXAMPLE
Export-Associations
.NOTES
Associations will be exported as Application_Associations.json file in script root folder
.NOTES
You need to install all apps according to an exported JSON file to restore all associations
.NOTES
Machine-wide
#>
function Export-Associations
{
Dism.exe /Online /Export-DefaultAppAssociations:"$env:TEMP\Application_Associations.xml"
Clear-Variable -Name AllJSON, ProgramPath, Icon -ErrorAction Ignore
$AllJSON = @()
$AppxProgIds = @((Get-ChildItem -Path "Registry::HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppModel\PackageRepository\Extensions\ProgIDs").PSChildName)
[xml]$XML = Get-Content -Path "$env:TEMP\Application_Associations.xml" -Encoding UTF8 -Force
$XML.DefaultAssociations.Association | ForEach-Object -Process {
# Clear varibale not to begin double "\" char
$null = $ProgramPath, $Icon
if ($AppxProgIds -contains $_.ProgId)
{
# ProgId is a UWP app
# ProgrammPath
if (Test-Path -Path "HKCU:\Software\Classes\$($_.ProgId)\Shell\Open\Command")
{
if ([Microsoft.Win32.Registry]::GetValue("HKEY_CURRENT_USER\Software\Classes\$($_.ProgId)\shell\open\command", "DelegateExecute", $null))
{
$ProgramPath, $Icon = ""
}
}
}
else
{
if (Test-Path -Path "Registry::HKEY_CLASSES_ROOT\$($_.ProgId)")
{
# ProgrammPath
if ([Microsoft.Win32.Registry]::GetValue("HKEY_CURRENT_USER\Software\Classes\$($_.ProgId)\shell\open\command", "", $null))
{
$PartProgramPath = (Get-ItemPropertyValue -Path "HKCU:\Software\Classes\$($_.ProgId)\Shell\Open\Command" -Name "(default)").Trim()
$Program = $PartProgramPath.Substring(0, ($PartProgramPath.IndexOf(".exe") + 4)).Trim('"')
if ($Program)
{
if (Test-Path -Path $([System.Environment]::ExpandEnvironmentVariables($Program)))
{
$ProgramPath = $PartProgramPath
}
}
}
elseif ([Microsoft.Win32.Registry]::GetValue("HKEY_LOCAL_MACHINE\SOFTWARE\Classes\$($_.ProgId)\Shell\Open\Command", "", $null))
{
$PartProgramPath = (Get-ItemPropertyValue -Path "HKLM:\SOFTWARE\Classes\$($_.ProgId)\Shell\Open\Command" -Name "(default)").Trim()
$Program = $PartProgramPath.Substring(0, ($PartProgramPath.IndexOf(".exe") + 4)).Trim('"')
if ($Program)
{
if (Test-Path -Path $([System.Environment]::ExpandEnvironmentVariables($Program)))
{
$ProgramPath = $PartProgramPath
}
}
}
# Icon
if ([Microsoft.Win32.Registry]::GetValue("HKEY_CURRENT_USER\Software\Classes\$($_.ProgId)\DefaultIcon", "", $null))
{
$IconPartPath = (Get-ItemPropertyValue -Path "HKCU:\Software\Classes\$($_.ProgId)\DefaultIcon" -Name "(default)")
if ($IconPartPath.EndsWith(".ico"))
{
$IconPath = $IconPartPath
}
else
{
if ($IconPartPath.Contains(","))
{
$IconPath = $IconPartPath.Substring(0, $IconPartPath.IndexOf(",")).Trim('"')
}
else
{
$IconPath = $IconPartPath.Trim('"')
}
}
if ($IconPath)
{
if (Test-Path -Path $([System.Environment]::ExpandEnvironmentVariables($IconPath)))
{
$Icon = $IconPartPath
}
}
}
elseif ([Microsoft.Win32.Registry]::GetValue("HKEY_LOCAL_MACHINE\SOFTWARE\Classes\$($_.ProgId)\DefaultIcon", "", $null))
{
$IconPartPath = (Get-ItemPropertyValue -Path "HKLM:\SOFTWARE\Classes\$($_.ProgId)\DefaultIcon" -Name "(default)").Trim()
if ($IconPartPath.EndsWith(".ico"))
{
$IconPath = $IconPartPath
}
else
{
if ($IconPartPath.Contains(","))
{
$IconPath = $IconPartPath.Substring(0, $IconPartPath.IndexOf(",")).Trim('"')
}
else
{
$IconPath = $IconPartPath.Trim('"')
}
}
if ($IconPath)
{
if (Test-Path -Path $([System.Environment]::ExpandEnvironmentVariables($IconPath)))
{
$Icon = $IconPartPath
}
}
}
elseif ([Microsoft.Win32.Registry]::GetValue("HKEY_CURRENT_USER\Software\Classes\$($_.ProgId)\shell\open\command", "", $null))
{
$IconPartPath = (Get-ItemPropertyValue -Path "HKCU:\Software\Classes\$($_.ProgId)\shell\open\command" -Name "(default)").Trim()
$IconPath = $IconPartPath.Substring(0, $IconPartPath.IndexOf(".exe") + 4).Trim('"')
if ($IconPath)
{
if (Test-Path -Path $([System.Environment]::ExpandEnvironmentVariables($IconPath)))
{
$Icon = "$IconPath,0"
}
}
}
elseif ([Microsoft.Win32.Registry]::GetValue("HKEY_LOCAL_MACHINE\SOFTWARE\Classes\$($_.ProgId)\Shell\Open\Command", "", $null))
{
$IconPartPath = (Get-ItemPropertyValue -Path "HKLM:\SOFTWARE\Classes\$($_.ProgId)\Shell\Open\Command" -Name "(default)").Trim()
$IconPath = $IconPartPath.Substring(0, $IconPartPath.IndexOf(".exe") + 4)
if ($IconPath)
{
if (Test-Path -Path $([System.Environment]::ExpandEnvironmentVariables($IconPath)))
{
$Icon = "$IconPath,0"
}
}
}
}
}
$_.ProgId = $_.ProgId.Replace("\", "\\")
if ($ProgramPath)
{
$ProgramPath = $ProgramPath.Replace("\", "\\").Replace('"', '\"')
}
if ($Icon)
{
$Icon = $Icon.Replace("\", "\\").Replace('"', '\"')
}
# Create a hash table
$JSON = @"
[
{
"ProgId": "$($_.ProgId)",
"ProgrammPath": "$ProgramPath",
"Extension": "$($_.Identifier)",
"Icon": "$Icon"
}
]
"@ | ConvertFrom-JSON
$AllJSON += $JSON
}
# Save in UTF-8 without BOM
$AllJSON | ConvertTo-Json | Set-Content -Path "$PSScriptRoot\..\Application_Associations.json" -Encoding utf8NoBOM -Force
Remove-Item -Path "$env:TEMP\Application_Associations.xml" -Force
}
<#
.SYNOPSIS
Import all Windows associations
.EXAMPLE
Import-Associations
.NOTES
You have to install all apps according to an exported JSON file to restore all associations
.NOTES
Current user
#>
function Import-Associations
{
Add-Type -AssemblyName System.Windows.Forms
$OpenFileDialog = New-Object -TypeName System.Windows.Forms.OpenFileDialog
$OpenFileDialog.Filter = "*.json|*.json|{0} (*.*)|*.*" -f $Localization.AllFilesFilter
$OpenFileDialog.InitialDirectory = $PSScriptRoot
$OpenFileDialog.Multiselect = $false
# Force move the open file dialog to the foreground
$Focus = New-Object -TypeName System.Windows.Forms.Form -Property @{TopMost = $true}
$OpenFileDialog.ShowDialog($Focus)
if ($OpenFileDialog.FileName)
{
$AppxProgIds = @((Get-ChildItem -Path "Registry::HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppModel\PackageRepository\Extensions\ProgIDs").PSChildName)
try
{
$JSON = Get-Content -Path $OpenFileDialog.FileName -Encoding UTF8 -Force | ConvertFrom-JSON
}
catch [System.Exception]
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.JSONNotValid -f $ProgramPath), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.JSONNotValid -f $ProgramPath), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
$JSON | ForEach-Object -Process {
if ($AppxProgIds -contains $_.ProgId)
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ([string]($_.ProgId, "|", $_.Extension)) -Verbose
Set-Association -ProgramPath $_.ProgId -Extension $_.Extension
}
else
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ([string]($_.ProgrammPath, "|", $_.Extension, "|", $_.Icon)) -Verbose
Set-Association -ProgramPath $_.ProgrammPath -Extension $_.Extension -Icon $_.Icon
}
}
}
}
<#
.SYNOPSIS
Default terminal app
.PARAMETER WindowsTerminal
Set Windows Terminal as default terminal app to host the user interface for command-line applications
.PARAMETER ConsoleHost
Set Windows Console Host as default terminal app to host the user interface for command-line applications
.EXAMPLE
DefaultTerminalApp -WindowsTerminal
.EXAMPLE
DefaultTerminalApp -ConsoleHost
.NOTES
Current user
#>
function DefaultTerminalApp
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "WindowsTerminal"
)]
[switch]
$WindowsTerminal,
[Parameter(
Mandatory = $true,
ParameterSetName = "ConsoleHost"
)]
[switch]
$ConsoleHost
)
if ($WindowsTerminal)
{
if (-not (Get-AppxPackage -Name Microsoft.WindowsTerminal))
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.PackageNotInstalled -f "Windows Terminal"), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.PackageNotInstalled -f "Windows Terminal"), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
}
switch ($PSCmdlet.ParameterSetName)
{
"WindowsTerminal"
{
# Find the current GUID of Windows Terminal
$PackageFullName = (Get-AppxPackage -Name Microsoft.WindowsTerminal).PackageFullName
if (-not (Test-Path -Path "HKCU:\Console\%%Startup"))
{
New-Item -Path "HKCU:\Console\%%Startup" -Force
}
Get-ChildItem -Path "HKLM:\SOFTWARE\Classes\PackagedCom\Package\$PackageFullName\Class" | ForEach-Object -Process {
if ((Get-ItemPropertyValue -Path $_.PSPath -Name ServerId) -eq 0)
{
New-ItemProperty -Path "HKCU:\Console\%%Startup" -Name DelegationConsole -PropertyType String -Value $_.PSChildName -Force
}
if ((Get-ItemPropertyValue -Path $_.PSPath -Name ServerId) -eq 1)
{
New-ItemProperty -Path "HKCU:\Console\%%Startup" -Name DelegationTerminal -PropertyType String -Value $_.PSChildName -Force
}
}
}
"ConsoleHost"
{
New-ItemProperty -Path "HKCU:\Console\%%Startup" -Name DelegationConsole -PropertyType String -Value "{B23D10C0-E52E-411E-9D5B-C09FDF709C7D}" -Force
New-ItemProperty -Path "HKCU:\Console\%%Startup" -Name DelegationTerminal -PropertyType String -Value "{B23D10C0-E52E-411E-9D5B-C09FDF709C7D}" -Force
}
}
}
<#
.SYNOPSIS
Install the latest Microsoft Visual C++ Redistributable Packages 2017—2026 (x86/x64)
.EXAMPLE
Install-VCRedist
.LINK
https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist
.NOTES
Machine-wide
#>
function Install-VCRedist
{
# Get latest build version
# https://github.com/ScoopInstaller/Extras/blob/master/bucket/vcredist2022.json
try
{
$Parameters = @{
Uri = "https://raw.githubusercontent.com/ScoopInstaller/Extras/refs/heads/master/bucket/vcredist2022.json"
UseBasicParsing = $true
Verbose = $true
}
$LatestVCRedistVersion = (Invoke-RestMethod @Parameters).version
}
catch [System.Net.WebException]
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.NoResponse -f "https://raw.githubusercontent.com"), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.NoResponse -f "https://raw.githubusercontent.com"), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
# Checking whether vc_redist builds installed
if (Test-Path -Path "$env:ProgramData\Package Cache\*\vc_redist.x86.exe")
{
# Choose the first item if user has more than one package installed
$CurrentVCredistx86Version = (Get-Item -Path "$env:ProgramData\Package Cache\*\vc_redist.x86.exe" | Select-Object -First 1).VersionInfo.FileVersion
}
else
{
$CurrentVCredistx86Version = "0.0"
}
if (Test-Path -Path "$env:ProgramData\Package Cache\*\vc_redist.x64.exe")
{
# Choose the first item if user has more than one package installed
$CurrentVCredistx64Version = (Get-Item -Path "$env:ProgramData\Package Cache\*\vc_redist.x64.exe" | Select-Object -First 1).VersionInfo.FileVersion
}
else
{
$CurrentVCredistx64Version = "0.0"
}
$DownloadsFolder = Get-ItemPropertyValue -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" -Name "{374DE290-123F-4565-9164-39C4925E467B}"
# Proceed if currently installed build is lower than available from Microsoft or json file is unreachable, or redistributable is not installed
if (([System.Version]$LatestVCRedistVersion -gt [System.Version]$CurrentVCredistx86Version) -or ($CurrentVCredistx86Version -eq "0.0"))
{
try
{
$Parameters = @{
Uri = "https://aka.ms/vc14/vc_redist.x86.exe"
OutFile = "$DownloadsFolder\vc_redist.x86.exe"
UseBasicParsing = $true
Verbose = $true
}
Invoke-WebRequest @Parameters
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.InstallNotification -f "Visual C++ Redistributable x86 $LatestVCRedistVersion") -Verbose
Write-Information -MessageData "" -InformationAction Continue
Start-Process -FilePath "$DownloadsFolder\vc_redist.x86.exe" -ArgumentList "/install /passive /norestart" -Wait
}
catch [System.Net.WebException]
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.NoResponse -f "https://download.visualstudio.microsoft.com"), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.NoResponse -f "https://download.visualstudio.microsoft.com"), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
}
else
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.PackageIsInstalled -f "Microsoft Visual C++ Redistributable Packages 2017-2026 x86"), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.PackageIsInstalled -f "Microsoft Visual C++ Redistributable Packages 2017-2026 x86"), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
}
if (([System.Version]$LatestVCRedistVersion -gt [System.Version]$CurrentVCredistx64Version) -or ($CurrentVCredistx64Version -eq "0.0"))
{
try
{
$Parameters = @{
Uri = "https://aka.ms/vc14/vc_redist.x64.exe"
OutFile = "$DownloadsFolder\vc_redist.x64.exe"
UseBasicParsing = $true
Verbose = $true
}
Invoke-WebRequest @Parameters
}
catch [System.Net.WebException]
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.NoResponse -f "https://download.visualstudio.microsoft.com"), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.NoResponse -f "https://download.visualstudio.microsoft.com"), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.InstallNotification -f "Visual C++ Redistributable x64 $LatestVCRedistVersion") -Verbose
Write-Information -MessageData "" -InformationAction Continue
Start-Process -FilePath "$DownloadsFolder\vc_redist.x64.exe" -ArgumentList "/install /passive /norestart" -Wait
}
else
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.PackageIsInstalled -f "Microsoft Visual C++ Redistributable Packages 2017-2026 x64"), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.PackageIsInstalled -f "Microsoft Visual C++ Redistributable Packages 2017-2026 x64"), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
}
# PowerShell 5.1 (7.5 too) interprets 8.3 file name literally, if an environment variable contains a non-Latin word
# https://github.com/PowerShell/PowerShell/issues/21070
$Paths = @(
"$DownloadsFolder\vc_redist.x64.exe",
"$env:TEMP\dd_vcredist_amd64_*.log",
"$DownloadsFolder\vc_redist.x86.exe",
"$env:TEMP\dd_vcredist_x86_*.log"
)
Get-ChildItem -Path $Paths -Force -ErrorAction Ignore | Remove-Item -Force -ErrorAction Ignore
}
<#
.SYNOPSIS
Install the latest .NET Desktop Runtime 8, 9, 10
.PARAMETER NET8
Install the latest .NET Desktop Runtime 8
.PARAMETER NET9
Install the latest .NET Desktop Runtime 9
.PARAMETER NET10
Install the latest .NET Desktop Runtime 10
.EXAMPLE
Install-DotNetRuntimes -Runtimes NET8, NET9, NET10
.LINK
https://dotnet.microsoft.com/en-us/download/dotnet
.NOTES
Machine-wide
#>
function Install-DotNetRuntimes
{
[CmdletBinding()]
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Runtimes"
)]
[ValidateSet("NET8", "NET9", "NET10")]
[string[]]
$Runtimes
)
$DownloadsFolder = Get-ItemPropertyValue -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" -Name "{374DE290-123F-4565-9164-39C4925E467B}"
foreach ($Runtime in $Runtimes)
{
switch ($Runtime)
{
NET8
{
try
{
# Get latest build version
# https://github.com/dotnet/core/blob/main/release-notes/releases-index.json
$Parameters = @{
Uri = "https://builds.dotnet.microsoft.com/dotnet/release-metadata/8.0/releases.json"
Verbose = $true
UseBasicParsing = $true
}
$LatestNET8Version = (Invoke-RestMethod @Parameters)."latest-release"
}
catch [System.Net.WebException]
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.NoResponse -f "https://builds.dotnet.microsoft.com"), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.NoResponse -f "https://builds.dotnet.microsoft.com"), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
# Checking whether .NET 8 installed
if (Test-Path -Path "$env:ProgramData\Package Cache\*\windowsdesktop-runtime-$LatestNET8Version-win-x64.exe")
{
# Choose the first item if user has more than one package installed
# FileVersion has four properties while $LatestNET8Version has only three, unless the [System.Version] accelerator fails
$CurrentNET8Version = (Get-Item -Path "$env:ProgramData\Package Cache\*\windowsdesktop-runtime-$LatestNET8Version-win-x64.exe" | Select-Object -First 1).VersionInfo.FileVersion
$CurrentNET8Version = "{0}.{1}.{2}" -f $CurrentNET8Version.Split(".")
}
else
{
$CurrentNET8Version = "0.0"
}
# Proceed if currently installed build is lower than available from Microsoft or json file is unreachable, or .NET 8 is not installed at all
if (([System.Version]$LatestNET8Version -gt [System.Version]$CurrentNET8Version) -or ($CurrentNET8Version -eq "0.0"))
{
try
{
# .NET Desktop Runtime 8
$Parameters = @{
Uri = "https://builds.dotnet.microsoft.com/dotnet/WindowsDesktop/$LatestNET8Version/windowsdesktop-runtime-$LatestNET8Version-win-x64.exe"
OutFile = "$DownloadsFolder\windowsdesktop-runtime-$LatestNET8Version-win-x64.exe"
UseBasicParsing = $true
Verbose = $true
}
Invoke-WebRequest @Parameters
}
catch [System.Net.WebException]
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.NoResponse -f "https://builds.dotnet.microsoft.com"), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.NoResponse -f "https://builds.dotnet.microsoft.com"), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.InstallNotification -f ".NET 8 $LatestNET8Version") -Verbose
Write-Information -MessageData "" -InformationAction Continue
Start-Process -FilePath "$DownloadsFolder\windowsdesktop-runtime-$LatestNET8Version-win-x64.exe" -ArgumentList "/install /passive /norestart" -Wait
}
else
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.PackageIsInstalled -f ".NET 8"), ($Localization.Skipped -f ("{0} -{1} {2}" -f $MyInvocation.MyCommand.Name, $MyInvocation.BoundParameters.Keys.Trim(), $_)) -join " ") -Verbose
Write-Error -Message (($Localization.PackageIsInstalled -f ".NET 8"), ($Localization.Skipped -f ("{0} -{1} {2}" -f $MyInvocation.MyCommand.Name, $MyInvocation.BoundParameters.Keys.Trim(), $_)) -join " ") -ErrorAction SilentlyContinue
}
}
NET9
{
try
{
# Get latest build version
# https://github.com/dotnet/core/blob/main/release-notes/releases-index.json
$Parameters = @{
Uri = "https://builds.dotnet.microsoft.com/dotnet/release-metadata/9.0/releases.json"
Verbose = $true
UseBasicParsing = $true
}
$LatestNET9Version = (Invoke-RestMethod @Parameters)."latest-release"
}
catch [System.Net.WebException]
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.NoResponse -f "https://builds.dotnet.microsoft.com"), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.NoResponse -f "https://builds.dotnet.microsoft.com"), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
# Checking whether .NET 9 installed
if (Test-Path -Path "$env:ProgramData\Package Cache\*\windowsdesktop-runtime-$LatestNET9Version-win-x64.exe")
{
# Choose the first item if user has more than one package installed
# FileVersion has four properties while $LatestNET9Version has only three, unless the [System.Version] accelerator fails
$CurrentNET9Version = (Get-Item -Path "$env:ProgramData\Package Cache\*\windowsdesktop-runtime-$LatestNET9Version-win-x64.exe" | Select-Object -First 1).VersionInfo.FileVersion
$CurrentNET9Version = "{0}.{1}.{2}" -f $CurrentNET9Version.Split(".")
}
else
{
$CurrentNET9Version = "0.0"
}
# Proceed if currently installed build is lower than available from Microsoft or json file is unreachable, or .NET 9 is not installed at all
if (([System.Version]$LatestNET9Version -gt [System.Version]$CurrentNET9Version) -or ($CurrentNET9Version -eq "0.0"))
{
try
{
# .NET Desktop Runtime 9
$Parameters = @{
Uri = "https://builds.dotnet.microsoft.com/dotnet/WindowsDesktop/$LatestNET9Version/windowsdesktop-runtime-$LatestNET9Version-win-x64.exe"
OutFile = "$DownloadsFolder\windowsdesktop-runtime-$LatestNET9Version-win-x64.exe"
UseBasicParsing = $true
Verbose = $true
}
Invoke-WebRequest @Parameters
}
catch [System.Net.WebException]
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.NoResponse -f "https://builds.dotnet.microsoft.com"), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.NoResponse -f "https://builds.dotnet.microsoft.com"), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.InstallNotification -f ".NET 9 $LatestNET9Version") -Verbose
Write-Information -MessageData "" -InformationAction Continue
Start-Process -FilePath "$DownloadsFolder\windowsdesktop-runtime-$LatestNET9Version-win-x64.exe" -ArgumentList "/install /passive /norestart" -Wait
}
else
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.PackageIsInstalled -f ".NET 9"), ($Localization.Skipped -f ("{0} -{1} {2}" -f $MyInvocation.MyCommand.Name, $MyInvocation.BoundParameters.Keys.Trim(), $_)) -join " ") -Verbose
Write-Error -Message (($Localization.PackageIsInstalled -f ".NET 9"), ($Localization.Skipped -f ("{0} -{1} {2}" -f $MyInvocation.MyCommand.Name, $MyInvocation.BoundParameters.Keys.Trim(), $_)) -join " ") -ErrorAction SilentlyContinue
}
}
NET10
{
try
{
# Get latest build version
# https://github.com/dotnet/core/blob/main/release-notes/releases-index.json
$Parameters = @{
Uri = "https://builds.dotnet.microsoft.com/dotnet/release-metadata/10.0/releases.json"
Verbose = $true
UseBasicParsing = $true
}
$LatestNET10Version = (Invoke-RestMethod @Parameters)."latest-release"
}
catch [System.Net.WebException]
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.NoResponse -f "https://builds.dotnet.microsoft.com"), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.NoResponse -f "https://builds.dotnet.microsoft.com"), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
# Checking whether .NET 10 installed
if (Test-Path -Path "$env:ProgramData\Package Cache\*\windowsdesktop-runtime-$LatestNET10Version-win-x64.exe")
{
# Choose the first item if user has more than one package installed
# FileVersion has four properties while $LatestNET10Version has only three, unless the [System.Version] accelerator fails
$CurrentNET10Version = (Get-Item -Path "$env:ProgramData\Package Cache\*\windowsdesktop-runtime-$LatestNET10Version-win-x64.exe" | Select-Object -First 1).VersionInfo.FileVersion
$CurrentNET10Version = "{0}.{1}.{2}" -f $CurrentNET10Version.Split(".")
}
else
{
$CurrentNET10Version = "0.0"
}
# Proceed if currently installed build is lower than available from Microsoft or json file is unreachable, or .NET 10 is not installed at all
if (([System.Version]$LatestNET10Version -gt [System.Version]$CurrentNET10Version) -or ($CurrentNET10Version -eq "0.0"))
{
try
{
# .NET Desktop Runtime 10
$Parameters = @{
Uri = "https://builds.dotnet.microsoft.com/dotnet/WindowsDesktop/$LatestNET10Version/windowsdesktop-runtime-$LatestNET10Version-win-x64.exe"
OutFile = "$DownloadsFolder\windowsdesktop-runtime-$LatestNET10Version-win-x64.exe"
UseBasicParsing = $true
Verbose = $true
}
Invoke-WebRequest @Parameters
}
catch [System.Net.WebException]
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.NoResponse -f "https://builds.dotnet.microsoft.com"), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.NoResponse -f "https://builds.dotnet.microsoft.com"), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.InstallNotification -f ".NET 10 $LatestNET10Version") -Verbose
Write-Information -MessageData "" -InformationAction Continue
Start-Process -FilePath "$DownloadsFolder\windowsdesktop-runtime-$LatestNET10Version-win-x64.exe" -ArgumentList "/install /passive /norestart" -Wait
}
else
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.PackageIsInstalled -f ".NET 10"), ($Localization.Skipped -f ("{0} -{1} {2}" -f $MyInvocation.MyCommand.Name, $MyInvocation.BoundParameters.Keys.Trim(), $_)) -join " ") -Verbose
Write-Error -Message (($Localization.PackageIsInstalled -f ".NET 10"), ($Localization.Skipped -f ("{0} -{1} {2}" -f $MyInvocation.MyCommand.Name, $MyInvocation.BoundParameters.Keys.Trim(), $_)) -join " ") -ErrorAction SilentlyContinue
}
}
}
}
# PowerShell 5.1 (7.5 too) interprets 8.3 file name literally, if an environment variable contains a non-Latin word
# https://github.com/PowerShell/PowerShell/issues/21070
$Paths = @(
"$env:TEMP\Microsoft_Windows_Desktop_Runtime*.log",
"$DownloadsFolder\windowsdesktop-runtime-$LatestNET8Version-win-x64.exe",
"$DownloadsFolder\windowsdesktop-runtime-$LatestNET9Version-win-x64.exe",
"$DownloadsFolder\windowsdesktop-runtime-$LatestNET10Version-win-x64.exe"
)
Get-ChildItem -Path $Paths -Force -ErrorAction Ignore | Remove-Item -Force -ErrorAction Ignore
}
<#
.SYNOPSIS
Bypass RKN restrictins using antizapret.prostovpn.org proxy
.PARAMETER Enable
Enable proxying only blocked sites from the unified registry of Roskomnadzor using antizapret.prostovpn.org proxy
.PARAMETER Disable
Disable proxying only blocked sites from the unified registry of Roskomnadzor using antizapret.prostovpn.org proxy
.EXAMPLE
AntizapretProxy -Enable
.EXAMPLE
AntizapretProxy -Disable
.LINK
https://antizapret.prostovpn.org
.NOTES
Current user
#>
function AntizapretProxy
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
# If current region is Russia
if ((Get-WinHomeLocation).GeoId -eq "203")
{
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" -Name AutoConfigURL -PropertyType String -Value "https://p.thenewone.lol:8443/proxy.pac" -Force
}
else
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.GeoIdNotSupported -f $MyInvocation.Line.Trim()), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.GeoIdNotSupported -f $MyInvocation.Line.Trim()), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
}
}
"Disable"
{
Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" -Name AutoConfigURL -Force -ErrorAction Ignore
}
}
$Signature = @{
Namespace = "WinAPI"
Name = "wininet"
Language = "CSharp"
CompilerOptions = $CompilerOptions
MemberDefinition = @"
[DllImport("wininet.dll", SetLastError = true, CharSet=CharSet.Auto)]
public static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int dwBufferLength);
"@
}
if (-not ("WinAPI.wininet" -as [type]))
{
Add-Type @Signature
}
# Apply changed proxy settings
# https://learn.microsoft.com/en-us/windows/win32/wininet/option-flags
$INTERNET_OPTION_SETTINGS_CHANGED = 39
$INTERNET_OPTION_REFRESH = 37
[WinAPI.wininet]::InternetSetOption(0, $INTERNET_OPTION_SETTINGS_CHANGED, 0, 0)
[WinAPI.wininet]::InternetSetOption(0, $INTERNET_OPTION_REFRESH, 0, 0)
}
<#
.SYNOPSIS
Desktop shortcut creation upon Microsoft Edge update
.PARAMETER Channels
List Microsoft Edge channels to prevent desktop shortcut creation upon its update
.PARAMETER Disable
Do not prevent desktop shortcut creation upon Microsoft Edge update
.EXAMPLE
PreventEdgeShortcutCreation -Channels Stable, Beta, Dev, Canary
.EXAMPLE
PreventEdgeShortcutCreation -Disable
.NOTES
Machine-wide
#>
function PreventEdgeShortcutCreation
{
[CmdletBinding()]
param
(
[Parameter(
Mandatory = $false,
ParameterSetName = "Channels"
)]
[ValidateSet("Stable", "Beta", "Dev", "Canary")]
[string[]]
$Channels,
[Parameter(
Mandatory = $false,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
if (-not (Get-Package -Name "Microsoft Edge" -ErrorAction Ignore))
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.PackageNotInstalled -f "Microsoft Edge"), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.PackageNotInstalled -f "Microsoft Edge"), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
if (-not (Test-Path -Path HKLM:\SOFTWARE\Policies\Microsoft\EdgeUpdate))
{
New-Item -Path HKLM:\SOFTWARE\Policies\Microsoft\EdgeUpdate -Force
}
foreach ($Channel in $Channels)
{
switch ($Channel)
{
Stable
{
if (Get-Package -Name "Microsoft Edge" -ErrorAction Ignore)
{
New-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\EdgeUpdate -Name "CreateDesktopShortcut{56EB18F8-B008-4CBD-B6D2-8C97FE7E9062}" -PropertyType DWord -Value 0 -Force
# msedgeupdate.admx is not a default ADMX template
if (Test-Path -Path "$env:SystemRoot\PolicyDefinitions\msedgeupdate.admx")
{
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\EdgeUpdate -Name "CreateDesktopShortcut{56EB18F8-B008-4CBD-B6D2-8C97FE7E9062}" -Type DWORD -Value 3
}
}
}
Beta
{
if (Get-Package -Name "Microsoft Edge Beta" -ErrorAction Ignore)
{
New-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\EdgeUpdate -Name "CreateDesktopShortcut{2CD8A007-E189-409D-A2C8-9AF4EF3C72AA}" -PropertyType DWord -Value 0 -Force
# msedgeupdate.admx is not a default ADMX template
if (Test-Path -Path "$env:SystemRoot\PolicyDefinitions\msedgeupdate.admx")
{
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\EdgeUpdate -Name "CreateDesktopShortcut{2CD8A007-E189-409D-A2C8-9AF4EF3C72AA}" -Type DWORD -Value 3
}
}
}
Dev
{
if (Get-Package -Name "Microsoft Edge Dev" -ErrorAction Ignore)
{
New-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\EdgeUpdate -Name "CreateDesktopShortcut{0D50BFEC-CD6A-4F9A-964C-C7416E3ACB10}" -PropertyType DWord -Value 0 -Force
# msedgeupdate.admx is not a default ADMX template
if (Test-Path -Path "$env:SystemRoot\PolicyDefinitions\msedgeupdate.admx")
{
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\EdgeUpdate -Name "CreateDesktopShortcut{0D50BFEC-CD6A-4F9A-964C-C7416E3ACB10}" -Type DWORD -Value 3
}
}
}
Canary
{
if (Get-Package -Name "Microsoft Edge Canary" -ErrorAction Ignore)
{
New-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\EdgeUpdate -Name "CreateDesktopShortcut{65C35B14-6C1D-4122-AC46-7148CC9D6497}" -PropertyType DWord -Value 0 -Force
# msedgeupdate.admx is not a default ADMX template
if (Test-Path -Path "$env:SystemRoot\PolicyDefinitions\msedgeupdate.admx")
{
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\EdgeUpdate -Name "CreateDesktopShortcut{65C35B14-6C1D-4122-AC46-7148CC9D6497}" -Type DWORD -Value 3
}
}
}
}
}
if ($Disable)
{
$Names = @(
"CreateDesktopShortcut{56EB18F8-B008-4CBD-B6D2-8C97FE7E9062}",
"CreateDesktopShortcut{2CD8A007-E189-409D-A2C8-9AF4EF3C72AA}",
"CreateDesktopShortcut{0D50BFEC-CD6A-4F9A-964C-C7416E3ACB10}",
"CreateDesktopShortcut{65C35B14-6C1D-4122-AC46-7148CC9D6497}"
)
Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\EdgeUpdate -Name $Names -Force -ErrorAction Ignore
if (Test-Path -Path "$env:SystemRoot\PolicyDefinitions\msedgeupdate.admx")
{
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\EdgeUpdate -Name "CreateDesktopShortcut{56EB18F8-B008-4CBD-B6D2-8C97FE7E9062}" -Type CLEAR
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\EdgeUpdate -Name "CreateDesktopShortcut{2CD8A007-E189-409D-A2C8-9AF4EF3C72AA}" -Type CLEAR
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\EdgeUpdate -Name "CreateDesktopShortcut{0D50BFEC-CD6A-4F9A-964C-C7416E3ACB10}" -Type CLEAR
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\EdgeUpdate -Name "CreateDesktopShortcut{65C35B14-6C1D-4122-AC46-7148CC9D6497}" -Type CLEAR
}
}
}
<#
.SYNOPSIS
Back up the system registry to %SystemRoot%\System32\config\RegBack folder when PC restarts and create a RegIdleBackup in the Task Scheduler task to manage subsequent backups
.PARAMETER Enable
Back up the system registry to %SystemRoot%\System32\config\RegBack folder
.PARAMETER Disable
Do not back up the system registry to %SystemRoot%\System32\config\RegBack folder
.EXAMPLE
RegistryBackup -Enable
.EXAMPLE
RegistryBackup -Disable
.NOTES
Machine-wide
#>
function RegistryBackup
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\Maintenance" -Name MaintenanceDisabled -Force -ErrorAction Ignore
Get-ScheduledTask -TaskName RegIdleBackup -ErrorAction Ignore | Enable-ScheduledTask -ErrorAction Ignore
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Configuration Manager" -Name EnablePeriodicBackup -PropertyType DWord -Value 1 -Force
}
"Disable"
{
Remove-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Configuration Manager" -Name EnablePeriodicBackup -Force -ErrorAction Ignore
}
}
}
<#
.SYNOPSIS
Configure Windows AI
.PARAMETER Disable
Disable Windows AI functions
.PARAMETER Enable
Enable Windows AI functions
.EXAMPLE
WindowsAI -Disable
.EXAMPLE
WindowsAI -Enable
.NOTES
Machine-wide
#>
function WindowsAI
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
$Paths = @(
"HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI",
"HKCU:\Software\Policies\Microsoft\Windows\WindowsAI",
"HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsCopilot",
"HKCU:\Software\Policies\Microsoft\Windows\WindowsCopilot"
)
Remove-Item -Path $Paths -Force -ErrorAction Ignore
Remove-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\PolicyManager\default\WindowsAI\DisableAIDataAnalysis -Name value -Force -ErrorAction Ignore
if (-not (Get-CimInstance -ClassName Win32_PnPEntity | Where-Object -FilterScript {($null -ne $_.ClassGuid) -and ($_.PNPClass -eq "ComputeAccelerator")}))
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message $Localization.CopilotPCSupport -Verbose
Write-Error -Message $Localization.CopilotPCSupport -ErrorAction SilentlyContinue
}
Write-Information -MessageData "" -InformationAction Continue
# Extract the localized "Please wait..." string from %SystemRoot%\System32\shell32.dll
Write-Verbose -Message ([WinAPI.GetStrings]::GetString(12612)) -Verbose
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
# Disable Recall
Disable-WindowsOptionalFeature -Online -FeatureName Recall
# Remove Copilot application
Get-AppxPackage -Name Microsoft.Copilot | Remove-AppxPackage
}
"Enable"
{
# Enable Recall
Enable-WindowsOptionalFeature -Online -FeatureName Recall
# Open Copilot page in Microsoft Store
Start-Process -FilePath "ms-windows-store://pdp/?ProductId=9NHT9RB2F4HD"
}
}
}
#endregion System
#region WSL
<#
.SYNOPSIS
Windows Subsystem for Linux (WSL)
.EXAMPLE Enable Windows Subsystem for Linux (WSL) and install the latest WSL Linux kernel version
Install-WSL
.NOTES
The "Receive updates for other Microsoft products" setting will be enabled automatically to receive kernel updates
.NOTES
Machine-wide
#>
function Install-WSL
{
try
{
# https://github.com/microsoft/WSL/blob/master/distributions/DistributionInfo.json
# wsl --list --online relies on Internet connection too, so it's much convenient to parse DistributionInfo.json, rather than parse a cmd output
$Parameters = @{
Uri = "https://raw.githubusercontent.com/microsoft/WSL/master/distributions/DistributionInfo.json"
UseBasicParsing = $true
Verbose = $true
}
$Distributions = (Invoke-RestMethod @Parameters).Distributions | ForEach-Object -Process {
[PSCustomObject]@{
"Distribution" = $_.FriendlyName
"Alias" = $_.Name
}
}
}
catch [System.Net.WebException]
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.NoResponse -f "https://raw.githubusercontent.com"), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.NoResponse -f "https://raw.githubusercontent.com"), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
Add-Type -AssemblyName PresentationCore, PresentationFramework
#region Variables
$null = $CommandTag
#region XAML Markup
# The section defines the design of the upcoming dialog box
[xml]$XAML = @"
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Name="Window"
Title="WSL"
MinHeight="460"
MinWidth="350"
SizeToContent="WidthAndHeight"
WindowStartupLocation="CenterScreen"
TextOptions.TextFormattingMode="Display"
SnapsToDevicePixels="True"
FontFamily="Candara"
FontSize="16"
ShowInTaskbar="True"
Background="#F1F1F1"
Foreground="#262626">
<Window.Resources>
<Style TargetType="RadioButton">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="10"/>
</Style>
<Style TargetType="TextBlock">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="0, 0, 0, 2"/>
</Style>
<Style TargetType="Button">
<Setter Property="Margin" Value="20"/>
<Setter Property="Padding" Value="10"/>
<Setter Property="IsEnabled" Value="False"/>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Name="PanelContainer" Grid.Row="0"/>
<Button Name="ButtonInstall" Content="Install" Grid.Row="2"/>
</Grid>
</Window>
"@
#endregion XAML Markup
$Form = [Windows.Markup.XamlReader]::Load((New-Object -TypeName System.Xml.XmlNodeReader -ArgumentList $XAML))
$XAML.SelectNodes("//*[@*[contains(translate(name(.),'n','N'),'Name')]]") | ForEach-Object -Process {
Set-Variable -Name $_.Name -Value $Form.FindName($_.Name)
}
$ButtonInstall.Content = $Localization.Install
#endregion Variables
#region Functions
function RadioButtonChecked
{
$Global:CommandTag = $_.OriginalSource.Tag
if (-not $ButtonInstall.IsEnabled)
{
$ButtonInstall.IsEnabled = $true
}
}
function ButtonInstallClicked
{
Write-Warning -Message $Global:CommandTag
Start-Process -FilePath wsl.exe -ArgumentList "--install --distribution $Global:CommandTag" -Wait
$Form.Close()
# Receive updates for other Microsoft products when you update Windows
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings -Name AllowMUUpdateService -PropertyType DWord -Value 1 -Force
# Check for updates
& "$env:SystemRoot\System32\UsoClient.exe" StartInteractiveScan
}
#endregion
foreach ($Distribution in $Distributions)
{
$Panel = New-Object -TypeName System.Windows.Controls.StackPanel
$RadioButton = New-Object -TypeName System.Windows.Controls.RadioButton
$TextBlock = New-Object -TypeName System.Windows.Controls.TextBlock
$Panel.Orientation = "Horizontal"
$RadioButton.GroupName = "WslDistribution"
$RadioButton.Tag = $Distribution.Alias
$RadioButton.Add_Checked({RadioButtonChecked})
$TextBlock.Text = $Distribution.Distribution
$Panel.Children.Add($RadioButton) | Out-Null
$Panel.Children.Add($TextBlock) | Out-Null
$PanelContainer.Children.Add($Panel) | Out-Null
}
$ButtonInstall.Add_Click({ButtonInstallClicked})
#region Sendkey function
# Emulate the Backspace key sending to prevent the console window to freeze
Start-Sleep -Milliseconds 500
Add-Type -AssemblyName System.Windows.Forms
# We cannot use Get-Process -Id $PID as script might be invoked via Terminal with different $PID
Get-Process -Name powershell, WindowsTerminal -ErrorAction Ignore | Where-Object -FilterScript {$_.MainWindowTitle -match "Sophia Script for Windows 11"} | ForEach-Object -Process {
# Show window, if minimized
[WinAPI.ForegroundWindow]::ShowWindowAsync($_.MainWindowHandle, 10)
Start-Sleep -Seconds 1
# Force move the console window to the foreground
[WinAPI.ForegroundWindow]::SetForegroundWindow($_.MainWindowHandle)
Start-Sleep -Seconds 1
# Emulate the Backspace key sending
[System.Windows.Forms.SendKeys]::SendWait("{BACKSPACE 1}")
}
#endregion Sendkey function
# Force move the WPF form to the foreground
$Window.Add_Loaded({$Window.Activate()})
$Form.ShowDialog() | Out-Null
}
#endregion WSL
#region UWP apps
<#
.SYNOPSIS
Uninstall UWP apps
.PARAMETER ForAllUsers
"ForAllUsers" argument sets a checkbox to unistall packages for all users
.EXAMPLE
Uninstall-UWPApps
.EXAMPLE
Uninstall-UWPApps -ForAllUsers
.NOTES
Load the WinRT.Runtime.dll and Microsoft.Windows.SDK.NET.dll assemblies in the current session in order to get localized UWP apps names
.LINK
https://github.com/microsoft/CsWinRT
https://www.nuget.org/packages/Microsoft.Windows.SDK.NET.Ref
.NOTES
Current user
#>
function Uninstall-UWPApps
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $false)]
[switch]
$ForAllUsers
)
Add-Type -AssemblyName "$PSScriptRoot\..\Binaries\WinRT.Runtime.dll"
Add-Type -AssemblyName "$PSScriptRoot\..\Binaries\Microsoft.Windows.SDK.NET.dll"
Add-Type -AssemblyName PresentationCore, PresentationFramework
#region Variables
# The following UWP apps will have their checkboxes unchecked
$UncheckedAppxPackages = @(
# Windows Media Player
"Microsoft.ZuneMusic",
# Screen Sketch
"Microsoft.ScreenSketch",
# Photos (and Video Editor)
"Microsoft.Windows.Photos",
"Microsoft.Photos.MediaEngineDLC",
# Calculator
"Microsoft.WindowsCalculator",
# Windows Advanced Settings
"Microsoft.Windows.DevHome",
# Windows Camera
"Microsoft.WindowsCamera",
# Xbox Identity Provider
"Microsoft.XboxIdentityProvider",
# Xbox Console Companion
"Microsoft.XboxApp",
# Xbox
"Microsoft.GamingApp",
"Microsoft.GamingServices",
# Paint
"Microsoft.Paint",
# Xbox TCUI
"Microsoft.Xbox.TCUI",
# Xbox Speech To Text Overlay
"Microsoft.XboxSpeechToTextOverlay",
# Xbox Game Bar
"Microsoft.XboxGamingOverlay",
# Xbox Game Bar Plugin
"Microsoft.XboxGameOverlay"
)
# The following UWP apps will be excluded from the display
$ExcludedAppxPackages = @(
# Dolby Access
"DolbyLaboratories.DolbyAccess",
"DolbyLaboratories.DolbyDigitalPlusDecoderOEM",
# AMD Radeon Software
"AdvancedMicroDevicesInc-2.AMDRadeonSoftware",
# Intel Graphics Control Center
"AppUp.IntelGraphicsControlPanel",
"AppUp.IntelGraphicsExperience",
# ELAN Touchpad
"ELANMicroelectronicsCorpo.ELANTouchpadforThinkpad",
"ELANMicroelectronicsCorpo.ELANTrackPointforThinkpa",
# Microsoft Application Compatibility Enhancements
"Microsoft.ApplicationCompatibilityEnhancements",
# AVC Encoder Video Extension
"Microsoft.AVCEncoderVideoExtension",
# Microsoft Desktop App Installer
"Microsoft.DesktopAppInstaller",
# Store Experience Host
"Microsoft.StorePurchaseApp",
# Cross Device Experience Host
"MicrosoftWindows.CrossDevice",
# Notepad
"Microsoft.WindowsNotepad",
# Microsoft Store
"Microsoft.WindowsStore",
# Windows Terminal
"Microsoft.WindowsTerminal",
"Microsoft.WindowsTerminalPreview",
# Web Media Extensions
"Microsoft.WebMediaExtensions",
# AV1 Video Extension
"Microsoft.AV1VideoExtension",
# Windows Subsystem for Linux
"MicrosoftCorporationII.WindowsSubsystemForLinux",
# HEVC Video Extensions from Device Manufacturer
"Microsoft.HEVCVideoExtension",
"Microsoft.HEVCVideoExtensions",
# Raw Image Extension
"Microsoft.RawImageExtension",
# HEIF Image Extensions
"Microsoft.HEIFImageExtension",
# MPEG-2 Video Extension
"Microsoft.MPEG2VideoExtension",
# VP9 Video Extensions
"Microsoft.VP9VideoExtensions",
# Webp Image Extensions
"Microsoft.WebpImageExtension",
# PowerShell
"Microsoft.PowerShell",
# NVIDIA Control Panel
"NVIDIACorp.NVIDIAControlPanel",
# Realtek Audio Console
"RealtekSemiconductorCorp.RealtekAudioControl",
# Synaptics
"SynapticsIncorporated.SynapticsControlPanel",
"SynapticsIncorporated.241916F58D6E7",
"ELANMicroelectronicsCorpo.ELANTrackPointforThinkpa",
"ELANMicroelectronicsCorpo.TrackPoint"
)
#region Variables
#region XAML Markup
# The section defines the design of the upcoming dialog box
[xml]$XAML = @"
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="Window"
MinHeight="400" MinWidth="415"
SizeToContent="Width" WindowStartupLocation="CenterScreen"
TextOptions.TextFormattingMode="Display" SnapsToDevicePixels="True"
FontFamily="Candara" FontSize="16" ShowInTaskbar="True"
Background="#F1F1F1" Foreground="#262626">
<Window.Resources>
<Style TargetType="StackPanel">
<Setter Property="Orientation" Value="Horizontal"/>
<Setter Property="VerticalAlignment" Value="Top"/>
</Style>
<Style TargetType="CheckBox">
<Setter Property="Margin" Value="10,13,10,13"/>
<Setter Property="IsChecked" Value="True"/>
</Style>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="0,10,10,10"/>
</Style>
<Style TargetType="Button">
<Setter Property="Margin" Value="20"/>
<Setter Property="Padding" Value="10"/>
<Setter Property="IsEnabled" Value="False"/>
</Style>
<Style TargetType="Border">
<Setter Property="BorderThickness" Value="0,1,0,1"/>
<Setter Property="BorderBrush" Value="#000000"/>
</Style>
<Style TargetType="ScrollViewer">
<Setter Property="HorizontalScrollBarVisibility" Value="Disabled"/>
<Setter Property="BorderBrush" Value="#000000"/>
<Setter Property="BorderThickness" Value="0,1,0,1"/>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel x:Name="PanelSelectAll" Grid.Column="0" HorizontalAlignment="Left">
<CheckBox x:Name="CheckBoxSelectAll" IsChecked="False"/>
<TextBlock x:Name="TextBlockSelectAll" Margin="10,10,0,10"/>
</StackPanel>
<StackPanel x:Name="PanelRemoveForAll" Grid.Column="1" HorizontalAlignment="Right">
<TextBlock x:Name="TextBlockRemoveForAll" Margin="10,10,0,10"/>
<CheckBox x:Name="CheckBoxForAllUsers" IsChecked="False"/>
</StackPanel>
</Grid>
<Border Grid.Row="1">
<ScrollViewer>
<StackPanel x:Name="PanelContainer" Orientation="Vertical"/>
</ScrollViewer>
</Border>
<Button x:Name="ButtonUninstall" Grid.Row="2"/>
</Grid>
</Window>
"@
#endregion XAML Markup
$Form = [Windows.Markup.XamlReader]::Load((New-Object -TypeName System.Xml.XmlNodeReader -ArgumentList $XAML))
$XAML.SelectNodes("//*[@*[contains(translate(name(.),'n','N'),'Name')]]") | ForEach-Object -Process {
Set-Variable -Name $_.Name -Value $Form.FindName($_.Name)
}
$Window.Title = $Localization.UWPAppsTitle
$ButtonUninstall.Content = $Localization.Uninstall
$TextBlockRemoveForAll.Text = $Localization.UninstallUWPForAll
# Extract the localized "Select all" string from %SystemRoot%\System32\shell32.dll
$TextBlockSelectAll.Text = [WinAPI.GetStrings]::GetString(31276)
$ButtonUninstall.Add_Click({ButtonUninstallClick})
$CheckBoxForAllUsers.Add_Click({CheckBoxForAllUsersClick})
$CheckBoxSelectAll.Add_Click({CheckBoxSelectAllClick})
#endregion Variables
#region Functions
function Get-AppxBundle
{
[CmdletBinding()]
param
(
[string[]]
$Exclude,
[switch]
$AllUsers
)
Write-Information -MessageData "" -InformationAction Continue
# Extract the localized "Please wait..." string from %SystemRoot%\System32\shell32.dll
Write-Verbose -Message ([WinAPI.GetStrings]::GetString(12612)) -Verbose
$AppxPackages = @(Get-AppxPackage -PackageTypeFilter Bundle -AllUsers:$AllUsers | Where-Object -FilterScript {$_.Name -notin $ExcludedAppxPackages})
# The -PackageTypeFilter Bundle doesn't contain these packages, and we need to add manually
$Packages = @(
# Outlook
"Microsoft.OutlookForWindows",
# Microsoft Teams
"MSTeams",
# Microsoft Edge Game Assist
"Microsoft.Edge.GameAssist"
)
foreach ($Package in $Packages)
{
if (Get-AppxPackage -Name $Package -AllUsers:$AllUsers)
{
$AppxPackages += Get-AppxPackage -Name $Package -AllUsers:$AllUsers
}
}
$PackagesIds = [Windows.Management.Deployment.PackageManager]::new().FindPackages() | Select-Object -Property DisplayName -ExpandProperty Id | Select-Object -Property Name, DisplayName
foreach ($AppxPackage in $AppxPackages)
{
$PackageId = $PackagesIds | Where-Object -FilterScript {$_.Name -eq $AppxPackage.Name}
if (-not $PackageId)
{
continue
}
[PSCustomObject]@{
Name = $AppxPackage.Name
PackageFullName = $AppxPackage.PackageFullName
# Sometimes there's more than one package presented in Windows with the same package name like {Microsoft Teams, Microsoft Teams} and we need to display the first one
DisplayName = $PackageId.DisplayName | Select-Object -First 1
}
}
}
function Add-Control
{
[CmdletBinding()]
param
(
[Parameter(
Mandatory = $true,
ValueFromPipeline = $true
)]
[ValidateNotNull()]
[PSCustomObject[]]
$Packages
)
process
{
foreach ($Package in $Packages)
{
$CheckBox = New-Object -TypeName System.Windows.Controls.CheckBox
$CheckBox.Tag = $Package.PackageFullName
$TextBlock = New-Object -TypeName System.Windows.Controls.TextBlock
if ($Package.DisplayName)
{
$TextBlock.Text = $Package.DisplayName
}
else
{
$TextBlock.Text = $Package.Name
}
$StackPanel = New-Object -TypeName System.Windows.Controls.StackPanel
$StackPanel.Children.Add($CheckBox) | Out-Null
$StackPanel.Children.Add($TextBlock) | Out-Null
$PanelContainer.Children.Add($StackPanel) | Out-Null
if ($UncheckedAppxPackages.Contains($Package.Name))
{
$CheckBox.IsChecked = $false
}
else
{
$CheckBox.IsChecked = $true
$PackagesToRemove.Add($Package.PackageFullName)
}
$CheckBox.Add_Click({CheckBoxClick})
}
}
}
function CheckBoxForAllUsersClick
{
$PanelContainer.Children.RemoveRange(0, $PanelContainer.Children.Count)
$PackagesToRemove.Clear()
$AppXPackages = Get-AppxBundle -Exclude $ExcludedAppxPackages -AllUsers:$CheckBoxForAllUsers.IsChecked
$AppXPackages | Add-Control
ButtonUninstallSetIsEnabled
}
function ButtonUninstallClick
{
Write-Information -MessageData "" -InformationAction Continue
# Extract the localized "Please wait..." string from %SystemRoot%\System32\shell32.dll
Write-Verbose -Message ([WinAPI.GetStrings]::GetString(12612)) -Verbose
$Window.Close() | Out-Null
# If MSTeams is selected to uninstall, delete quietly "Microsoft Teams Meeting Add-in for Microsoft Office" too
# & "$env:SystemRoot\System32\msiexec.exe" --% /x {A7AB73A3-CB10-4AA5-9D38-6AEFFBDE4C91} /qn
if ($PackagesToRemove -match "MSTeams")
{
Start-Process -FilePath "$env:SystemRoot\System32\msiexec.exe" -ArgumentList "/x {A7AB73A3-CB10-4AA5-9D38-6AEFFBDE4C91} /qn" -Wait
}
$PackagesToRemove | Remove-AppxPackage -AllUsers:$CheckBoxForAllUsers.IsChecked -Verbose
}
function CheckBoxClick
{
$CheckBox = $_.Source
if ($CheckBox.IsChecked)
{
$PackagesToRemove.Add($CheckBox.Tag) | Out-Null
}
else
{
$PackagesToRemove.Remove($CheckBox.Tag)
}
ButtonUninstallSetIsEnabled
}
function CheckBoxSelectAllClick
{
$CheckBox = $_.Source
if ($CheckBox.IsChecked)
{
$PackagesToRemove.Clear()
foreach ($Item in $PanelContainer.Children.Children)
{
if ($Item -is [System.Windows.Controls.CheckBox])
{
$Item.IsChecked = $true
$PackagesToRemove.Add($Item.Tag)
}
}
}
else
{
$PackagesToRemove.Clear()
foreach ($Item in $PanelContainer.Children.Children)
{
if ($Item -is [System.Windows.Controls.CheckBox])
{
$Item.IsChecked = $false
}
}
}
ButtonUninstallSetIsEnabled
}
function ButtonUninstallSetIsEnabled
{
if ($PackagesToRemove.Count -gt 0)
{
$ButtonUninstall.IsEnabled = $true
}
else
{
$ButtonUninstall.IsEnabled = $false
}
}
#endregion Functions
# Check "For all users" checkbox to uninstall packages from all accounts
if ($ForAllUsers)
{
$CheckBoxForAllUsers.IsChecked = $true
}
$PackagesToRemove = [Collections.Generic.List[string]]::new()
$AppXPackages = Get-AppxBundle -Exclude $ExcludedAppxPackages -AllUsers:$ForAllUsers
$AppXPackages | Add-Control
if ($AppxPackages.Count -eq 0)
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.NoUWPApps, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.NoUWPApps, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
}
else
{
#region Sendkey function
# Emulate the Backspace key sending to prevent the console window to freeze
Start-Sleep -Milliseconds 500
Add-Type -AssemblyName System.Windows.Forms
# We cannot use Get-Process -Id $PID as script might be invoked via Terminal with different $PID
Get-Process -Name powershell, WindowsTerminal -ErrorAction Ignore | Where-Object -FilterScript {$_.MainWindowTitle -match "Sophia Script for Windows 11"} | ForEach-Object -Process {
# Show window, if minimized
[WinAPI.ForegroundWindow]::ShowWindowAsync($_.MainWindowHandle, 10)
Start-Sleep -Seconds 1
# Force move the console window to the foreground
[WinAPI.ForegroundWindow]::SetForegroundWindow($_.MainWindowHandle)
Start-Sleep -Seconds 1
# Emulate the Backspace key sending to prevent the console window to freeze
[System.Windows.Forms.SendKeys]::SendWait("{BACKSPACE 1}")
}
#endregion Sendkey function
if ($PackagesToRemove.Count -gt 0)
{
$ButtonUninstall.IsEnabled = $true
}
# Force move the WPF form to the foreground
$Window.Add_Loaded({$Window.Activate()})
$Form.ShowDialog() | Out-Null
}
}
#endregion UWP apps
#region Gaming
<#
.SYNOPSIS
Xbox Game Bar
.PARAMETER Disable
Disable Xbox Game Bar
.PARAMETER Enable
Enable Xbox Game Bar
.EXAMPLE
XboxGameBar -Disable
.EXAMPLE
XboxGameBar -Enable
.NOTES
To prevent popping up the "You'll need a new app to open this ms-gamingoverlay" warning, you need to disable the Xbox Game Bar app, even if you uninstalled it before
.NOTES
Current user
#>
function XboxGameBar
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\GameDVR -Name AppCaptureEnabled -PropertyType DWord -Value 0 -Force
New-ItemProperty -Path HKCU:\System\GameConfigStore -Name GameDVR_Enabled -PropertyType DWord -Value 0 -Force
}
"Enable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\GameDVR -Name AppCaptureEnabled -PropertyType DWord -Value 1 -Force
New-ItemProperty -Path HKCU:\System\GameConfigStore -Name GameDVR_Enabled -PropertyType DWord -Value 1 -Force
}
}
}
<#
.SYNOPSIS
Xbox Game Bar tips
.PARAMETER Disable
Disable Xbox Game Bar tips
.PARAMETER Enable
Enable Xbox Game Bar tips
.EXAMPLE
XboxGameTips -Disable
.EXAMPLE
XboxGameTips -Enable
.NOTES
Current user
#>
function XboxGameTips
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
if (-not (Get-AppxPackage -Name Microsoft.GamingApp))
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.PackageNotInstalled -f "Xbox"), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.PackageNotInstalled -f "Xbox"), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\GameBar -Name ShowStartupPanel -PropertyType DWord -Value 0 -Force
}
"Enable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\GameBar -Name ShowStartupPanel -PropertyType DWord -Value 1 -Force
}
}
}
<#
.SYNOPSIS
Hardware-accelerated GPU scheduling
.PARAMETER Enable
Enable hardware-accelerated GPU scheduling
.PARAMETER Disable
Disable hardware-accelerated GPU scheduling
.EXAMPLE
GPUScheduling -Enable
.EXAMPLE
GPUScheduling -Disable
.NOTES
Only with a dedicated GPU and WDDM verion is 2.7 or higher. Restart needed
.NOTES
Current user
#>
function GPUScheduling
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
# Determining whether PC has an external graphics card
$AdapterDACType = Get-CimInstance -ClassName CIM_VideoController | Where-Object -FilterScript {($_.AdapterDACType -ne "Internal") -and ($null -ne $_.AdapterDACType)}
# Determining whether an OS is not installed on a virtual machine
$ComputerSystemModel = (Get-CimInstance -ClassName CIM_ComputerSystem).Model -notmatch "Virtual"
# Checking whether a WDDM verion is 2.7 or higher
$WddmVersion_Min = [Microsoft.Win32.Registry]::GetValue("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GraphicsDrivers\FeatureSetUsage", "WddmVersion_Min", $null)
if ($AdapterDACType -and ($ComputerSystemModel -notmatch "Virtual") -and ($WddmVersion_Min -ge 2700))
{
New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Control\GraphicsDrivers -Name HwSchMode -PropertyType DWord -Value 2 -Force
}
}
"Disable"
{
New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Control\GraphicsDrivers -Name HwSchMode -PropertyType DWord -Value 1 -Force
}
}
}
#endregion Gaming
#region Scheduled tasks
<#
.SYNOPSIS
The "Windows Cleanup" scheduled task for cleaning up Windows unused files and updates
.PARAMETER Register
Create the "Windows Cleanup" scheduled task for cleaning up Windows unused files and updates
.PARAMETER Delete
Delete the "Windows Cleanup" and "Windows Cleanup Notification" scheduled tasks for cleaning up Windows unused files and updates
.EXAMPLE
CleanupTask -Register
.EXAMPLE
CleanupTask -Delete
.NOTES
A native interactive toast notification pops up every 30 days
.NOTES
Windows Script Host has to be enabled
.NOTES
Current user
#>
function CleanupTask
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Register"
)]
[switch]
$Register,
[Parameter(
Mandatory = $true,
ParameterSetName = "Delete"
)]
[switch]
$Delete
)
switch ($PSCmdlet.ParameterSetName)
{
"Register"
{
# Enable notifications
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\PushNotifications -Name ToastEnabled -Force -ErrorAction Ignore
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Notifications\Settings\Windows.ActionCenter.SmartOptOut -Name Enable -Force -ErrorAction Ignore
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Notifications\Settings\Sophia -Name ShowBanner, ShowInActionCenter, Enabled -Force -ErrorAction Ignore
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\SystemSettings\AccountNotifications -Name EnableAccountNotifications -Force -ErrorAction Ignore
Remove-ItemProperty -Path HKCU:\Software\Policies\Microsoft\Windows\Explorer, HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer -Name DisableNotificationCenter -Force -ErrorAction Ignore
Remove-ItemProperty -Path HKCU:\Software\Policies\Microsoft\Windows\CurrentVersion\PushNotifications -Name NoToastApplicationNotification -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\Explorer -Name DisableNotificationCenter -Type CLEAR
Set-Policy -Scope User -Path Software\Policies\Microsoft\Windows\Explorer -Name DisableNotificationCenter -Type CLEAR
# Remove registry keys if Windows Script Host is disabled
Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows Script Host\Settings", "HKLM:\SOFTWARE\Microsoft\Windows Script Host\Settings" -Name Enabled -Force -ErrorAction Ignore
# Checking whether VBS engine is enabled
if ((Get-WindowsCapability -Online -Name VBSCRIPT*).State -ne "Installed")
{
try
{
Get-WindowsCapability -Online -Name VBSCRIPT* | Add-WindowsCapability -Online
}
catch
{
Write-Information -MessageData "" -InformationAction Continue
Write-Warning -Message ($Localization.WindowsComponentBroken -f (Get-WindowsCapability -Online -Name VBSCRIPT*).DisplayName)
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message "https://massgrave.dev/genuine-installation-media" -Verbose
Write-Verbose -Message "https://t.me/sophia_chat" -Verbose
Write-Verbose -Message "https://discord.gg/sSryhaEv79" -Verbose
$Global:Failed = $true
exit
}
}
# Checking if we're trying to create the task when it was already created as another user
if (Get-ScheduledTask -TaskPath "\Sophia\" -TaskName "Windows Cleanup" -ErrorAction Ignore)
{
# Also we can parse "$env:SystemRoot\System32\Tasks\Sophia\Windows Cleanup" to сheck whether the task was created
$ScheduleService = New-Object -ComObject Schedule.Service
$ScheduleService.Connect()
$ScheduleService.GetFolder("\Sophia").GetTasks(0) | Where-Object -FilterScript {$_.Name -eq "Windows Cleanup"} | Foreach-Object {
# Get user's SID the task was created as
$Global:SID = ([xml]$_.xml).Task.Principals.Principal.UserID
}
# Convert SID to username
$TaskUserAccount = (New-Object -TypeName System.Security.Principal.SecurityIdentifier($SID)).Translate([System.Security.Principal.NTAccount]).Value -split "\\" | Select-Object -Last 1
if ($TaskUserAccount -ne $env:USERNAME)
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.ScheduledTaskCreatedByAnotherUser -f "Windows Cleanup", $TaskUserAccount), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.ScheduledTaskCreatedByAnotherUser -f "Windows Cleanup", $TaskUserAccount), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
}
# Remove all old tasks
# We have to use -ErrorAction Ignore in both cases, unless we get an error
Get-ScheduledTask -TaskPath "\Sophia Script\", "\SophiApp\" -ErrorAction Ignore | ForEach-Object -Process {
Unregister-ScheduledTask -TaskName $_.TaskName -Confirm:$false -ErrorAction Ignore
}
# Remove folders in Task Scheduler. We cannot remove all old folders explicitly and not get errors if any of folders do not exist
$ScheduleService = New-Object -ComObject Schedule.Service
$ScheduleService.Connect()
if (Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\Sophia Script")
{
$ScheduleService.GetFolder("\").DeleteFolder("Sophia Script", $null)
}
if (Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\SophiApp")
{
$ScheduleService.GetFolder("\").DeleteFolder("SophiApp", $null)
}
Get-ChildItem -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches | ForEach-Object -Process {
Remove-ItemProperty -Path $_.PsPath -Name StateFlags1337 -Force -ErrorAction Ignore
}
$VolumeCaches = @(
"BranchCache",
"Delivery Optimization Files",
"Device Driver Packages",
"Language Pack",
"Previous Installations",
"Setup Log Files",
"System error memory dump files",
"System error minidump files",
"Temporary Files",
"Temporary Setup Files",
"Update Cleanup",
"Upgrade Discarded Files",
"Windows Defender",
"Windows ESD installation files",
"Windows Upgrade Log Files"
)
foreach ($VolumeCache in $VolumeCaches)
{
if (-not (Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\$VolumeCache"))
{
New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\$VolumeCache" -Force
}
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\$VolumeCache" -Name StateFlags1337 -PropertyType DWord -Value 2 -Force
}
if (-not (Test-Path -Path Registry::HKEY_CLASSES_ROOT\AppUserModelId\Sophia))
{
New-Item -Path Registry::HKEY_CLASSES_ROOT\AppUserModelId\Sophia -Force
}
# Register app
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOT\AppUserModelId\Sophia -Name DisplayName -Value Sophia -PropertyType String -Force
# Determines whether the app can be seen in Settings where the user can turn notifications on or off
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOT\AppUserModelId\Sophia -Name ShowInSettings -Value 0 -PropertyType DWord -Force
# Register the "WindowsCleanup" protocol to be able to run the scheduled task by clicking the "Run" button in a toast
if (-not (Test-Path -Path Registry::HKEY_CLASSES_ROOT\WindowsCleanup\shell\open\command))
{
New-Item -Path Registry::HKEY_CLASSES_ROOT\WindowsCleanup\shell\open\command -Force
}
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOT\WindowsCleanup -Name "(default)" -PropertyType String -Value "URL:WindowsCleanup" -Force
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOT\WindowsCleanup -Name "URL Protocol" -PropertyType String -Value "" -Force
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOT\WindowsCleanup -Name EditFlags -PropertyType DWord -Value 2162688 -Force
# Start the "Windows Cleanup" task if the "Run" button clicked
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOT\WindowsCleanup\shell\open\command -Name "(default)" -PropertyType String -Value 'powershell.exe -Command "& {Start-ScheduledTask -TaskPath ''\Sophia\'' -TaskName ''Windows Cleanup''}"' -Force
$CleanupTaskPS = @"
# https://github.com/farag2/Sophia-Script-for-Windows
# https://t.me/sophia_chat
Get-Process -Name cleanmgr, Dism, DismHost | Stop-Process -Force
`$ProcessInfo = New-Object -TypeName System.Diagnostics.ProcessStartInfo
`$ProcessInfo.FileName = "`$env:SystemRoot\System32\cleanmgr.exe"
`$ProcessInfo.Arguments = "/sagerun:1337"
`$ProcessInfo.UseShellExecute = `$true
`$ProcessInfo.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Minimized
`$Process = New-Object -TypeName System.Diagnostics.Process
`$Process.StartInfo = `$ProcessInfo
`$Process.Start() | Out-Null
Start-Sleep -Seconds 3
`$ProcessInfo = New-Object -TypeName System.Diagnostics.ProcessStartInfo
`$ProcessInfo.FileName = "`$env:SystemRoot\System32\Dism.exe"
`$ProcessInfo.Arguments = "/Online /English /Cleanup-Image /StartComponentCleanup /NoRestart"
`$ProcessInfo.UseShellExecute = `$true
`$ProcessInfo.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Minimized
`$Process = New-Object -TypeName System.Diagnostics.Process
`$Process.StartInfo = `$ProcessInfo
`$Process.Start() | Out-Null
"@
# Save script to be able to call them from VBS file
if (-not (Test-Path -Path $env:SystemRoot\System32\Tasks\Sophia))
{
New-Item -Path $env:SystemRoot\System32\Tasks\Sophia -ItemType Directory -Force
}
# Save in UTF8 with BOM
Set-Content -Path "$env:SystemRoot\System32\Tasks\Sophia\Windows_Cleanup.ps1" -Value $CleanupTaskPS -Encoding utf8BOM -Force
# Create vbs script that will help us calling Windows_Cleanup.ps1 script silently, without interrupting system from Focus Assist mode turned on, when a powershell.exe console pops up
$CleanupTaskVBS = @"
' https://github.com/farag2/Sophia-Script-for-Windows
' https://t.me/sophia_chat
CreateObject("Wscript.Shell").Run "powershell.exe -ExecutionPolicy Bypass -NoProfile -NoLogo -WindowStyle Hidden -File %SystemRoot%\System32\Tasks\Sophia\Windows_Cleanup.ps1", 0
"@
# Save in UTF8 without BOM
Set-Content -Path "$env:SystemRoot\System32\Tasks\Sophia\Windows_Cleanup.vbs" -Value $CleanupTaskVBS -Encoding utf8NoBOM -Force
# Create "Windows Cleanup" task
# We cannot create a schedule task if %COMPUTERNAME% is equal to %USERNAME%, so we have to use a "$env:COMPUTERNAME\$env:USERNAME" method
# https://github.com/PowerShell/PowerShell/issues/21377
$Action = New-ScheduledTaskAction -Execute wscript.exe -Argument "$env:SystemRoot\System32\Tasks\Sophia\Windows_Cleanup.vbs"
$Settings = New-ScheduledTaskSettingsSet -Compatibility Win8 -StartWhenAvailable
# If PC is domain joined, we cannot obtain its SID, because account is cloud managed
$Principal = if ($env:USERDOMAIN)
{
New-ScheduledTaskPrincipal -UserId $env:USERNAME -RunLevel Highest
}
else
{
New-ScheduledTaskPrincipal -UserId "$env:COMPUTERNAME\$env:USERNAME" -RunLevel Highest
}
$Parameters = @{
TaskName = "Windows Cleanup"
TaskPath = "Sophia"
Principal = $Principal
Action = $Action
Description = $Localization.CleanupTaskDescription -f $env:USERNAME
Settings = $Settings
}
Register-ScheduledTask @Parameters -Force
# Set author for scheduled task
$Task = Get-ScheduledTask -TaskName "Windows Cleanup"
$Task.Author = "Team Sophia"
$Task | Set-ScheduledTask
# We have to call PowerShell script via another VBS script silently because VBS has appropriate feature to suppress console appearing (none of other workarounds work)
# powershell.exe process wakes up system anyway even from turned on Focus Assist mode (not a notification toast)
# https://github.com/DCourtel/Windows_10_Focus_Assist/blob/master/FocusAssistLibrary/FocusAssistLib.cs
# https://redplait.blogspot.com/2018/07/wnf-ids-from-perfntcdll-adk-version.html
$ToastNotificationPS = @"
# https://github.com/farag2/Sophia-Script-for-Windows
# https://t.me/sophia_chat
# Get Focus Assist status
# https://github.com/DCourtel/Windows_10_Focus_Assist/blob/master/FocusAssistLibrary/FocusAssistLib.cs
# https://redplait.blogspot.com/2018/07/wnf-ids-from-perfntcdll-adk-version.html
`$CompilerParameters = [System.CodeDom.Compiler.CompilerParameters]::new("System.dll")
`$CompilerParameters.TempFiles = [System.CodeDom.Compiler.TempFileCollection]::new(`$env:TEMP, `$false)
`$CompilerParameters.GenerateInMemory = `$true
`$Signature = @{
Namespace = "WinAPI"
Name = "Focus"
Language = "CSharp"
CompilerParameters = `$CompilerParameters
MemberDefinition = @""
[DllImport("NtDll.dll", SetLastError = true)]
private static extern uint NtQueryWnfStateData(IntPtr pStateName, IntPtr pTypeId, IntPtr pExplicitScope, out uint nChangeStamp, out IntPtr pBuffer, ref uint nBufferSize);
[StructLayout(LayoutKind.Sequential)]
public struct WNF_TYPE_ID
{
public Guid TypeId;
}
[StructLayout(LayoutKind.Sequential)]
public struct WNF_STATE_NAME
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public uint[] Data;
public WNF_STATE_NAME(uint Data1, uint Data2) : this()
{
uint[] newData = new uint[2];
newData[0] = Data1;
newData[1] = Data2;
Data = newData;
}
}
public enum FocusAssistState
{
NOT_SUPPORTED = -2,
FAILED = -1,
OFF = 0,
PRIORITY_ONLY = 1,
ALARMS_ONLY = 2
};
// Returns the state of Focus Assist if available on this computer
public static FocusAssistState GetFocusAssistState()
{
try
{
WNF_STATE_NAME WNF_SHEL_QUIETHOURS_ACTIVE_PROFILE_CHANGED = new WNF_STATE_NAME(0xA3BF1C75, 0xD83063E);
uint nBufferSize = (uint)Marshal.SizeOf(typeof(IntPtr));
IntPtr pStateName = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(WNF_STATE_NAME)));
Marshal.StructureToPtr(WNF_SHEL_QUIETHOURS_ACTIVE_PROFILE_CHANGED, pStateName, false);
uint nChangeStamp = 0;
IntPtr pBuffer = IntPtr.Zero;
bool success = NtQueryWnfStateData(pStateName, IntPtr.Zero, IntPtr.Zero, out nChangeStamp, out pBuffer, ref nBufferSize) == 0;
Marshal.FreeHGlobal(pStateName);
if (success)
{
return (FocusAssistState)pBuffer;
}
}
catch {}
return FocusAssistState.FAILED;
}
""@
}
if (-not ("WinAPI.Focus" -as [type]))
{
Add-Type @Signature
}
while ([WinAPI.Focus]::GetFocusAssistState() -ne "OFF")
{
Start-Sleep -Seconds 600
}
[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null
[Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] | Out-Null
[xml]`$ToastTemplate = @""
<toast duration="Long">
<visual>
<binding template="ToastGeneric">
<text>$($Localization.CleanupTaskNotificationTitle)</text>
<group>
<subgroup>
<text hint-style="body" hint-wrap="true">$($Localization.CleanupTaskNotificationEvent)</text>
</subgroup>
</group>
</binding>
</visual>
<audio src="ms-winsoundevent:notification.default" />
<actions>
<action content="$($Localization.Run)" arguments="WindowsCleanup:" activationType="protocol"/>
<action content="" arguments="dismiss" activationType="system"/>
</actions>
</toast>
""@
`$ToastXml = [Windows.Data.Xml.Dom.XmlDocument]::New()
`$ToastXml.LoadXml(`$ToastTemplate.OuterXml)
`$ToastMessage = [Windows.UI.Notifications.ToastNotification]::New(`$ToastXML)
[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier("Sophia").Show(`$ToastMessage)
"@
# Save in UTF8 with BOM
Set-Content -Path "$env:SystemRoot\System32\Tasks\Sophia\Windows_Cleanup_Notification.ps1" -Value $ToastNotificationPS -Encoding utf8BOM -Force
# Replace here-string double quotes with single ones
(Get-Content -Path "$env:SystemRoot\System32\Tasks\Sophia\Windows_Cleanup_Notification.ps1" -Encoding utf8BOM).Replace('@""', '@"').Replace('""@', '"@') | Set-Content -Path "$env:SystemRoot\System32\Tasks\Sophia\Windows_Cleanup_Notification.ps1" -Encoding utf8BOM -Force
# Create vbs script that will help us calling Windows_Cleanup_Notification.ps1 script silently, without interrupting system from Focus Assist mode turned on, when a powershell.exe console pops up
$ToastNotificationVBS = @"
' https://github.com/farag2/Sophia-Script-for-Windows
' https://t.me/sophia_chat
CreateObject("Wscript.Shell").Run "powershell.exe -ExecutionPolicy Bypass -NoProfile -NoLogo -WindowStyle Hidden -File %SystemRoot%\System32\Tasks\Sophia\Windows_Cleanup_Notification.ps1", 0
"@
# Save in UTF8 without BOM
Set-Content -Path "$env:SystemRoot\System32\Tasks\Sophia\Windows_Cleanup_Notification.vbs" -Value $ToastNotificationVBS -Encoding utf8NoBOM -Force
# Create the "Windows Cleanup Notification" task
# We cannot create a schedule task if %COMPUTERNAME% is equal to %USERNAME%, so we have to use a "$env:COMPUTERNAME\$env:USERNAME" method
# https://github.com/PowerShell/PowerShell/issues/21377
$Action = New-ScheduledTaskAction -Execute wscript.exe -Argument "$env:SystemRoot\System32\Tasks\Sophia\Windows_Cleanup_Notification.vbs"
$Settings = New-ScheduledTaskSettingsSet -Compatibility Win8 -StartWhenAvailable
# If PC is domain joined, we cannot obtain its SID, because account is cloud managed
$Principal = if ($env:USERDOMAIN)
{
New-ScheduledTaskPrincipal -UserId $env:USERNAME -RunLevel Highest
}
else
{
New-ScheduledTaskPrincipal -UserId "$env:COMPUTERNAME\$env:USERNAME" -RunLevel Highest
}
$Trigger = New-ScheduledTaskTrigger -Daily -DaysInterval 30 -At 9pm
$Parameters = @{
TaskName = "Windows Cleanup Notification"
TaskPath = "Sophia"
Action = $Action
Settings = $Settings
Principal = $Principal
Trigger = $Trigger
Description = $Localization.CleanupNotificationTaskDescription -f $env:USERNAME
}
Register-ScheduledTask @Parameters -Force
# Set author for scheduled task
$Task = Get-ScheduledTask -TaskName "Windows Cleanup Notification"
$Task.Author = "Team Sophia"
$Task | Set-ScheduledTask
# Start Task Scheduler in the end if any scheduled task was created
$Global:ScheduledTasks = $true
}
"Delete"
{
# Remove files first unless we cannot remove folder if there's no more tasks there
$Paths = @(
"$env:SystemRoot\System32\Tasks\Sophia\Windows_Cleanup_Notification.vbs",
"$env:SystemRoot\System32\Tasks\Sophia\Windows_Cleanup_Notification.ps1",
"$env:SystemRoot\System32\Tasks\Sophia\Windows_Cleanup.ps1",
"$env:SystemRoot\System32\Tasks\Sophia\Windows_Cleanup.vbs"
)
Remove-Item -Path $Paths -Force -ErrorAction Ignore
# Remove all old tasks
# We have to use -ErrorAction Ignore in both cases, unless we get an error
Get-ScheduledTask -TaskPath "\Sophia Script\", "\SophiApp\" -ErrorAction Ignore | ForEach-Object -Process {
Unregister-ScheduledTask -TaskName $_.TaskName -Confirm:$false -ErrorAction Ignore
}
# Remove folder in Task Scheduler if there is no tasks left there. We cannot remove all old folders explicitly and not get errors if any of folders do not exist
$ScheduleService = New-Object -ComObject Schedule.Service
$ScheduleService.Connect()
if (Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\Sophia Script")
{
$ScheduleService.GetFolder("\").DeleteFolder("Sophia Script", $null)
}
if (Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\SophiApp")
{
$ScheduleService.GetFolder("\").DeleteFolder("SophiApp", $null)
}
# Removing current task
Unregister-ScheduledTask -TaskPath "\Sophia\" -TaskName "Windows Cleanup", "Windows Cleanup Notification" -Confirm:$false -ErrorAction Ignore
Get-ChildItem -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches | ForEach-Object -Process {
Remove-ItemProperty -Path $_.PsPath -Name StateFlags1337 -Force -ErrorAction Ignore
}
Remove-Item -Path Registry::HKEY_CLASSES_ROOT\WindowsCleanup -Recurse -Force -ErrorAction Ignore
# Remove folder in Task Scheduler if there is no tasks left there
if (Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\Sophia")
{
if (($ScheduleService.GetFolder("Sophia").GetTasks(0) | Select-Object -Property Name).Name.Count -eq 0)
{
$ScheduleService.GetFolder("\").DeleteFolder("Sophia", $null)
}
}
}
}
}
<#
.SYNOPSIS
The "SoftwareDistribution" scheduled task for cleaning up the %SystemRoot%\SoftwareDistribution\Download folder
.PARAMETER Register
Create the "SoftwareDistribution" scheduled task for cleaning up the %SystemRoot%\SoftwareDistribution\Download folder
.PARAMETER Delete
Delete the "SoftwareDistribution" scheduled task for cleaning up the %SystemRoot%\SoftwareDistribution\Download folder
.EXAMPLE
SoftwareDistributionTask -Register
.EXAMPLE
SoftwareDistributionTask -Delete
.NOTES
The task will wait until the Windows Updates service finishes running. The task runs every 90 days
.NOTES
Windows Script Host has to be enabled
.NOTES
Current user
#>
function SoftwareDistributionTask
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Register"
)]
[switch]
$Register,
[Parameter(
Mandatory = $true,
ParameterSetName = "Delete"
)]
[switch]
$Delete
)
switch ($PSCmdlet.ParameterSetName)
{
"Register"
{
# Enable notifications
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\PushNotifications -Name ToastEnabled -Force -ErrorAction Ignore
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Notifications\Settings\Windows.ActionCenter.SmartOptOut -Name Enable -Force -ErrorAction Ignore
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Notifications\Settings\Sophia -Name ShowBanner, ShowInActionCenter, Enabled -Force -ErrorAction Ignore
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\SystemSettings\AccountNotifications -Name EnableAccountNotifications -Force -ErrorAction Ignore
Remove-ItemProperty -Path HKCU:\Software\Policies\Microsoft\Windows\Explorer, HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer -Name DisableNotificationCenter -Force -ErrorAction Ignore
Remove-ItemProperty -Path HKCU:\Software\Policies\Microsoft\Windows\CurrentVersion\PushNotifications -Name NoToastApplicationNotification -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\Explorer -Name DisableNotificationCenter -Type CLEAR
Set-Policy -Scope User -Path Software\Policies\Microsoft\Windows\Explorer -Name DisableNotificationCenter -Type CLEAR
# Remove registry keys if Windows Script Host is disabled
Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows Script Host\Settings", "HKLM:\SOFTWARE\Microsoft\Windows Script Host\Settings" -Name Enabled -Force -ErrorAction Ignore
# Checking whether VBS engine is enabled
if ((Get-WindowsCapability -Online -Name VBSCRIPT*).State -ne "Installed")
{
try
{
Get-WindowsCapability -Online -Name VBSCRIPT* | Add-WindowsCapability -Online
}
catch
{
Write-Information -MessageData "" -InformationAction Continue
Write-Warning -Message ($Localization.WindowsComponentBroken -f (Get-WindowsCapability -Online -Name VBSCRIPT*).DisplayName)
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message "https://massgrave.dev/genuine-installation-media" -Verbose
Write-Verbose -Message "https://t.me/sophia_chat" -Verbose
Write-Verbose -Message "https://discord.gg/sSryhaEv79" -Verbose
$Global:Failed = $true
exit
}
}
# Checking if we're trying to create the task when it was already created as another user
if (Get-ScheduledTask -TaskPath "\Sophia\" -TaskName SoftwareDistribution -ErrorAction Ignore)
{
# Also we can parse $env:SystemRoot\System32\Tasks\Sophia\SoftwareDistribution to сheck whether the task was created
$ScheduleService = New-Object -ComObject Schedule.Service
$ScheduleService.Connect()
$ScheduleService.GetFolder("\Sophia").GetTasks(0) | Where-Object -FilterScript {$_.Name -eq "SoftwareDistribution"} | Foreach-Object {
# Get user's SID the task was created as
$Global:SID = ([xml]$_.xml).Task.Principals.Principal.UserID
}
# Convert SID to username
$TaskUserAccount = (New-Object -TypeName System.Security.Principal.SecurityIdentifier($SID)).Translate([System.Security.Principal.NTAccount]).Value -split "\\" | Select-Object -Last 1
if ($TaskUserAccount -ne $env:USERNAME)
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.ScheduledTaskCreatedByAnotherUser -f "SoftwareDistribution", $TaskUserAccount), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.ScheduledTaskCreatedByAnotherUser -f "SoftwareDistribution", $TaskUserAccount), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
}
# Remove all old tasks
# We have to use -ErrorAction Ignore in both cases, unless we get an error
Get-ScheduledTask -TaskPath "\Sophia Script\", "\SophiApp\" -ErrorAction Ignore | ForEach-Object -Process {
Unregister-ScheduledTask -TaskName $_.TaskName -Confirm:$false -ErrorAction Ignore
}
# Remove folders in Task Scheduler. We cannot remove all old folders explicitly and not get errors if any of folders do not exist
$ScheduleService = New-Object -ComObject Schedule.Service
$ScheduleService.Connect()
if (Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\Sophia Script")
{
$ScheduleService.GetFolder("\").DeleteFolder("Sophia Script", $null)
}
if (Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\SophiApp")
{
$ScheduleService.GetFolder("\").DeleteFolder("SophiApp", $null)
}
if (-not (Test-Path -Path Registry::HKEY_CLASSES_ROOT\AppUserModelId\Sophia))
{
New-Item -Path Registry::HKEY_CLASSES_ROOT\AppUserModelId\Sophia -Force
}
# Register app
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOT\AppUserModelId\Sophia -Name DisplayName -Value Sophia -PropertyType String -Force
# Determines whether the app can be seen in Settings where the user can turn notifications on or off
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOT\AppUserModelId\Sophia -Name ShowInSettings -Value 0 -PropertyType DWord -Force
# We have to call PowerShell script via another VBS script silently because VBS has appropriate feature to suppress console appearing (none of other workarounds work)
# powershell.exe process wakes up system anyway even from turned on Focus Assist mode (not a notification toast)
# https://github.com/DCourtel/Windows_10_Focus_Assist/blob/master/FocusAssistLibrary/FocusAssistLib.cs
# https://redplait.blogspot.com/2018/07/wnf-ids-from-perfntcdll-adk-version.html
$SoftwareDistributionTaskPS = @"
# https://github.com/farag2/Sophia-Script-for-Windows
# https://t.me/sophia_chat
# Get Focus Assist status
# https://github.com/DCourtel/Windows_10_Focus_Assist/blob/master/FocusAssistLibrary/FocusAssistLib.cs
# https://redplait.blogspot.com/2018/07/wnf-ids-from-perfntcdll-adk-version.html
`$CompilerParameters = [System.CodeDom.Compiler.CompilerParameters]::new("System.dll")
`$CompilerParameters.TempFiles = [System.CodeDom.Compiler.TempFileCollection]::new(`$env:TEMP, `$false)
`$CompilerParameters.GenerateInMemory = `$true
`$Signature = @{
Namespace = "WinAPI"
Name = "Focus"
Language = "CSharp"
CompilerParameters = `$CompilerParameters
MemberDefinition = @""
[DllImport("NtDll.dll", SetLastError = true)]
private static extern uint NtQueryWnfStateData(IntPtr pStateName, IntPtr pTypeId, IntPtr pExplicitScope, out uint nChangeStamp, out IntPtr pBuffer, ref uint nBufferSize);
[StructLayout(LayoutKind.Sequential)]
public struct WNF_TYPE_ID
{
public Guid TypeId;
}
[StructLayout(LayoutKind.Sequential)]
public struct WNF_STATE_NAME
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public uint[] Data;
public WNF_STATE_NAME(uint Data1, uint Data2) : this()
{
uint[] newData = new uint[2];
newData[0] = Data1;
newData[1] = Data2;
Data = newData;
}
}
public enum FocusAssistState
{
NOT_SUPPORTED = -2,
FAILED = -1,
OFF = 0,
PRIORITY_ONLY = 1,
ALARMS_ONLY = 2
};
// Returns the state of Focus Assist if available on this computer
public static FocusAssistState GetFocusAssistState()
{
try
{
WNF_STATE_NAME WNF_SHEL_QUIETHOURS_ACTIVE_PROFILE_CHANGED = new WNF_STATE_NAME(0xA3BF1C75, 0xD83063E);
uint nBufferSize = (uint)Marshal.SizeOf(typeof(IntPtr));
IntPtr pStateName = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(WNF_STATE_NAME)));
Marshal.StructureToPtr(WNF_SHEL_QUIETHOURS_ACTIVE_PROFILE_CHANGED, pStateName, false);
uint nChangeStamp = 0;
IntPtr pBuffer = IntPtr.Zero;
bool success = NtQueryWnfStateData(pStateName, IntPtr.Zero, IntPtr.Zero, out nChangeStamp, out pBuffer, ref nBufferSize) == 0;
Marshal.FreeHGlobal(pStateName);
if (success)
{
return (FocusAssistState)pBuffer;
}
}
catch {}
return FocusAssistState.FAILED;
}
""@
}
if (-not ("WinAPI.Focus" -as [type]))
{
Add-Type @Signature
}
# Wait until it will be "OFF" (0)
while ([WinAPI.Focus]::GetFocusAssistState() -ne "OFF")
{
Start-Sleep -Seconds 600
}
# Wait until Windows Update service will stop
(Get-Service -Name wuauserv).WaitForStatus("Stopped", "01:00:00")
Get-ChildItem -Path `$env:SystemRoot\SoftwareDistribution\Download -Recurse -Force | Remove-Item -Recurse -Force
# Remove files which can be removed in a user scope only
Get-ChildItem -Path $env:SystemRoot\SoftwareDistribution\Download -Recurse | Remove-Item -Recurse
[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null
[Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] | Out-Null
[xml]`$ToastTemplate = @""
<toast duration="Long">
<visual>
<binding template="ToastGeneric">
<text>$($Localization.SoftwareDistributionTaskNotificationEvent)</text>
</binding>
</visual>
<audio src="ms-winsoundevent:notification.default" />
</toast>
""@
`$ToastXml = [Windows.Data.Xml.Dom.XmlDocument]::New()
`$ToastXml.LoadXml(`$ToastTemplate.OuterXml)
`$ToastMessage = [Windows.UI.Notifications.ToastNotification]::New(`$ToastXML)
[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier("Sophia").Show(`$ToastMessage)
"@
# Save script to be able to call them from VBS file
if (-not (Test-Path -Path $env:SystemRoot\System32\Tasks\Sophia))
{
New-Item -Path $env:SystemRoot\System32\Tasks\Sophia -ItemType Directory -Force
}
# Save in UTF8 with BOM
Set-Content -Path "$env:SystemRoot\System32\Tasks\Sophia\SoftwareDistributionTask.ps1" -Value $SoftwareDistributionTaskPS -Encoding utf8BOM -Force
# Replace here-string double quotes with single ones
(Get-Content -Path "$env:SystemRoot\System32\Tasks\Sophia\SoftwareDistributionTask.ps1" -Encoding utf8BOM).Replace('@""', '@"').Replace('""@', '"@') | Set-Content -Path "$env:SystemRoot\System32\Tasks\Sophia\SoftwareDistributionTask.ps1" -Encoding utf8BOM -Force
# Create vbs script that will help us calling PS1 script silently, without interrupting system from Focus Assist mode turned on, when a powershell.exe console pops up
$SoftwareDistributionTaskVBS = @"
' https://github.com/farag2/Sophia-Script-for-Windows
' https://t.me/sophia_chat
CreateObject("Wscript.Shell").Run "powershell.exe -ExecutionPolicy Bypass -NoProfile -NoLogo -WindowStyle Hidden -File %SystemRoot%\System32\Tasks\Sophia\SoftwareDistributionTask.ps1", 0
"@
# Save in UTF8 without BOM
Set-Content -Path "$env:SystemRoot\System32\Tasks\Sophia\SoftwareDistributionTask.vbs" -Value $SoftwareDistributionTaskVBS -Encoding utf8NoBOM -Force
# Create the "SoftwareDistribution" task
# We cannot create a schedule task if %COMPUTERNAME% is equal to %USERNAME%, so we have to use a "$env:COMPUTERNAME\$env:USERNAME" method
# https://github.com/PowerShell/PowerShell/issues/21377
$Action = New-ScheduledTaskAction -Execute wscript.exe -Argument "$env:SystemRoot\System32\Tasks\Sophia\SoftwareDistributionTask.vbs"
$Settings = New-ScheduledTaskSettingsSet -Compatibility Win8 -StartWhenAvailable
# If PC is domain joined, we cannot obtain its SID, because account is cloud managed
$Principal = if ($env:USERDOMAIN)
{
New-ScheduledTaskPrincipal -UserId $env:USERNAME -RunLevel Highest
}
else
{
New-ScheduledTaskPrincipal -UserId "$env:COMPUTERNAME\$env:USERNAME" -RunLevel Highest
}
$Trigger = New-ScheduledTaskTrigger -Daily -DaysInterval 90 -At 9pm
$Parameters = @{
TaskName = "SoftwareDistribution"
TaskPath = "Sophia"
Action = $Action
Settings = $Settings
Principal = $Principal
Trigger = $Trigger
Description = $Localization.FolderTaskDescription -f "%SystemRoot%\SoftwareDistribution\Download", $env:USERNAME
}
Register-ScheduledTask @Parameters -Force
# Set author for scheduled task
$Task = Get-ScheduledTask -TaskName "SoftwareDistribution"
$Task.Author = "Team Sophia"
$Task | Set-ScheduledTask
$Global:ScheduledTasks = $true
}
"Delete"
{
# Remove files first unless we cannot remove folder if there's no more tasks there
Remove-Item -Path "$env:SystemRoot\System32\Tasks\Sophia\SoftwareDistributionTask.vbs", "$env:SystemRoot\System32\Tasks\Sophia\SoftwareDistributionTask.ps1" -Force -ErrorAction Ignore
# Remove all old tasks
# We have to use -ErrorAction Ignore in both cases, unless we get an error
Get-ScheduledTask -TaskPath "\Sophia Script\", "\SophiApp\" -ErrorAction Ignore | ForEach-Object -Process {
Unregister-ScheduledTask -TaskName $_.TaskName -Confirm:$false -ErrorAction Ignore
}
# Remove folder in Task Scheduler if there is no tasks left there. We cannot remove all old folders explicitly and not get errors if any of folders do not exist
$ScheduleService = New-Object -ComObject Schedule.Service
$ScheduleService.Connect()
if (Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\Sophia Script")
{
$ScheduleService.GetFolder("\").DeleteFolder("Sophia Script", $null)
}
if (Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\SophiApp")
{
$ScheduleService.GetFolder("\").DeleteFolder("SophiApp", $null)
}
# Removing current task
Unregister-ScheduledTask -TaskPath "\Sophia\" -TaskName SoftwareDistribution -Confirm:$false -ErrorAction Ignore
# Remove folder in Task Scheduler if there is no tasks left there
if (Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\Sophia")
{
if (($ScheduleService.GetFolder("Sophia").GetTasks(0) | Select-Object -Property Name).Name.Count -eq 0)
{
$ScheduleService.GetFolder("\").DeleteFolder("Sophia", $null)
}
}
}
}
}
<#
.SYNOPSIS
The "Temp" scheduled task for cleaning up the %TEMP% folder
.PARAMETER Register
Create the "Temp" scheduled task for cleaning up the %TEMP% folder
.PARAMETER Delete
Delete the "Temp" scheduled task for cleaning up the %TEMP% folder
.EXAMPLE
TempTask -Register
.EXAMPLE
TempTask -Delete
.NOTES
Only files older than one day will be deleted. The task runs every 60 days
.NOTES
Windows Script Host has to be enabled
.NOTES
Current user
#>
function TempTask
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Register"
)]
[switch]
$Register,
[Parameter(
Mandatory = $true,
ParameterSetName = "Delete"
)]
[switch]
$Delete
)
switch ($PSCmdlet.ParameterSetName)
{
"Register"
{
# Enable notifications
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\PushNotifications -Name ToastEnabled -Force -ErrorAction Ignore
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Notifications\Settings\Windows.ActionCenter.SmartOptOut -Name Enable -Force -ErrorAction Ignore
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Notifications\Settings\Sophia -Name ShowBanner, ShowInActionCenter, Enabled -Force -ErrorAction Ignore
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\SystemSettings\AccountNotifications -Name EnableAccountNotifications -Force -ErrorAction Ignore
Remove-ItemProperty -Path HKCU:\Software\Policies\Microsoft\Windows\Explorer, HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer -Name DisableNotificationCenter -Force -ErrorAction Ignore
Remove-ItemProperty -Path HKCU:\Software\Policies\Microsoft\Windows\CurrentVersion\PushNotifications -Name NoToastApplicationNotification -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\Explorer -Name DisableNotificationCenter -Type CLEAR
Set-Policy -Scope User -Path Software\Policies\Microsoft\Windows\Explorer -Name DisableNotificationCenter -Type CLEAR
# Remove registry keys if Windows Script Host is disabled
Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows Script Host\Settings", "HKLM:\SOFTWARE\Microsoft\Windows Script Host\Settings" -Name Enabled -Force -ErrorAction Ignore
# Checking whether VBS engine is enabled
if ((Get-WindowsCapability -Online -Name VBSCRIPT*).State -ne "Installed")
{
try
{
Get-WindowsCapability -Online -Name VBSCRIPT* | Add-WindowsCapability -Online
}
catch
{
Write-Information -MessageData "" -InformationAction Continue
Write-Warning -Message ($Localization.WindowsComponentBroken -f (Get-WindowsCapability -Online -Name VBSCRIPT*).DisplayName)
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message "https://massgrave.dev/genuine-installation-media" -Verbose
Write-Verbose -Message "https://t.me/sophia_chat" -Verbose
Write-Verbose -Message "https://discord.gg/sSryhaEv79" -Verbose
$Global:Failed = $true
exit
}
}
# Checking if we're trying to create the task when it was already created as another user
if (Get-ScheduledTask -TaskPath "\Sophia\" -TaskName Temp -ErrorAction Ignore)
{
# Also we can parse $env:SystemRoot\System32\Tasks\Sophia\Temp to сheck whether the task was created
$ScheduleService = New-Object -ComObject Schedule.Service
$ScheduleService.Connect()
$ScheduleService.GetFolder("\Sophia").GetTasks(0) | Where-Object -FilterScript {$_.Name -eq "Temp"} | Foreach-Object {
# Get user's SID the task was created as
$Global:SID = ([xml]$_.xml).Task.Principals.Principal.UserID
}
# Convert SID to username
$TaskUserAccount = (New-Object -TypeName System.Security.Principal.SecurityIdentifier($SID)).Translate([System.Security.Principal.NTAccount]).Value -split "\\" | Select-Object -Last 1
if ($TaskUserAccount -ne $env:USERNAME)
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.ScheduledTaskCreatedByAnotherUser -f "Temp", $TaskUserAccount), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.ScheduledTaskCreatedByAnotherUser -f "Temp", $TaskUserAccount), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
}
# Remove all old tasks
# We have to use -ErrorAction Ignore in both cases, unless we get an error
Get-ScheduledTask -TaskPath "\Sophia Script\", "\SophiApp\" -ErrorAction Ignore | ForEach-Object -Process {
Unregister-ScheduledTask -TaskName $_.TaskName -Confirm:$false -ErrorAction Ignore
}
# Remove folders in Task Scheduler. We cannot remove all old folders explicitly and not get errors if any of folders do not exist
$ScheduleService = New-Object -ComObject Schedule.Service
$ScheduleService.Connect()
if (Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\Sophia Script")
{
$ScheduleService.GetFolder("\").DeleteFolder("Sophia Script", $null)
}
if (Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\SophiApp")
{
$ScheduleService.GetFolder("\").DeleteFolder("SophiApp", $null)
}
if (-not (Test-Path -Path Registry::HKEY_CLASSES_ROOT\AppUserModelId\Sophia))
{
New-Item -Path Registry::HKEY_CLASSES_ROOT\AppUserModelId\Sophia -Force
}
# Register app
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOT\AppUserModelId\Sophia -Name DisplayName -Value Sophia -PropertyType String -Force
# Determines whether the app can be seen in Settings where the user can turn notifications on or off
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOT\AppUserModelId\Sophia -Name ShowInSettings -Value 0 -PropertyType DWord -Force
# We have to call PowerShell script via another VBS script silently because VBS has appropriate feature to suppress console appearing (none of other workarounds work)
# powershell.exe process wakes up system anyway even from turned on Focus Assist mode (not a notification toast)
$TempTaskPS = @"
# https://github.com/farag2/Sophia-Script-for-Windows
# https://t.me/sophia_chat
# Get Focus Assist status
# https://github.com/DCourtel/Windows_10_Focus_Assist/blob/master/FocusAssistLibrary/FocusAssistLib.cs
# https://redplait.blogspot.com/2018/07/wnf-ids-from-perfntcdll-adk-version.html
`$CompilerParameters = [System.CodeDom.Compiler.CompilerParameters]::new("System.dll")
`$CompilerParameters.TempFiles = [System.CodeDom.Compiler.TempFileCollection]::new(`$env:TEMP, `$false)
`$CompilerParameters.GenerateInMemory = `$true
`$Signature = @{
Namespace = "WinAPI"
Name = "Focus"
Language = "CSharp"
CompilerParameters = `$CompilerParameters
MemberDefinition = @""
[DllImport("NtDll.dll", SetLastError = true)]
private static extern uint NtQueryWnfStateData(IntPtr pStateName, IntPtr pTypeId, IntPtr pExplicitScope, out uint nChangeStamp, out IntPtr pBuffer, ref uint nBufferSize);
[StructLayout(LayoutKind.Sequential)]
public struct WNF_TYPE_ID
{
public Guid TypeId;
}
[StructLayout(LayoutKind.Sequential)]
public struct WNF_STATE_NAME
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public uint[] Data;
public WNF_STATE_NAME(uint Data1, uint Data2) : this()
{
uint[] newData = new uint[2];
newData[0] = Data1;
newData[1] = Data2;
Data = newData;
}
}
public enum FocusAssistState
{
NOT_SUPPORTED = -2,
FAILED = -1,
OFF = 0,
PRIORITY_ONLY = 1,
ALARMS_ONLY = 2
};
// Returns the state of Focus Assist if available on this computer
public static FocusAssistState GetFocusAssistState()
{
try
{
WNF_STATE_NAME WNF_SHEL_QUIETHOURS_ACTIVE_PROFILE_CHANGED = new WNF_STATE_NAME(0xA3BF1C75, 0xD83063E);
uint nBufferSize = (uint)Marshal.SizeOf(typeof(IntPtr));
IntPtr pStateName = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(WNF_STATE_NAME)));
Marshal.StructureToPtr(WNF_SHEL_QUIETHOURS_ACTIVE_PROFILE_CHANGED, pStateName, false);
uint nChangeStamp = 0;
IntPtr pBuffer = IntPtr.Zero;
bool success = NtQueryWnfStateData(pStateName, IntPtr.Zero, IntPtr.Zero, out nChangeStamp, out pBuffer, ref nBufferSize) == 0;
Marshal.FreeHGlobal(pStateName);
if (success)
{
return (FocusAssistState)pBuffer;
}
}
catch {}
return FocusAssistState.FAILED;
}
""@
}
if (-not ("WinAPI.Focus" -as [type]))
{
Add-Type @Signature
}
# Wait until it will be "OFF" (0)
while ([WinAPI.Focus]::GetFocusAssistState() -ne "OFF")
{
Start-Sleep -Seconds 600
}
# Run the task
Get-ChildItem -Path `$env:TEMP -Recurse -Force | Where-Object -FilterScript {`$_.CreationTime -lt (Get-Date).AddDays(-1)} | Remove-Item -Recurse -Force
# Unnecessary folders to remove
`$Paths = @(
# Get "C:\$WinREAgent" path because we need to open brackets for $env:SystemDrive but not for $WinREAgent
(-join ("`$env:SystemDrive\", '`$WinREAgent')),
(-join ("`$env:SystemDrive\", '`$SysReset')),
(-join ("`$env:SystemDrive\", '`$Windows.~WS')),
(-join ("`$env:SystemDrive\", '`$GetCurrent')),
"`$env:SystemDrive\ESD",
"`$env:SystemDrive\Intel",
"`$env:SystemDrive\PerfLogs",
"`$env:SystemRoot\ServiceProfiles\NetworkService\AppData\Local\Temp"
)
if ((Get-ChildItem -Path `$env:SystemDrive\Recovery -Force | Where-Object -FilterScript {`$_.Name -eq "ReAgentOld.xml"}).FullName)
{
`$Paths += "$env:SystemDrive\Recovery"
}
Remove-Item -Path `$Paths -Recurse -Force
[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null
[Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] | Out-Null
[xml]`$ToastTemplate = @""
<toast duration="Long">
<visual>
<binding template="ToastGeneric">
<text>$($Localization.TempTaskNotificationEvent)</text>
</binding>
</visual>
<audio src="ms-winsoundevent:notification.default" />
</toast>
""@
`$ToastXml = [Windows.Data.Xml.Dom.XmlDocument]::New()
`$ToastXml.LoadXml(`$ToastTemplate.OuterXml)
`$ToastMessage = [Windows.UI.Notifications.ToastNotification]::New(`$ToastXML)
[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier("Sophia").Show(`$ToastMessage)
"@
# Save script to be able to call them from VBS file
if (-not (Test-Path -Path $env:SystemRoot\System32\Tasks\Sophia))
{
New-Item -Path $env:SystemRoot\System32\Tasks\Sophia -ItemType Directory -Force
}
# Save in UTF8 with BOM
Set-Content -Path "$env:SystemRoot\System32\Tasks\Sophia\TempTask.ps1" -Value $TempTaskPS -Encoding utf8BOM -Force
# Replace here-string double quotes with single ones
(Get-Content -Path "$env:SystemRoot\System32\Tasks\Sophia\TempTask.ps1" -Encoding utf8BOM).Replace('@""', '@"').Replace('""@', '"@') | Set-Content -Path "$env:SystemRoot\System32\Tasks\Sophia\TempTask.ps1" -Encoding utf8BOM -Force
# Create vbs script that will help us calling PS1 script silently, without interrupting system from Focus Assist mode turned on, when a powershell.exe console pops up
$TempTaskVBS = @"
' https://github.com/farag2/Sophia-Script-for-Windows
' https://t.me/sophia_chat
CreateObject("Wscript.Shell").Run "powershell.exe -ExecutionPolicy Bypass -NoProfile -NoLogo -WindowStyle Hidden -File %SystemRoot%\System32\Tasks\Sophia\TempTask.ps1", 0
"@
# Save in UTF8 without BOM
Set-Content -Path "$env:SystemRoot\System32\Tasks\Sophia\TempTask.vbs" -Value $TempTaskVBS -Encoding utf8NoBOM -Force
# Create the "Temp" task
# We cannot create a schedule task if %COMPUTERNAME% is equal to %USERNAME%, so we have to use a "$env:COMPUTERNAME\$env:USERNAME" method
# https://github.com/PowerShell/PowerShell/issues/21377
$Action = New-ScheduledTaskAction -Execute wscript.exe -Argument "$env:SystemRoot\System32\Tasks\Sophia\TempTask.vbs"
$Settings = New-ScheduledTaskSettingsSet -Compatibility Win8 -StartWhenAvailable
# If PC is domain joined, we cannot obtain its SID, because account is cloud managed
$Principal = if ($env:USERDOMAIN)
{
New-ScheduledTaskPrincipal -UserId $env:USERNAME -RunLevel Highest
}
else
{
New-ScheduledTaskPrincipal -UserId "$env:COMPUTERNAME\$env:USERNAME" -RunLevel Highest
}
$Trigger = New-ScheduledTaskTrigger -Daily -DaysInterval 60 -At 9pm
$Parameters = @{
TaskName = "Temp"
TaskPath = "Sophia"
Action = $Action
Settings = $Settings
Principal = $Principal
Trigger = $Trigger
Description = $Localization.FolderTaskDescription -f "%TEMP%", $env:USERNAME
}
Register-ScheduledTask @Parameters -Force
# Set author for scheduled task
$Task = Get-ScheduledTask -TaskName "Temp"
$Task.Author = "Team Sophia"
$Task | Set-ScheduledTask
$Global:ScheduledTasks = $true
}
"Delete"
{
# Remove files first unless we cannot remove folder if there's no more tasks there
Remove-Item -Path "$env:SystemRoot\System32\Tasks\Sophia\TempTask.vbs", "$env:SystemRoot\System32\Tasks\Sophia\TempTask.ps1" -Force -ErrorAction Ignore
# Remove all old tasks
# We have to use -ErrorAction Ignore in both cases, unless we get an error
Get-ScheduledTask -TaskPath "\Sophia Script\", "\SophiApp\" -ErrorAction Ignore | ForEach-Object -Process {
Unregister-ScheduledTask -TaskName $_.TaskName -Confirm:$false -ErrorAction Ignore
}
# Remove folder in Task Scheduler if there is no tasks left there. We cannot remove all old folders explicitly and not get errors if any of folders do not exist
$ScheduleService = New-Object -ComObject Schedule.Service
$ScheduleService.Connect()
if (Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\Sophia Script")
{
$ScheduleService.GetFolder("\").DeleteFolder("Sophia Script", $null)
}
if (Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\SophiApp")
{
$ScheduleService.GetFolder("\").DeleteFolder("SophiApp", $null)
}
# Removing current task
Unregister-ScheduledTask -TaskPath "\Sophia\" -TaskName Temp -Confirm:$false -ErrorAction Ignore
# Remove folder in Task Scheduler if there is no tasks left there
if (Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\Sophia")
{
if (($ScheduleService.GetFolder("Sophia").GetTasks(0) | Select-Object -Property Name).Name.Count -eq 0)
{
$ScheduleService.GetFolder("\").DeleteFolder("Sophia", $null)
}
}
}
}
}
#endregion Scheduled tasks
#region Microsoft Defender & Security
<#
.SYNOPSIS
Microsoft Defender Exploit Guard network protection
.PARAMETER Enable
Enable Microsoft Defender Exploit Guard network protection
.PARAMETER Disable
Disable Microsoft Defender Exploit Guard network protection
.EXAMPLE
NetworkProtection -Enable
.EXAMPLE
NetworkProtection -Disable
.NOTES
Current user
#>
function NetworkProtection
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
if (-not $Global:DefenderDefaultAV)
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.ThirdPartyAVInstalled, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.ThirdPartyAVInstalled, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
Set-MpPreference -EnableNetworkProtection Enabled
}
"Disable"
{
Set-MpPreference -EnableNetworkProtection Disabled
}
}
}
<#
.SYNOPSIS
Detection for potentially unwanted applications
.PARAMETER Enable
Enable detection for potentially unwanted applications and block them
.PARAMETER Disable
Disable detection for potentially unwanted applications and block them
.EXAMPLE
PUAppsDetection -Enable
.EXAMPLE
PUAppsDetection -Disable
.NOTES
Current user
#>
function PUAppsDetection
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
if (-not $Global:DefenderDefaultAV)
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.ThirdPartyAVInstalled, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.ThirdPartyAVInstalled, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
Set-MpPreference -PUAProtection Enabled
}
"Disable"
{
Set-MpPreference -PUAProtection Disabled
}
}
}
<#
.SYNOPSIS
Sandboxing for Microsoft Defender
.PARAMETER Enable
Enable sandboxing for Microsoft Defender
.PARAMETER Disable
Disable sandboxing for Microsoft Defender
.EXAMPLE
DefenderSandbox -Enable
.EXAMPLE
DefenderSandbox -Disable
.NOTES
Machine-wide
#>
function DefenderSandbox
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
if (-not $Global:DefenderDefaultAV)
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.ThirdPartyAVInstalled, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.ThirdPartyAVInstalled, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
& "$env:SystemRoot\System32\setx.exe" /M MP_FORCE_USE_SANDBOX 1
}
"Disable"
{
& "$env:SystemRoot\System32\setx.exe" /M MP_FORCE_USE_SANDBOX 0
}
}
}
<#
.SYNOPSIS
The "Process Creation" Event Viewer custom view
.PARAMETER Enable
Create the "Process Creation" сustom view in the Event Viewer to log executed processes and their arguments
.PARAMETER Disable
Remove the "Process Creation" custom view in the Event Viewer
.EXAMPLE
EventViewerCustomView -Enable
.EXAMPLE
EventViewerCustomView -Disable
.NOTES
In order this feature to work events auditing and command line in process creation events will be enabled
.NOTES
Machine-wide
#>
function EventViewerCustomView
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
# Enable events auditing generated when a process is created (starts)
auditpol /set /subcategory:"{0CCE922B-69AE-11D9-BED3-505054503030}" /success:enable /failure:enable
# Include command line in process creation events
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit -Name ProcessCreationIncludeCmdLine_Enabled -PropertyType DWord -Value 1 -Force
Set-Policy -Scope Computer -Path SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit -Name ProcessCreationIncludeCmdLine_Enabled -Type DWORD -Value 1
$XML = @"
<ViewerConfig>
<QueryConfig>
<QueryParams>
<UserQuery />
</QueryParams>
<QueryNode>
<Name>$($Localization.EventViewerCustomViewName)</Name>
<Description>$($Localization.EventViewerCustomViewDescription)</Description>
<QueryList>
<Query Id="0" Path="Security">
<Select Path="Security">*[System[(EventID=4688)]]</Select>
</Query>
</QueryList>
</QueryNode>
</QueryConfig>
</ViewerConfig>
"@
if (-not (Test-Path -Path "$env:ProgramData\Microsoft\Event Viewer\Views"))
{
New-Item -Path "$env:ProgramData\Microsoft\Event Viewer\Views" -ItemType Directory -Force
}
# Save ProcessCreation.xml in the UTF-8 with BOM encoding
Set-Content -Path "$env:ProgramData\Microsoft\Event Viewer\Views\ProcessCreation.xml" -Value $XML -Encoding utf8BOM -NoNewline -Force
}
"Disable"
{
Remove-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit -Name ProcessCreationIncludeCmdLine_Enabled -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit -Name ProcessCreationIncludeCmdLine_Enabled -Type CLEAR
Remove-Item -Path "$env:ProgramData\Microsoft\Event Viewer\Views\ProcessCreation.xml" -Force -ErrorAction Ignore
}
}
}
<#
.SYNOPSIS
Logging for all Windows PowerShell modules
.PARAMETER Enable
Enable logging for all Windows PowerShell modules
.PARAMETER Disable
Disable logging for all Windows PowerShell modules
.EXAMPLE
PowerShellModulesLogging -Enable
.EXAMPLE
PowerShellModulesLogging -Disable
.NOTES
Machine-wide
#>
function PowerShellModulesLogging
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
if (-not (Test-Path -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging\ModuleNames))
{
New-Item -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging\ModuleNames -Force
}
New-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging -Name EnableModuleLogging -PropertyType DWord -Value 1 -Force
New-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging\ModuleNames -Name * -PropertyType String -Value * -Force
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging -Name EnableModuleLogging -Type DWORD -Value 1
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging\ModuleNames -Name * -Type SZ -Value *
}
"Disable"
{
Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging -Name EnableModuleLogging -Force -ErrorAction Ignore
Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging\ModuleNames -Name * -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging -Name EnableModuleLogging -Type CLEAR
}
}
}
<#
.SYNOPSIS
Logging for all PowerShell scripts input to the Windows PowerShell event log
.PARAMETER Enable
Enable logging for all PowerShell scripts input to the Windows PowerShell event log
.PARAMETER Disable
Disable logging for all PowerShell scripts input to the Windows PowerShell event log
.EXAMPLE
PowerShellScriptsLogging -Enable
.EXAMPLE
PowerShellScriptsLogging -Disable
.NOTES
Machine-wide
#>
function PowerShellScriptsLogging
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
if (-not (Test-Path -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging))
{
New-Item -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging -Force
}
New-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging -Name EnableScriptBlockLogging -PropertyType DWord -Value 1 -Force
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging -Name EnableScriptBlockLogging -Type DWORD -Value 1
}
"Disable"
{
Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging -Name EnableScriptBlockLogging -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging -Name EnableScriptBlockLogging -Type CLEAR
}
}
}
<#
.SYNOPSIS
Microsoft Defender SmartScreen
.PARAMETER Enable
Enable apps and files checking within Microsoft Defender SmartScreen
.PARAMETER Disable
Disable apps and files checking within Microsoft Defender SmartScreen
.EXAMPLE
AppsSmartScreen -Enable
.EXAMPLE
AppsSmartScreen -Disable
.NOTES
Machine-wide
#>
function AppsSmartScreen
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
if (-not $Global:DefenderDefaultAV)
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.ThirdPartyAVInstalled, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.ThirdPartyAVInstalled, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer -Name SmartScreenEnabled -PropertyType String -Value Warn -Force
}
"Disable"
{
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer -Name SmartScreenEnabled -PropertyType String -Value Off -Force
}
}
}
<#
.SYNOPSIS
The Attachment Manager
.PARAMETER Disable
Microsoft Defender SmartScreen doesn't marks downloaded files from the Internet as unsafe
.PARAMETER Enable
Microsoft Defender SmartScreen marks downloaded files from the Internet as unsafe
.EXAMPLE
SaveZoneInformation -Disable
.EXAMPLE
SaveZoneInformation -Enable
.NOTES
Current user
#>
function SaveZoneInformation
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments -Name SaveZoneInformation -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments -Name SaveZoneInformation -Type CLEAR
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
if (-not (Test-Path -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies\Attachments))
{
New-Item -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies\Attachments -Force
}
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies\Attachments -Name SaveZoneInformation -PropertyType DWord -Value 1 -Force
Set-Policy -Scope User -Path Software\Microsoft\Windows\CurrentVersion\Policies\Attachments -Name SaveZoneInformation -Type DWORD -Value 1
}
"Enable"
{
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies\Attachments -Name SaveZoneInformation -Force -ErrorAction Ignore
Set-Policy -Scope User -Path Software\Microsoft\Windows\CurrentVersion\Policies\Attachments -Name SaveZoneInformation -Type CLEAR
}
}
}
<#
.SYNOPSIS
Windows Sandbox
.PARAMETER Disable
Disable Windows Sandbox
.PARAMETER Enable
Enable Windows Sandbox
.EXAMPLE
WindowsSandbox -Disable
.EXAMPLE
WindowsSandbox -Enable
.NOTES
Current user
#>
function WindowsSandbox
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable
)
$EditionID = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").EditionID
if (($EditionID -notmatch "Professional") -and ($EditionID -notmatch "Enterprise") -and ($EditionID -notmatch "Education"))
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.NoHomeWindowsEditionSupport -f $MyInvocation.Line.Trim()), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.NoHomeWindowsEditionSupport -f $MyInvocation.Line.Trim()), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
switch ($PSCmdlet.ParameterSetName)
{
"Disable"
{
# Checking whether x86 virtualization is enabled in the firmware
if ((Get-CimInstance -ClassName CIM_Processor).VirtualizationFirmwareEnabled)
{
Disable-WindowsOptionalFeature -FeatureName Containers-DisposableClientVM -Online -NoRestart
}
else
{
try
{
# Determining whether Hyper-V is enabled
if ((Get-CimInstance -ClassName CIM_ComputerSystem).HypervisorPresent)
{
Disable-WindowsOptionalFeature -FeatureName Containers-DisposableClientVM -Online -NoRestart
}
}
catch [System.Exception]
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.EnableHardwareVT, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.EnableHardwareVT, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
}
}
}
"Enable"
{
# Checking whether x86 virtualization is enabled in the firmware
if ((Get-CimInstance -ClassName CIM_Processor).VirtualizationFirmwareEnabled)
{
Enable-WindowsOptionalFeature -FeatureName Containers-DisposableClientVM -All -Online -NoRestart
}
else
{
try
{
# Determining whether Hyper-V is enabled
if ((Get-CimInstance -ClassName CIM_ComputerSystem).HypervisorPresent)
{
Enable-WindowsOptionalFeature -FeatureName Containers-DisposableClientVM -All -Online -NoRestart
}
}
catch [System.Exception]
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.EnableHardwareVT, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.EnableHardwareVT, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
}
}
}
}
}
<#
.SYNOPSIS
Configure DNS using DNS-over-HTTPS
.PARAMETER Cloudflare
Enable DNS-over-HTTPS using Cloudflare DNS
.PARAMETER Google
Enable DNS-over-HTTPS using Google Public DNS
.PARAMETER Quad9
Enable DNS-over-HTTPS using Quad9 DNS
.PARAMETER ComssOne
Enable DNS-over-HTTPS using Comss.one DNS
.PARAMETER AdGuard
Enable DNS-over-HTTPS using AdGuard DNS
.PARAMETER Disable
Set default ISP's DNS records
.EXAMPLE
DNSoverHTTPS -Cloudflare
.EXAMPLE
DNSoverHTTPS -Google
.EXAMPLE
DNSoverHTTPS -Quad9
.EXAMPLE
DNSoverHTTPS -ComssOne
.EXAMPLE
DNSoverHTTPS -AdGuard
.EXAMPLE
DNSoverHTTPS -Disable
.LINK
https://learn.microsoft.com/en-us/windows-server/networking/dns/doh-client-support
.NOTES
Machine-wide
#>
function DNSoverHTTPS
{
[CmdletBinding()]
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Cloudflare"
)]
[switch]
$Cloudflare,
[Parameter(
Mandatory = $true,
ParameterSetName = "Google"
)]
[switch]
$Google,
[Parameter(
Mandatory = $true,
ParameterSetName = "Quad9"
)]
[switch]
$Quad9,
[Parameter(
Mandatory = $true,
ParameterSetName = "ComssOne"
)]
[switch]
$ComssOne,
[Parameter(
Mandatory = $true,
ParameterSetName = "AdGuard"
)]
[switch]
$AdGuard,
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
# Determining whether Hyper-V is enabled
# After enabling Hyper-V feature a virtual switch being created, so we need to use different method to isolate the proper adapter
if ((Get-CimInstance -ClassName CIM_ComputerSystem).HypervisorPresent)
{
$InterfaceGuids = @((Get-NetRoute | Where-Object -FilterScript {$_.DestinationPrefix -eq "0.0.0.0/0"} | Get-NetAdapter | Where-Object -FilterScript {$_.Status -eq "Up"}).InterfaceGuid)
}
else
{
$InterfaceGuids = @((Get-NetAdapter -Physical | Where-Object -FilterScript {$_.Status -eq "Up"}).InterfaceGuid)
}
if ($Disable)
{
# Determining whether Hyper-V is enabled
if ((Get-CimInstance -ClassName CIM_ComputerSystem).HypervisorPresent)
{
# Configure DNS servers automatically
Get-NetRoute | Where-Object -FilterScript {$_.DestinationPrefix -eq "0.0.0.0/0"} | Get-NetAdapter | Where-Object -FilterScript {$_.Status -eq "Up"} | Set-DnsClientServerAddress -ResetServerAddresses
}
else
{
# Configure DNS servers automatically
Get-NetAdapter -Physical | Where-Object -FilterScript {$_.Status -eq "Up"} | Get-NetIPInterface -AddressFamily IPv4 | Set-DnsClientServerAddress -ResetServerAddresses
}
foreach ($InterfaceGuid in $InterfaceGuids)
{
Remove-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\InterfaceSpecificParameters\$InterfaceGuid\DohInterfaceSettings\Doh" -Recurse -Force -ErrorAction Ignore
}
return
}
switch ($PSCmdlet.ParameterSetName)
{
# https://developers.cloudflare.com/1.1.1.1/setup/windows/
"Cloudflare"
{
$PrimaryDNS = "1.1.1.1"
$SecondaryDNS = "1.0.0.1"
}
# https://developers.google.com/speed/public-dns/docs/using
"Google"
{
$PrimaryDNS = "8.8.8.8"
$SecondaryDNS = "8.8.4.4"
}
# https://quad9.net/service/service-addresses-and-features/
"Quad9"
{
$PrimaryDNS = "9.9.9.9"
$SecondaryDNS = "149.112.112.112"
}
# https://www.comss.ru/page.php?id=7315
"ComssOne"
{
$PrimaryDNS = "83.220.169.155"
$SecondaryDNS = "212.109.195.93"
$Query = "https://dns.comss.one/dns-query"
}
# https://adguard-dns.io/public-dns.html
"AdGuard"
{
$PrimaryDNS = "94.140.14.14"
$SecondaryDNS = "94.140.14.15"
$Query = "https://dns.adguard-dns.com/dns-query"
}
}
# Set primary and secondary DNS servers
if ((Get-CimInstance -ClassName CIM_ComputerSystem).HypervisorPresent)
{
Get-NetRoute | Where-Object -FilterScript {$_.DestinationPrefix -eq "0.0.0.0/0"} | Get-NetAdapter | Where-Object -FilterScript {$_.Status -eq "Up"} | Set-DnsClientServerAddress -ServerAddresses $PrimaryDNS, $SecondaryDNS
}
else
{
Get-NetAdapter -Physical | Where-Object -FilterScript {$_.Status -eq "Up"} | Get-NetIPInterface -AddressFamily IPv4 | Set-DnsClientServerAddress -ServerAddresses $PrimaryDNS, $SecondaryDNS
}
foreach ($InterfaceGuid in $InterfaceGuids)
{
if (-not (Test-Path -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\InterfaceSpecificParameters\$InterfaceGuid\DohInterfaceSettings\Doh\$PrimaryDNS"))
{
New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\InterfaceSpecificParameters\$InterfaceGuid\DohInterfaceSettings\Doh\$PrimaryDNS" -Force
}
if (-not (Test-Path -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\InterfaceSpecificParameters\$InterfaceGuid\DohInterfaceSettings\Doh\$SecondaryDNS"))
{
New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\InterfaceSpecificParameters\$InterfaceGuid\DohInterfaceSettings\Doh\$SecondaryDNS" -Force
}
# Encrypted preffered, unencrypted allowed
if ($Query)
{
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\InterfaceSpecificParameters\$InterfaceGuid\DohInterfaceSettings\Doh\$PrimaryDNS" -Name DohFlags -PropertyType QWord -Value 2 -Force
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\InterfaceSpecificParameters\$InterfaceGuid\DohInterfaceSettings\Doh\$PrimaryDNS" -Name DohTemplate -PropertyType String -Value $Query -Force
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\InterfaceSpecificParameters\$InterfaceGuid\DohInterfaceSettings\Doh\$SecondaryDNS" -Name DohFlags -PropertyType QWord -Value 2 -Force
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\InterfaceSpecificParameters\$InterfaceGuid\DohInterfaceSettings\Doh\$SecondaryDNS" -Name DohTemplate -PropertyType String -Value $Query -Force
}
else
{
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\InterfaceSpecificParameters\$InterfaceGuid\DohInterfaceSettings\Doh\$PrimaryDNS" -Name DohFlags -PropertyType QWord -Value 5 -Force
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\InterfaceSpecificParameters\$InterfaceGuid\DohInterfaceSettings\Doh\$SecondaryDNS" -Name DohFlags -PropertyType QWord -Value 5 -Force
}
}
Clear-DnsClientCache
Register-DnsClient
}
<#
.SYNOPSIS
Local Security Authority protection
.PARAMETER Enable
Enable Local Security Authority protection to prevent code injection without UEFI lock
.PARAMETER Disable
Disable Local Security Authority protection
.EXAMPLE
LocalSecurityAuthority -Enable
.EXAMPLE
LocalSecurityAuthority -Disable
.NOTES
https://learn.microsoft.com/en-us/windows-server/security/credentials-protection-and-management/configuring-additional-lsa-protection
.NOTES
Machine-wide
#>
function LocalSecurityAuthority
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\System -Name RunAsPPL -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\System -Name RunAsPPL -Type CLEAR
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
# Checking whether x86 virtualization is enabled in the firmware
if ((Get-CimInstance -ClassName CIM_Processor).VirtualizationFirmwareEnabled)
{
New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Control\Lsa -Name RunAsPPL -PropertyType DWord -Value 2 -Force
New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Control\Lsa -Name RunAsPPLBoot -PropertyType DWord -Value 2 -Force
}
else
{
try
{
# Determining whether Hyper-V is enabled
if ((Get-CimInstance -ClassName CIM_ComputerSystem).HypervisorPresent)
{
New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Control\Lsa -Name RunAsPPL -PropertyType DWord -Value 2 -Force
New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Control\Lsa -Name RunAsPPLBoot -PropertyType DWord -Value 2 -Force
}
}
catch [System.Exception]
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.EnableHardwareVT, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.EnableHardwareVT, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
}
}
}
"Disable"
{
Remove-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Control\Lsa -Name RunAsPPL, RunAsPPLBoot -Force -ErrorAction Ignore
}
}
}
#endregion Microsoft Defender & Security
#region Context menu
<#
.SYNOPSIS
The "Extract all" item in the Windows Installer (.msi) context menu
.PARAMETER Show
Show the "Extract all" item in the Windows Installer (.msi) context menu
.PARAMETER Remove
Hide the "Extract all" item from the Windows Installer (.msi) context menu
.EXAMPLE
MSIExtractContext -Show
.EXAMPLE
MSIExtractContext -Hide
.NOTES
Current user
#>
function MSIExtractContext
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Show"
)]
[switch]
$Show,
[Parameter(
Mandatory = $true,
ParameterSetName = "Hide"
)]
[switch]
$Hide
)
switch ($PSCmdlet.ParameterSetName)
{
"Show"
{
if (-not (Test-Path -Path Registry::HKEY_CLASSES_ROOT\Msi.Package\shell\Extract\Command))
{
New-Item -Path Registry::HKEY_CLASSES_ROOT\Msi.Package\shell\Extract\Command -Force
}
$Value = "msiexec.exe /a `"%1`" /qb TARGETDIR=`"%1 extracted`""
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOT\Msi.Package\shell\Extract\Command -Name "(default)" -PropertyType String -Value $Value -Force
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOT\Msi.Package\shell\Extract -Name MUIVerb -PropertyType String -Value "@shell32.dll,-37514" -Force
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOT\Msi.Package\shell\Extract -Name Icon -PropertyType String -Value "%SystemRoot%\System32\shell32.dll,-16817" -Force
}
"Hide"
{
Remove-Item -Path Registry::HKEY_CLASSES_ROOT\Msi.Package\shell\Extract -Recurse -Force -ErrorAction Ignore
}
}
}
<#
.SYNOPSIS
The "Install" item for the Cabinet (.cab) filenames extensions context menu
.PARAMETER Show
Show the "Install" item in the Cabinet (.cab) filenames extensions context menu
.PARAMETER Hide
Hide the "Install" item from the Cabinet (.cab) filenames extensions context menu
.EXAMPLE
CABInstallContext -Show
.EXAMPLE
CABInstallContext -Hide
.NOTES
Current user
#>
function CABInstallContext
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Show"
)]
[switch]
$Show,
[Parameter(
Mandatory = $true,
ParameterSetName = "Hide"
)]
[switch]
$Hide
)
switch ($PSCmdlet.ParameterSetName)
{
"Show"
{
if
(
([Microsoft.Win32.Registry]::GetValue("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.cab\UserChoice", "ProgId", $null) -eq "CABFolder") -or
(-not (Get-ChildItem -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.cab\UserChoice -ErrorAction Ignore))
)
{
if (-not (Test-Path -Path Registry::HKEY_CLASSES_ROOT\CABFolder\Shell\runas\Command))
{
New-Item -Path Registry::HKEY_CLASSES_ROOT\CABFolder\Shell\runas\Command -Force
}
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOT\CABFolder\Shell\runas\Command -Name "(default)" -PropertyType String -Value "cmd /c DISM.exe /Online /Add-Package /PackagePath:`"%1`" /NoRestart & pause" -Force
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOT\CABFolder\Shell\runas -Name MUIVerb -PropertyType String -Value "@shell32.dll,-10210" -Force
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOT\CABFolder\Shell\runas -Name HasLUAShield -PropertyType String -Value "" -Force
}
else
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.ThirdPartyArchiverInstalled, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.ThirdPartyArchiverInstalled, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
}
"Hide"
{
Remove-Item -Path Registry::HKEY_CLASSES_ROOT\CABFolder\Shell\runas -Recurse -Force -ErrorAction Ignore
}
}
}
<#
.SYNOPSIS
The "Edit with Clipchamp" item in the media files context menu
.PARAMETER Hide
Hide the "Edit with Clipchamp" item from the media files context menu
.PARAMETER Show
Show the "Edit with Clipchamp" item in the media files context menu
.EXAMPLE
EditWithClipchampContext -Hide
.EXAMPLE
EditWithClipchampContext -Show
.NOTES
Current user
#>
function EditWithClipchampContext
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Hide"
)]
[switch]
$Hide,
[Parameter(
Mandatory = $true,
ParameterSetName = "Show"
)]
[switch]
$Show
)
if (-not (Get-AppxPackage -Name Clipchamp.Clipchamp))
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.PackageNotInstalled -f "Microsoft Clipchamp"), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.PackageNotInstalled -f "Microsoft Clipchamp"), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked" -Name "{8AB635F8-9A67-4698-AB99-784AD929F3B4}" -Force -ErrorAction Ignore
switch ($PSCmdlet.ParameterSetName)
{
"Hide"
{
if (-not (Test-Path -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked"))
{
New-Item -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked" -Force
}
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked" -Name "{8AB635F8-9A67-4698-AB99-784AD929F3B4}" -PropertyType String -Value "" -Force
}
"Show"
{
Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked" -Name "{8AB635F8-9A67-4698-AB99-784AD929F3B4}" -Force -ErrorAction Ignore
}
}
}
<#
.SYNOPSIS
The "Edit with Photos" item in the media files context menu
.PARAMETER Hide
Hide the "Edit with Photos" item from the media files context menu
.PARAMETER Show
Show the "Edit with Photos" item in the media files context menu
.EXAMPLE
EditWithPhotosContext -Hide
.EXAMPLE
EditWithPhotosContext -Show
.NOTES
Current user
#>
function EditWithPhotosContext
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Hide"
)]
[switch]
$Hide,
[Parameter(
Mandatory = $true,
ParameterSetName = "Show"
)]
[switch]
$Show
)
if (-not (Get-AppxPackage -Name Microsoft.Windows.Photos))
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.PhotosNotInstalled, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.PhotosNotInstalled, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked" -Name "{BFE0E2A4-C70C-4AD7-AC3D-10D1ECEBB5B4}" -Force -ErrorAction Ignore
switch ($PSCmdlet.ParameterSetName)
{
"Hide"
{
if (-not (Test-Path -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked"))
{
New-Item -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked" -Force
}
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked" -Name "{BFE0E2A4-C70C-4AD7-AC3D-10D1ECEBB5B4}" -PropertyType String -Value "" -Force
}
"Show"
{
Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked" -Name "{BFE0E2A4-C70C-4AD7-AC3D-10D1ECEBB5B4}" -Force -ErrorAction Ignore
}
}
}
<#
.SYNOPSIS
The "Edit with Paint" item in the media files context menu
.PARAMETER Hide
Hide the "Edit with Paint" item from the media files context menu
.PARAMETER Show
Show the "Edit with Paint" item in the media files context menu
.EXAMPLE
EditWithPaintContext -Hide
.EXAMPLE
EditWithPaintContext -Show
.NOTES
Current user
#>
function EditWithPaintContext
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Hide"
)]
[switch]
$Hide,
[Parameter(
Mandatory = $true,
ParameterSetName = "Show"
)]
[switch]
$Show
)
if (-not (Get-AppxPackage -Name Microsoft.Paint))
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.PackageNotInstalled -f "Paint"), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.PackageNotInstalled -f "Paint"), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked" -Name "{2430F218-B743-4FD6-97BF-5C76541B4AE9}" -Force -ErrorAction Ignore
switch ($PSCmdlet.ParameterSetName)
{
"Hide"
{
if (-not (Test-Path -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked"))
{
New-Item -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked" -Force
}
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked" -Name "{2430F218-B743-4FD6-97BF-5C76541B4AE9}" -PropertyType String -Value "" -Force
}
"Show"
{
Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked" -Name "{2430F218-B743-4FD6-97BF-5C76541B4AE9}" -Force -ErrorAction Ignore
}
}
}
<#
.SYNOPSIS
The "Print" item in the .bat and .cmd context menu
.PARAMETER Hide
Hide the "Print" item from the .bat and .cmd context menu
.PARAMETER Show
Show the "Print" item in the .bat and .cmd context menu
.EXAMPLE
PrintCMDContext -Hide
.EXAMPLE
PrintCMDContext -Show
.NOTES
Current user
#>
function PrintCMDContext
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Hide"
)]
[switch]
$Hide,
[Parameter(
Mandatory = $true,
ParameterSetName = "Show"
)]
[switch]
$Show
)
switch ($PSCmdlet.ParameterSetName)
{
"Hide"
{
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOT\batfile\shell\print -Name ProgrammaticAccessOnly -PropertyType String -Value "" -Force
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOT\cmdfile\shell\print -Name ProgrammaticAccessOnly -PropertyType String -Value "" -Force
}
"Show"
{
Remove-ItemProperty -Path Registry::HKEY_CLASSES_ROOT\batfile\shell\print, Registry::HKEY_CLASSES_ROOT\cmdfile\shell\print -Name ProgrammaticAccessOnly -Force -ErrorAction Ignore
}
}
}
<#
.SYNOPSIS
The "Compressed (zipped) Folder" item in the "New" context menu
.PARAMETER Hide
Hide the "Compressed (zipped) Folder" item from the "New" context menu
.PARAMETER Show
Show the "Compressed (zipped) Folder" item to the "New" context menu
.EXAMPLE
CompressedFolderNewContext -Hide
.EXAMPLE
CompressedFolderNewContext -Show
.NOTES
Current user
#>
function CompressedFolderNewContext
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Hide"
)]
[switch]
$Hide,
[Parameter(
Mandatory = $true,
ParameterSetName = "Show"
)]
[switch]
$Show
)
switch ($PSCmdlet.ParameterSetName)
{
"Hide"
{
Remove-Item -Path Registry::HKEY_CLASSES_ROOT\.zip\CompressedFolder\ShellNew -Force -ErrorAction Ignore
}
"Show"
{
if (-not (Test-Path -Path Registry::HKEY_CLASSES_ROOT\.zip\CompressedFolder\ShellNew))
{
New-Item -Path Registry::HKEY_CLASSES_ROOT\.zip\CompressedFolder\ShellNew -Force
}
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOT\.zip\CompressedFolder\ShellNew -Name Data -PropertyType Binary -Value ([byte[]](80,75,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)) -Force
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOT\.zip\CompressedFolder\ShellNew -Name ItemName -PropertyType ExpandString -Value "@%SystemRoot%\System32\zipfldr.dll,-10194" -Force
}
}
}
<#
.SYNOPSIS
The "Open", "Print", and "Edit" items if more than 15 files selected
.PARAMETER Enable
Enable the "Open", "Print", and "Edit" items if more than 15 files selected
.PARAMETER Disable
Disable the "Open", "Print", and "Edit" items if more than 15 files selected
.EXAMPLE
MultipleInvokeContext -Enable
.EXAMPLE
MultipleInvokeContext -Disable
.NOTES
Current user
#>
function MultipleInvokeContext
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer -Name MultipleInvokePromptMinimum -PropertyType DWord -Value 300 -Force
}
"Disable"
{
Remove-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer -Name MultipleInvokePromptMinimum -Force -ErrorAction Ignore
}
}
}
<#
.SYNOPSIS
The "Look for an app in the Microsoft Store" item in the "Open with" dialog
.PARAMETER Hide
Hide the "Look for an app in the Microsoft Store" item in the "Open with" dialog
.PARAMETER Show
Show the "Look for an app in the Microsoft Store" item in the "Open with" dialog
.EXAMPLE
UseStoreOpenWith -Hide
.EXAMPLE
UseStoreOpenWith -Show
.NOTES
Current user
#>
function UseStoreOpenWith
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Hide"
)]
[switch]
$Hide,
[Parameter(
Mandatory = $true,
ParameterSetName = "Show"
)]
[switch]
$Show
)
# Remove all policies in order to make changes visible in UI
Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer -Name NoUseStoreOpenWith -Force -ErrorAction Ignore
Set-Policy -Scope Computer -Path SOFTWARE\Policies\Microsoft\Windows\Explorer -Name NoUseStoreOpenWith -Type CLEAR
switch ($PSCmdlet.ParameterSetName)
{
"Hide"
{
if (-not (Test-Path -Path HKCU:\Software\Policies\Microsoft\Windows\Explorer))
{
New-Item -Path HKCU:\Software\Policies\Microsoft\Windows\Explorer -Force
}
New-ItemProperty -Path HKCU:\Software\Policies\Microsoft\Windows\Explorer -Name NoUseStoreOpenWith -PropertyType DWord -Value 1 -Force
Set-Policy -Scope User -Path Software\Policies\Microsoft\Windows\Explorer -Name NoUseStoreOpenWith -Type DWORD -Value 1
}
"Show"
{
Remove-ItemProperty -Path HKCU:\Software\Policies\Microsoft\Windows\Explorer -Name NoUseStoreOpenWith -Force -ErrorAction Ignore
Set-Policy -Scope User -Path Software\Policies\Microsoft\Windows\Explorer -Name NoUseStoreOpenWith -Type CLEAR
}
}
}
<#
.SYNOPSIS
The "Open in Windows Terminal" item in the folders context menu
.PARAMETER Hide
Hide the "Open in Windows Terminal" item in the folders context menu
.PARAMETER Show
Show the "Open in Windows Terminal" item in the folders context menu
.EXAMPLE
OpenWindowsTerminalContext -Show
.EXAMPLE
OpenWindowsTerminalContext -Hide
.NOTES
Current user
#>
function OpenWindowsTerminalContext
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Show"
)]
[switch]
$Show,
[Parameter(
Mandatory = $true,
ParameterSetName = "Hide"
)]
[switch]
$Hide
)
if (-not (Get-AppxPackage -Name Microsoft.WindowsTerminal))
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.PackageNotInstalled -f "Windows Terminal"), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.PackageNotInstalled -f "Windows Terminal"), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked" -Name "{9F156763-7844-4DC4-B2B1-901F640F5155}" -Force -ErrorAction Ignore
switch ($PSCmdlet.ParameterSetName)
{
"Show"
{
Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked" -Name "{9F156763-7844-4DC4-B2B1-901F640F5155}" -Force -ErrorAction Ignore
}
"Hide"
{
if (-not (Test-Path -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked"))
{
New-Item -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked" -Force
}
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked" -Name "{9F156763-7844-4DC4-B2B1-901F640F5155}" -PropertyType String -Value "" -Force
}
}
}
<#
.SYNOPSIS
Open Windows Terminal in context menu as administrator
.PARAMETER Enable
Open Windows Terminal in context menu as administrator by default
.PARAMETER Disable
Do not open Windows Terminal in context menu as administrator by default
.EXAMPLE
OpenWindowsTerminalAdminContext -Enable
.EXAMPLE
OpenWindowsTerminalAdminContext -Disable
.NOTES
Current user
#>
function OpenWindowsTerminalAdminContext
{
param
(
[Parameter(
Mandatory = $true,
ParameterSetName = "Enable"
)]
[switch]
$Enable,
[Parameter(
Mandatory = $true,
ParameterSetName = "Disable"
)]
[switch]
$Disable
)
if (-not (Get-AppxPackage -Name Microsoft.WindowsTerminal))
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.PackageNotInstalled -f "Windows Terminal"), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.PackageNotInstalled -f "Windows Terminal"), ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
if (-not (Test-Path -Path "$env:LOCALAPPDATA\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json"))
{
Start-Process -FilePath wt -PassThru
Start-Sleep -Seconds 2
Stop-Process -Name WindowsTerminal -Force -PassThru
}
try
{
$Terminal = Get-Content -Path "$env:LOCALAPPDATA\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json" -Encoding utf8 -Force | ConvertFrom-Json
}
catch [System.ArgumentException]
{
Invoke-Item -Path "$env:LOCALAPPDATA\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState"
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message (($Localization.JSONNotValid -f $OpenFileDialog.FileName), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message (($Localization.JSONNotValid -f $OpenFileDialog.FileName), ($Localization.RestartFunction -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
switch ($PSCmdlet.ParameterSetName)
{
"Enable"
{
$Paths = @(
"HKCU:\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked",
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked"
)
Remove-ItemProperty -Path $Paths -Name "{9F156763-7844-4DC4-B2B1-901F640F5155}" -ErrorAction Ignore
if ($Terminal.profiles.defaults.elevate)
{
$Terminal.profiles.defaults.elevate = $true
}
else
{
$Terminal.profiles.defaults | Add-Member -MemberType NoteProperty -Name elevate -Value $true -Force
}
}
"Disable"
{
if ($Terminal.profiles.defaults.elevate)
{
$Terminal.profiles.defaults.elevate = $false
}
else
{
$Terminal.profiles.defaults | Add-Member -MemberType NoteProperty -Name elevate -Value $false -Force
}
}
}
# Save in UTF-8 with BOM despite JSON must not has the BOM: https://datatracker.ietf.org/doc/html/rfc8259#section-8.1. Unless Terminal profile names which contains non-Latin characters will have "?" instead of titles
ConvertTo-Json -InputObject $Terminal -Depth 4 | Set-Content -Path "$env:LOCALAPPDATA\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json" -Encoding utf8BOM -Force
}
#endregion Context menu
<#
.SYNOPSIS
Scan the Windows registry and display all policies (even created manually) in the Local Group Policy Editor snap-in (gpedit.msc)
.EXAMPLE
ScanRegistryPolicies
.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
Current user
#>
function ScanRegistryPolicies
{
if (-not (Test-Path -Path "$env:SystemRoot\System32\gpedit.msc"))
{
Write-Information -MessageData "" -InformationAction Continue
Write-Verbose -Message ($Localization.gpeditNotSupported, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -Verbose
Write-Error -Message ($Localization.gpeditNotSupported, ($Localization.Skipped -f $MyInvocation.Line.Trim()) -join " ") -ErrorAction SilentlyContinue
return
}
Write-Information -MessageData "" -InformationAction Continue
# Extract the localized "Please wait..." string from %SystemRoot%\System32\shell32.dll
Write-Verbose -Message ([WinAPI.GetStrings]::GetString(12612)) -Verbose
Write-Information -MessageData "" -InformationAction Continue
# Policy paths to scan recursively
$PolicyKeys = @(
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies",
"HKLM:\SOFTWARE\Policies\Microsoft",
"HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies",
"HKCU:\Software\Policies\Microsoft"
)
foreach ($Path in (@(Get-ChildItem -Path $PolicyKeys -Recurse -Force -ErrorAction Ignore)))
{
foreach ($Item in $Path.Property)
{
# Checking whether property isn't equal to "(default)" and exists
if (($null -ne $Item) -and ($Item -ne "(default)"))
{
# Where all ADMX templates are located to compare with
foreach ($admx in @(Get-ChildItem -Path "$env:SystemRoot\PolicyDefinitions" -File -Filter *.admx -Force))
{
# Parse every ADMX template searching if it contains full path and registry key simultaneously
# No -Force argument
[xml]$admxtemplate = Get-Content -Path $admx.FullName -Encoding UTF8
$SplitPath = $Path.Name.Replace("HKEY_LOCAL_MACHINE\", "").Replace("HKEY_CURRENT_USER\", "")
if ($admxtemplate.policyDefinitions.policies.policy | Where-Object -FilterScript {($_.key -eq $SplitPath) -and (($_.valueName -eq $Item) -or ($_.Name -eq $Item))})
{
Write-Verbose -Message ([string]($Path.Name, "|", $Item.Replace("{}", ""), "|", $(Get-ItemPropertyValue -Path $Path.PSPath -Name $Item))) -Verbose
$Type = switch ((Get-Item -Path $Path.PSPath).GetValueKind($Item))
{
"DWord"
{
(Get-Item -Path $Path.PSPath).GetValueKind($Item).ToString().ToUpper()
}
"ExpandString"
{
"EXSZ"
}
"String"
{
"SZ"
}
}
$Scope = if ($Path.Name -match "HKEY_LOCAL_MACHINE")
{
"Computer"
}
else
{
"User"
}
$Parameters = @{
# e.g. User
Scope = $Scope
# e.g. SOFTWARE\Microsoft\Windows\CurrentVersion\Policies
Path = $Path.Name.Replace("HKEY_LOCAL_MACHINE\", "").Replace("HKEY_CURRENT_USER\", "")
# e.g. NoUseStoreOpenWith
Name = $Item.Replace("{}", "")
# e.g. DWORD
Type = $Type
# e.g. 1
Value = Get-ItemPropertyValue -Path $Path.PSPath -Name $Item
}
Set-Policy @Parameters
}
}
}
}
}
}