New-SqlSpnPlan Builds an SPN registration plan from a verified account, resolved infrastructure, and a role.
Description
Composes the canonical plan object that the rest of the module consumes: { PlanGuid, AccountDn, ProposedSpns, Role, Scenario, TargetDomain, CrossForest }
The service class for each SPN comes from Get-SqlRoleMetadata. For FCI Engine registrations, if the supplied VerifiedAccount is not a computer object the function attempts to resolve the cluster Virtual Computer Object (VCO) from the infrastructure's virtual name; on success a warning is emitted and the plan targets the VCO. On lookup failure the caller is instructed to pass an explicit -VirtualComputerAccount.
Returns $null for roles that do not require an SPN (e.g., Agent under most configurations).
Recipes
$acct = Get-SqlSpnAccount -SamAccountName 'svc_sql_prod'
$infra = Get-SqlSpnInfrastructure -Scenario Standalone -TargetName SQLSRV01
$plan = New-SqlSpnPlan -VerifiedAccount $acct -Infrastructure $infra -Role Engine
Notes
Cross-forest detection comes from Get-SqlSpnInfrastructure; this function propagates TargetDomain so Invoke-SqlSpnExecutionEngine can pass setspn -T.
Role coverage (v1.4.0, DR-309 + DR-311): Public surface narrowed to the proven Engine core. The ValidateSet exposes only Engine and Agent (Agent's RequireSpn=$false; returns $null as a documented no-op). SSAS, SSRS, PBIRS, Browser, and the remaining BTRD roles are deferred as named, demand-sequenced, prove-before-expose post-v1 expansions. The internal Get-SqlRoleMetadata table retains entries; they are simply not user-reachable in v1.
Scenario coverage (v1.4.0, DR-309): Standalone, AlwaysOn, and FCI - all three lab-proven end-to-end on a real domain (Waves 1-3, 2026-05-17). MSDTC removed from the public Scenario surface; the prior MSDTC=>MSSQLSvc/ pinning test is inverted to assert MSDTC is NOT publicly accepted in v1.
Parameters
Was this page helpful? Report an issue or suggest an improvement →