Printing to on-prem printers from Azure AD-joined devices


Since most of us have been using Active Directory for ages, you probably also take for granted the process for printing to your on-premises printers:  They are published to Active Directory, you can search for them, and you can easily connect to them.  But what happens when you join your devices to Azure AD instead?  As discussed in https://blogs.technet.microsoft.com/mniehaus/2018/02/21/afraid-of-windows-10-with-azure-ad-join-try-it-out-part-2/, you can certainly connect to a Windows Server (AD-joined) hosted print queue if you know its UNC path (authentication works via a Kerberos ticket).  But how do you discover that printer in the first place?  The low-tech approach is to label the printer with its UNC path, so you just walk up to it, read the UNC, and type it in.

Fortunately, we’ve released a higher-tech approach that solves two different problems:

  • Discovering Windows Server-hosted printers from Azure AD-joined devices
  • Printing to those printers from anywhere in the world

This solution is called Hybrid Cloud Printing because it connects those Azure AD-joined devices to your existing Active Directory-joined Windows Server printing infrastructure.  That was announced back in February via the Enterprise Mobility blog.  As you can probably guess from the diagram included in that blog, there are a few components in the solution:

First, some requirements:

  • Windows 10 1703 (Creators Update) or higher.
  • Windows Server 2016 on your print servers.
  • An Azure AD tenant.
  • Azure AD Connect, to synchronize your Active Directory with Azure AD.
  • An MDM service, e.g. Intune, to configure the print settings on each device.

Then, you need to set it up.  To make the connection from internet-facing Azure AD-joined devices to those on-prem Windows Server 2016-hosted services, Azure Application Proxy is used.  This makes an outbound connection to Azure, which is used to then allow inbound traffic to the published services.  There are two ways this can be set up:

  • Azure Active Directory pre-authentication, where Azure AD makes sure the user is authenticated before the traffic passes through the proxy.
  • Passthrough authentication, letting Windows Server authenticate the users via Kerberos.

Typically the first option is recommended, to support things like conditional access and multi-factor authentication.  I recommend sticking with that that recommendation, following the “five” steps at https://docs.microsoft.com/en-us/windows-server/administration/hybrid-cloud-print/hybrid-cloud-print-deploy:

  1. Install Azure AD Connect to sync between Azure AD and AD.  I covered that in https://blogs.technet.microsoft.com/mniehaus/2018/01/19/afraid-of-windows-10-with-azure-ad-join-try-it-out-part-1/.
  2. Install the Cloud Print package on the print server.
  3. Install the Azure Application Proxy.
  4. Configure the MDM policies.
  5. Publish desired shared printers.

Since each of those steps includes multiple sub-steps, it’s really more like a 20-25 step process.  And initially I walked through all of those steps – and it didn’t work at all.  Fortunately, one of the ConfigMgr/Intune MVPs, Sandy Yinghua, has a blog that documents how she did it.  I used those steps to verify my configuration and with that was able to get everything working.  I would note that I did things a little differently:

  • I didn’t use a custom internet URL (mcs.smsboot.com in her example) for the Azure App Proxy-published websites.  Instead, I used the generated msappproxy.net URLs because then I didn’t need additional certs.
  • I did get a public cert for my print server, so that I didn’t need to distribute a trusted root cert to the client machines when they talk to the print server via the Azure App Proxy.  Self-signed certs aren’t any fun (although Intune has no issues deploying them, so it wouldn’t be that bad).

But otherwise, my setup matches.  Here are the device configuration settings I configured in Intune:

What those look like in Intune:

image

And here are a few commands that I used as I was experimenting with the printer publishing process:

Publish a test printer

Publish-CloudPrinter -Printer EcpPrintTest -Manufacturer Microsoft -Model FilePrinterEcp -OrgLocation '{"attrs": [{"category":"country", "vs":"USA", "depth":0}, {"category":"organization", "vs":"AutoPilotRocks", "depth":1}, {"category":"site", "vs":"Redmond", "depth":2}, {"category":"building", "vs":"109", "depth":3}]}’ -Sddl "O:BAG:SYD:(A;;LCSWSDRCWDWO;;;S-1-5-21-501278528-1731656756-2472999879-1114)(A;OIIO;RPWPSDRCWDWO;;;S-1-5-21-501278528-1731656756-2472999879-1114)(A;OIIO;GA;;;CO)(A;OIIO;GA;;;AC)(A;;SWRC;;;WD)(A;CIIO;GX;;;WD)(A;;SWRC;;;AC)(A;CIIO;GX;;;AC)(A;;LCSWDTSDRCWDWO;;;BA)(A;OICIIO;GA;;;BA)" -DiscoveryEndpoint https://clouddiscoveryproxy-autopilotrocks.msappproxy.net/mcs -PrintServerEndpoint https://cloudprintproxy-autopilotrocks.msappproxy.net/ecp -AzureClientId 23772c3e-1a3b-4f28-86f9-ec614a53a776 -AzureTenantGuid 0b458c6e-97ce-4c7e-bc5e-1d29552989a5

