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.