Unlock-sqmSqlLogin
Security
sqmSQLTool v1.9.105+ · Unlock
✓ -WhatIf supported · ✓ idempotent (no-op if already unlocked)
is_locked = 1 under CHECK_POLICY = ON, enforced via the Windows account-lockout policy) after too many bad password attempts: unlocking it without touching the password — whether you know the current one or not — and a real password reset for when it's genuinely lost. T-SQL has no standalone ALTER LOGIN ... UNLOCK; UNLOCK only works paired with PASSWORD =. Without -NewPassword, this function instead uses the documented CHECK_POLICY = OFF / = ON toggle, which clears the lockout flag without touching the password hash at all. Neither code path restates CHECK_POLICY/CHECK_EXPIRATION in its ALTER LOGIN statement, so SQL Server leaves both exactly as they were — and the function re-reads sys.sql_logins afterward to confirm that, rather than trusting "no exception thrown" as proof nothing drifted.
ⓘ Why the toggle instead of just re-supplying the same password?
ALTER LOGIN ... WITH PASSWORD = 'same-as-before' UNLOCK would technically work if you know the password, but it re-hashes it and is one more place the plaintext has to pass through. The CHECK_POLICY toggle unlocks the account regardless of whether the caller knows the password at all — it's the only option when the password is unknown but shouldn't be reset.
⚠
-MustChange (only valid together with -NewPassword) maps to SQL Server's MUST_CHANGE clause, which itself requires CHECK_EXPIRATION = ON on the login. This function checks that up front and fails with a clear message naming the login and instance instead of letting SQL Server's own error surface unexplained.
Parameters
| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
| -SqlInstance | string[] | Optional | $env:COMPUTERNAME | Pipeline-capable. One login name applied across one or more instances. |
| -SqlCredential | PSCredential | Optional | , | SQL credential for the connection. |
| -Login | string | Required | , | SQL-Auth login to unlock. |
| -NewPassword | SecureString | Optional | , | Without it: unlock only, password untouched. With it: real reset via PASSWORD = @newpwd UNLOCK, passed as a query parameter and never logged. |
| -MustChange | switch | Switch | $false | Adds MUST_CHANGE. Requires -NewPassword and CHECK_EXPIRATION = ON on the login, or the function throws before touching anything. |
| -ContinueOnError | switch | Switch | $false | With multiple -SqlInstance values, keep going after a per-instance failure instead of stopping. |
| -EnableException | switch | Switch | $false | Throw immediately (takes precedence over -ContinueOnError). |
| -WhatIf / -Confirm | switch | Switch | , | Standard ShouldProcess support (ConfirmImpact 'Medium'). |
Execution Flow
Return Value
One
PSCustomObject per instance: SqlInstance, Login, WasLocked, PasswordChanged, CheckPolicy, CheckExpiration, IsLockedNow, Status (Success / AlreadyUnlocked / NotFound / WhatIfSkipped / Failed), Message.
Examples
Unlock only — password stays exactly as it was, known or not
Unlock-sqmSqlLogin -SqlInstance SQL01 -Login app_user
Password genuinely lost — real reset, forced change at next login
$newPw = Read-Host -AsSecureString 'New password' Unlock-sqmSqlLogin -SqlInstance SQL01 -Login app_user -NewPassword $newPw -MustChange
Same login, unlocked across every AlwaysOn replica in one call
"SQL01","SQL02","SQL03" | Unlock-sqmSqlLogin -Login app_user -ContinueOnError -Confirm:$false
Preview only — nothing is changed
Unlock-sqmSqlLogin -SqlInstance SQL01 -Login app_user -WhatIf