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. |
| -CheckPolicyNonSysadmin | switch | $false | Check password policy violations for non-sysadmin logins. Default: $true. |
| -CheckPolicySysadmin | switch | $false | Check password policy violations for sysadmin logins. Default: $true. |
| -ContinueOnError | switch | $false | Continue on error for an instance. |
| -EnableException | switch | $false | Throw exceptions immediately (overrides ContinueOnError). |
| -HtmlReportTemplate | string | 'Standard' | HTML template style: 'Standard', 'Compact', 'Detailed'. Default: 'Standard'. |
| -ReportBuiltInAdmins | switch | $false | When BUILTIN\Administrators is found in logins, report as warning. Default: $true. |
| -SkipAccessCheck | switch | $false | Skip the last-access determination entirely. Use when the account lacks the rights it needs (VIEW SERVER STATE / xp_readerrorlog) or to speed the audit up. No inactivity findings are produced in that case. |
| -SqlCredential | PSCredential | , | Optional PSCredential. |
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
Example 1, Audit local instance with all defaults
Invoke-sqmLoginAuditExample 2, Audit with AD orphan check
Invoke-sqmLoginAudit -SqlInstance "SQL01" -CheckAdOrphansExample 3, Include system logins, exclude service accounts
Invoke-sqmLoginAudit -SqlInstance "SQL01" -IncludeSystemLogins `
-ExcludeLogin 'NT SERVICE\*', 'sqmsa'Example 4, Pipeline: audit multiple instances, continue on error
"SQL01", "SQL02" | Invoke-sqmLoginAudit -ContinueOnErrorExample 5, 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