0 votes

We're testing Yubikeys for MFA in Microsoft Entra. Is it possible for us to pull a list of users with a registered Yubikey, and also get the serial number from Entra (shows in the 'Details' field of Entra registration)?

We're trying to get this as a report available to some admins in Adaxes, but I'm not sure how to pull that data.

ago by (20 points)

2 Answers

0 votes
ago by (299k points)

Hello,

Unfortunately, there is no such built-in functionality in Adaxes. It might be possible using a script, but we do not have anything like that.

0 votes
ago by (350 points)

Here's our script that we use to pull all registered MFA methods for our users. You'll want to run this in an Adaxes Scheduled Task. As far as I know, you can't retrieve the serial number - the only options to do so are to physically look at the key or use the Yubikey programming tool.

We have our script set to run a few times a day. We then have a simple report that returns the stored data (see Step 1 below).

Somre prerequisites:

  1. A custom attribue in Adaxes to store the data in. We use adm-CustomAttributeTextMultiValue2 - you'll need to modify line 98 in the script accordingly.
  2. An Entra app registration that uses a certificate for authentication. The app must have at a minimum User.Readdelegated permissions (more permissions may be required, but I think this should suffice).
  3. The certificate for the app stored in Local Computer\Personal\Certificates on your Adaxes server.
  4. You'll need to know which model(s) of Yubikey you have, and add the AAGUID for each model (found here). You'll then need to modify the switch statement (around line 63 in the script) to include each AAGUID you have. We only use one model - the YubiKey 5 NFC - so the script looks for the AAGUID of 2fc0579f-8113-47ea-b116-bb5a8db9202a.
  5. You'll need to edit the variables on lines 8, 9, and 10.
  6. Finally, you'll need the Microsoft.Graph.Users Powershell module installed for all users on your Adaxes server.

<#
.SYNOPSIS
    Uses the Microsoft Graph API to query user's registered MFA methods and updates the adm-CustomAttributeTextMultiValue2 attribute.
#>


$certThumbprint = "your cert thumbprint"
$tenantId = "your Entra tenant ID"
$clientId = "your Entra app ID"

# check if we have the cert for graph authentication
try {
    if (-not(Get-ChildItem -Path "Cert:\$certThumbprint" -Recurse)) {
        throw [Microsoft.PowerShell.Commands.CertificateNotFoundException]::New("Could not find certificate with thumbprint $certThumbprint")
    }
}
catch {
    $Context.LogException($_.Exception)
    break
}

try {
    # set up the graph auth parameters
    $graphAuthParams = @{
        tenantId = $tenantId
        clientId = $clientId$
        CertificateThumbprint = $certThumbprint
    }
    Connect-MgGraph @graphAuthParams -NoWelcome -ErrorAction Stop
    $users = Get-MgUser -All
}

catch {
    $Context.LogMessage("Failed to connect to Microsoft Graph", "Error")
    $Context.LogException($_.Exception)
    break
}

# store authentication methods in a hashtable
$userMethods = @{}

foreach ($user in $users) {

    try {
        $admUser = Get-AdmUser -Identity $user.userprincipalname -ErrorAction SilentlyContinue
        if (-not($admUser)) {
            # user exists in graph but not adaxes
            $Context.LogMessage("User $($user.userprincipalname) not found in Adaxes", "Information")
            continue
        }

        $admUserContext = $Context.BindToObjectByDN($admUser.DistinguishedName)

        # all of our "real" users will have a user mailbox (as opposed to shared, room, etc.)
        # see https://www.adaxes.com/sdk/ADM_EXCHANGE_MAILBOXTYPE_ENUM/
        if ($admUserContext.MailboxType -eq "ADM_EXCHANGE_MAILBOXTYPE_USER") {
            #$Context.LogMessage("Getting MFA methods for $($admUserContext.Name)", "Information")
            $methods = Get-MgUserAuthenticationMethod -UserId $user.id
            $registeredMethods = @()

            foreach ($method in $methods) {
                switch ($method.AdditionalProperties["@odata.type"]) {
                    "#microsoft.graph.fido2AuthenticationMethod" {
                        switch ($method.AdditionalProperties['aaGuid']) {
                            '90a3ccdf-635c-4729-a248-9b709135078f' { $registeredMethods += "Passkey" }
                            '2fc0579f-8113-47ea-b116-bb5a8db9202a' { $registeredMethods += $method.AdditionalProperties['model'] }                
                        }
                    }
                    "#microsoft.graph.microsoftAuthenticatorAuthenticationMethod" {
                        $registeredMethods += "Authenticator App"
                    }
                    "#microsoft.graph.windowsHelloForBusinessAuthenticationMethod" {
                        $registeredMethods += "WHfB"
                    }
                    # users shouldn't have a phone method registered - we can use this in reports later
                    "#microsoft.graph.phoneAuthenticationMethod" {
                        $registeredMethods += "Phone"
                    }
                }
            }

            $userMethods.Add($user.userprincipalname, ($registeredMethods | Select-Object -Unique))
        }
    }

    catch {
        $Context.LogException($_.Exception)
    }    
}

foreach ($method in $userMethods.GetEnumerator()) {   

    # only process users who have MFA configured
    if ($method.Value) {
        #$Context.LogMessage("Updating MFA method list for $($method.Key)", "Information")
        # custom attributes can only be set when using the -adaxesservice parameter
        Set-AdmUser -Identity $method.Key -Replace @{'adm-customattributetextmultivalue2' = $method.Value } -AdaxesService localhost -ErrorAction SilentlyContinue    
    }    
}

Disconnect-MgGraph -ErrorAction SilentlyContinue

Related questions

0 votes
1 answer

Good morning, I need to get the serial number of PC and update the description with the value result. I tried with %serialNumber% but the is empty. Can u help me? thanks, Simone

asked Nov 17, 2021 by Simone.Vailati (430 points)
0 votes
1 answer

I used the script below to try and accomplish this but I get an error. I did try to leave a comment but it would not let me. I tried running ... .adaxes.com/script-repository/add-users-located-in-particular-organizational-units-to-unmanaged-accounts-s178.htm

asked Nov 14, 2022 by raul.ramirez (210 points)
0 votes
1 answer

Is there a comparison between the OnPrem user object and Entra user object in the built-in condition? Which determines the most recent inactivity from both environments. Or should a choice be made between the OnPrem domain or Entra based on the Activity scope?

asked Dec 13, 2024 by IwistIT (40 points)
0 votes
1 answer

As part of offboarding a user I need to generate a report of all AD groups, Entra groups and all Azure / M365 roles and licenses the user has before they ... about keeping a record of the leavers configured profile to simplify cloning them onto new starters.

asked Jun 24, 2024 by dhardyuk (20 points)
0 votes
1 answer

I'm wanting to store information in a custom user attribute in Entra ID but I'm wondering if this is possible within a "Update the user" action in Adaxes? ... PowerShell? https://learn.microsoft.com/en-us/entra/external-id/customers/concept-user-attributes

asked Dec 11, 2024 by smcfarland (60 points)
3,633 questions
3,321 answers
8,398 comments
548,760 users