Execution Flow
Synopsis
Each check uses the internal _AddFinding helper to add a structured row to $detailRows. Password-age and policy checks are differentiated between sysadmin and non-sysadmin logins: sysadmins are held to the stricter -MaxPasswordAgeDaysSysadmin threshold (default 365 days) while non-sysadmins use -MaxPasswordAgeDays (default 180). The last-login column is always NULL in sys.server_principals — never-used detection falls back to CreateDate for SQL logins. Duplicate SID detection groups by [System.BitConverter]::ToString($row.Sid).
$script:dbatoolsAvailable). AD orphan detection additionally requires the ActiveDirectory module (RSAT). The HTML report is generated inline — no external templates needed.Syntax
Invoke-sqmLoginAudit [-SqlInstance <String[]>] # default: $env:COMPUTERNAME; pipeline [-SqlCredential <PSCredential>] [-InactivityThresholdDays <Int>] # default: 90 [-MaxPasswordAgeDays <Int>] # default: 180 (non-sysadmin) | 0 = disable [-MaxPasswordAgeDaysSysadmin <Int>] # default: 365 (sysadmin) | 0 = disable [-ExcludeLogin <String[]>] # wildcards supported [-IncludeSystemLogins] # include NT SERVICE\*, NT AUTHORITY\* [-CheckPolicyNonSysadmin] # default: $true [-CheckPolicySysadmin] # default: $true [-ReportBuiltInAdmins] # default: $true [-CheckAdOrphans] # requires ActiveDirectory module [-GenerateHtmlReport] # default: $true [-OutputPath <String>] # default: Get-sqmDefaultOutputPath [-ContinueOnError] [-EnableException] [-NoOpen] # skip auto-open of TXT report [-WhatIf]
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| -SqlInstance | String[] | $env:COMPUTERNAME | One or more instances. Pipeline-capable. |
| -InactivityThresholdDays | Int | 90 | Logins without activity since this many days are flagged as inactive. |
| -MaxPasswordAgeDays | Int | 180 | Max password age for non-sysadmin SQL logins. Set to 0 to disable. |
| -MaxPasswordAgeDaysSysadmin | Int | 365 | Max password age for sysadmin SQL logins. Set to 0 to disable. |
| -ExcludeLogin | String[] | — | Login names or wildcard patterns to exclude from the audit. |
| -IncludeSystemLogins | Switch | $false | Include NT SERVICE\* and NT AUTHORITY\* logins. |
| -CheckAdOrphans | Switch | $false | Check Windows logins against AD. Requires ActiveDirectory module (RSAT). |
| -GenerateHtmlReport | Switch | $true | Generate a dark-theme HTML report alongside TXT and CSV. |
| -OutputPath | String | Get-sqmDefaultOutputPath | Directory for report files. |
| -NoOpen | Switch | $false | Skip auto-opening the TXT report after completion. |
Return Value
Returns one PSCustomObject per processed instance.
| Property | Description |
|---|---|
| SqlInstance | Instance name. |
| DetailRows | Array of finding objects: LoginName, LoginType, IsEnabled, IsSysadmin, Category, FindingType, Detail, Status. |
| Status | OK — no findings; Warning — one or more findings; Error — connection error. |
| TxtFile / CsvFile / HtmlFile | Paths to the generated report files. |
Examples
# Audit local instance with all defaults Invoke-sqmLoginAudit # Audit with AD orphan check Invoke-sqmLoginAudit -SqlInstance "SQL01" -CheckAdOrphans # Include system logins, exclude service accounts Invoke-sqmLoginAudit -SqlInstance "SQL01" -IncludeSystemLogins ` -ExcludeLogin 'NT SERVICE\*', 'sqmsa' # Pipeline: audit multiple instances, continue on error "SQL01", "SQL02" | Invoke-sqmLoginAudit -ContinueOnError # Check only findings (not clean logins) $r = Invoke-sqmLoginAudit -SqlInstance "SQL01" -NoOpen $r[0].DetailRows | Where-Object Status -eq 'Warning' | Format-Table LoginName, Category, FindingType, Detail