Query published printers

Publish-CloudPrinter -Query -DiscoveryEndpoint https://clouddiscoveryproxy-autopilotrocks.msappproxy.net/mcs -AzureClientId 23772c3e-1a3b-4f28-86f9-ec614a53a776 -AzureTenantGuid 0b458c6e-97ce-4c7e-bc5e-1d29552989a5

Unpublish a printer

Publish-CloudPrinter -Unpublish -Printer EcpPrintTest -DiscoveryEndpoint https://clouddiscoveryproxy-autopilotrocks.msappproxy.net/mcs -PrintServerEndpoint https://cloudprintproxy-autopilotrocks.msappproxy.net/ecp -AzureClientId 23772c3e-1a3b-4f28-86f9-ec614a53a776 -AzureTenantGuid 0b458c6e-97ce-4c7e-bc5e-1d29552989a5

Trying it out

Let’s look at the client experience then.  The first sign of something different is on the “Printers & scanners” page in Settings.  There is a new “Search for cloud printers” link:

image

When you click that, you can then browse from a list of available locations, presented in a hierarchy that you can define:

image

And you can search for printers by keyword (or just leave the keyword blank to get all printers in that location):

image

And finally, select the printer and click “Add device” to add it:

image

Finally, I have a printer, with a slightly different icon to show that it’s a cloud printer:

image

And printing works, from any internet-connected location (thanks to the Azure Application Proxy).  The particular “printer” in this case is useful for testing, as it doesn’t waste any paper:  It just drops an XPS file into a folder on the server.

image

Check out the Ignite 2017 video at https://www.youtube.com/watch?v=Bvt1L--lqE4 for more information.  And with any luck, this will be integrated into Windows Server 2019 and easier to set up.


Comments (5)

  1. Hi Michael, is it supported or does it also work with Azure AD Domain Services instead of on-prem AD? And is AD Connect also a hard requirement, or can it work with cloud accounts in Azure AD Domain Services?

    1. The assumption is that your print server is joined to Active Directory, and when using passthrough authentication with the Azure Application Proxy, that your AAD user accounts are sourced/synchronized with those from AD. Where AD resides shouldn’t matter (although the supportability of using Azure AD Domain Services with on-prem devices joining is questionable).

      Because the on-prem AD-joined print server needs to authenticate an AD user to allow printing, I don’t know if this would work with any cloud-only accounts. Maybe with Azure AD pre-authentication? (That would assume Azure Application Proxy is able to use a different AD credential than the Azure AD account, not sure if that’s possible.)

      1. Anonymous says:
        (The content was deleted per user request)
      2. Well I created the setup 🙂 and hit some errors that are not entirely clear.
        I currently use passthrough authentication for the AAP maybe i can try pre-authentication with principalsallowedtodelegatetoaccount in AADDS

        When publishing a printer from an Azure AD joined Windows 10 device:

        Invoke-RestMethod : {“Message”:”An error has occurred.”,”ExceptionMessage”:”An error occurred when trying to create a controller of type
        ‘DevicesController’. Make sure that the controller has a parameterless public constructor.”
        (Exception from HRESULT: 0x8007000B)”,”ExceptionType”:”System.BadImageFormatException”,”StackTrace”:” at
        System.Data.SQLite.UnsafeNativeMethods.sqlite3_config_none(SQLiteConfigOpsEnum op)\r\n at
        System.Data.SQLite.SQLite3.StaticIsInitialized()\r\n at System.Data.SQLite.SQLiteLog.Initialize()\r\n at
        System.Data.SQLite.SQLiteConnection..ctor(String connectionString, Boolean parseViaFramework)\r\n at
        MopriaServiceLibrary.Models.DevicesContextWrapper..ctor()\r\n at lambda_method(Closure )\r\n at
        System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor,
        Type controllerType)”}}
        At C:\Program Files\WindowsPowerShell\Modules\PublishCloudPrinter\1.0.0.0\PublishCloudPrinter.psm1:177 char:5

        When publishing a printer from the print server:

        Publish-CloudPrinter : Exception calling “RetrieveOAuthToken” with “3” argument(s): “System.AggregateException: One or
        more errors occurred. —> System.Exception: Error requesting OAuth token. WebTokenRequestStatus:
        UserInteractionRequired, error: 3400073247, message: Integrated Windows authentication supported only in federation
        flow.

Skip to main content