Saturday, 12 April 2025

On-premises printing with cloud native devices

In the past year my colleagues and I have helped many customers to prepare their environments for cloud native devices. 

What is a cloud native device? It's a device where all management is provided by the cloud. In the Microsoft world this means a device which is Entra joined and enrolled in Intune. The key here is the authentication. The device must authenticate with Entra. Entra hybrid devices authenticate with Active Directory so they do not qualify as cloud native devices.

Printing is usually one of the challenges organizations face. Often Group Policy Objects have traditionally been used to control access to printers. By default non-administrators are not allowed to install drivers on domain joined devices. This can be managed by allowing users to install driver packages for the classes below, all configured by GPO:

  • {4658ee7e-f050-11d1-b6bd-00c04fa372a7}
  • {4d36e979-e325-11ce-bfc1-08002be10318}
All the users need to do is browse to the print server and double click the printer to add the queue without any elevation.

GPOs are not applied to Entra devices so we need to find another way to deal with printers using Intune. I know, I know we should be using Universal Printing. However many customers have heavy investments in on-premises printing and we need to help them rather than tell them that they are wrong.

There is an equivalent Intune configuration policy where we can allow users to install drivers for the same classes above. However I don't want users to install drivers at all. I want to pre-install all the necessary print drivers to make the device as secure as possible. It's pretty straightforward and involves a couple of scripts. 

Disclaimer: I'm not a master scripter. The scripts don't contain any error checking. However they are functional and they work well. No complaints please 😏😏😏

I've picked an example printer that I worked with recently.


The Canon Image Runner Advanced C256i is a big old expensive printer and was one of the models used by a recent customer. The customer provided the print driver.


Tip: you do not need all the files that are downloaded in a bundle from the vendor website. In this case it contained 47.4MB of data.


You just need the drivers. Typically this is a folder containing .inf and .cab files. This one had 17MB of data. You'll notice a few extra files here. We'll come to them shortly.

First we need to check that these files will add the print driver that I need. Open the .inf file to see what is inside. It's called cnnv4_cb3_fgeneric.inf in this example but the name will be different in each case.


I can see that this .inf file is aware of two print drivers

  • Canon Generic LIPSLX V4
  • Canon Generic UFR II V4
Which one do I need? I had a look in the properties of the queue on the print server and could see that I needed "Canon Generic LIPSLX V4". Now I could get started.

The install.cmd file is a simple script that performs the following actions:
  1. Creates a local folder C:\PrinterDrivers\Canon
  2. Copies all the required files to this folder
  3. Adds the print driver using prndrvr.vbs
What is prndrvr.vbs? It's a Visual Basic script native to the operating system which adds, deletes and lists printer drivers. You can read about it here. 

The script uses the following parameters:
  • a: adds a printer
  • m: specifies (by name) the driver you want to install
  • i: specifies the complete path and file name for the driver you want to install
