Add Update-SsrsCertificate.ps1 for SSRS certificate renewal #1

Merged
hannah-vernon merged 1 commit from feature/ssrs-certificate-update into dev 2026-07-31 17:26:37 -05:00

What does this PR do?

Adds Update-SsrsCertificate.ps1, a companion to Install-SqlServerCertificate.ps1
that rebinds SQL Server Reporting Services (SSRS) to a renewed TLS certificate when
SSRS is co-located with the SQL Server instance. It uses the supported Reporting
Services WMI provider (MSReportServer_ConfigurationSetting), the same mechanism
the Reporting Services Configuration Manager uses, so no netsh is required. It
verifies and, if needed, rewrites the <CertificateHash> values in
rsreportserver.config (backing the file up first), and can restart the SSRS
service.

Key design point: HTTP.SYS allows only one certificate per IP:port, and the report
server's two applications (ReportServerWebService, ReportServerWebApp) normally
share 0.0.0.0:443. The script groups bindings by IP:port and removes all of a
group's bindings before recreating them against the renewed certificate. Rebinding
one application at a time collides with its sibling on the shared binding and can
leave a binding removed without a replacement.

Fixes #

How was this tested?

  • PowerShell parser validation passes ([Parser]::ParseFile() returns no errors)
  • Ran with -WhatIf against a live SSRS instance: lists current bindings, reports the planned actions, and makes no changes
  • Manually tested on a live SSRS 2019 (Developer edition) instance: full rebind of both applications on 0.0.0.0:443 from an initial self-signed certificate to a renewed one, plus rsreportserver.config <CertificateHash> verification

Assumptions

  • The -RestartReportServer path (a Restart-Service call) requires a configured
    report server database so the service can start; it was not exercised in the test
    environment above and will be validated on a server that has one during the real
    renewal.
  • The renewed certificate is already imported into LocalMachine\My (for example by
    Install-SqlServerCertificate.ps1) and chains to a trusted root, which SSRS
    requires before it will bind a certificate.

Checklist

  • I have read the Contributing Guide
  • Changes are focused - one logical change per PR
  • Script runs cleanly under Set-StrictMode -Version Latest
  • State-changing actions honor -WhatIf via SupportsShouldProcess
  • Documentation updated (if user-visible behavior changed)
  • No commented-out code or debug leftovers
  • No real certificates, keys, or infrastructure names committed
## What does this PR do? Adds `Update-SsrsCertificate.ps1`, a companion to `Install-SqlServerCertificate.ps1` that rebinds SQL Server Reporting Services (SSRS) to a renewed TLS certificate when SSRS is co-located with the SQL Server instance. It uses the supported Reporting Services WMI provider (`MSReportServer_ConfigurationSetting`), the same mechanism the Reporting Services Configuration Manager uses, so no `netsh` is required. It verifies and, if needed, rewrites the `<CertificateHash>` values in `rsreportserver.config` (backing the file up first), and can restart the SSRS service. Key design point: HTTP.SYS allows only one certificate per IP:port, and the report server's two applications (`ReportServerWebService`, `ReportServerWebApp`) normally share `0.0.0.0:443`. The script groups bindings by IP:port and removes all of a group's bindings before recreating them against the renewed certificate. Rebinding one application at a time collides with its sibling on the shared binding and can leave a binding removed without a replacement. Fixes # ## How was this tested? - [x] PowerShell parser validation passes (`[Parser]::ParseFile()` returns no errors) - [x] Ran with `-WhatIf` against a live SSRS instance: lists current bindings, reports the planned actions, and makes no changes - [x] Manually tested on a live SSRS 2019 (Developer edition) instance: full rebind of both applications on `0.0.0.0:443` from an initial self-signed certificate to a renewed one, plus `rsreportserver.config` `<CertificateHash>` verification ## Assumptions - The `-RestartReportServer` path (a `Restart-Service` call) requires a configured report server database so the service can start; it was not exercised in the test environment above and will be validated on a server that has one during the real renewal. - The renewed certificate is already imported into `LocalMachine\My` (for example by `Install-SqlServerCertificate.ps1`) and chains to a trusted root, which SSRS requires before it will bind a certificate. ## Checklist - [x] I have read the [Contributing Guide](../CONTRIBUTING.md) - [x] Changes are focused - one logical change per PR - [x] Script runs cleanly under `Set-StrictMode -Version Latest` - [x] State-changing actions honor `-WhatIf` via `SupportsShouldProcess` - [x] Documentation updated (if user-visible behavior changed) - [x] No commented-out code or debug leftovers - [x] No real certificates, keys, or infrastructure names committed
Rebinds SQL Server Reporting Services to a renewed TLS certificate using the
supported Reporting Services WMI provider (MSReportServer_ConfigurationSetting),
with no netsh. Verifies and, if needed, rewrites the CertificateHash values in
rsreportserver.config (with a backup), and can restart the SSRS service.

- Groups SSL bindings by IP:port and rebinds each group as a unit (remove all,
  then recreate) because HTTP.SYS allows one certificate per IP:port and the two
  report server applications share 0.0.0.0:443.
- Uses lowercase thumbprints, as the WMI provider requires and writes.
- Honors -WhatIf via ShouldProcess while still running the read-only WMI queries
  needed to plan.
- Validated against a live SSRS 2019 instance (rebind + config verification);
  the -RestartReportServer path is exercised on servers with a configured report
  server database.

Docs: README gains an SSRS section; AGENT-README covers the second script and the
SSRS-specific gotchas.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
hannah-vernon/Install-SqlServerCertificate!1
No description provided.