Windows Server Update Services (WSUS) — сервис обновлений операционных систем и продуктов Microsoft. Программа бесплатно может быть скачана с сайта Microsoft и установлена на серверную ОС семейства Windows Server. Сервер обновлений синхронизируется с сайтом Microsoft, скачивая обновления, которые могут быть распространены внутри корпоративной локальной сети. Это экономит внешний трафик компании и позволяет быстрее устанавливать исправления ошибок и уязвимостей в операционных системах Windows на рабочих местах, а также позволяет централизованно управлять обновлениями серверов и рабочих станций.
Очистка базы
Если база WSUS разрослась и отъела всё свободное пространство или же просто WSUS стал дико тормозить.
- Пробуем запустить «Мастер очистки сервера» из консоли управления WSUS.
Если это не помогает, надо выполнить очистку напрямую в базе. Для этого необходимо подключиться к экземпляру SQL Server инструментом Management Studio. Management Studio стала отдельным продуктом. Его можно скачать по этой ссылке:
- Подключаемся к экземпляру базы, для подключения используется строка:
\\.\pipe\MICROSOFT##WID\tsql\query
Экземпляр SQL базы не обязательно будет иметь такое имя, параметры можно посмотреть:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Update Services\Server\Setup
параметр SqlServerName.
Management Studio запускается исключительно от имени администратора, в противном случае к экземпляру базы подключиться не удастся. Выполняем команды:
EXEC SUSDB.dbo.spDeclineExpiredUpdates;1
EXEC SUSDB.dbo.spDeclineSupersededUpdates;1
Для команды spCompressUpdate используется «обёртка»:
USE SUSDB
DECLARE @var1 INT, @curitem INT, @totaltodelete INT
DECLARE @msg nvarchar(200)
CREATE TABLE #results (Col1 INT) INSERT INTO #results(Col1)
EXEC spGetUpdatesToCompress
SET @totaltodelete = (SELECT COUNT(*) FROM #results)
SELECT @curitem=1
DECLARE WC Cursor FOR SELECT Col1 FROM #results
OPEN WC
FETCH NEXT FROM WC INTO @var1 WHILE (@@FETCH_STATUS > -1)
BEGIN SET @msg = cast(@curitem as varchar(5)) + '/' + cast(@totaltodelete as varchar(5)) + ': Compressing ' + CONVERT(varchar(10), @var1) + ' ' + cast(getdate() as varchar(30))
RAISERROR(@msg,0,1) WITH NOWAIT
EXEC spCompressUpdate @localUpdateID=@var1
SET @curitem = @curitem +1
FETCH NEXT FROM WC INTO @var1
END
CLOSE WC
DEALLOCATE WC
DROP TABLE #results
Такая же обертка для spDeleteUpdate:
USE SUSDB
DECLARE @var1 INT, @curitem INT, @totaltodelete INT
DECLARE @msg nvarchar(200)
CREATE TABLE #results (Col1 INT) INSERT INTO #results(Col1)
EXEC spGetObsoleteUpdatesToCleanup
SET @totaltodelete = (SELECT COUNT(*) FROM #results)
SELECT @curitem=1
DECLARE WC Cursor FOR SELECT Col1 FROM #results
OPEN WC
FETCH NEXT FROM WC INTO @var1 WHILE (@@FETCH_STATUS > -1)
BEGIN SET @msg = cast(@curitem as varchar(5)) + '/' + cast(@totaltodelete as varchar(5)) + ': Deleting ' + CONVERT(varchar(10), @var1) + ' ' + cast(getdate() as varchar(30))
RAISERROR(@msg,0,1) WITH NOWAIT
EXEC spDeleteUpdate @localUpdateID=@var1
SET @curitem = @curitem +1
FETCH NEXT FROM WC INTO @var1
END
CLOSE WC
DEALLOCATE WC
DROP TABLE #results
Во время работы «обёрток» клиенты прекращают получать обновления. Можно в любой момент прервать выполнение скрипта без потери прогресса. Для того, чтобы продолжить процесс, необхзодимо удалить временную таблицу:
DROP TABLE #results
Команду «Delete computers not contacting server» следует выполнить из мастера при необходимости.
Переиндексация базы
Для переиндексации базы используйте следующий скрипт:
/******************************************************************************
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
SET NOCOUNT ON;
-- 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;
DECLARE @schemaname nvarchar(130);
DECLARE @objectname nvarchar(130);
DECLARE @indexname nvarchar(130);
DECLARE @numrows int
DECLARE @density float;
DECLARE @fragmentation float;
DECLARE @command nvarchar(4000);
DECLARE @fillfactorset bit
DECLARE @numpages int
-- Select indexes that need to be defragmented based on the following
-- * Page density is low
-- * External fragmentation is high in relation to index size
PRINT 'Estimating fragmentation: Begin. ' + convert(nvarchar, getdate(), 121)
INSERT @work_to_do
SELECT
f.object_id
, index_id
, avg_page_space_used_in_percent
, avg_fragmentation_in_percent
, record_count
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)
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)
PRINT 'Number of indexes to rebuild: ' + cast(@@ROWCOUNT as nvarchar(20))
PRINT 'Estimating fragmentation: End. ' + convert(nvarchar, getdate(), 121)
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
-- Declare the cursor for the list of indexes to be processed.
DECLARE curIndexes CURSOR FOR SELECT * FROM @work_to_do
-- Open the cursor.
OPEN curIndexes
-- Loop through the indexes
WHILE (1=1)
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)
FROM
sys.objects AS o
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
FROM
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;
EXEC (@command);
PRINT convert(nvarchar, getdate(), 121) + N' Done.';
END
-- Close and deallocate the cursor.
CLOSE curIndexes;
DEALLOCATE curIndexes;
IF EXISTS (SELECT * FROM @work_to_do)
BEGIN
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
PRINT 'Estimated number of pages freed: ' + cast(@numpages as nvarchar(20))
END
GO
--Update all statistics
PRINT 'Updating all statistics.' + convert(nvarchar, getdate(), 121)
EXEC sp_updatestats
PRINT 'Done updating statistics.' + convert(nvarchar, getdate(), 121)
GO
После всех операций, проверяем свободное место на диске, при необходимости заново запускаем «Мастер очистки сервера».
После проделанных операций и запуска «Мастер очистки сервера» удалось очистить ~460 Гб из 2 Тб.
Настройка TempDB
Microsoft рекомендует:
Как правило, если число логических процессоров меньше или равно восьми (8),
используйте одинаковое количество файлов данных в качестве логических процессоров.
Если число логических процессоров больше восьми (8), используйте восемь файлов данных.
Если это не так, число файлов данных увеличивается на 4 (4) до числа логических
процессоров до тех пор, пока не будет снижено до приемлемых уровней. Кроме того,
внести изменения в рабочие нагрузки или код.
Я останавился на четырех файлах. Начальный размер файлов должен быть одинаковым. Значения Autogrowth выставляем не по 1Мб, а хотя бы по 10Мб.
Работа с машинами через wuauclt
Сбросить регистрацию компа на wsus и запустить поиск обновлений:
wuauclt.exe /resetauthorization /detectnow
Работа с машинами через usoclient
Windows 10 и Windows 2016 wuauclt более не имеет эффекта на работу Windows Update. Новый инструмент управлением загрузкой обновлений называется usoclient — «Update Session Orchestrator».
Базово достаточно указать:
usoclient.exe StartScan
Урвоень адвансед
Параметры которые воспринимает usoclient:
- StartScan Базовая команда
- StartDownload Команда загрузит обновления
- ScanInstallWait Эта команда найдёт и загрузит, но не установит обновления. Может примениться не сразу.
- StartInstall Команда установит обновления
- ResumeUpdatev Возобновляет установку обновлений при загрузке машины.
- RefreshSettings Обновляет настройки, чтобы увидеть, были ли внесены какие-либо изменения.
- RestartDevice Перезагружает компьютер, чтобы завершить установку обновлений — однако эта команда могла быть отключена в самых последних (1803 и более поздних) версиях Windows.
- StartInteractiveScan Запускает сканирование — похоже, ведет себя так же, как StartScan
Адвансед турбо про уровень
Ещё один из способов:
powershell (New-Object -ComObject Microsoft.Update.AutoUpdate).DetectNow()