我正在构建一个脚本,它将使用Windows Update自动查找,下载和安装更新。
我正在使用此代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WUApiLib;
namespace update_script
{
class Program
{
static void Main(string[] args)
{
UpdatesAvailable();
EnableUpdateServices();//enables everything windows need in order to make an update
InstallUpdates(DownloadUpdates());
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
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");
//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 UpdateCollection DownloadUpdates()
{
UpdateSession UpdateSession = new UpdateSession();
IUpdateSearcher SearchUpdates = UpdateSession.CreateUpdateSearcher();
ISearchResult UpdateSearchResult = SearchUpdates.Search("IsInstalled=0 and IsPresent=0");
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)
{
try
{
Updates.AcceptEula();
}
catch (Exception)
{
// Write a line to tell the user that an error occured with accepting this Eula
Console.WriteLine("Det oppsto en feil under akseptering av en Eula");
}
}
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.
UpdateCollection DownloadCollection = new UpdateCollection();
UpdateDownloader Downloader = UpdateSession.CreateUpdateDownloader();
for (int i = 0; i < UpdateCollection.Count; i++)
{
DownloadCollection.Add(UpdateCollection[i]);
}
// Define outside try-catch statement
UpdateCollection InstallCollection = new UpdateCollection();
try
{
Downloader.Updates = DownloadCollection;
Console.WriteLine("Downloading Updates");
IDownloadResult DownloadResult = Downloader.Download();
for (int i = 0; i < UpdateCollection.Count; i++)
{
if (DownloadCollection[i].IsDownloaded)
{
InstallCollection.Add(DownloadCollection[i]);
}
}
}
catch (Exception)
{
// Error occured, tell the user
Console.WriteLine("An error occurred while downloading the updates. Please reboot and try again.");
}
return InstallCollection;
}
public static void InstallUpdates(UpdateCollection DownloadedUpdates)
{
try
{
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
IInstallationResult InstallResult = InstallAgent.Install();
Console.WriteLine("install block over");
// Check if a reboot is required
if (InstallAgent.RebootRequiredBeforeInstallation)
{
// Reboot
Console.WriteLine("Reboot required");
}
}
catch (Exception)
{
// An error occured
Console.WriteLine("An error occured while trying to install the updates. Try again but remember to run as administrator");
}
}
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");
}
}
}
}
我认为它第一次运行时运行良好,但它第二次引发了异常。
以管理员身份运行时,会发生此错误:
此外,这样的脚本是否需要以管理员身份运行?
感谢您的帮助! 埃里克
答案 0 :(得分:0)
我使用以下VBscript:
Set updateSession = CreateObject("Microsoft.Update.Session")
Set updateSearcher = updateSession.CreateupdateSearcher()
WScript.Echo "Searching for updates..." & vbCRLF
Set searchResult = updateSearcher.Search("IsInstalled=0 and Type='Software'")
If searchResult.Updates.Count > 0 Then
WScript.Echo "List of applicable items on the machine:"
For I = 0 To searchResult.Updates.Count-1
Set update = searchResult.Updates.Item(I)
WScript.Echo I + 1 & "> " & update.Title
Next
WScript.Echo vbCRLF & "Creating collection of updates to download:"
Set updatesToDownload = CreateObject("Microsoft.Update.UpdateColl")
For I = 0 to searchResult.Updates.Count-1
Set update = searchResult.Updates.Item(I)
WScript.Echo I + 1 & "> adding: " & update.Title
updatesToDownload.Add(update)
Next
WScript.Echo vbCRLF & "Downloading updates..."
Set downloader = updateSession.CreateUpdateDownloader()
downloader.Updates = updatesToDownload
downloader.Download()
WScript.Echo vbCRLF & "List of downloaded updates:"
For I = 0 To searchResult.Updates.Count-1
Set update = searchResult.Updates.Item(I)
If update.IsDownloaded Then
WScript.Echo I + 1 & "> " & update.Title
End If
Next
Set updatesToInstall = CreateObject("Microsoft.Update.UpdateColl")
WScript.Echo vbCRLF & _
"Creating collection of downloaded updates to install:"
For I = 0 To searchResult.Updates.Count-1
set update = searchResult.Updates.Item(I)
If update.IsDownloaded = true Then
WScript.Echo I + 1 & "> adding: " & update.Title
updatesToInstall.Add(update)
End If
Next
WScript.Echo "Installing updates..."
Set installer = updateSession.CreateUpdateInstaller()
installer.Updates = updatesToInstall
Set installationResult = installer.Install()
'Output results of install
WScript.Echo "Installation Result: " & installationResult.ResultCode
WScript.Echo "Reboot Required: " & installationResult.RebootRequired & vbCRLF
WScript.Echo "Listing of updates installed and individual installation results:"
For I = 0 to updatesToInstall.Count - 1
WScript.Echo I + 1 & "> " & updatesToInstall.Item(i).Title & ": " & _
installationResult.GetUpdateResult(i).ResultCode
Next
If installationResult.RebootRequired = True Then
Reboot(".")
End If
Else
WScript.Echo "There are no applicable updates."
End If
WScript.Quit
Function Reboot(StrSrv)
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate,authenticationLevel=Pkt,(Shutdown)}!\\" & StrSrv & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem",,48)
For Each objItem In colItems
WScript.Echo objitem.Reboot
Next
End Function
我使用以下包装器并安排它每周运行一次。我最近为Windows 10修改了它,它现在启用/禁用Windows Update服务以在脚本未运行时限制更新。我喜欢在发生问题时保留更新日志。
D:
cd \WindowsUpdate
REM ************************************************************
REM ***
REM *** Enable Windows Update Service
REM ***
REM ************************************************************
sc config wuauserv start=demand
REM ************************************************************
REM ***
REM *** Generate Date/Time string for Log File
REM ***
REM ************************************************************
IF "%time:~0,1%" == " " (
set time_stamp=[%date:~-4%-%date:~4,2%-%date:~7,2%@0%time:~1,1%.%time:~3,2%.%time:~6,2%]
) ELSE (
set time_stamp=[%date:~-4%-%date:~4,2%-%date:~7,2%@%time:~0,2%.%time:~3,2%.%time:~6,2%]
)
REM ************************************************************
REM ***
REM *** Handle any file settings
REM ***
REM ************************************************************
Set LOG=D:\WindowsUpdate\Logs\Update%time_stamp%.LOG
REM ************************************************************
REM ***
REM *** Execute the WindowsUpdate Check
REM ***
REM ************************************************************
cscript WindowsUpdate.vbs >%LOG%
REM ************************************************************
REM ***
REM *** Disable Windows Update Service
REM ***
REM ************************************************************
sc config wuauserv start=disabled
REM ************************************************************
REM ***
REM *** End of script
REM ***
REM ************************************************************