Feature request: Alert on systems in AD\Entra but not in Immybot

Hey all,

This would be a helpful feature request to determine if we have our tools installed, namely Immybot, across all endpoints within a given environment. The most important thing to install in our stack is Immybot, as all of our other tools are coming from this agent.

An AD query on domain controller should help to gather a list and compare that to Immy computers.

Since there is an Azure integration, we should be able to query the Azure instance of the client in question, compare that to Immy computers and then email our alerts email with the odd ones out.

For the AD piece…here’s a quick script we just created to help us detect systems that have checked into AD recently (within 7 days by default) but don’t exist within ImmyBot.

param(
    [string]$PreferredDomainControllerName,
    [int]$Last_Checked_In_Days = 7,
    [ValidateScript({
        if ($_ -match "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$") {
            $true
        } else {
            throw "The provided string is not a valid email address."
        }
    })]
    [string]$EmailAddress = '[email protected]'
)

function Write-Log {
    param(
        [string]$Message,
        [string]$Level = "INFO"
    )

    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    Write-Host "[$timestamp] [$Level] $Message"
}

# Initialize a boolean variable to track status
$ImmyBotAgentsOk = $true

try {
    # Retrieve Domain Controller based on preference
    if (![string]::IsNullOrEmpty($PreferredDomainControllerName)) {
        $DomainController = Get-ImmyDomainController -PreferredDomainControllerName $PreferredDomainControllerName
    } else {
        $DomainController = Get-ImmyDomainController
    }

    if(!$DomainController) {
        throw "Unable to find domain controller."
    }

    Write-Log "Found Domain Controller: $($DomainController.Name)"
        
    # Execute command on Domain Controller
    $ADComputers = $DomainController | Invoke-ImmyCommand -IncludeLocals -Timeout 300 {
        # Accessing external variable within the script block
        $Last_Checked_In_Days = $using:Last_Checked_In_Days
        $CutOffDate = (Get-Date).AddDays(-$Last_Checked_In_Days).ToFileTime()
        $Filter = "LastLogonTimeStamp -ge '$CutOffDate'"
        
        try {
            # Retrieve recently checked-in AD computer names, DNS host names, and last logon dates
            Get-ADComputer -Filter $Filter -Property DNSHostName, LastLogonDate | ForEach-Object {
                # Split the DNSHostName to remove the domain portion
                $hostname = ($_.DNSHostName -split '\.')[0]
                # Return a custom object with the necessary properties
                [PSCustomObject]@{
                    Name          = $hostname
                    LastLogonDate = $_.LastLogonDate
                }
            }
        } catch {
            Write-Host "Error retrieving AD computers with filter '$Filter': $_" -Level "ERROR"
            @() # Return an empty array in case of error
        }
    }

    # Retrieve computers from ImmyBot
    $ImmyBotComputers = Get-ImmyComputer -IncludeOffline | Select-Object -ExpandProperty Name

    # Initialize a list to keep track of missing computers
    $MissingImmyBotComputers = @()

    # Compare and find computers missing in ImmyBot
    foreach ($ADComputer in $ADComputers) {
        if ($ADComputer.Name -notin $ImmyBotComputers) {
            Write-Log "AD Computer '$($ADComputer.Name)' not found in ImmyBot. Last Logon Date: $($ADComputer.LastLogonDate)" -Level "WARNING"
            $MissingImmyBotComputers += $ADComputer
            # Update status variable to indicate an issue
            $ImmyBotAgentsOk = $false
        }
    }

    # Prepare and send email if there are missing computers
    if ($MissingImmyBotComputers.Count -gt 0) {
        $subject = "$TenantName - AD computers are missing ImmyBot agents"
        $body = "The following AD computers are missing ImmyBot agents:<br/><table border=`"1`"><tr><th>Computer Name</th><th>Last Logon Date</th></tr>"
        foreach ($Computer in $MissingImmyBotComputers) {
            $body += "<tr><td>$($Computer.Name)</td><td>$($Computer.LastLogonDate)</td></tr>"
        }
        $body += "</table>"
        Send-ImmyEmail -Subject $subject -To $EmailAddress -Body $body
        Write-Log "Email sent to $EmailAddress with details of computers missing ImmyBot agents." -Level "INFO"        
    } else {
        Write-Log "Success: All AD computers are accounted for in ImmyBot (ImmyBot agent fully deployed)." -Level "INFO"        
    }
} catch {
    Write-Log "An error occurred: $_" -Level "ERROR"    
}

# Return the status
return $ImmyBotAgentsOk