[CmdletBinding()] param( [Parameter(Mandatory = $true)][string]$ServerInstance, [Parameter(Mandatory = $true)][string]$SqlLogin, [Parameter(Mandatory = $true)][SecureString]$SqlPassword, [string]$DatabaseName = 'WscMvcTest' ) # Idempotent: creates the M5 integration test database and its one table if # missing, does nothing if they already exist. This is a deliberate, explicit # deployment step (SPEC SS10/SS9: "no broad filesystem/DB write privileges"; # a web request must never create schema) - never called from Default.asp or # any WSC, only from this tool. Credentials are supplied as parameters at # invocation time, never embedded in this (tracked) script - see # docs/DECISIONS.md for where the actual secret lives. SqlPassword is a # SecureString and is only ever converted to plain text in the narrow window # where sqlcmd.exe (an external process with no SecureString-aware API) # actually needs it as a command-line argument. $ErrorActionPreference = 'Stop' $plainPassword = [Runtime.InteropServices.Marshal]::PtrToStringUni( [Runtime.InteropServices.Marshal]::SecureStringToGlobalAllocUnicode($SqlPassword) ) $createDbSql = @" IF DB_ID(N'$DatabaseName') IS NULL BEGIN CREATE DATABASE [$DatabaseName]; END "@ $createTableSql = @" IF OBJECT_ID(N'dbo.Widgets', N'U') IS NULL BEGIN CREATE TABLE dbo.Widgets ( Id INT IDENTITY(1,1) PRIMARY KEY, Name NVARCHAR(100) NOT NULL ); END "@ try { Write-Output "Ensuring database [$DatabaseName] exists on $ServerInstance ..." sqlcmd -S $ServerInstance -U $SqlLogin -P $plainPassword -d master -Q $createDbSql -b if ($LASTEXITCODE -ne 0) { throw "sqlcmd failed creating database (exit $LASTEXITCODE)" } Write-Output "Ensuring dbo.Widgets table exists ..." sqlcmd -S $ServerInstance -U $SqlLogin -P $plainPassword -d $DatabaseName -Q $createTableSql -b if ($LASTEXITCODE -ne 0) { throw "sqlcmd failed creating table (exit $LASTEXITCODE)" } } finally { $plainPassword = $null } Write-Output "Test database ready: [$DatabaseName] on $ServerInstance (table dbo.Widgets)."