install.cmd script (you'll need to replace the vendor name, the driver name and the inf filename).

@echo off

mkdir C:\PrinterDrivers\Canon
xcopy *.* /h /c /k /e /r /y C:\PrinterDrivers\Canon

cscript "C:\Windows\System32\Printing_Admin_Scripts\en-US\prndrvr.vbs" -a -m "Canon Generic LIPSLX V4" -i "C:\PrinterDrivers\Canon\cnnv4_cb3_fgeneric.inf"

I'm going to deploy the solution as a Win32 app. Therefore I also need a detection method. I'm using a custom script for that. The script performs the following:
  1. Executes Get-PrinterDriver
  2. Looks for "Canon Generic LIPSLX V4"
  3. Returns an exit code, 0 = success
Detection_Script.ps1

$driverExists = Get-Printerdriver | Where-Object {$_.Name -like "Canon Generic LIPSLX V4"}

if($driverExists) {
  Write-Host "Success"
  Exit 0
} else {
  Exit 1
}

Next job is to create and deploy a Win32 app using Install.cmd as the installation and Detection_Script.ps1 as the custom detection.


This is the result. The correct print driver is pre-installed. You can see a few others there as well as the Canon.

What happens next? Well, now you can just browse to the print server and double click to add the print queue. The driver already exists so you will not be prompted for elevation.

Alternatively you could create an available Win32 app which could be self-installed via Company Portal. Replace with the name of your print server and queue

Add-Printer -ConnectionName \\printserver.domain.local\Canon_Colour

This will work as the installation script.

$printerExists = Get-CimInstance -Class Win32_Printer | Where-Object {$_.Name -like "\\printserver.domain.local\Canon_Colour}

if($printerExists) {
  Write-Host "Success"
  Exit 0
} else {
  Exit 1
}

This will work as the detection script.

Thanks to my colleague Rahul Jindal for reminding me about prndrvr

I hope this helps. Until next time.....



Saturday, 8 March 2025

Apple Rapid Security Response and Intune

Back to main macOS page

Rapid Security Responses (RSR) are a type of software release for iPhone, iPad, and MacOS devices. They deliver important security improvements between major software updates. They can also be used to mitigate some security issues more quickly. Rapid Security Responses are supported for versions starting with iOS 16.4.1, iPadOS 16.4.1, and macOS 13.3.1.

By default, Apple devices automatically apply Rapid Security Responses. Users may be prompted to restart their device.


iPhone or iPad: Go to Settings > General > Software Update > Automatic Updates, you should see that "Security Responses & System Files" is turned on. This is from my iOS 18.3.1 device.

Mac: Choose Apple menu > System Settings. Click General in the sidebar, then click Software Update on the right. Click the Show Detail button next to Automatic Updates, you should see that "Install Security Responses and system files" is turned on.

When a Rapid Security Response has been applied, a letter appears after the software version number, for example, macOS 13.3.1 became 13.3.1 (a) after the first RSR was applied, then (b) etc. Build numbers is a bit more complicated. The build number for macOS 13.3.1 is 22E261 but 13.3.1 (a) is 22E772610a. You need to know the build number if you will be configuring Intune policies.

So what can we configure with Intune? Remember RSR is enabled by default.

Settings catalog

Some configurations are available via the Settings Catalog and are identical for iOS and macOS.

Settings are available in two categories:


Restrictions:

  • Allow Rapid Security Response Installation - if 'false', Rapid Security Response will be disabled
  • Allow Rapid Security Response Removal - if 'false', users are unable to remove the Rapid Security Response option.

Declarative Device Management preview Software Update Settings:

  • Enable - if 'false', Rapid Security Responses are not offered for user installation. If 'true', Rapid Security Responses are offered to the user.
  • Enable Rollback - if 'false', Rapid Security Response rollbacks are not offered to the user. If 'true', Rapid Security Response rollbacks are offered to the user.

Compliance

You can configure an Apple Rapid Security Response update as the minimum OS build in an Intune compliance policy, for use with conditional access. 


Enter the supplemental build version. For example, 22E772610a is macOS 13.3.1 (a). Note that this had some teething problems when first released as the version wasn't detected correctly and conditional access blocked compliant devices. 

I hope this helps you to understand Apple Rapid Security Responses and what you can configure in Intune. Until next time...... 


Friday, 7 February 2025

Help, NDES is broken......

I was working with a new customer recently and they pointed out that they were having a problem with NDES. 

What is NDES? The Network Device Enrollment Service (NDES) is one of the role services of Active Directory Certificate Services (AD CS). NDES acts as a Registration Authority to enable devices running without domain credentials to get certificates from the internal Certificate Authority, based on the Simple Certificate Enrollment Protocol (SCEP).

Therefore the customer was unable to issue SCEP certificates via Intune and was unable to enforce 802.1x authentication to their network. 

An Intune managed Windows 10/11 client was a good place to start, in particular the event logs (Applications and Services Logs > Microsoft > Windows > DeviceManagement-Enterprise-Diagnostic-Provider > Admin). Event IDs 307 and 32 were repeating.

Event ID 307 - SCEP: FailedLogError Message : (SCEPInstallCertificateWithScepHelper:Failed to Initialize SCEP enrollment with NDES Server https://xxxxx.msappproxy.net/certsrv/mscep/mscep.dll/pkiclient , CA Cert thumbprint 'xxxx' and server certs)


Event ID 32 - SCEP: Certificate enroll failed. Result: (Internal server error (500)).


Just for kicks I opened a browser and navigated to the NDES server URL (from event ID 307). It gave me the same Internal Server Error (500) that I could see in event ID 32.


Next I had a look on the NDES server. The IIS log files can be found in the following folder: %SystemDrive%\inetpub\logs\logfiles\w3svc1. On 10th August we could see a status code of 200: This status indicates the connection with the NDES server is successful.


On 11th August we could see a status code of 500. This Microsoft troubleshooting guide tells me that Status code of 500 could mean that the IIS_IUSRS group might lack correct permissions (Impersonate a client after authentication).


However, I opened the Local Security Policy editor (secpol.exe), expanded Local Policies, and then selected User Rights Assignment. Double-clicking Impersonate a client after authentication in the right pane, I could see that the IIS_IUSRS group had the correct permissions.


The SCEP application pool was started so no problem there.


The Application event log on the server gave me some direction. Event IDs 10 and 2 were repeating. 
Event ID 10: The Network Device Enrollment Service cannot retrieve one of its required certificates (0x80070057). The parameter is incorrect.  


Event ID 2: The Network Device Enrollment Service cannot be started (0x80070057). The parameter is incorrect. 


This prompted me to look at the computer certificates on the NDES server. Sure enough, they had expired. There were three certificates to deal with:
  • Certificate based on the CEP Encryption certificate template
  • Certificate based on the Exchange Enrollment Agent (Offline Request) certificate template
  • Certificate based on the NDES SSL certificate template
Perfect, I just need to renew these certificates, right? Well not really.


I started with the CEP Encryption certificate, right-clicked on the certificate and selected Request Certificate with New Key.  


However the CEP Encryption template was not available so I couldn't "renew" the certificate. I needed a brand new certificate with exactly the same details.


I made a note of the Subject details for the existing certificate.


Now to create the new certificate, I right-clicked on the Personal folder and selected All Tasks > Request New Certificate.


I selected the Active Directory Enrollment Policy and clicked Next.


This time the CEP Encryption template was available. However more information was required. I clicked on the link to configure the certificate.


I added the same Subject details that I had captured earlier from the existing certificate, applied this and completed the wizard to generate the certificate.


The certificate was created with excessive permissions for the service account. I clicked Manage Private Keys.....



.... and unchecked the box for Full Control for the service account.

Next up is the NDES SSL Certificate. 


It's the same process as above except this time we use a different template. Don't forget to remove the Full Control permissions from the service account when you are finished.

Last but not least we get to the certificate based on the Exchange Enrollment Agent (Offline Request) certificate template. The process to generate this certificate is a little different than the others. Nickolaj Andersen has published the steps in a good post here. Please follow these steps to generate the third certificate. They are pretty straightforward.

I executed an IIS reset and figured that I was good to go.


The Network Device Enrollment Service policy module started successfully.


NDES looked to be functioning correctly.


Happy days, the NDES service finally started. But alas, certificates were still not being issued. There were still errors in the clients event log referring to "BadGateway: This corporate app can't be accessed". 


Opening a browser and navigating to the NDES URL gave the same information but also showed that the source of this error was the Azure AD Application Proxy. From that I figured that there was a communication error between the AAD Application proxy and the NDES server. 


I remembered that I hadn't reconfigured the Site Bindings in IIS to use the new NDES SSL certificate. Once I did that and executed another IIS Reset, the certificates started to fly and the customer was back in business with SCEP and 802.1x authentication.

I hope this helps. Until next time......