Release: -Action rename, community health files, and securify (issue #1) #1

Merged
hannah-vernon merged 13 commits from dev into main 2026-06-04 16:42:11 -05:00

What does this PR do?

Promotes the accumulated dev work to main as a release. This includes:

  • Rename of the -TestMode switch to -Action in Invoke-DagFailover.ps1, with updated README parameter docs.
  • sqlcmd argument and duplicate-parsing fixes (-v variable format, shared parse_server_names.sql include, PRINT truncation fix for AGs with many databases).
  • New parameterized helpers: Check-DagSync.ps1 (replacing check-sync.cmd) and the DR login script wrapper with a shared exclusion file.
  • Community health files: LICENSE (MIT), CONTRIBUTING.md, CODE_OF_CONDUCT.md, SECURITY.md, issue/PR templates.

How was this tested?

  • PowerShell scripts parse cleanly ([System.Management.Automation.Language.Parser]::ParseFile(...) returns no errors)
  • .sql changes validated with sqlcmd against a non-production Distributed AG
  • Manually tested on a live Distributed Availability Group: ran .\Invoke-DagFailover.ps1 end to end. Failover completed successfully and DNS was updated as expected. The SQL Server environment reported the failover via SQL Server Agent Alerts on Error 1480. Post-failover connectivity confirmed: all applications using the Distributed AG reconnected successfully.

Checklist

  • I have read the Contributing Guide
  • Changes are focused - one logical change per PR
  • No real server names, hostnames, IP addresses, or credentials are committed
  • Documentation updated (README, parameter tables) if behavior changed
  • No commented-out code or debug leftovers
## What does this PR do? Promotes the accumulated `dev` work to `main` as a release. This includes: - Rename of the `-TestMode` switch to `-Action` in `Invoke-DagFailover.ps1`, with updated README parameter docs. - sqlcmd argument and duplicate-parsing fixes (`-v` variable format, shared `parse_server_names.sql` include, PRINT truncation fix for AGs with many databases). - New parameterized helpers: `Check-DagSync.ps1` (replacing `check-sync.cmd`) and the DR login script wrapper with a shared exclusion file. - Community health files: `LICENSE` (MIT), `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`, `SECURITY.md`, issue/PR templates. ## How was this tested? - [x] PowerShell scripts parse cleanly (`[System.Management.Automation.Language.Parser]::ParseFile(...)` returns no errors) - [x] `.sql` changes validated with `sqlcmd` against a non-production Distributed AG - [x] Manually tested on a live Distributed Availability Group: ran `.\Invoke-DagFailover.ps1` end to end. Failover completed successfully and DNS was updated as expected. The SQL Server environment reported the failover via SQL Server Agent Alerts on Error 1480. Post-failover connectivity confirmed: all applications using the Distributed AG reconnected successfully. ## Checklist - [x] I have read the [Contributing Guide](../CONTRIBUTING.md) - [x] Changes are focused - one logical change per PR - [x] No real server names, hostnames, IP addresses, or credentials are committed - [x] Documentation updated (README, parameter tables) if behavior changed - [x] No commented-out code or debug leftovers
sqlcmd requires variables in Name="Value" format with no spaces around
the equals sign.  The spaces caused sqlcmd to reject the entire argument
string as invalid ('Invalid argument' error).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Server name parsing (extracting bare hostname from SERVER\INSTANCE,
SERVER.domain, or SERVER,PORT formats) was duplicated across steps
02, 03, 04a, 08, and 09.  This commit:

- Creates parse_server_names.sql as a shared batch fragment
- Replaces inline CHARINDEX logic in steps 02, 03, 08 with :r include
- Refactors step 04a to use the include (renames @agname_* variables
  to @primary_name/@secondary_name for consistency)
- Simplifies step 09 hostname extraction using variables already
  available from step 04a
- Upgrades all consumers to handle SERVER.domain and SERVER,PORT
  formats (previously only steps 04a and 09 handled these)
- Updates README file inventory

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The old check-sync.cmd had hardcoded server names, making it unusable
on machines that cannot reach those specific servers.  The new
Check-DagSync.ps1 accepts -Primary, -Secondary, and -SqlInstance
parameters, matching the pattern used by Invoke-DagFailover.ps1.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Shows the full sqlcmd command line before each invocation when
-Debug is passed, making it easier to diagnose connection and
variable issues on different environments.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
PRINT truncates nvarchar(max) at 4000 characters (8000 bytes).
When the AG contains enough databases, the generated LSN SQL
exceeds this limit and gets silently cut off mid-line, leaving
an unclosed bracket that cascades into parse errors for
parse_server_names.sql and all subsequent code.

Replace the string-concatenation + single PRINT approach with
a cursor that PRINTs one row at a time (~200 chars each).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Move the hardcoded login exclusion list into excluded-logins.txt
(plain text, one login per line, # comments).  The new
Check-ActiveLogins.ps1 reads the file, validates each name against
a strict character whitelist to prevent SQL injection, writes a
sanitized temp query, and runs it via sqlcmd.

Also replaces NOT IN with NOT EXISTS for the exclusion filter.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Create Generate-DrLoginScripts.ps1 to replace the hardcoded
generate_dr_login_scripts.sql.  Both Check-ActiveLogins.ps1 and
Generate-DrLoginScripts.ps1 now share excluded-logins.txt with
a pipe-delimited format (login | reason).  Login names are
validated against a strict character whitelist; reason text is
validated separately.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Rename the Invoke-DagFailover.ps1 -TestMode parameter to -Action (still
mapped to the TestMode sqlcmd variable) and document the Failback/Failover
behavior in README.md, including a warning that Failback is not an undo
mechanism for a failed Failover.

Add repository community health files:
- LICENSE (MIT)
- CONTRIBUTING.md (branch model, PowerShell parse-validation and sqlcmd
  testing standards, PR expectations)
- CODE_OF_CONDUCT.md (Contributor Covenant v2.1, contact coc@mvct.com)
- SECURITY.md (vulnerability reporting, contact vuln@mvct.com)
- .forgejo/ issue templates, issue config, and pull request template

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
# Conflicts:
#	README.md
Securify before public: delete disable_logins.sql and enable_logins.sql (static
lists that contained real production login names), superseded by
Generate-DrLoginScripts.ps1.  Untrack excluded-logins.txt and git-ignore it so
site-specific login names are never committed; add excluded-logins.sample.txt as
a genericized template.  Update README references accordingly.

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/dag-failover!1
No description provided.