Building SailPoint IdentityNow Azure AD Source Filters

When you have a large Azure AD tenant it is likely that you want to scope your SailPoint IdentityNow Source based on the different type of identities it contains. Using the Filtering and Scoping section of the Azure AD Source Configuration Guide from Compass I first started constructing queries as I normally would with Azure AD against the Microsoft Graph API.

However the queries/filters I was using against Microsoft Graph were not working for the Azure AD IdentityNow Source. On aggregation the Source Connector would throw errors such as;

….java.lang.RuntimeException – sailpoint.connector.ConnectorException: Exception occurred. Error message – Exception occurred in processReadRequest. Error – Response Code – 400 Error – Bad Request Property ‘msGraphAADAttribute’ does not exist as a declared property or extension property…..

Following some discussions with the IdentityNow Professional Services guys I learned that the IdentityNow Azure AD Source Connector uses the Azure AD v1 Graph API endpoint.

With this information I was then able to use the Azure Active Directory v1 Graph API Explorer to develop queries that would then work for ‘User Filters’.  This is extremely quick and useful. For guidance on using Azure AD Filters this Microsoft document will get you started.

Azure AD v1 Graph Filter Tester.PNG

Configuring Azure AD Source Filters

To configure Source Filters for the IdentityNow Azure AD Source I use PowerShell as per the many IdentityNow Configuration and Automation posts I’ve previous written.

SailPoint IdentityNow Authentication

The script snippets below just show the commands to create three different Azure AD Source Filters (if you need all three like me you will need to configure three separate Sources with a different filter on each). In order to utilise these you will need to be authenticated to the SailPoint IdentityNow API. This post details connecting to the SailPoint IdentityNow v3 API endpoint using PowerShell.

Below shows three snippets for scoping the Azure AD Source down to specific User Types;

  • AAD Guest Accounts (B2B)
  • AAD Hybrid Accounts (On Premise AD and Azure AD)
  • AAD Cloud Only Accounts

To update a source you send a POST request to the Update Source API where yourOrg is your Tenant Org Name and SourceNumber is the number of the Source to update (e.g. 12345). The body is the connector_userFilters attribute with the value for the filter.

https://yourOrg.api.identitynow.com/cc/api/source/update/SOURCENumber

Hybrid Accounts

The following shows the tail of the output from the returned object after updating the Source for a filter for Azure AD Hybrid Accounts;

dirSyncEnabled eq true and userType eq 'member'

Hybrid Users.PNG

Azure AD Cloud Only Accounts

The following shows the tail of the output from the returned object after updating the Source for a filter for Azure AD Cloud Only Accounts;

dirSyncEnabled eq false and userType eq 'member'

Cloud Only Users.PNG

Azure AD Guest (B2B) Accounts

The following shows the tail of the output from the returned object after updating the Source for a filter for Azure AD Cloud Only Accounts;

userType eq 'guest'

B2B Guests.PNG

Summary

Knowing the API the IdentityNow Azure AD Source is using allows us to construct filters to scope the Azure AD Source to the specific users for an implementation.

CIRCUITPY Volume not visible for an Adafruit Circuit Playground Express on Windows 10 1803

I’ve just returned from the US and whilst there I picked myself up an Adafruit Circuit Playground Express. I plugged it into my computer and by all reports it should just appear as a removable drive on Windows 10. Alas that didn’t happen for me. I could get it into BOOT mode by pressing the Reset switch, but no matter what I did I couldn’t get the expected CIRCUITPY volume to be visible in File Explorer. Here’s how I got it working along with configuring VSCode as the editor.

Prerequisites

  • Visual Studio Code
    • Python Extension (from Microsoft) for VSCode. Install through VSCode Extensions

