hawk icon indicating copy to clipboard operation
hawk copied to clipboard

Bug: PowerShell Core Suggestion Messages

Open jonnybottles opened this issue 10 months ago • 1 comments

What Happened?

When running tenant investigation functions in PowerShell Core (but not PowerShell Desktop), several functions generate unwanted Suggestion [4,General]: The most similar commands are... messages after completing their operations. This affects 12 specific tenant investigation functions that interact with Exchange Online.

Steps to Reproduce

  1. Install Hawk module version 4.0
  2. Open PowerShell Core (not PowerShell Desktop)
  3. Run Start-HawkTenantInvestigation
  4. At the end of the of tenant investigation notice the message Suggestion [4,General]: The most similar commands are... :

Technical Analysis

  • Issue only occurs in PowerShell Core
  • Only affects functions that use Exchange Online cmdlets through Get-AllUnifiedAuditLogEntry
  • Does not affect functionality or data collection
  • User investigation functions using the same cmdlets do not exhibit this behavior due to different scoping
  • ** The only functions that this occurs on when running a tenant investigation are:
    • Get-HawkTenantConfiguration
    • Get-HawkTenantEDiscoveryConfiguration
    • Get-HawkTenantAdminInboxRuleCreation
    • Get-HawkTenantAdminInboxRuleModification
    • Get-HawkTenantAdminInboxRuleRemoval
    • Get-HawkTenantAdminMailboxPermissionChange
    • Get-HawkTenantAdminEmailForwardingChange
    • Get-HawkTenantEDiscoveryLog
    • Get-HawkTenantDomainActivity
    • Get-HawkTenantRBACChange
    • Get-HawkTenantAzureAppAuditLog
    • Get-HawkTenantEXOAdmin
  • Pattern suggests PowerShell Core handles Exchange Online session cleanup differently than Desktop

Previously attempted fixes:

1. Using Global Parameter Defaults in preimport.ps1

$session = Test-EXOConnection
if ($PSVersionTable.PSEdition -eq 'Core') {
    $PSDefaultParameterValues['*:InformationAction'] = 'SilentlyContinue'
}

2. Attempted global parameter values in preimport.ps1:

if ($PSVersionTable.PSEdition -eq 'Core') {
    $PSDefaultParameterValues['*:InformationAction'] = 'SilentlyContinue'
}

3. Adding Explicit return or break to end Block in Start-HawkTenantInvestigation:

end {
    try {
        # Calculate end time
        $investigationEndTime = Get-Date
        Write-HawkInvestigationSummary -StartTime $investigationStartTime -EndTime $investigationEndTime -InvestigationType 'Tenant' | Out-Null
        Out-LogFile "Tenant Investigation completed" -Information
        return
    }
    catch {
        Out-LogFile "Error in investigation summary: $($_.Exception.Message)" -isError
        Write-Error -ErrorRecord $_ -ErrorAction Continue
        return
    }
}

4. Mirroring Start-HawkTenantInvestigation to Match Start-HawkUserInvestigation Structure:

process {
    if ($PSCmdlet.ShouldProcess("Investigating Tenant")) {
        Get-HawkTenantConfiguration
        Get-HawkTenantEDiscoveryConfiguration
        Get-HawkTenantAdminInboxRuleCreation
        Get-HawkTenantAdminInboxRuleModification
        Get-HawkTenantAdminInboxRuleRemoval
        Get-HawkTenantAdminMailboxPermissionChange
        Get-HawkTenantAdminEmailForwardingChange
        Get-HawkTenantEDiscoveryLog
        Get-HawkTenantDomainActivity
        Get-HawkTenantRBACChange
        Get-HawkTenantEntraIDAuditLog
        Get-HawkTenantAzureAppAuditLog
        Get-HawkTenantEXOAdmin
        Get-HawkTenantConsentGrant
        Get-HawkTenantRiskyUsers
        Get-HawkTenantRiskDetections
        Get-HawkTenantEntraIDAdmin
        Get-HawkTenantAppAndSPNCredentialDetail
        Get-HawkTenantEntraIDUser
    }
}

5. Investigating Folder Creation Differences Between Tenant and User Investigations:

  • Found that Out-MultipleFileType handles folder creation differently for user vs tenant investigations.
  • User investigations create user-specific folders, while tenant investigations create a Tenant folder.
if ([string]::IsNullOrEmpty($User)) {
    $path = Join-Path $Hawk.FilePath "\Tenant"
} else {
    $path = Join-Path $Hawk.FilePath $User
}

6. Ensuring Write-HawkInvestigationSummary Does Not Return Output:

end {
    try {
        $investigationEndTime = Get-Date
        $null = Write-HawkInvestigationSummary -StartTime $investigationStartTime -EndTime $investigationEndTime -InvestigationType 'Tenant'
        $null = Out-LogFile "Tenant Investigation completed" -Information
    }
    catch {
        $null = Out-LogFile "Error in investigation summary: $($_.Exception.Message)" -isError
        Write-Error -ErrorRecord $_ -ErrorAction Continue
    }
}

Acceptance Criteria

  • Root cause determined
  • Suggestion prompt no longer displayed after a Tenant Investigation
  • User Guide->Troubleshooting section of Hawk website is updated

jonnybottles avatar Feb 06 '25 11:02 jonnybottles

This behavior appears to be related to PowerShell's command suggestion feature, which became a mainstream (non-experimental) feature in PowerShell 7.5. We are actively investigating this issue. Our current understanding is that this behavior is tied to PowerShell's new FeedbackProvider system, which replaced the previous experimental PSCommandNotFoundSuggestion feature. Since this is now a core PowerShell feature, it can no longer be disabled through experimental feature flags. See more at:

https://learn.microsoft.com/en-us/powershell/scripting/learn/experimental-features?view=powershell-7.5

https://github.com/PowerShell/PowerShell/issues/10213

jonnybottles avatar Feb 07 '25 13:02 jonnybottles