11903 lines
354 KiB
PowerShell
11903 lines
354 KiB
PowerShell
<#
|
||
.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
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|