Environment Configuration

    1. Install the Arduino IDE from the Microsoft Store
    2. Open VSCode and install the Arduino Extension (from Microsoft)
      • go to the Command Palette and open Preferences: Open User Settings
      • under Arduino: Pathadd the path to Arduino. It should be something like C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.21.0_x86__mdqgnx93n4wtt depending on the version you have
      • under Arduino: Additional Urlsselect edit in settings.json and add the following line and save the file
        • “https://adafruit.github.io/arduino-board-index/package_adafruit_index.json
      • Open the Command Palette and select Arduino Board Config. Select Adafruit Circuit Playground
    3. Verify that the Adafruit Circuit Playground board is showing in the VSCode system tray along with the COM port is using on your computer.
    4. Update the Bootloader
      • Currently the latest bootloader is available from here https://github.com/adafruit/uf2-samdx1/releases/latest
        • for Circuit Playground Express you are looking for the update-bootloader-circuitplay_m0-v2.0.0-adafruit.VERSION.uf2 file
      • Click the reset button (in the middle of the board) and you should see the CPLAYBOOT drive volume in your computer File Explorer
      • Drop the bootloader uf2 file onto the drive
    5. Update to the latest Circuit Python Release
      • That is available from here https://circuitpython.org/board/circuitplayground_express/
        • Currently that is v3.1.2
      • Drop the updated Circuit Python .u2f file onto the CPLAYBOOT volume
    6. Restore the Demo Python Script
      • The demo is available from here https://github.com/adafruit/Adafruit_Learning_System_Guides/raw/master/Introducing_CircuitPlaygroundExpress/CPXDemoContent.zip
      • Unzip the download and drop the demo script (main.py and *.wav files)  onto the CIRCUITPY volume
      • It will restart and go through the neopixel demo (with startup sound)
    7. Using VSCode open the main.py file from the CIRCUITPY volume
      • update the following line from False to True and save the file
        • TOUCH_PIANO =True

         

With that all done I was up and running.

Hopefully that helps someone else get quickly starting and avoid all the troubleshooting I went through to get up and running.

Changing SailPoint IdentityNow Identity Profiles Priorities using PowerShell

In SailPoint IdentityNow a single user is highly likely to be represented on multiple Sources, that in turn are likely to be authoritative for differing SailPoint IdentityNow Identity Profiles. Often the first or last Identity Profile you create isn’t the one you wish to have the highest or lowest profile and you therefore need to change an Identity Profiles precedence so that the correct Identity Profile is associated with your identities.

The priority of IdentityNow Identity Profiles cannot be changed through the Portal, but it is possible to perform the change via the API as detailed in this Compass document.

Rather than following the Postman path described in that document, knowing I’m going to need to do this irregularly but relatively quickly I’ve written a little PowerShell script to make the changes.

By default an Identity Profile when created is added to the bottom of the list and their priority increased by 10 from the last Identity Profiles’ priority. The script will by default make the Identity Profile you choose 5 higher that the Identity Profile you’re moving it above.

The following screenshot shows 5 Identity Profiles in their priority order. Let’s say we wanted to move the System Accounts Identity Profile from the bottom priority to between Cloud Identities and Badged Identities.

IdentityNow Priority List.PNG

Using the script (at the bottom of this post) we can authenticate to IdentityNow and retrieve the IdentityNow Profiles with their Priorities. It will ask which IdentityNow Profile you wish to increase the priority of. By default it defaults to the one at the lowest priority.

Identity Profile Priority Changer 1.PNG

You are then prompted for where you would like to move it. Type the name of the Identity Profile you want to move it above.

Identity Profile Priority Changer 2a.PNG

Confirm your selections by typing ‘y’. Anything else will cancel the operation.

Identity Profile Priority Changer 3.PNG

The update will be made in IdentityNow and the output will indicate the updated priority given to the Identity Profile that was moved.

Identity Profile Priority Changer 4.PNG

Checking in the IdentityNow Portal we can see that they Identity Profile was moved from the bottom to between Cloud Identities and Badged Identities.

