mirror of
https://github.com/awarre/Optimize-WsusServer.git
synced 2026-05-03 14:00:31 +00:00
Update Optimize-WsusServer.ps1
Super important removal of trailing whitespace.
This commit is contained in:
+64
-65
@@ -31,7 +31,7 @@
|
||||
|
||||
.PARAMETER InstallDailyTask
|
||||
Creates a scheduled task to run the OptimizeServer function nightly.
|
||||
|
||||
|
||||
.PARAMETER InstallWeeklyTask
|
||||
Creates a scheduled task to run the OptimizeDatabase function weekly.
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
Version: 0.1.1
|
||||
Author: Austin Warren
|
||||
Creation Date: 2020/07/31
|
||||
|
||||
|
||||
.EXAMPLE
|
||||
Optimize-WsusServer.ps1 -FirstRun
|
||||
Optimize-WsusServer.ps1 -DeepClean
|
||||
@@ -170,7 +170,7 @@ REFERENCES
|
||||
$createCustomIndexesSQLQuery = @"
|
||||
USE [SUSDB]
|
||||
IF 0 = (SELECT COUNT(*) as index_count
|
||||
FROM sys.indexes
|
||||
FROM sys.indexes
|
||||
WHERE object_id = OBJECT_ID('[dbo].[tbLocalizedPropertyForRevision]')
|
||||
AND name='nclLocalizedPropertyID')
|
||||
BEGIN
|
||||
@@ -186,14 +186,14 @@ BEGIN
|
||||
END ;
|
||||
GO
|
||||
IF 0 = (SELECT COUNT(*) as index_count
|
||||
FROM sys.indexes
|
||||
FROM sys.indexes
|
||||
WHERE object_id = OBJECT_ID('[dbo].[tbRevisionSupersedesUpdate]')
|
||||
AND name='nclSupercededUpdateID')
|
||||
BEGIN
|
||||
-- Create custom index in tbRevisionSupersedesUpdate
|
||||
CREATE NONCLUSTERED INDEX [nclSupercededUpdateID] ON [dbo].[tbRevisionSupersedesUpdate]
|
||||
(
|
||||
[SupersededUpdateID] ASC
|
||||
CREATE NONCLUSTERED INDEX [nclSupercededUpdateID] ON [dbo].[tbRevisionSupersedesUpdate]
|
||||
(
|
||||
[SupersededUpdateID] ASC
|
||||
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY];
|
||||
END
|
||||
ELSE
|
||||
@@ -214,27 +214,27 @@ GO
|
||||
Reference: https://support.microsoft.com/en-us/help/4490644/complete-guide-to-microsoft-wsus-and-configuration-manager-sup-maint
|
||||
#>
|
||||
$wsusDBMaintenanceSQLQuery = @"
|
||||
/******************************************************************************
|
||||
This sample T-SQL script performs basic maintenance tasks on SUSDB
|
||||
1. Identifies indexes that are fragmented and defragments them. For certain
|
||||
tables, a fill-factor is set in order to improve insert performance.
|
||||
Based on MSDN sample at http://msdn2.microsoft.com/en-us/library/ms188917.aspx
|
||||
and tailored for SUSDB requirements
|
||||
2. Updates potentially out-of-date table statistics.
|
||||
******************************************************************************/
|
||||
/******************************************************************************
|
||||
This sample T-SQL script performs basic maintenance tasks on SUSDB
|
||||
1. Identifies indexes that are fragmented and defragments them. For certain
|
||||
tables, a fill-factor is set in order to improve insert performance.
|
||||
Based on MSDN sample at http://msdn2.microsoft.com/en-us/library/ms188917.aspx
|
||||
and tailored for SUSDB requirements
|
||||
2. Updates potentially out-of-date table statistics.
|
||||
******************************************************************************/
|
||||
|
||||
USE SUSDB;
|
||||
GO
|
||||
USE SUSDB;
|
||||
GO
|
||||
SET NOCOUNT ON;
|
||||
|
||||
-- Rebuild or reorganize indexes based on their fragmentation levels
|
||||
-- Rebuild or reorganize indexes based on their fragmentation levels
|
||||
DECLARE @work_to_do TABLE (
|
||||
objectid int
|
||||
, indexid int
|
||||
, pagedensity float
|
||||
, fragmentation float
|
||||
, numrows int
|
||||
)
|
||||
)
|
||||
|
||||
DECLARE @objectid int;
|
||||
DECLARE @indexid int;
|
||||
@@ -262,7 +262,7 @@ SELECT
|
||||
FROM
|
||||
sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, 'SAMPLED') AS f
|
||||
WHERE
|
||||
(f.avg_page_space_used_in_percent < 85.0 and f.avg_page_space_used_in_percent/100.0 * page_count < page_count - 1)
|
||||
(f.avg_page_space_used_in_percent < 85.0 and f.avg_page_space_used_in_percent/100.0 * page_count < page_count - 1)
|
||||
or (f.page_count > 50 and f.avg_fragmentation_in_percent > 15.0)
|
||||
or (f.page_count > 10 and f.avg_fragmentation_in_percent > 80.0)
|
||||
|
||||
@@ -274,8 +274,8 @@ SELECT @numpages = sum(ps.used_page_count)
|
||||
FROM
|
||||
@work_to_do AS fi
|
||||
INNER JOIN sys.indexes AS i ON fi.objectid = i.object_id and fi.indexid = i.index_id
|
||||
INNER JOIN sys.dm_db_partition_stats AS ps on i.object_id = ps.object_id and i.index_id = ps.index_id
|
||||
|
||||
INNER JOIN sys.dm_db_partition_stats AS ps on i.object_id = ps.object_id and i.index_id = ps.index_id
|
||||
|
||||
-- Declare the cursor for the list of indexes to be processed.
|
||||
DECLARE curIndexes CURSOR FOR SELECT * FROM @work_to_do
|
||||
|
||||
@@ -288,7 +288,7 @@ BEGIN
|
||||
FETCH NEXT FROM curIndexes
|
||||
INTO @objectid, @indexid, @density, @fragmentation, @numrows;
|
||||
IF @@FETCH_STATUS < 0 BREAK;
|
||||
|
||||
|
||||
SELECT
|
||||
@objectname = QUOTENAME(o.name)
|
||||
, @schemaname = QUOTENAME(s.name)
|
||||
@@ -297,7 +297,7 @@ BEGIN
|
||||
INNER JOIN sys.schemas as s ON s.schema_id = o.schema_id
|
||||
WHERE
|
||||
o.object_id = @objectid;
|
||||
|
||||
|
||||
SELECT
|
||||
@indexname = QUOTENAME(name)
|
||||
, @fillfactorset = CASE fill_factor WHEN 0 THEN 0 ELSE 1 END
|
||||
@@ -305,14 +305,14 @@ BEGIN
|
||||
sys.indexes
|
||||
WHERE
|
||||
object_id = @objectid AND index_id = @indexid;
|
||||
|
||||
IF ((@density BETWEEN 75.0 AND 85.0) AND @fillfactorset = 1) OR (@fragmentation < 30.0)
|
||||
SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REORGANIZE';
|
||||
ELSE IF @numrows >= 5000 AND @fillfactorset = 0
|
||||
SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REBUILD WITH (FILLFACTOR = 90)';
|
||||
ELSE
|
||||
SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REBUILD';
|
||||
PRINT convert(nvarchar, getdate(), 121) + N' Executing: ' + @command;
|
||||
|
||||
IF ((@density BETWEEN 75.0 AND 85.0) AND @fillfactorset = 1) OR (@fragmentation < 30.0)
|
||||
SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REORGANIZE';
|
||||
ELSE IF @numrows >= 5000 AND @fillfactorset = 0
|
||||
SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REBUILD WITH (FILLFACTOR = 90)';
|
||||
ELSE
|
||||
SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REBUILD';
|
||||
PRINT convert(nvarchar, getdate(), 121) + N' Executing: ' + @command;
|
||||
EXEC (@command);
|
||||
PRINT convert(nvarchar, getdate(), 121) + N' Done.';
|
||||
END
|
||||
@@ -323,13 +323,13 @@ DEALLOCATE curIndexes;
|
||||
|
||||
IF EXISTS (SELECT * FROM @work_to_do)
|
||||
BEGIN
|
||||
PRINT 'Estimated number of pages in fragmented indexes: ' + cast(@numpages as nvarchar(20))
|
||||
PRINT 'Estimated number of pages in fragmented indexes: ' + cast(@numpages as nvarchar(20))
|
||||
SELECT @numpages = @numpages - sum(ps.used_page_count)
|
||||
FROM
|
||||
@work_to_do AS fi
|
||||
INNER JOIN sys.indexes AS i ON fi.objectid = i.object_id and fi.indexid = i.index_id
|
||||
INNER JOIN sys.dm_db_partition_stats AS ps on i.object_id = ps.object_id and i.index_id = ps.index_id
|
||||
|
||||
INNER JOIN sys.indexes AS i ON fi.objectid = i.object_id and fi.indexid = i.index_id
|
||||
INNER JOIN sys.dm_db_partition_stats AS ps on i.object_id = ps.object_id and i.index_id = ps.index_id
|
||||
|
||||
PRINT 'Estimated number of pages freed: ' + cast(@numpages as nvarchar(20))
|
||||
END
|
||||
GO
|
||||
@@ -347,13 +347,13 @@ function Confirm-Prompt ($prompt) {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Y/N confirmation prompt.
|
||||
|
||||
|
||||
.DESCRIPTION
|
||||
Displays Y/N confirmation prompt and returns true or false.
|
||||
|
||||
|
||||
.PARAMETER prompt
|
||||
String displayed as prompt
|
||||
|
||||
|
||||
.EXAMPLE
|
||||
Confirm-Prompt "Is this a question?"
|
||||
#>
|
||||
@@ -381,19 +381,19 @@ function Optimize-WsusUpdates {
|
||||
|
||||
Write-Host "Deleting obsolete computers from WSUS database"
|
||||
Invoke-WsusServerCleanup -CleanupObsoleteComputers
|
||||
|
||||
|
||||
Write-Host "Deleting obsolete updates"
|
||||
Invoke-WsusServerCleanup -CleanupObsoleteUpdates
|
||||
|
||||
|
||||
Write-Host "Deleting unneeded content files"
|
||||
Invoke-WsusServerCleanup -CleanupUnneededContentFiles
|
||||
|
||||
|
||||
Write-Host "Deleting obsolete update revisions"
|
||||
Invoke-WsusServerCleanup -CompressUpdates
|
||||
|
||||
|
||||
Write-Host "Declining expired updates"
|
||||
Invoke-WsusServerCleanup -DeclineExpiredUpdates
|
||||
|
||||
|
||||
Write-Host "Declining superceded updates"
|
||||
Invoke-WsusServerCleanup -DeclineSupersededUpdates
|
||||
}
|
||||
@@ -423,7 +423,7 @@ function Optimize-WsusDatabase {
|
||||
elseif (($wsusSqlServerName -match '##WIN') -Or ($wsusSqlServerName -match '##SSEE')) {
|
||||
#Check OS version
|
||||
$osVersion = [decimal]("$(([environment]::OSVersion.Version).Major).$(([environment]::OSVersion.Version).Minor)")
|
||||
|
||||
|
||||
if ($osVersion -gt 6.2) {
|
||||
$serverInstance = 'np:\\.\pipe\MICROSOFT##WID\tsql\query'
|
||||
}
|
||||
@@ -487,9 +487,9 @@ function New-WsusMaintainenceTask($interval) {
|
||||
}
|
||||
|
||||
$scriptName = Split-Path $MyInvocation.PSCommandPath -Leaf
|
||||
|
||||
|
||||
#Create "C:\Scripts" to store PS script
|
||||
$null = New-Item -Path "$scriptPath" -ItemType Directory -Force
|
||||
$null = New-Item -Path "$scriptPath" -ItemType Directory -Force
|
||||
Write-Host "Created Directory: $scriptPath"
|
||||
|
||||
# Copy current script to script
|
||||
@@ -556,7 +556,7 @@ function Get-WsusIISConfig {
|
||||
|
||||
# Recycling Config Root
|
||||
$wsusPoolRecyclingConfig = Get-IISConfigElement -ConfigElement $wsusPoolConfig -ChildElementName "recycling" | Get-IISConfigElement -ChildElementName "periodicRestart"
|
||||
|
||||
|
||||
$recyclingMemory = Get-IISConfigAttributeValue -ConfigElement $wsusPoolRecyclingConfig -AttributeName "memory"
|
||||
$recyclingPrivateMemory = Get-IISConfigAttributeValue -ConfigElement $wsusPoolRecyclingConfig -AttributeName "privateMemory"
|
||||
|
||||
@@ -566,7 +566,7 @@ function Get-WsusIISConfig {
|
||||
$clientExecutionTimeout = ($clientWebServiceConfig | select-object -ExpandProperty executionTimeout).TotalSeconds
|
||||
|
||||
# Return hash of IIS settings
|
||||
@{
|
||||
@{
|
||||
QueueLength = $queueLength
|
||||
LoadBalancerCapabilities = $loadBalancerCapabilities
|
||||
CpuResetInterval = $cpuResetInterval
|
||||
@@ -581,13 +581,13 @@ function Test-WsusIISConfig ($settings, $recommended) {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Compares current WSUS IIS settings to recommended values.
|
||||
|
||||
|
||||
.DESCRIPTION
|
||||
Compares current WSUS IIS settings to recommended values. Prompts user to commit changes.
|
||||
|
||||
|
||||
.PARAMETER settings
|
||||
Hash of current WSUS IIS settings.
|
||||
|
||||
|
||||
.PARAMETER recommended
|
||||
Hash of recommended WSUS IIS settings.
|
||||
#>
|
||||
@@ -600,7 +600,7 @@ function Test-WsusIISConfig ($settings, $recommended) {
|
||||
# This could be better designed to match minimum requirements instead of specific values, but it isn't.
|
||||
If ($recommended[$key] -ne $settings[$key]) {
|
||||
Write-Host "$key`n`tCurrent:`t$($settings[$key])`n`tRecommended:`t$($recommended[$key])" -BackgroundColor Black -ForegroundColor Red
|
||||
|
||||
|
||||
if (Confirm-Prompt "Update $key to recommended value?") {
|
||||
Update-WsusIISConfig $key $recommended[$key]
|
||||
}
|
||||
@@ -692,13 +692,13 @@ function Update-WsusIISConfig ($settingKey, $recommendedValue) {
|
||||
function RemoveUpdates($searchStrings, $updateProp, $force=$false) {
|
||||
[reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration") | Out-Null
|
||||
$wsusServer = [Microsoft.UpdateServices.Administration.AdminProxy]::GetUpdateServer();
|
||||
$scope = New-Object Microsoft.UpdateServices.Administration.UpdateScope
|
||||
$scope = New-Object Microsoft.UpdateServices.Administration.UpdateScope
|
||||
$updates = $wsusServer.GetUpdates($scope)
|
||||
$declinedCount = 0
|
||||
$searchCount = 0
|
||||
$userMsg = 'Found'
|
||||
$color = 'Yellow'
|
||||
|
||||
$color = 'Yellow'
|
||||
|
||||
if ($force) {
|
||||
$userMsg = 'Declined'
|
||||
$color = 'Red'
|
||||
@@ -723,13 +723,13 @@ function RemoveUpdates($searchStrings, $updateProp, $force=$false) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($searchCount -gt 0) {
|
||||
Write-Host "$searchCount `"$searchString`" Updates $userMsg!" -ForegroundColor "Blue" -BackgroundColor White
|
||||
} else {
|
||||
Write-Host " n$searchCount `"$searchString`" Updates $userMsg" -ForegroundColor "White"
|
||||
}
|
||||
|
||||
|
||||
#Prompt user to confirm declining updates. Do no prompt if force flag is enable to prevent loop
|
||||
if ((-not $force) -and ($searchCount -ne 0)){
|
||||
$confirm = Confirm-Prompt "Are you sure you want to decline all ($searchCount) listed ($searchString) updates?"
|
||||
@@ -753,7 +753,7 @@ function DeepClean ($titles, $productTitles) {
|
||||
Checks for unneeded WSUS updates to be deleted.
|
||||
|
||||
.DESCRIPTION
|
||||
Checks for unneeded WSUS updates by product category to be deleted. This
|
||||
Checks for unneeded WSUS updates by product category to be deleted.
|
||||
|
||||
.PARAMETER titles
|
||||
Parameter description
|
||||
@@ -781,10 +781,10 @@ function DeepClean ($titles, $productTitles) {
|
||||
#>
|
||||
|
||||
$declinedTotal = 0
|
||||
|
||||
|
||||
#Remove updates by Title
|
||||
Write-Host "Searching for unneeded updates by Title. This process can take a long time. Please wait." -BackgroundColor White -ForegroundColor Blue
|
||||
$declinedTotal += RemoveUpdates $titles 'Title'
|
||||
$declinedTotal += RemoveUpdates $titles 'Title'
|
||||
|
||||
#Remove updates by ProductTitles
|
||||
Write-Host "Searching for unneeded updates by ProductTitle. This process can take a long time. Please wait." -BackgroundColor White -ForegroundColor Blue
|
||||
@@ -802,7 +802,7 @@ function Disable-Drivers {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Disable WSUS device driver syncronization and caching.
|
||||
|
||||
|
||||
.DESCRIPTION
|
||||
Disable WSUS device driver syncronization and caching. Automatic driver sychronization is one of the primary causes of WSUS slowness, crashing, and wasted storage space.
|
||||
|
||||
@@ -811,17 +811,16 @@ function Disable-Drivers {
|
||||
#>
|
||||
|
||||
Get-WsusClassification | Where-Object -FilterScript {$_.Classification.Title -Eq "Drivers"} | Set-WsusClassification -Disable
|
||||
Get-WsusClassification | Where-Object -FilterScript {$_.Classification.Title -Eq "Driver Sets"} | Set-WsusClassification -Disable
|
||||
Get-WsusClassification | Where-Object -FilterScript {$_.Classification.Title -Eq "Driver Sets"} | Set-WsusClassification -Disable
|
||||
}
|
||||
|
||||
|
||||
#-----------------------------------------------------------[Execution]------------------------------------------------------------
|
||||
|
||||
# Check commandline parameters.
|
||||
switch($true) {
|
||||
($FirstRun) {
|
||||
Write-Host "All of the following processes are highly recommended!" -ForegroundColor Blue -BackgroundColor White
|
||||
|
||||
|
||||
switch($true) {
|
||||
(Confirm-Prompt "Run WSUS IIS configuration optimization?") {
|
||||
$wsusIISConfig = Get-WsusIISConfig
|
||||
|
||||
Reference in New Issue
Block a user