Bypass version mismatch when publishing

Topics: Enhancement Request, Feature Request, Publishing Issue
May 31, 2016 at 8:18 PM
Hello,

I would like to propose some additional options for this utility.

I frequently use this tool from remote computers, and since upgrading to windows 10 on my workstation, I was no longer able to publish remotely due to version mismatch.

I have found a workaround to this, and it seems to work in my environment with no issues.

I have also found a method by which you can make published updates visible in the wsus console without direct database access.

I have linked an example solution which makes use of both of these workarounds HERE - https://www.sendspace.com/file/hzfn4b

Included below are the relevant bits from the provided solution in case the download link goes missing.
using System;
using System.IO;
using System.Reflection;
using System.Xml;
using System.Xml.Xsl;
using Microsoft.UpdateServices.Internal;
using Microsoft.UpdateServices.Internal.BaseApi;
using Microsoft.UpdateServices.Internal.DatabaseAccess;

namespace UpdateServicesNonLocalPublisher
{
    public class AdminDataAccessProxyProxy : AdminDataAccessProxy
    {
        private static readonly XslCompiledTransform removeLocallyPublishedTransform = new XslCompiledTransform();

        static AdminDataAccessProxyProxy()
        {
            removeLocallyPublishedTransform.Load("TranslateSusToNonLocalPublish.xslt");
        }

        public AdminDataAccessProxyProxy(UpdateServer updateServer) : base(updateServer)
        {
        }

        public override void ImportUpdateForPublishing(string susXml, string uspXml, ServerSyncUrlData[] urlData, bool sdpOnly)
        {
            using (var reader = XmlReader.Create(new StringReader(susXml)))
            {
                using (var output = new StringWriter())
                using (var writer = XmlWriter.Create(output))
                {
                    removeLocallyPublishedTransform.Transform(reader, writer);
                    susXml = output.ToString();
                }
            }

            base.ImportUpdateForPublishing(susXml, uspXml, urlData, sdpOnly);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var versionField = typeof(UpdateServer).GetField("version", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
            var adminDataAccessProxyTypeField = typeof(ClassFactory).GetField("adminDataAccessProxyType", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Static);

            // set DataAccessProxy to modify xml on the fly
            adminDataAccessProxyTypeField.SetValue(null, typeof(AdminDataAccessProxyProxy));

            // get update server
            var server = Microsoft.UpdateServices.Administration.AdminProxy.GetUpdateServer("wsus", true, 8531) as UpdateServer;

            // backup original version
            var origServerVersion = server.Version;

            // patch version, get publisher, restore original version
            versionField.SetValue(server, ProductVersion.Version);
            var publisher = server.GetPublisher(@"package.xml") as Publisher;
            versionField.SetValue(server, origServerVersion);

            // publish package
            publisher.PublishSignedPackage(@"package.cab", null);


            Console.ReadLine();
        }
    }
}
Below is the XML transform file: TranslateSusToNonLocalPublish.xslt
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:upd="http://schemas.microsoft.com/msus/2002/12/Update">
  <xsl:output encoding="utf-8" method="xml" indent="yes" />

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="upd:Update/upd:Properties/@IsLocallyPublished">
    <xsl:attribute name="IsLocallyPublished">false</xsl:attribute>
  </xsl:template>
</xsl:stylesheet>
the XML transform and AdminDataAccessProxyProxy class are for making published packages visible in the console. (Just be aware that if a category/product/vendor already exist in the database they do need to be manually made visible, or deleted first).

The versionField is for bypassing version mismatch errors.

These two features would be very nice to have (optional features of course), and when disabled would cause no risk.

Thanks,
Austin Morton