IdentityNow Priority List Updated.PNG

The Script

Below is the script that performs the changes to Identity Profiles priorities. Update the following script for;

  • Line 2 for your Client ID
  • Line 4 for your Client Secret
  • Line 8 for your Org name
  • Line 10 for your Admin Account name
  • Line 11 for your Admin Account password

Summary

Using this script is a quick way to change the priority of Identity Profiles in SailPoint IdentityNow.

SailPoint IdentityNow Identity Profiles Mapping Report

Last year I wrote this post here that detailed using the SailPoint IdentityNow API to generate an IdentityNow Sources HTML Report using PowerShell.
In a similar vein here is a post that does a similar function, but for the IdentityNow Identity Profiles. The example script below will connect to IdentityNow and extract all the Identity Profiles and pull out the details for the Mappings and create an HTML Report with a section for each Identity Profile.

SailPoint IdentityNow Identity Profiles Report.PNG

Report Script

Update the script below for;

  • Line 2 for your v1 API ClientID
  • Line 4 for your v1 API Client Secret
  • Line 8 for your Org Name
  • Line 10 for your Admin Name
  • Line 11 for your Admin Password
  • Line 22 for an image path for the report
  • Line 27 for the output path for the report

The Report

The resulting report that will be located in the output path you specified, will let you expand each of your Identity Profiles and see the attributes mapping configuration associated with it. A snippet of an Identity Profile is shown below.

SailPoint IdentityNow Identity Profiles Report Details.PNG

Summary

The ability to report on the attribute mappings for Identity Profiles gives a quick way to document or report on the attribute mappings. If you’re so inclined the script can be easily extended to report on all other aspects of the configuration items of an IdentityNow Identity Profile.

The image I’m using in the report is from this page and sized at 240 x 82 px.

Darren’s PowerShell Snippets Volume 1

I live in PowerShell and my memory is pretty good. There are a number of common PowerShell commands and one-liners or functions that I use a lot and I can remember them. However, then there are the ones I use less regularly and I often find myself trying to recall the last time I used them in a script, in order to locate that script just to get those couple of lines. So I’m posting a bunch of them in this post, if for nothing else to help me find them quickly. Let’s consider this as my common PowerShell Snippets and Volume 1.

Unix Time

For a number of API’s I interact with I need to provide the current time in Unix format as part of the API request. This online liner around Get-Date does that.

$utime = [int][double]::Parse((Get-Date -UFormat %s))

the output looks like this

1551906706

URL Encode

Often you need to encode a URL or query. The following shows taking a query and URL encoding it.

$query = "attributes.firstname='Darren' AND attributes.lastname='Robinson'"
Add-Type -AssemblyName System.Web
$queryEncoded = [System.Web.HttpUtility]::UrlEncode($query)

The encoded query then looks like

attributes.firstname%3d%27Darren%27+AND+attributes.lastname%3d%27Robinson%27

Basic Authentication Header

The following will create a Basic Authentication Header from a ClientID and Client Secret that can then be used with Invoke-RestMethod or Invoke-WebRequest

$clientID = 'abcd1234567'
$clientSecret = 'abcd12345sdkslslfjahd'
$Bytes = [System.Text.Encoding]::utf8.GetBytes("$($clientID):$($clientSecret)")
$encodedAuth =[Convert]::ToBase64String($Bytes)
$header = @{Authorization = "Basic $($encodedAuth)" }

You then use the $header variable in your web request e.g

invoke-restmethod -method get -uri "https://webservice.com" -headers $header

Converting a String to Proper/Title Case

Sometimes you get a string that is SHOUTING at you. Or just badly formatted and you need to make it look as it should. The following will convert a string to Title Case

$Surname = (Get-Culture).textinfo.totitlecase("BaDlY-ForMAtted SurNAME".tolower())

The BaDlY-ForMAtted SurNAME will then become

Badly-Formatted Surname

TLS

