functions/User/Start-HawkUserInvestigation.ps1

Function Start-HawkUserInvestigation {
    <#
    .SYNOPSIS
        Performs a comprehensive user-specific investigation using Hawk's automated data collection capabilities.
 
    .DESCRIPTION
        Start-HawkUserInvestigation automates the collection and analysis of Microsoft 365 security data
        for specific users. It runs multiple specialized cmdlets to gather detailed information about user
        configuration, activities, and potential security concerns.
 
        The command can run in either interactive mode (default) or non-interactive mode. Interactive mode is used
        when only UserPrincipalName is provided, while non-interactive mode is automatically enabled when any
        additional parameter is specified.
 
        Data collected includes:
        - User mailbox configuration and statistics
        - Inbox rules and email forwarding settings
        - Authentication history and mailbox audit logs
        - Administrative changes affecting the user
        - Message trace data and mobile device access
        - AutoReply configuration
 
        All collected data is stored in a structured format for analysis, with suspicious findings
        highlighted for investigation.
 
    .PARAMETER UserPrincipalName
        Single UPN of a user, comma-separated list of UPNs, or an array of objects that contain UPNs.
        This is the only required parameter and specifies which users to investigate.
 
    .PARAMETER StartDate
        The beginning date for the investigation period. When specified, must be used with EndDate.
        Cannot be later than EndDate and the date range cannot exceed 365 days.
        Providing this parameter automatically enables non-interactive mode.
        Format: MM/DD/YYYY
 
    .PARAMETER EndDate
        The ending date for the investigation period. When specified, must be used with StartDate.
        Cannot be in the future and the date range cannot exceed 365 days.
        Providing this parameter automatically enables non-interactive mode.
        Format: MM/DD/YYYY
 
    .PARAMETER DaysToLookBack
        Alternative to StartDate/EndDate. Specifies the number of days to look back from the current date.
        Must be between 1 and 365. Cannot be used together with StartDate.
        Providing this parameter automatically enables non-interactive mode.
 
    .PARAMETER FilePath
        The file system path where investigation results will be stored.
        Required in non-interactive mode. Must be a valid file system path.
        Providing this parameter automatically enables non-interactive mode.
 
    .PARAMETER SkipUpdate
        Switch to bypass the automatic check for Hawk module updates.
        Useful in automated scenarios or air-gapped environments.
        Providing this parameter automatically enables non-interactive mode.
 
    .PARAMETER Confirm
        Prompts you for confirmation before executing each investigation step.
        By default, confirmation prompts appear for operations that could collect sensitive data.
 
    .PARAMETER WhatIf
        Shows what would happen if the command runs. The command is not executed.
        Use this parameter to understand which investigation steps would be performed without actually collecting data.
 
    .OUTPUTS
        Creates multiple CSV and JSON files containing investigation results.
        All outputs are organized in user-specific folders under the specified FilePath directory.
        See individual cmdlet help for specific output details.
 
    .EXAMPLE
        Start-HawkUserInvestigation -UserPrincipalName user@contoso.com
 
        Investigates a single user in interactive mode, prompting for date range and output location.
 
    .EXAMPLE
        Start-HawkUserInvestigation -UserPrincipalName user@contoso.com -DaysToLookBack 30 -FilePath "C:\Investigation"
 
        Investigates a single user looking back 30 days, saving results to C:\Investigation.
        Runs in non-interactive mode because parameters beyond UserPrincipalName were specified.
 
    .EXAMPLE
        Start-HawkUserInvestigation `
            -UserPrincipalName (Get-Mailbox -Filter {CustomAttribute1 -eq "C-level"}) `
            -StartDate "01/01/2024" `
            -EndDate "01/31/2024" `
            -FilePath "C:\Investigation"
 
        Investigates all users with CustomAttribute1="C-level" for January 2024.
        Runs in non-interactive mode because multiple parameters were specified.
    .LINK
        https://hawkforensics.io
 
    .LINK
        https://github.com/T0pCyber/hawk
    #>

    [CmdletBinding(SupportsShouldProcess = $true)]
    param (
        [Parameter(Mandatory = $true)]
        [array]$UserPrincipalName,

        [DateTime]$StartDate,
        [DateTime]$EndDate,
        [int]$DaysToLookBack,
        [string]$FilePath,
        [switch]$SkipUpdate
    )

    begin {
        $NonInteractive = Test-HawkNonInteractiveMode -PSBoundParameters $PSBoundParameters
        Send-AIEvent -Event "CmdRun"

        if ($NonInteractive) {
            $processedDates = Test-HawkDateParameter -PSBoundParameters $PSBoundParameters -StartDate $StartDate -EndDate $EndDate -DaysToLookBack $DaysToLookBack
            $StartDate = $processedDates.StartDate
            $EndDate = $processedDates.EndDate

            # Now call validation with updated StartDate/EndDate
            $validation = Test-HawkInvestigationParameter `
                -StartDate $StartDate -EndDate $EndDate `
                -DaysToLookBack $DaysToLookBack -FilePath $FilePath -NonInteractive

            if (-not $validation.IsValid) {
                foreach ($error in $validation.ErrorMessages) {
                    Stop-PSFFunction -Message $error -EnableException $true
                }
            }

            try {
                Initialize-HawkGlobalObject -StartDate $StartDate -EndDate $EndDate `
                    -DaysToLookBack $DaysToLookBack -FilePath $FilePath `
                    -SkipUpdate:$SkipUpdate -NonInteractive:$NonInteractive
            }
            catch {
                Stop-PSFFunction -Message "Failed to initialize Hawk: $_" -EnableException $true
            }
        }
    }

    process {
        if (Test-PSFFunctionInterrupt) { return }

        # Check if Hawk object exists and is fully initialized
        if (Test-HawkGlobalObject) {
            Initialize-HawkGlobalObject
        }
        $investigationStartTime = Get-Date


        if ($PSCmdlet.ShouldProcess("Investigating Users")) {
            Out-LogFile "Starting User Investigation." -Action
            Send-AIEvent -Event "CmdRun"


            # Verify the UPN input
            [array]$UserArray = Test-UserObject -ToTest $UserPrincipalName

            foreach ($Object in $UserArray) {
                [string]$User = $Object.UserPrincipalName

                if ($PSCmdlet.ShouldProcess("Running Get-HawkUserConfiguration for $User")) {
                    Write-Output ""
                    Out-LogFile "Running Get-HawkUserConfiguration." -Action
                    Get-HawkUserConfiguration -User $User
                }

                if ($PSCmdlet.ShouldProcess("Running Get-HawkUserInboxRule for $User")) {
                    Write-Output ""
                    Out-LogFile "Running Get-HawkUserInboxRule." -Action
                    Get-HawkUserInboxRule -User $User
                }

                if ($PSCmdlet.ShouldProcess("Running Get-HawkUserEmailForwarding for $User")) {
                    Write-Output ""
                    Out-LogFile "Running Get-HawkUserEmailForwarding." -Action
                    Get-HawkUserEmailForwarding -User $User
                }

                if ($PSCmdlet.ShouldProcess("Running Get-HawkUserAutoReply for $User")) {
                    Write-Output ""
                    Out-LogFile "Running Get-HawkUserAutoReply." -Action
                    Get-HawkUserAutoReply -User $User
                }

                if ($PSCmdlet.ShouldProcess("Running Get-HawkUserEntraIDSignInLog for $User")) {
                    Write-Output ""
                    Out-LogFile "Running Get-HawkUserEntraIDSignInLog." -Action
                    Get-HawkUserEntraIDSignInLog -UserPrincipalName $User
                }

                if ($PSCmdlet.ShouldProcess("Running Get-HawkUserUALSignInLog for $User")) {
                    Write-Output ""
                    Out-LogFile "Running Get-HawkUserUALSignInLog." -Action
                    Get-HawkUserUALSignInLog -User $User -ResolveIPLocations
                }

                if ($PSCmdlet.ShouldProcess("Running Get-HawkUserMailboxAuditing for $User")) {
                    Write-Output ""
                    Out-LogFile "Running Get-HawkUserMailboxAuditing." -Action
                    Get-HawkUserMailboxAuditing -User $User
                }

                if ($PSCmdlet.ShouldProcess("Running Get-HawkUserAdminAudit for $User")) {
                    Write-Output ""
                    Out-LogFile "Running Get-HawkUserAdminAudit." -Action
                    Get-HawkUserAdminAudit -User $User
                }

                if ($PSCmdlet.ShouldProcess("Running Get-HawkUserMessageTrace for $User")) {
                    Write-Output ""
                    Out-LogFile "Running Get-HawkUserMessageTrace." -Action
                    Get-HawkUserMessageTrace -User $User
                }

                if ($PSCmdlet.ShouldProcess("Running Get-HawkUserMailItemsAccessed for $User")) {
                    Write-Output ""
                    Out-LogFile "Running Get-HawkUserMailItemsAccessed." -Action
                    Get-HawkUserMailItemsAccessed -UserPrincipalName $User
                }
                if ($PSCmdlet.ShouldProcess("Running Get-HawkUserExchangeSearchQuery for $User")) {
                    Write-Output ""
                    Out-LogFile "Running Get-HawkUserExchangeSearchQuery." -Action
                    Get-HawkUserExchangeSearchQuery -UserPrincipalName $User
                }

                if ($PSCmdlet.ShouldProcess("Running Get-HawkUserMailSendActivity for $User")) {
                    Write-Output ""
                    Out-LogFile "Running Get-HawkUserMailSendActivity." -Action
                    Get-HawkUserMailSendActivity -UserPrincipalName $User
                }

                if ($PSCmdlet.ShouldProcess("Running Get-HawkUserSharePointSearchQuery for $User")) {
                    Write-Output ""
                    Out-LogFile "Running Get-HawkUserSharePointSearchQuery." -Action
                    Get-HawkUserSharePointSearchQuery -UserPrincipalName $User
                }

                if ($PSCmdlet.ShouldProcess("Running Get-HawkUserMobileDevice for $User")) {
                    Write-Output ""
                    Out-LogFile "Running Get-HawkUserMobileDevice." -Action
                    Get-HawkUserMobileDevice -User $User
                }

            }
        }

    } end {
        # Calculate end time and display summary
        $investigationEndTime = Get-Date
        Write-HawkInvestigationSummary -StartTime $investigationStartTime -EndTime $investigationEndTime -InvestigationType 'User' -UserPrincipalName $UserPrincipalName
    }

}