#c# #windows-update
#c# #центр обновления Windows
Вопрос:
Я хочу искать обновления в wsus или локальной папке вместо Microsoft. Есть идеи? Вот что у меня есть, но это подключается только к обновлениям Windows через Интернет.
Обновить
Я УЗНАЛ ОТВЕТ С ПОМОЩЬЮ скрипта VBS. Сервер ssdefault устанавливается групповой политикой. Итак, если я применю групповую политику к АВП, я смогу выполнять автоматические обновления на основе WSUS. Для выполнения шагов групповой политики перейдите к: http://technet.microsoft.com/en-us/library/cc512630.aspx Убедитесь, что параметр указать местоположение службы интрасети указывает на ваш сервер wsus. В нашем случае это было http://wsus как для статистики, так и для службы обновлений.Вы также должны включить автоматические обновления, как описано в статье.
Если вы собираетесь использовать приведенный ниже код c #, обязательно измените UpdateSearchResult.Online = false; если ypu хочет искать WSUS вместо Online.Спасибо всем, кто, возможно, пытался ответить на этот вопрос.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WUApiLib;//this is required to use the Interfaces given by microsoft.
//todo check isassigned and guids for the following and include them in the search.
//http://msdn.microsoft.com/en-us/library/ff357803(VS.85).aspx
//determine the size of the update in mb
namespace MSHWindowsUpdateAgent
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Analyzing your needs");
UpdatesAvailable();
if (NeedsUpdate())
{
EnableUpdateServices();//enables everything windows need in order to make an update
InstallUpdates(DownloadUpdates());
}
else
{
Console.WriteLine("There are no updates for your computer at this time.");
}
Console.WriteLine("Press any key to finalize the process");
Console.Read();
}
//this is my first try.. I can see the need for abstract classes here...
//but at least it gives most people a good starting point.
public static void InstalledUpdates()
{
UpdateSession UpdateSession = new UpdateSession();
IUpdateSearcher UpdateSearchResult = UpdateSession.CreateUpdateSearcher();
UpdateSearchResult.Online = true;//checks for updates online
ISearchResult SearchResults = UpdateSearchResult.Search("IsInstalled=1 AND IsHidden=0");
//for the above search criteria refer to
//http://msdn.microsoft.com/en-us/library/windows/desktop/aa386526(v=VS.85).aspx
//Check the remakrs section
Console.WriteLine("The following updates are available");
foreach (IUpdate x in SearchResults.Updates)
{
Console.WriteLine(x.Title);
}
}
public static void UpdatesAvailable()
{
UpdateSession UpdateSession = new UpdateSession();
IUpdateSearcher UpdateSearchResult = UpdateSession.CreateUpdateSearcher();
UpdateSearchResult.Online = true;//checks for updates online
ISearchResult SearchResults = UpdateSearchResult.Search(
"IsInstalled=0 AND IsPresent=0 and IsAssigned=1 AND CategoryIDs contains 'E6CF1350-C01B-414D-A61F-263D14D133B4' OR CategoryIDs contains '0FA1201D-4330-4FA8-8AE9-B877473B6441' ");
//for the above search criteria refer to
//http://msdn.microsoft.com/en-us/library/windows/desktop/aa386526(v=VS.85).aspx
//Check the remakrs section
foreach (IUpdate x in SearchResults.Updates)
{
Console.WriteLine(x.Title);
}
}
public static bool NeedsUpdate()
{
UpdateSession UpdateSession = new UpdateSession();
IUpdateSearcher UpdateSearchResult = UpdateSession.CreateUpdateSearcher();
UpdateSearchResult.Online = true;//checks for updates online
ISearchResult SearchResults = UpdateSearchResult.Search("IsInstalled=0 AND IsPresent=0 and IsAssigned=1 AND CategoryIDs contains 'E6CF1350-C01B-414D-A61F-263D14D133B4' OR CategoryIDs contains '0FA1201D-4330-4FA8-8AE9-B877473B6441'");
//for the above search criteria refer to
//http://msdn.microsoft.com/en-us/library/windows/desktop/aa386526(v=VS.85).aspx
//Check the remakrs section
if (SearchResults.Updates.Count > 0)
return true;
else return false;
}
public static UpdateCollection DownloadUpdates()
{
UpdateSession UpdateSession = new UpdateSession();
IUpdateSearcher SearchUpdates = UpdateSession.CreateUpdateSearcher();
ISearchResult UpdateSearchResult = SearchUpdates.Search("IsInstalled=0 AND IsPresent=0 and IsAssigned=1 AND CategoryIDs contains 'E6CF1350-C01B-414D-A61F-263D14D133B4' OR CategoryIDs contains '0FA1201D-4330-4FA8-8AE9-B877473B6441'");
UpdateCollection UpdateCollection = new UpdateCollection();
//Accept Eula code for each update
for (int i = 0; i < UpdateSearchResult.Updates.Count; i )
{
IUpdate Updates = UpdateSearchResult.Updates[i];
if (Updates.EulaAccepted == false)
{
Updates.AcceptEula();
}
UpdateCollection.Add(Updates);
}
//Accept Eula ends here
//if it is zero i am not sure if it will trow an exception -- I havent tested it.
if (UpdateSearchResult.Updates.Count > 0)
{
UpdateCollection DownloadCollection = new UpdateCollection();
UpdateDownloader Downloader = UpdateSession.CreateUpdateDownloader();
for (int i = 0; i < UpdateCollection.Count; i )
{
DownloadCollection.Add(UpdateCollection[i]);
}
Downloader.Updates = DownloadCollection;
Console.WriteLine("Downloading Updates... This may take several minutes.");
IDownloadResult DownloadResult = Downloader.Download();
UpdateCollection InstallCollection = new UpdateCollection();
for (int i = 0; i < UpdateCollection.Count; i )
{
if (DownloadCollection[i].IsDownloaded)
{
InstallCollection.Add(DownloadCollection[i]);
}
}
Console.WriteLine("Download Finished");
return InstallCollection;
}
else
return UpdateCollection;
}
public static void InstallUpdates(UpdateCollection DownloadedUpdates)
{
Console.WriteLine("Installing updates now...");
UpdateSession UpdateSession = new UpdateSession();
UpdateInstaller InstallAgent = UpdateSession.CreateUpdateInstaller() as UpdateInstaller;
InstallAgent.Updates = DownloadedUpdates;
//Starts a synchronous installation of the updates.
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa386491(v=VS.85).aspx#methods
if (DownloadedUpdates.Count > 0)
{
IInstallationResult InstallResult = InstallAgent.Install();
if (InstallResult.ResultCode == OperationResultCode.orcSucceeded)
{
Console.WriteLine("Updates installed succesfully");
if (InstallResult.RebootRequired == true)
{
Console.WriteLine("Reboot is required for one of more updates.");
}
}
else
{
Console.WriteLine("Updates failed to install do it manually");
}
}
else
{
Console.WriteLine("The computer that this script was executed is up to date");
}
}
public static void EnableUpdateServices()
{
IAutomaticUpdates updates = new AutomaticUpdates();
if (!updates.ServiceEnabled)
{
Console.WriteLine("Not all updates services where enabled. Enabling Now" updates.ServiceEnabled);
updates.EnableService();
Console.WriteLine("Service enable success");
}
}
}
}
Запуск следующего скрипта помогает мне определить конфигурацию WUA
'---------------------START-----------------------
' Einstellungen für die automatischen Updates
' http://www.wsus.de/
' Version 1.05.04.1
' Translated quick and dirty into English Marco Biagini
' mbiagini@ehsd.cccounty.us
'--------------------------------------------
On Error Resume Next
Set objWshNet = CreateObject("Wscript.Network")
const HKCU = amp;H80000001
const HKLM = amp;H80000002
strDefComputer = lcase(objWshNet.ComputerName)
Set oArgs = WScript.Arguments
If oArgs.Count = 0 Then
strComputer = InputBox("Please enter the name or IP address of the Computer that you want to check WSUS settings", "Automatic Updates", strDefComputer)
Else
strComputer = oArgs(0)
End If
If strComputer = "" Then
WScript.Quit
End if
strComputer = lcase(strComputer)
if left(strComputer,2)="\" then
strComputer=right(strComputer,(len(strComputer)-2))
end if
Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\" amp; strComputer amp; "rootdefault:StdRegProv")
If Err.Number <> 0 Then
msgbox "Unable to connect to:" amp; VBCRLF amp; VBCRLF amp; " " amp; strComputer amp; VBCRLF, vbCritical, "Communication Error"
WScript.Quit
End If
Resultmsg = "**** Results of WUA Settings ****" amp; VBCRLF amp; VBCRLF
strMsg = "No Auto Update: "
strKeyPath = "SoftwarePoliciesMicrosoftWindowsWindowsUpdateAU"
strValueName = "NoAutoUpdate"
If RegValueExists(strKeyPath, strValueName) Then
oReg.GetDWORDValue HKLM,strKeyPath,strValueName,dwValue
Resultmsg = Resultmsg amp; strMsg amp; GetNoAutoUpdate(dwValue) amp; VBCRLF amp; VBCRLF
Else
Resultmsg = Resultmsg amp; strMsg amp; "Automatic Updates are not configured" amp; VBCRLF amp; VBCRLF
End If
strMsg = "Use WU Server: "
strKeyPath = "SoftwarePoliciesMicrosoftWindowsWindowsUpdateAU"
strValueName = "UseWUServer"
If RegValueExists(strKeyPath, strValueName) Then
oReg.GetDWORDValue HKLM,strKeyPath,strValueName,dwValue
Resultmsg = Resultmsg amp; strMsg amp; GetUseWUServer(dwValue) amp; VBCRLF
If dwValue = "1" Then
strMsg = " - WSUS Server: "
strKeyPath = "SoftwarePoliciesMicrosoftWindowsWindowsUpdate"
strValueName = "WUServer"
If RegValueExists(strKeyPath, strValueName) Then
oReg.GetStringValue HKLM,strKeyPath,strValueName,strValue
Resultmsg = Resultmsg amp; strMsg amp; strValue amp; VBCRLF
Else
Resultmsg = Resultmsg amp; strMsg amp; "Automatic Updates are not configured" amp; VBCRLF
End If
strMsg = " - WU Status Server: "
strKeyPath = "SoftwarePoliciesMicrosoftWindowsWindowsUpdate"
strValueName = "WUStatusServer"
If RegValueExists(strKeyPath, strValueName) Then
oReg.GetStringValue HKLM,strKeyPath,strValueName,strValue
Resultmsg = Resultmsg amp; strMsg amp; strValue amp; VBCRLF
Else
Resultmsg = Resultmsg amp; strMsg amp; "Automatic Updates are not configured" amp; VBCRLF
End If
Else
Resultmsg = Resultmsg amp; VBCRLF
End If
Else
Resultmsg = Resultmsg amp; strMsg amp; "Automatic Updates are not configured" amp; VBCRLF
Resultmsg = Resultmsg amp; " - Client configured to receive Updates from windowsupdate.microsoft.com" amp; VBCRLF
End If
strMsg = " - TargetGroup: "
strKeyPath = "SoftwarePoliciesMicrosoftWindowsWindowsUpdate"
strValueName = "TargetGroup"
If RegValueExists(strKeyPath, strValueName) Then
oReg.GetStringValue HKLM,strKeyPath,strValueName,strValue
Resultmsg = Resultmsg amp; strMsg amp; strValue amp; VBCRLF amp; VBCRLF
Else
Resultmsg = Resultmsg amp; strMsg amp; "Value not configured" amp; VBCRLF amp; VBCRLF
End If
strMsg = "AU Options: "
strKeyPath = "SoftwarePoliciesMicrosoftWindowsWindowsUpdateAU"
strValueName = "AUOptions"
If RegValueExists(strKeyPath, strValueName) Then
oReg.GetDWORDValue HKLM,strKeyPath,strValueName,dwValue
Resultmsg = Resultmsg amp; strMsg amp; GetAUOptions(dwValue) amp; VBCRLF
If dwValue = "4" Then
strMsg = " - Scheduled Install Day: "
strKeyPath = "SoftwarePoliciesMicrosoftWindowsWindowsUpdateAU"
strValueName = "ScheduledInstallDay"
If RegValueExists(strKeyPath, strValueName) Then
oReg.GetDWORDValue HKLM,strKeyPath,strValueName,dwValue
Resultmsg = Resultmsg amp; strMsg amp; getday(dwValue) amp; VBCRLF
Else
Resultmsg = Resultmsg amp; strMsg amp; "Value not configured" amp; VBCRLF
End If
strMsg = " - Planned Installation Time: "
strKeyPath = "SoftwarePoliciesMicrosoftWindowsWindowsUpdateAU"
strValueName = "ScheduledInstallTime"
If RegValueExists(strKeyPath, strValueName) Then
oReg.GetDWORDValue HKLM,strKeyPath,strValueName,dwValue
Resultmsg = Resultmsg amp; strMsg amp; dwValue amp;":00 - 24 hours 4:00 is 4 AM, 16:00 is 4 PM" amp; VBCRLF
Else
Resultmsg = Resultmsg amp; strMsg amp; "Value not configured" amp; VBCRLF
End If
Else
Resultmsg = Resultmsg amp; VBCRLF
End If
Else
Resultmsg = Resultmsg amp; strMsg amp; "Value is not configured" amp; VBCRLF
strMsg = " - Benutzerdefinierte Einstellung: "
strKeyPath = "SoftwareMicrosoftWindowsCurrentVersionWindowsUpdateAuto Update"
strValueName = "AUOptions"
If RegValueExists(strKeyPath, strValueName) Then
oReg.GetDWORDValue HKLM,strKeyPath,strValueName,dwValue
Resultmsg = Resultmsg amp; strMsg amp; GetAUOptions(dwValue) amp; VBCRLF
If dwValue = "4" Then
strMsg = " - ScheduledInstallDay: "
strKeyPath = "SoftwareMicrosoftWindowsCurrentVersionWindowsUpdateAuto Update"
strValueName = "ScheduledInstallDay"
If RegValueExists(strKeyPath, strValueName) Then
oReg.GetDWORDValue HKLM,strKeyPath,strValueName,dwValue
Resultmsg = Resultmsg amp; strMsg amp; getday(dwValue) amp; VBCRLF
Else
Resultmsg = Resultmsg amp; strMsg amp; "Automatic Updates are not configured" amp; VBCRLF
End If
strMsg = " - ScheduledInstallTime: "
strKeyPath = "SoftwareMicrosoftWindowsCurrentVersionWindowsUpdateAuto Update"
strValueName = "ScheduledInstallTime"
If RegValueExists(strKeyPath, strValueName) Then
oReg.GetDWORDValue HKLM,strKeyPath,strValueName,dwValue
Resultmsg = Resultmsg amp; strMsg amp; dwValue amp;":00" amp; VBCRLF
Else
Resultmsg = Resultmsg amp; strMsg amp; "Automatic Updates are not configured" amp; VBCRLF
End If
Else
Resultmsg = Resultmsg amp; VBCRLF
End If
Else
Resultmsg = Resultmsg amp; strMsg amp; "Not configured" amp; VBCRLF
End If
End If
strMsg = " - NoAUShutdownOption: "
strKeyPath = "SoftwarePoliciesMicrosoftWindowsWindowsUpdateAU"
strValueName = "NoAUShutdownOption"
If RegValueExists(strKeyPath, strValueName) Then
oReg.GetDWORDValue HKLM,strKeyPath,strValueName,dwValue
Resultmsg = Resultmsg amp; strMsg amp; GetNoAUShutdownOption(dwValue) amp; VBCRLF amp; VBCRLF
Else
Resultmsg = Resultmsg amp; strMsg amp; "Value not configured" amp; VBCRLF amp; VBCRLF
End If
strMsg = "AutoInstallMinorUpdates: "
strKeyPath = "SoftwarePoliciesMicrosoftWindowsWindowsUpdateAU"
strValueName = "AutoInstallMinorUpdates"
If RegValueExists(strKeyPath, strValueName) Then
oReg.GetDWORDValue HKLM,strKeyPath,strValueName,dwValue
Resultmsg = Resultmsg amp; strMsg amp; GetAutoInstallMinorUpdates(dwValue) amp; VBCRLF amp; VBCRLF
Else
Resultmsg = Resultmsg amp; strMsg amp; "Value is not configured" amp; VBCRLF amp; VBCRLF
End If
strMsg = "DetectionFrequency: "
strKeyPath = "SoftwarePoliciesMicrosoftWindowsWindowsUpdateAU"
strValueName = "DetectionFrequency"
If RegValueExists(strKeyPath, strValueName) Then
oReg.GetDWORDValue HKLM,strKeyPath,strValueName,dwValue
Resultmsg = Resultmsg amp; strMsg amp;"Every " amp; dwValue amp;" Hours to search for updates"amp; VBCRLF
Else
Resultmsg = Resultmsg amp; strMsg amp; "Value is not configured"amp; VBCRLF
End If
strMsg = "RebootRelaunchTimeout: "
strKeyPath = "SoftwarePoliciesMicrosoftWindowsWindowsUpdateAU"
strValueName = "RebootRelaunchTimeout"
If RegValueExists(strKeyPath, strValueName) Then
oReg.GetDWORDValue HKLM,strKeyPath,strValueName,dwValue
Resultmsg = Resultmsg amp; strMsg amp; dwValue amp;" Minutes to wait until system restart"amp; VBCRLF
Else
Resultmsg = Resultmsg amp; strMsg amp; "Value is not configured" amp; VBCRLF
End If
strMsg = "RebootWarningTimeout: "
strKeyPath = "SoftwarePoliciesMicrosoftWindowsWindowsUpdateAU"
strValueName = "RebootWarningTimeout"
If RegValueExists(strKeyPath, strValueName) Then
oReg.GetDWORDValue HKLM,strKeyPath,strValueName,dwValue
Resultmsg = Resultmsg amp; strMsg amp; dwValue amp;" Minutes wait until system restart"amp; VBCRLF
Else
Resultmsg = Resultmsg amp; strMsg amp; "Value not configured" amp; VBCRLF
End If
strMsg = "NoAutoRebootWithLoggedOnUsers: "
strKeyPath = "SoftwarePoliciesMicrosoftWindowsWindowsUpdateAU"
strValueName = "NoAutoRebootWithLoggedOnUsers"
If RegValueExists(strKeyPath, strValueName) Then
oReg.GetDWORDValue HKLM,strKeyPath,strValueName,dwValue
Resultmsg = Resultmsg amp; strMsg amp; GetNoAutoReboot(dwValue) amp; VBCRLF
Else
Resultmsg = Resultmsg amp; strMsg amp; "Value not configured" amp; VBCRLF
Resultmsg = Resultmsg amp; " - Default: User will be presented with a 5 minutes countdown" amp; VBCRLF
End If
strMsg = "RescheduleWaitTime: "
strKeyPath = "SoftwarePoliciesMicrosoftWindowsWindowsUpdateAU"
strValueName = "RescheduleWaitTime"
If RegValueExists(strKeyPath, strValueName) Then
oReg.GetDWORDValue HKLM,strKeyPath,strValueName,dwValue
If dwValue = "0" Then Resultmsg = Resultmsg amp; strMsg amp; "Value not configured: " amp; dwValue amp; VBCRLF amp; VBCRLF End If
If dwValue = "1" Then Resultmsg = Resultmsg amp; strMsg amp; dwValue amp;" Minute" amp; VBCRLF amp; VBCRLF End If
If dwValue > "1" and dwValue < "61" Then Resultmsg = Resultmsg amp; strMsg amp; dwValue amp;" Minutes" amp; VBCRLF amp; VBCRLF End If
If dwValue > "60" Then Resultmsg = Resultmsg amp; strMsg amp; "Invalid Value" amp; dwValue amp; VBCRLF amp; VBCRLF End If
Else
Resultmsg = Resultmsg amp; strMsg amp; "Not Configured" amp; VBCRLF amp; VBCRLF
End If
Resultmsg = Resultmsg amp; "http://www.wsus.de" amp; VBCRLF amp; "Die Infoseite zu Windows Server Updates Services"
MsgBox Resultmsg,,strComputer
set oReg = nothing
Function GetNoAutoUpdate(Index)
Select Case Index
Case 0 GetNoAutoUpdate = "0 - Auto Update applied by GPO"
Case 1 GetNoAutoUpdate = "1 - No Auto Update is applied by GPO"
Case Else GetNoAutoUpdate = "Invalid Entry"
End select
End Function
Function GetUseWUServer(Index)
Select Case Index
Case 0 GetUseWUServer = "0 - Client is configured to receive updates from windowsupdate.microsoft.com"
Case 1 GetUseWUServer = "1 - Client is configured to receive updates from your WSUS Server"
Case Else GetUseWUServer = "Invalid Entry"
End select
End Function
Function GetDay(Index)
Select Case Index
Case "0" GetDay = "Every Day"
Case "1" GetDay = "Every Sunday"
Case "2" GetDay = "Every Monday"
Case "3" GetDay = "Every Tuesday"
Case "4" GetDay = "Every Wednesday"
Case "5" GetDay = "Every Thursday"
Case "6" GetDay = "Every Friday"
Case "7" GetDay = "Every Saturday"
Case Else GetDay = "Invalid Entry"
End select
End Function
Function GetAUOptions(Index)
Select Case Index
Case "0" GetAUOptions = "0"
Case "1" GetAUOptions = "1 - Deaktiviert in den Benutzereinstellungen"
Case "2" GetAUOptions = "2 - Notify before download and Install."
Case "3" GetAUOptions = "3 - Autom. Download, notify before installation."
Case "4" GetAUOptions = "4 - Autom. Download, install according to GPO settings."
Case "5" GetAUOptions = "5 - Allow Local Administator installation and manual configuration."
case Else GetAUOptions = "Invalid Entry"
End select
End Function
Function GetNoAUShutdownOption(Index)
Select Case Index
Case 0 GetNoAUShutdownOption = "0 - 'Updates are being installed and system will be restarted' user ill be notified"
Case 1 GetNoAUShutdownOption = "1 - 'Updates are being installed and system will be restarted' user will NOT be notified"
Case Else GetNoAUShutdownOption = "Invalid Entry"
End select
End Function
Function GetAutoInstallMinorUpdates(Index)
Select Case Index
Case 0 GetAutoInstallMinorUpdates = "0 - Automatic updates are not immediately installed"
Case 1 GetAutoInstallMinorUpdates = "1 - Automatic updates are immediately installed"
Case Else GetAutoInstallMinorUpdates = "Invalid Entry"
End select
End Function
Function GetNoAutoReboot(Index)
Select Case Index
Case "0" GetNoAutoReboot = "0 - User Countdown of 5 Minutes"
Case "1" GetNoAutoReboot = "1 - User will be notified before a system restart"
case Else GetNoAutoReboot = "Invalid Entry"
End select
End Function
Function RegValueExists(sRegKey, sRegValue)
sRegKey = Trim(sRegKey)
sRegValue = LCase(Trim(sRegValue))
' init value
RegValueExists = False
If oReg.EnumValues(HKLM, sRegKey, aValueNames, aValueTypes) = 0 Then
If Not IsNull(aValueNames) Then
For i = 0 To UBound(aValueNames)
If LCase(aValueNames(i)) = sRegValue Then
RegValueExists = True
End If
Next
End If
End If
End Function
Function RegKeyExists(sRegKey)
sRegKey = Trim(sRegKey)
If oReg.EnumValues(HKLM, sRegKey, aValueNames, aValueTypes) = 0 Then
RegKeyExists = True
Else
RegKeyExists = False
End If
End Function
'---------------------END-----------------------
Комментарии:
1. Я только что обнаружил это: msdn.microsoft.com/en-us/library/windows/desktop /… но как мне настроить ssManagedServer? В настоящее время я работаю над этим.
2. Еще одна вещь, которую я только что обнаружил: когда я делаю: консоль. WriteLine(UpdateSearchResult. Выбор сервера. toString()); результат — ssDefault. Я обнаружил, что: ssDefault Используется только IUpdateSearcher. Указывает, что поисковый вызов должен выполнять поиск на сервере по умолчанию. Сервер по умолчанию, используемый агентом центра обновления Windows (WUA), такой же, как ssMangagedServer, если компьютер настроен на наличие управляемого сервера. Если компьютер не настроен на наличие управляемого сервера, WUA использует первую службу обновления, для которой свойству IsRegisteredWithAU IUpdateService присвоено значение true
3. Как получить все компьютеры (список), которые используют WUA — WSUS?
Ответ №1:
Я написал простое приложение на c #, которое извлекает все обновления с локального сервера с именем SRV1, используя его только в системах Windows 7. Он использует ASP.NET 3.5, который по умолчанию установлен Windows 7.
Просто измените SRV1 в исходном коде на свой локальный сервер wsus.
Исходный код можно найти здесь
Комментарии:
1. Я загрузил проект, но не увидел никакого кода, который подразумевал бы, что что-либо будет загружено из wsus.