PowerShell script to import a .pfx into LocalMachine\My, grant the SQL Server service account private-key access, and optionally assign the certificate to a SQL Server instance for TLS.
  • PowerShell 98.8%
  • Batchfile 1.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Hannah Vernon 377ad35e2c Add AGENT-README.md and badge
Adopt the AGENT-README.md convention (agent-readme.md draft v0.1): purpose,
commands, guardrails, conventions, context, current state, surprises, and
contacts for AI agents working in this repo.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-30 15:05:22 -05:00
.github Add Install-SqlServerCertificate script and standard repo files 2026-07-30 15:00:10 -05:00
.gitattributes Add .gitattributes and .gitignore 2026-07-30 14:58:38 -05:00
.gitignore Add .gitattributes and .gitignore 2026-07-30 14:58:38 -05:00
AGENT-README.md Add AGENT-README.md and badge 2026-07-30 15:05:22 -05:00
certutil-merge.txt Add Install-SqlServerCertificate script and standard repo files 2026-07-30 15:00:10 -05:00
CODE_OF_CONDUCT.md Add Install-SqlServerCertificate script and standard repo files 2026-07-30 15:00:10 -05:00
CONTRIBUTING.md Add Install-SqlServerCertificate script and standard repo files 2026-07-30 15:00:10 -05:00
get-cert-details.cmd Add Install-SqlServerCertificate script and standard repo files 2026-07-30 15:00:10 -05:00
Install-SqlServerCertificate.ps1 Add Install-SqlServerCertificate script and standard repo files 2026-07-30 15:00:10 -05:00
LICENSE Add Install-SqlServerCertificate script and standard repo files 2026-07-30 15:00:10 -05:00
README.md Add AGENT-README.md and badge 2026-07-30 15:05:22 -05:00
SECURITY.md Add Install-SqlServerCertificate script and standard repo files 2026-07-30 15:00:10 -05:00
THIRD-PARTY-NOTICES.md Add Install-SqlServerCertificate script and standard repo files 2026-07-30 15:00:10 -05:00

Install-SqlServerCertificate

agent-readme

A single, self-contained PowerShell script that imports a .pfx certificate into the Windows LocalMachine\My store, grants the SQL Server service account read access to the private key, and optionally assigns the certificate to a SQL Server instance for TLS and restarts the service.

It is designed for certificate renewals: swapping in a new certificate on a server that already has TLS configured.

Why

Rotating the TLS certificate SQL Server uses normally means several manual steps in SQL Server Configuration Manager plus a private-key ACL edit. This script performs those steps consistently and verifiably, and supports -WhatIf so a renewed certificate can be validated before any change is committed.

Requirements

  • Windows with the PKI PowerShell module (Import-PfxCertificate, present on Windows Server and Windows 10/11).
  • Windows PowerShell 5.1 or PowerShell 7+.
  • An elevated (Administrator) session. Writing to LocalMachine\My, editing the machine key ACL, and writing the instance registry all require it.

Quick start

Validate a renewed certificate without changing anything:

.\Install-SqlServerCertificate.ps1 -PfxPath 'C:\certs\renewed.pfx' -InstanceName 'SQL2019' -AssignToSqlServer -WhatIf

Import, grant key access, assign to the instance, and restart:

.\Install-SqlServerCertificate.ps1 -PfxPath 'C:\certs\renewed.pfx' -InstanceName 'SQL2019' -AssignToSqlServer -RestartSqlServer

Parameters

Name Required Description
-PfxPath Yes Full path to the .pfx file. You are prompted securely for its password.
-InstanceName No SQL Server instance name. Omit for the default instance (MSSQLSERVER); for a named instance pass just the name, e.g. SQL2019.
-AssignToSqlServer No Write the certificate thumbprint to the instance's SuperSocketNetLib\Certificate registry value so SQL Server uses it for TLS.
-RestartSqlServer No Restart the SQL Server service and restart any dependents (e.g. SQL Server Agent) that were running. Requires -AssignToSqlServer.

What the script does

  1. Prompts for the .pfx password as a SecureString.
  2. Loads the certificate in memory (using an ephemeral key, no store change) and validates that it meets SQL Server's requirements: a private key is present, the validity period covers now, the Enhanced Key Usage includes Server Authentication (1.3.6.1.5.5.7.3.1), and the Key Usage permits Key Encipherment or Digital Signature.
  3. Imports the certificate into LocalMachine\My, selecting the leaf certificate if the .pfx contains a chain.
  4. Resolves the SQL Server service account and grants it Read access to the private key file, handling both CNG and legacy CSP key locations, and verifies the grant by SID.
  5. With -AssignToSqlServer, writes the lowercase thumbprint to the instance's registry.
  6. With -RestartSqlServer, restarts the service and starts any dependents that were running.

-WhatIf runs steps 1 and 2 (real validation) and then reports the actions that would be taken, without importing, editing ACLs, touching the registry, or restarting anything.

Certificate requirements

For SQL Server to accept the certificate, it must:

  • have an exportable or usable private key readable by the service account,
  • be currently valid (not expired, not post-dated),
  • include the Server Authentication EKU, and
  • have a subject or SAN that matches the name clients connect to.

The script checks the first three programmatically. Subject/SAN matching is environment-specific and is left to the operator.

Safety notes

  • Assigning a certificate requires a service restart to take effect; that restart is a brief outage, so schedule it.
  • If the renewed certificate does not meet SQL Server's requirements, the service can fail to start. Use -WhatIf first to confirm validation passes.
  • The script assumes an RSA key (the norm for SQL Server TLS). An ECDSA certificate would need a small change to use GetECDsaPrivateKey.

Contributing

See CONTRIBUTING.md. Work happens on feature/* or fix/* branches off dev; main is the release branch.

License

MIT. See LICENSE.