Publishing Updates

 

Applies To: Windows Server Update Services

After you have written the update metadata, you need to publish the package, that is, import the update (binary plus metadata) into the server in order to allow it to be deployed to clients. This section describes how to publish a new package. To make revisions to a package, see the topic Revising and Versioning Updates.

Publishing will fail if a signing certificate has not been installed yet on the server and trust not bootstrapped. For more information, see the topic Setting Up the Trust Relationship.

This procedure explains how to use the WSUS API for local publishing of updates and applications.

To use the WSUS API for local publishing

  1. Use the SoftwareDistributionPackage class to author a package. The PopulatePackageFrom*() methods allow one to quickly set correct defaults for various package types, such as MSI, MSP, and EXE.

  2. Use the IPublisher interface to publish the package to the WSUS server.

  3. When the package is published, it can be approved and reports can be generated using the same APIs used for updates on Microsoft Update (for example, Approve).

Example

Publishing an MSP package

The following example shows how to publish a Windows Installer Patch (.msp) package.

IUpdateServer wsus = AdminProxy.GetUpdateServer();  
SoftwareDistributionPackage sdp = new SoftwareDistributionPackage();  
sdp.PopulatePackageFromWindowsInstallerPatch("C:\\PackageDir\\setup.msp");  
sdp.Title = "MSP Package";  
sdp.Description = "MSP Package Description";  
string sdpFilePath = Environment.GetEnvironmentVariable("TEMP") + "\\" + sdp.Title + sdp.PackageId.ToString();  
sdp.Save(sdpFilePath);  
IPublisher publisher = wsus.GetPublisher(sdpFilePath);  
FileInfo dir = new FileInfo(("C:\\PackageDir\\setup.msp");  
publisher.PublishPackage(dir.Directory.ToString, null);  
Publishing an MSI package

The steps for publishing Windows Installer (.msi) package or exe are similar to those for publishing an MSP patch, with the following differences:

MSI:

Call PopulatePackageFromWindowsInstaller, rather than PopulatePackageFromWindowsInstallerPatch, for initial package population.

Make sure to create a proper IsInstallable rule to check whether the MSI is installable on a given platform (e.g., on Windows Vista only).

IUpdateServer wsus = AdminProxy.GetUpdateServer();  
SoftwareDistributionPackage sdp = new SoftwareDistributionPackage();  
sdp.PopulatePackageFromWindowsInstaller("C:\\PackageDir\\setup.msi");  
sdp.Title = "MSI Package";  
sdp.Description = "MSI Package Description";  
//Look for Windows Vista  
sdp.IsInstallable = "<bar:WindowsVersion Comparison='GreaterThanOrEqualTo' MajorVersion='6' MinorVersion='0' />";  
string sdpFilePath = Environment.GetEnvironmentVariable("TEMP") + "\\" + sdp.Title + sdp.PackageId.ToString();  
sdp.Save(sdpFilePath);  
IPublisher publisher = wsus.GetPublisher(sdpFilePath);  
FileInfo dir = new FileInfo("C:\\PackageDir\\setup.msi");  
publisher.PublishPackage(dir.Directory.ToString(), null);  

Exe:

Call PopulatePackageFromExe, rather than PopulatePackageFromWindowsInstallerPatch, for initial package population.

Make sure to create a proper IsInstallable rule to check whether the executable is installable on a given machine (for example., if the exe can only be installed on Vista machines). Make sure to create a proper InstallableItems[0].IsInstalledApplicabilityRule rule to check if the exe is already installed on a given machine. We recommend file-based checks.

Make sure to set InstallCommandLine to the right set of flags to support a silent install (if you need the install to be automated). If this can’t be done, make sure to set InstallableItems[0].InstallBehavior.CanRequestUserInput to true.

Make sure to set InstallableItems[0].ReturnCodes (and DefaultResult and RebootByDefault) with values sufficient to allow the Windows Update agent to interpret the exit code of the exe.

IUpdateServer wsus = AdminProxy.GetUpdateServer();  
SoftwareDistributionPackage sdp = new SoftwareDistributionPackage();  
sdp.PopulatePackageFromExe("C:\\PackageDir\\setup.exe");  
sdp.Title = "Exe Package";  
sdp.Description = "Exe Package Description";  
sdp.IsInstallable = "<bar:WindowsVersion Comparison='GreaterThanOrEqualTo' MajorVersion='6' MinorVersion='0' />";  
CommandLineItem item = new CommandLineItem();  
item.IsInstalledApplicabilityRule = "<bar:FileExists Path='%windir%\\sample.dll' Version='1.0.0.1' />";  
  
// Add Property CommandLineExecutableName  
item.CommandLineExecutableName = "C:\\PackageDir\\setup.exe";  
ReturnCode codeSuccess = new ReturnCode();  
codeSuccess.InstallationResult = InstallationResult.Succeeded;  
codeSuccess.ReturnCodeValue = 0;  
ReturnCode codeFail = new ReturnCode();  
codeFail.InstallationResult = InstallationResult.Failed;  
codeFail.ReturnCodeValue = -1;  
item.ReturnCodes.Add(codeSuccess);  
item.ReturnCodes.Add(codeFail);  
item.DefaultResult = InstallationResult.Failed;  
item.RebootByDefault = false;  
  
//Set SDP File InstallableItem  
sdp.InstallableItems[0] = item;  
string sdpFilePath = Environment.GetEnvironmentVariable("TEMP") + "\\" + sdp.Title + sdp.PackageId.ToString();  
sdp.Save(sdpFilePath);  
IPublisher publisher = wsus.GetPublisher(sdpFilePath);  
FileInfo dir = new FileInfo("C:\\PackageDir\\setup.exe");  
publisher.PublishPackage(dir.Directory.ToString(), null);