• Testing GitHub Copilot

    GitHub Copilot

    GitHub Copilot has been around for a while and as with most AI solutions it is sometimes hard to get a grip on actual usage scenarios.

    I wanted to give it a try with a simple task: generate a Powershell script that lists all users in an Entra ID tenant and show who has a registered FIDO2 device and who doesn’t. At the time of writing this, there isn’t a report available in the Entra admin portal for this.

    First iteration

    I started with this simple prompt

    Powershell script to fetch FIDO2 usage per user in Entra ID

    and of course got a rapid response. At first I thought – wow, this look really nice. Was it that simple?

    # Install the Microsoft.Graph module if not already installed
    if (-not (Get-Module -ListAvailable -Name Microsoft.Graph)) {
        Install-Module -Name Microsoft.Graph -Scope CurrentUser -Force -AllowClobber
    }
    
    # Import the Microsoft.Graph module
    Import-Module Microsoft.Graph
    
    # Connect to Microsoft Graph
    Connect-MgGraph -Scopes "User.Read.All", "Directory.Read.All"
    
    # Function to get FIDO2 usage per user
    function Get-FIDO2Usage {
        $users = Get-MgUser -All
        $fido2Usage = @()
        foreach ($user in $users) {
            $authMethods = Get-MgUserAuthenticationMethod -UserId $user.Id
            $fido2Methods = $authMethods | Where-Object { 
                $_.ODataType -eq "#microsoft.graph.fido2AuthenticationMethod"
            }
    
            foreach ($method in $fido2Methods) {
                $fido2Usage += [PSCustomObject]@{
                    UserPrincipalName = $user.UserPrincipalName
                    DisplayName       = $user.DisplayName
                    FIDO2KeyId        = $method.Id
                    CreatedDateTime   = $method.CreatedDateTime
                }
            }
        }
        return $fido2Usage
    }
    
    # Fetch FIDO2 usage and export to CSV
    $fido2Usage = Get-FIDO2Usage
    $fido2Usage | Export-Csv -Path "FIDO2Usage.csv" -NoTypeInformation
    Write-Output "FIDO2 usage data has been exported to FIDO2Usage.csv"

    Unfortunately, it wasn’t that simple, I found a few bugs in the code and some things that I wanted done differently

    10th iteration

    After adding more and more commands in my prompt, I managed to get generated code that actually work.

    The following prompt got me a working cmdlet

    Generate a Powershell script to fetch FIDO2 usage per user in Entra ID
    Skip module installation and import but keep connection
    Return an array of objects
    add progress bar
    add an option to only show active users
    Fetch users with “Get-MgUser -Select DisplayName,UserPrincipalName,Id,AccountEnabled -All”
    The authmetod is $_.AdditionalProperties.’@odata.type’ -eq “#microsoft.graph.fido2AuthenticationMethod”
    Include users without FIdo2 in the output
    Replace FIDO2Key Id with “FIDO2AAGUID = $method.AdditionalProperties.aaGuid”
    Skip CreatedDateTime
    add “FIDO2Model = $method.AdditionalProperties.model”

    This was the returned code:

    # Connect to Microsoft Graph
    Connect-MgGraph -Scopes "User.Read.All", "UserAuthenticationMethod.Read.All"
    
    # Function to display progress bar
    function Show-Progress {
        param (
            [int]$PercentComplete,
            [string]$Status
        )
        Write-Progress -Activity "Fetching FIDO2 usage" -Status $Status -PercentComplete $PercentComplete
    }
    
    # Function to fetch FIDO2 usage
    function Get-FIDO2Usage {
        param (
            [switch]$OnlyActiveUsers
        )
        # Fetch users
        $users = Get-MgUser -Select DisplayName,UserPrincipalName,Id,AccountEnabled -All
    
        # Initialize progress bar
        $totalUsers = $users.Count
        $currentUser = 0
    
        $result = @()
    
        foreach ($user in $users) {
            $currentUser++
            $percentComplete = [math]::Round(($currentUser / $totalUsers) * 100)
            Show-Progress -PercentComplete $percentComplete -Status "Processing user $currentUser of $totalUsers"
    
            if ($OnlyActiveUsers -and -not $user.AccountEnabled) {
                continue
            }
    
            # Fetch FIDO2 methods for the user
            $authMethods = Get-MgUserAuthenticationMethod -UserId $user.Id
    
            $fido2Methods = $authMethods | Where-Object {
                $_.AdditionalProperties.'@odata.type' -eq "#microsoft.graph.fido2AuthenticationMethod"
            }
    
            if ($fido2Methods.Count -eq 0) {
                $result += [PSCustomObject]@{
                    DisplayName        = $user.DisplayName
                    UserPrincipalName  = $user.UserPrincipalName
                    AccountEnabled     = $user.AccountEnabled
                    FIDO2AAGUID        = "N/A"
                    FIDO2Model         = "N/A"
                }
            } else {
                foreach ($method in $fido2Methods) {
                    $result += [PSCustomObject]@{
                        DisplayName        = $user.DisplayName
                        UserPrincipalName  = $user.UserPrincipalName
                        AccountEnabled     = $user.AccountEnabled
                        FIDO2AAGUID        = $method.AdditionalProperties.aaGuid
                        FIDO2Model         = $method.AdditionalProperties.model
                    }
                }
            }
        }
        return $result
    }
    
    # Run the function
    $fido2Usage = Get-FIDO2Usage -OnlyActiveUsers
    $fido2Usage | Format-Table -AutoSize

    Conclusion

    I could for sure write a cleaner prompt, but to sum things up. I didn’t spend that many minutes fine tuning the prompt message to get a working cmdlet. Some changes was due to errors in the code and some changes was because I wasn’t clear enough in my first request.

    I will definitely keep using GitHub Copilot to speed things up. It does not generate bulletproof code, but gives me 80% of the code really quick.