**Discovering Inactive Users in Active Directory with PowerShell** In this blog post, we'll explore a PowerShell script that helps you identify inactive users in your Active Directory domain. This script is designed to work with Microsoft Teams and will send a notification message to the channel when it finds inactive users. ### Prerequisites


### The Script The script is composed of two functions: `Get-InactiveADUsers` and `Send-TeamsMessage`. Let's break them down:


function Get-InactiveADUsers {
    [CmdletBinding()]
    param(
        [int]$InactiveDays = 90,
        [string]$Domain
    )

    # Import the Active Directory module
    Import-Module ActiveDirectory

    # Calculate the date 90 days ago
    $cutoffDate = (Get-Date).AddDays(-$InactiveDays)

    Write-Host "`nQuerying domain: $Domain" -ForegroundColor Cyan
    
    try {
        # Get inactive users for the current domain, excluding SVC and service accounts
        $inactiveUsers = Get-ADUser -Filter {
            Enabled -eq $true -and 
            LastLogonDate -lt $cutoffDate -and 
            -not (SamAccountName -like "SVC*") -and
            -not (SamAccountName -like "service*")
        } -Properties Name, SamAccountName, UserPrincipalName, LastLogonDate -Server $Domain |
        Select-Object Name, SamAccountName, UserPrincipalName, 
        @{Name = 'LastLogonDate'; Expression = { $_.LastLogonDate.ToString('yyyy-MM-dd') } }

        # Output the results
        if ($inactiveUsers) {
            Write-Host "Total inactive users (excluding SVC and service accounts) in $Domain : $($inactiveUsers.Count)" -ForegroundColor Yellow
            return $inactiveUsers
        }
        else {
            Write-Host "No inactive users found (excluding SVC and service accounts) in $Domain" -ForegroundColor Green
            return $null
        }
    }
    catch {
        Write-Host "Error querying domain $Domain : $_" -ForegroundColor Red
        return $null
    }
}

The `Get-InactiveADUsers` function takes two parameters: `$InactiveDays` and `$Domain`. It calculates the date 90 days ago using the `AddDays` method, then uses the `Get-ADUser` cmdlet to retrieve users who have been inactive for that period of time. The function filters out service accounts and SVC accounts before returning a list of inactive users. ### How It Works The script works by iterating through a list of domains and calling the `Get-InactiveADUsers` function for each domain. If the function returns a list of inactive users, it calls the `Send-TeamsMessage` function to send a notification message to Microsoft Teams.


function Send-TeamsMessage {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$true)]
        [string]$Domain,

        [Parameter(Mandatory=$true)]
        [int]$InactiveDays,

        [Parameter(Mandatory=$true)]
        [array]$InactiveUsers,

        [Parameter(Mandatory=$true)]
        [string]$WebhookUrl
    )

    # Define the message to send to Teams
    $message = "👮IMPORTANT! The list of inactive users on $Domain that have been inactive for the last $InactiveDays days."

    if ($InactiveUsers.Count -gt 0) {
        $msgTable = $InactiveUsers | ConvertTo-Html -Fragment
        $messagetemp = $message + $msgTable

        if ($messagetemp.Length -gt 28000) {
            $message += "There are too many inactive users to display in teams message. Total count: $($InactiveUsers.Count)"
        }
        else {
            $message += $msgTable
        }

        # Create a JSON payload
        $jsonPayload = @{
            "text" = $message
        }

        # Convert the payload to JSON
        $jsonBody = $jsonPayload | ConvertTo-Json

        # Post the message to the Teams channel using the webhook
        try {
            Invoke-RestMethod -Uri $WebhookUrl -Method Post -ContentType "application/json" -Body $jsonBody
            Write-Verbose "Message sent successfully to Teams."
        }
        catch {
            Write-Error "Failed to send message to Teams: $_"
        }
    }
    else {
        Write-Verbose "No inactive users found. Message not sent to Teams."
    }
}

The `Send-TeamsMessage` function takes four parameters: `$Domain`, `$InactiveDays`, `$InactiveUsers`, and `$WebhookUrl`. It constructs a message using the `ConvertTo-Html` cmdlet, then sends the message to Microsoft Teams using the webhook URL. ### Key Code Snippets Here are some key code snippets from the script:


$domains = @("[Your Domains Here]")

foreach ($domain in $domains) {
    $inactiveUsers = Get-InactiveADUsers -Domain $domain -InactiveDays 90
    if ($inactiveUsers) {
        Send-TeamsMessage -Domain $domain -InactiveDays 90 -InactiveUsers $inactiveUsers -WebhookUrl "[your teams webhook here]"
    }
}

These code snippets show how the script iterates through a list of domains, calls the `Get-InactiveADUsers` function to retrieve inactive users, and then sends a notification message to Microsoft Teams using the `Send-TeamsMessage` function. ### Conclusion In this blog post, we've explored a PowerShell script that helps you identify inactive users in your Active Directory domain. The script uses the `Get-ADUser` cmdlet to retrieve inactive users, filters out service accounts and SVC accounts, and then sends a notification message to Microsoft Teams using the webhook URL.