Something's gone wrong!An error ocurred performing that action. Please try refreshing the page.

Certificate mapping for AAD Devices with AD accounts

By Katy Nicholson, posted on 31 August, 2024

Device certificate authentication to NPS (e.g. an 802.1x wireless network) requires the device to have a computer object in the on-premises Active Directory. This can be done using a script to get all Autopilot registered devices, and create an account in the local AD (see SysManSquad - Working around NPS limitations for AADJ Windows Devices) however the thumbprint of the device certificate needs to be added to the computer object's altSecurityIdentities attribute. While this can be ran as an hourly task, there is the risk of a device being unable to connect for up to an hour. Luckily through configuring auditing and a scheduled task triggered by an event being raised, we can perform this mapping immediately after certificate issue.

Pre-requisites for this post are:

  • Intune Certificate Connector is configured
  • Device PKCS certificate profile in Intune
  • Script to create local AD computer objects for Autopilot devices

More information about these is available in my previous post, Intune: 802.1x Wi-Fi, NPS and user PKCS certificates.

Configure Auditing

In order to log the event when a certificate is issued, we need to enable auditing of success on object access. This can be done in the local security policy however I'd recommend using Group Policy, especially if you already have an audit policy in place. Make sure you do not have both basic and advanced auditing rules configured as they may conflict.

Run auditpol /get /category:* to confirm that auditing is enabled. You should see that Object Access - Certification Services has the value Success.

In the Certification Authority console, configure Auditing (in the CA Properties) and turn on Issue and Manage Certificate Requests.

Script

Download the Trigger-DeviceCertUpdate.ps1 script from my GitHub repository and save in a suitable location. This script will be called by the task scheduler every time event 4887 is logged. It takes several parameters:

  • RequestID - from the event data
  • Requester - the username of the account which requested the certificate, from the event data
  • Subject - the subject that the certificate was issued to, e.g. CN=b9b7bab8-7edc-405d-ba05-9d59d97c823d, from the event data
  • LogPath - the path to save logs, e.g. C:\Scripts\Logs
  • CertAuthorityName - the name of the CA to target, e.g. lab-LAB-SRV-DC03-CA
  • IntuneCertUsername - the username that your Intune requested certificates are requested by. You would have entered this when configuring the Intune Certificate Connector.

It then gets the certificate from the CA based on the Request ID, and extracts the thumbnail. Finally it adds this to the computer object's altSecurityIdentities attribute, which is required for device certificate authentication to work.

Scheduled Task

Create a new scheduled task on the server(s) which will be issuing certificates. Configure the following settings:

  • General Tab
    • Run as: SYSTEM (or a user account with sufficient rights to query the CA and update computer objects in AD)
    • Run whether user is logged on or not
  • Triggers tab
    • Begin the task: On an event
    • Log: Security
    • Event ID: 4887
  • Actions tab
    • Start a program: powershell.exe
    • Arguments: -file C:\Scripts\Trigger-DeviceCertUpdate.ps1 -RequestID "$(RequestId)" -Requester "$(Requester)" -Subject "$(Subject)" -LogPath "C:\Scripts\Logs" -CertAuthorityName "lab-LAB-SRV-DC03-CA" -IntuneCertUsername "LAB\intunecert"
  • Settings tab
    • If the task is already running: Run a new instance in parallel

This will not work currently - as we need to pass the RequestId, Requester and Subject from the event data into the task. This cannot be done in the GUI however it is possible by editing the task XML.

Export the task, and edit the XML file in a text editor.

Underneath the Subscription node, add the following:

Copy
<ValueQueries> <Value name="RequestId">Event/EventData/Data[@Name="RequestId"]</Value> <Value name="Requester">Event/EventData/Data[@Name="Requester"]</Value> <Value name="Subject">Event/EventData/Data[@Name="Subject"]</Value> </ValueQueries>

Your XML should look something like this:

Copy
<?xml version="1.0" encoding="UTF-16"?> <Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"> <RegistrationInfo> <Date>2024-08-30T22:28:00.8434586</Date> <Author>LAB\kn</Author> <Description>When an Intune cert is issued to a device, this task calls the script to add the certificate thumbprint to the device object's altSecurityIdentifier attribute. Needs object access auditing turned on in security policy, and certificate issue auditing turned on in the CA.</Description> <URI>\Intune Cert Issued</URI> </RegistrationInfo> <Triggers> <EventTrigger> <Enabled>true</Enabled> <Subscription>&lt;QueryList&gt;&lt;Query Id="0" Path="Security"&gt;&lt;Select Path="Security"&gt;*[System[EventID=4887]]&lt;/Select&gt;&lt;/Query&gt;&lt;/QueryList&gt;</Subscription> <ValueQueries> <Value name="RequestId">Event/EventData/Data[@Name="RequestId"]</Value> <Value name="Requester">Event/EventData/Data[@Name="Requester"]</Value> <Value name="Subject">Event/EventData/Data[@Name="Subject"]</Value> </ValueQueries> </EventTrigger> </Triggers> <Principals> <Principal id="Author"> <UserId>S-1-5-18</UserId> <RunLevel>LeastPrivilege</RunLevel> </Principal> </Principals> <Settings> <MultipleInstancesPolicy>Parallel</MultipleInstancesPolicy> <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries> <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries> <AllowHardTerminate>true</AllowHardTerminate> <StartWhenAvailable>false</StartWhenAvailable> <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable> <IdleSettings> <StopOnIdleEnd>true</StopOnIdleEnd> <RestartOnIdle>false</RestartOnIdle> </IdleSettings> <AllowStartOnDemand>true</AllowStartOnDemand> <Enabled>true</Enabled> <Hidden>false</Hidden> <RunOnlyIfIdle>false</RunOnlyIfIdle> <WakeToRun>false</WakeToRun> <ExecutionTimeLimit>PT72H</ExecutionTimeLimit> <Priority>7</Priority> </Settings> <Actions Context="Author"> <Exec> <Command>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe</Command> <Arguments>-file C:\Scripts\Trigger-DeviceCertUpdate.ps1 -RequestID "$(RequestId)" -Requester "$(Requester)" -Subject "$(Subject)" -LogPath "C:\Scripts\Logs" -CertAuthorityName "lab-LAB-SRV-DC03-CA" -IntuneCertUsername "LAB\intunecert"</Arguments> </Exec> </Actions> </Task>

Delete your original scheduled task, and import your XML file.

Testing

To test everything is working, filter the Security event log for ID 4887 and watch for new events. Once a new event appears, check the log file generated by the script (these are in a format that can be opened with CMTrace). If certificates are being issued but the event is not being logged, make sure that your audit settings are not being overwritten (e.g. group policy overwriting local security policy, or having both advanced auditing and basic auditing configured with conflicting settings). Finally, check the properties of the computer object in AD to verify the certificate thumbprint has been added.

Screenshot of altSecurityIdentities attribute in AD Users and Computers.
Shortly after a certificate being issued, you should be able to see the thumbprint in the corresponding computer object's altSecurityIdentities attribute in AD Users and Computers.

Further Reading

In this post

Support My Work

I hope you find my content useful. Please consider tipping to support the running costs of hosting, licensing etc on my Ko-fi page.

Support me on Ko-fi

Search