I have written this up before in more detail for a slightly different scenario here. But often the quick one-liner to force PowerShell to use TLS 1.2 for web requests is

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

Splitting a Large Collection into manageable chunks

Way to regularly I have a data-set of 100k+ objects. In order to parallelise the processing of that data into multiple threads I need to break that 100k+ collection into smaller chunks.

The following takes LARGEDATASET, say a collection of 10’s or 100’s of thousands of objects and splits it into collections of 1000.

$counter = [pscustomobject] @{ Value = 0 }
$groupSize = 1000
$groups = $LARGEDATASET | Group-Object -Property { [math]::Floor($counter.Value++ / $groupSize) }

You can then determine how many it created with

$groups.Count

and then checkout each Group by incrementing through the collection array

$groups[0].Group

Parallel Processing

As an extension of splitting a large collection into smaller collections you may then want to process a collection with multiple threads (e.g in Parallel).

The following snippet leverages the Invoke-Parallel Function from Rambling Cookie Monster that I’ve mentioned previously such as here.

Change the Throttle switch for the number of threads. Change the timeout if required (if for instance you are smashing your (not someone else’s) API.

& .\PATH-TO\invoke-parallel.ps1
$result = Invoke-Parallel -InputObject $CollectionOfObjects -throttle 10 -runspaceTimeout 60 -ImportVariables -ImportModules -ScriptBlock {
   try {
        $query = Invoke-RestMethod -method Get -uri "https://api.application.com" -headers $header
      } catch {
        write-host $_
      }
   @($query)
}
$result.Count

Join Large Collections

This I mentioned previously in this post here.  This snippet is the ability to quickly join objects between two large collections. It utilises the Join-Object function again from Rambling Cookie Monster

$reportData = Join-Object -Left $collection1 -Right $collection2 -LeftJoinProperty UserPrincipalName -RightJoinProperty UserPrincipalName -Type AllInLeft

Un-escaping a JSON Document

Using ConvertTo-JSON will escape special characters as shown below.

{"description": "Australian G\u0026f Logistics Ltd"}

Using the following will unescape the JSON document (if the system you’re interfacing with doesn’t unescape on consumption).

$jsonString | ConvertTo-Json | % { [System.Text.RegularExpressions.Regex]::Unescape($_) }

The JSON document will then become

{"description": "Australian G&f Logistics Ltd"}

That’s it for Vol 1 of Darren’s PowerShell snippets. I’ll start compiling others as I search for them and don’t find them in this Vol.

Aggregating SailPoint IdentityNow Sources via API with PowerShell

Aggregating an IdentityNow Source can be achieved in a number of ways, but when you are in a development environment there will be times where you need to add additional attributes for a Source to load. If the additional attribute(s) is/are used for Correlation, it’s at this time you will need to perform a full aggregation from a Source to re-evaluate each object with the new Correlation rules and to bring in the additional attributes for each identity on the Source.

The LoadAccounts API briefly mentions this in this SailPoint IdentityNow Compass document. It also details the option that needs to be disabled disableOptimization so that each identity is imported and re-evaluated.

This post details how to call the LoadAccounts API using PowerShell and disable optimization.

Prerequisites

The LoadAccounts API is a Private API that has a different authentication process that the v2 and v3. In this post I detail accessing the v1 Private API’s using PowerShell.  That post gives some more detail around the v1 Private API’s.

The following script will aggregate a SailPoint IdentityNow Source disabling optimisation.

Update;

  • Line 2 with your API ClientID
  • Line 4 with your API Client Secret
  • Line 8 with your IdentityNow Org Name
  • Line 10 with your IdentityNow Admin Account Name
  • Line 11 with your IdentityNow Admin Account Password
  • Line 25 with the SourceID (5 digit number) for the Source to Aggregate

Line 29 contains the Web Request Post Body disableOptimization=true” that disables optimisation for the aggregation. If you just require an aggregation of a source omit the body.

Executing the script with valid credentials and a Source will result in the aggregate variable returning a summary for the trigger of the aggregation. You will notice in the attributes that optimizedAggregation is disabled.

Returned Object when initiating IdentityNow Aggregation via API with optimisation disabled.PNG

This is also reflected in the Aggregation Summary from the Portal when completed.

IdentityNow Aggregation via API with optimisation disabled.PNG

Summary

Using the above script it is possible to quickly perform a full aggregation and re-evaluation of correlation rules for an IdentityNow Source.

 

Creating SailPoint IdentityNow Access Profiles via API and PowerShell

Managing SailPoint IdentityNow Access Profiles is easy enough to do using the SailPoint IdentityNow Portal. But what if you have the requirement to update, report on, or create numerous Access Profiles? That’s where the SailPoint IdentityNow API comes into play. The Access Profiles API is documented here but doesn’t go into a lot of detail. In this post I’ll detail interfacing with it using PowerShell primarily to create and update Access Profiles.

Prerequisites

You will need to Authenticate to the IdentityNow API. Both v2 and v3 authentication methods work. I detail the v2 method here and the v3 method here. Personally I’m using the v3 method. Just make sure you change your Headers for the requests to whatever method you use and the naming of your variables.

For reference my v3token variable is $v3Token so my Authentication Header is then @{Authorization = “$($v3Token.token_type) $($v3Token.access_token)”}

Getting Access Profiles

The Access Profiles API URI is

https://$($yourOrgName).api.identitynow.com/v2/access-profiles

If you know the ID of the Access Profile you can return just that Access Profile via it’s ID (where $accessProfileID is the ID that looks like 2c91808466a64e330112a96902ff1f69)

https://$($yourOrgName).api.identitynow.com/v2/access-profiles/$($accessProfileID)

The following script will return Access Profiles from your SailPoint IdentityNow Tenant. Update;

  • Line 2 for your IdentityNow Org name

Updating Access Profiles

To update an Access Profile the API URI is;

https://$($orgName).api.identitynow.com/v2/access-profiles/$($accessProfileID)

The following will update an existing Access Profile to make Request Comments Required and Denied Comments Required equal False.

Update;

  • Line 2 for your IdentityNow Org name
  • Lines 6 for the ID of the Access Profile you want to update
  • Lines 9,10 for the settings to update

Preparing to create an Access Profile

In order to create an Access Profile, there are a number of configuration items that you will need to provide. The key items are;

  • SourceID is the (currently) five digit ID of a source that you can get from the IdentityNow Portal when looking at the properties of a Source. Or via API as I detailed in this post.
  • OwnerID is the Identity ID for the user you will make the owner. To do that you will need to query IdentityNow for the user (see below for an example)
  • Entitlements
    • In order to get the Entitlements ID(s) to assign to the Access Profile you will need to query the Source. This post here details querying Sources to get Entitlements whereby you can get the ExternalID of Entitlements.

Search for Owner ID Request Object

Here is an example Search Request JSON Object required for the Search User call. Update it for a unique attribute for an Identity to query and return.

Update for your criteria. e.g if you copy the JSON below;

  • create a variable name
    • $requestFilter = ‘JSON snippet content from below’
  • Update the search criteria for your search
    • $newRequestFilter = $requestFilter .Replace(“darren.robinson@customer.com.au”,”yourUser@mydomain.com”)
  • Then search for the user and get the ID of the identity
  • Update
    • Line 2 for your Orgname
    • Line 8 for the user to search for that matches the JSON object from above

Creating an Access Profile

Finally, now that we have the prerequisite information to create an Access Profile we can create it. Modify for your environment based off information retrieved from the processes above. Namely;

  • Line 1 for your Orgname
  • Line 2 for the SourceID associated with the Access Profile
  • Line 3 for the Access Profile Owner’s ID
  • Lines 7-10 for your Access Profile Details
  • Line 14 for the Entitlements
  • Line 19 for the Approver (see below for more details)

Access Profile Approvers

For Approvers you can provide the order for approval. For the approval by the Access Profile Owner and then the Manager use the following when creating the Access Profile in Line 19 above.

  • $accessProfile.add(“approvalSchemes”,”accessProfileOwner, manager”)

Other options are:

  • SourceOwner
  • appOwner
  • Governance Group. See managing Governance Groups here to get the Governance Group ID (GUID format)
    • workgroup: 86929844-3391-4ce2-80ef-760127e15813

Summary

Whilst the creation of an Access Profile via API does require some configuration, if you have multiple to create and you know the criteria it is possible to automate the task. I hope this helps others.

 

Searching and Returning SailPoint IdentityNow Entitlements using the API and PowerShell

Entitlements on IdentityNow Sources can be leveraged for many purposes within IdentityNow. Recently I’ve been looking to automate some Access Profiles that will in-turn have entitlements associated with them.

This post details how to query for Entitlements in IdentityNow using the v3 API and PowerShell.

Prerequisites

You will need to Authenticate to the IdentityNow API. The v3 authentication method is required. I detail the v3 method here. The Headers for the requests detailed in this post use the following variables for the JWT oAuth Token.

My v3token variable is $v3Token so my Authentication Header is then
@{Authorization = “$($v3Token.token_type) $($v3Token.access_token)”; “Content-Type” = “application/json”}

Searching for Entitlements

The Base API URI to search for entitlements is;

https://$($org).api.identitynow.com/cc/api/entitlement/list

You will also need to provide a timestamp and a source for which you want to retrieve entitlements for.

Generating the Timestamp

The timestamp is in Unix format which can be generated in PowerShell like this;

$utime = [int][double]::Parse((Get-Date -UFormat %s))

Getting a list of Sources

I’ve previously described listing IdentityNow Sources in this post and this post. Essentially though you can return a list of all sources by performing a GET request to

https://$($orgName).api.identitynow.com/cc/api/source/list

Obtain the Source ExternalID from the source of  your choice that you then wish to return entitlements for.

Entitlement Results

You can limit the number of entitlements returned by using the limit option. The following will return the first 1000 entitlements for a source starting at 0

&start=0&limit=1000

If the source has more than 1000 then you will need to page the results to return the next 1000 results. Continue until you’ve returned all.

&start=1000&limit=1000

Of course you can just not provide a limit and all entitlements will be returned in a single call.

Finding an Entitlement on a Source

Using the power of PowerShell it is quick to find the Entitlement you want if you know some of the information about it. For referencing an Entitlement when creating an Access Profile via the API you will need the Entitlement ID  e.g

$myEntitlement = $sourceEntitlements.items | Select-Object | Where-Object {$_.displayName -like "*Sydney*"}
$myEntitlement.id

Summary

Using the IdentityNow API and the v3 endpoints we can retrieve entitlements for a Source and quickly locate the entitlement and the entitlement ID for use during automation of IdentityNow tasks such as Access Profile creation.

Azure AD/Active Directory User Security Evaluation Reporter

During December 2018 – February 2019 Microsoft have run an online Microsoft Graph Security Hackathon on Devpost.

The criteria of the hackathon was;

  • Build or update a functioning Microsoft Graph-powered solution that leverages the Microsoft Graph Security API

Following the announcement of the Hackathon I was encouraged by Kloud management to enter. During the busy month of December I started to formulate a concept for entry in the Hackathon taking learnings from the hackathon I entered in 2018. Over the Xmas holiday period I started working on my entry which continued into January and February at nights and weekends.

Problem

A Security Administrator within an Organisation enables security related configuration options on an Azure Tenant to implement security controls that align an organisation with Microsoft recommendations and best practice.

The Azure Security Score provides an evaluation on the alignment of an organisation with best practice, however to some extent it still requires end users to have the right configuration for security related elements of their profile. But as a Service Desk Operator or Cyber Security Officer there isn’t a single view of a user’s security posture that can give you an individual user security score summary. My solution……

Microsoft User Security Evaluation Reporter (USER)

Microsoft User Security Evaluation Reporter (USER) is an Azure AD and Active Directory tool for use by the Service Desk and Cyber Security Officers to get instant visibility of an organisations Azure Security Score that allows them to then evaluate current risks within an organisation right down to individual users.

When the Microsoft USER loads the current Azure Security Score is retrieved, evaluated and displayed for alignment with Microsoft Recommendations. Also, on load the last 5 Active Security Risk Events are displayed.

Microsoft USER Recent Risk Events and Azure Secure Score.PNG

The Service Desk Operator or Cyber Security Officer can select one of the recent Security Events or search for a user and drill down into the associated identity. They will be quickly able to understand the users’ individual security posture aligned with best practice.

What are the recent Security Risk Events for that user? Does that user;

  • Have MFA enabled? Is MFA enabled with an Authenticator App as the primary method?
  • Is the users Active Directory password in the Pwned Passwords v4 list from Have I Been Pwned?
  • Has the user recently being attempting Azure Password Reset functions?
  • What are the last 10 logins for that user?
  • What is the base user information for that user and what devices are registered to that user? Are they Azure AD Joined?

User Secure Score Summary.PNG

The clip below gives a walk through with more detail of my Microsoft USER tool.

How I built it

The solution is built using;

  • NodeJS and Javascript
  • leveraging Azure Functions to interface with Azure AD, Microsoft Graph, Azure Table Service
  • Lithnet Password Protection for Active Directory that in turn leverages the Have I Been Pwned v4 dataset
  • All secrets are stored in Azure Key Vault.
  • The WebApp is Application Insights enabled.
  • The WebApp is deployed using a Docker Container into Azure App Service

The architecture is shown below.

MS User Security Evaluation Reporter Architecture

The Code

A Repo with the code can be found here. Keep in mind I’m not a developer and this is my first WebApp that was put together late at night and over weekends and only tested in Chrome and Edge. The Readme also contains hopefully everything you should need to deploy it.

 

Recovering from USB device driver is still in memory / USB Composite Device has error (Code 38)

Something you don’t often think about is how many devices you plug into your computer …….. until you plug-in a device and it doesn’t show up or interact as expected. This post details how I recovered from such a situation so I can find it next time, and hopefully it also helps others recover quickly, rather than the numerous dead-ends I went through to fix the problem.

My Situation

I’ve been evaluating a number of different YubiKey’s recently and out of the blue they stopped being recognised. Below is a message from the YubiKey Manager indicating that there is no device inserted (when in actual fact there is).

Insert YubiKey

To prove the point, plugging in two YubiKey’s informs me I should only have one at a time.

Insert only one YubiKey

Going into Device Manager and selecting Show hidden devices reveals the plethora of USB devices I’ve previously inserted into my computer.

Yubikey Device Manager Properties

Looking into the USB Composite Device‘s with the warning symbols reveals

Windows cannot load the device driver for this hardware because a previous instance of the device driver is still in memory. (Code 38)

USB Composite Device Manager

The Fix

After trying numerous different avenues, this is how I repaired the issue and got up and running again.

Navigate to Windows => Settings => Update and Security => Troubleshoot => Run the troubleshooter

Hardware Troubleshooter.PNG

The troubleshooter will detect the USB Composite Device has error for the devices being problematic. Select one and continue.

USB Composite Devices has error

Select Apply this fix

Apply Fix

Repeat for other USB Composite Device has error errors. Then Restart the computer.

Restart PC

After Restart you should be back in action like I was.

YubiKey Manager - Success.PNG

Hope this helps someone else, and will help me find it next time too.