KnowBe4.psm1

function Get-KnowBe4Campaign {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory = $true)]
        [String]$AccessToken   
    )
    [String]$authorizationHeader = "Authorization: Bearer $AccessToken"
    curl.exe https://us.api.knowbe4.com/v1/phishing/campaigns -H $authorizationHeader | ConvertFrom-Json | ForEach-Object {
        return $_
    }
}

function Get-KnowBe4User {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory = $true)]
        [String]$AccessToken   
    )
    [String]$authorizationHeader = "Authorization: Bearer $AccessToken"
    curl.exe https://us.api.knowbe4.com/v1/users -H $authorizationHeader | ConvertFrom-Json | ForEach-Object {
        return $_
    }
}

function Get-KnowBe4IncompleteTraining {
    Param(
        [CmdletBinding()]

        [Parameter(Mandatory = $true,
        HelpMessage = "This token is generated by KnowBe4 and accessible from your Account Settings page under 'API.' You must check 'Enable API Access' to use this token.")]
        $AccessToken,

        [Parameter(Mandatory = $true,
        HelpMessage = "If your server URL is training.knowbe4.com, your base URL is 'US'. If your server URL is eu.knowbe4.com, your base URL is 'EU.'")]
        [ValidateSet('US','EU')][String]$BaseURL
    )

    $curls = 0 # counting how many API requests are made
    $authorizationHeader = "Authorization: Bearer $AccessToken"
    $BaseURL = $BaseURL.ToUpper()
    switch ($BaseURL) {
        'US' {$URL = 'https://us.api.knowbe4.com'}
        'EU' {$URL = 'https://eu.api.knowbe4.com'}
    }

    # This will only get active users
    # $userCollection is not very efficient as far as limiting API requests, but it works for now
    $n = 1
    $y = 1
    $userCollection = @()
    Do {
        New-Variable -Name "$($n)_enrolls" -Value (curl "$URL/v1/users?status=active&per_page=250&page=$n" -H $authorizationHeader -s | ConvertFrom-Json)
        $curl++

        $testVal = $((Get-Variable -Name "$($n)_enrolls").Value)
        $n++
    } Until ($testVal -eq $null)

    Do {
        $userCollection += $((Get-Variable -Name "$($y)_enrolls" -ErrorAction SilentlyContinue).Value)
        $y++
    } Until ($y -gt $n)

    $userCollection | ForEach-Object {
        [String]$userID = $_.id

        Write-Verbose "Collecting enrollments for user $_.first_name $_.last_name."
        $userEnrollments = curl.exe "$URL/v1/training/enrollments?user_id=$userID" -H $authorizationHeader -s | ConvertFrom-Json
        $curl++
        $userEnrollments | Where-Object {$_.Status -ne 'Passed'} | ForEach-Object {
            [String]$firstName = ($_.User).first_name
            [String]$lastName = ($_.User).last_name
            [String]$name = $firstName + " " + $lastName

            [Datetime]$enrollDate = $_.enrollment_date

            [Boolean]$started = if($_.start_date -eq $null) { $false } else { $true }

            # Creating a new object to rename the properties
            $obj = New-Object psobject

            $obj | Add-Member -Type NoteProperty -Name 'EnrollmentID'       -Value $_.enrollment_id
            $obj | Add-Member -Type NoteProperty -Name 'UserID'             -Value ($_.User).id
            $obj | Add-Member -Type NoteProperty -Name 'Name'               -Value $name
            $obj | Add-Member -Type NoteProperty -Name 'GivenName'          -Value ($_.User).first_name
            $obj | Add-Member -Type NoteProperty -Name 'Surname'            -Value ($_.User).last_name
            $obj | Add-Member -Type NoteProperty -Name 'Email'              -Value ($_.User).email
            $obj | Add-Member -Type NoteProperty -Name 'Campaign'           -Value $_.campaign_name
            $obj | Add-Member -Type NoteProperty -Name 'Module'             -Value $_.module_name
            $obj | Add-Member -Type NoteProperty -Name 'EnrollDate'         -Value $enrollDate
            $obj | Add-Member -Type NoteProperty -Name 'StartDate'          -Value $_.start_date
            $obj | Add-Member -Type NoteProperty -Name 'CompletetionDate'   -Value $_.completion_date 
            $obj | Add-Member -Type NoteProperty -Name 'Status'             -Value $_.status
            $obj | Add-Member -Type NoteProperty -Name 'Started'            -Value $started
            $obj | Add-Member -Type NoteProperty -Name 'TimeSpent'          -Value $time_spent 
            $obj | Add-Member -Type NoteProperty -Name 'PolicyAcknowledged' -Value $_.policy_acknowledged

            Return $obj
        }
    }
    Write-Verbose "Number of API Requests: $curl"
}