SQL Server 2025 on Windows — Complete Setup Guide
Terraform EC2 User Data
When provisioning a Windows EC2 instance with Terraform, the user_data block must be wrapped in <powershell> tags. The example below installs Chocolatey and uses it to install common packages automatically on first boot.
# User data for Windows EC2 must be wrapped in <powershell> tags
user_data = <<-EOF
<powershell>
# 1. Set execution policy to allow script execution
Set-ExecutionPolicy Bypass -Scope Process -Force;
# 2. Download and install Chocolatey
[System.Net.ServicePointManager]::SecurityProtocol = `
[System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'));
# 3. Use Chocolatey to install packages (-y flag auto-accepts licenses)
# Installing Visual C++ Redistributable and Google Chrome
choco install vcredist140 googlechrome -y
# 4. Create a log file to verify successful completion
"Chocolatey installation completed" | Out-File -FilePath C:\install_log.txt
</powershell>
EOF
Learn SQL Queries: https://www.w3schools.com/sql/
PowerShell Installation Script
The following script installs and fully configures SQL Server 2025 Express on a Windows machine. Run it as Administrator.
# ============================================================
# SQL Server 2025 Express — Full Setup Script
# ============================================================
# Set execution policy
Set-ExecutionPolicy Bypass -Scope Process -Force
# ── 1. Install Chocolatey ────────────────────────────────────
[System.Net.ServicePointManager]::SecurityProtocol = `
[System.Net.ServicePointManager]::SecurityProtocol -bor 3072
Invoke-Expression ((New-Object System.Net.WebClient).DownloadString(
'https://chocolatey.org/install.ps1'))
# Reload PATH so choco is available immediately
$env:PATH = [System.Environment]::GetEnvironmentVariable("PATH","Machine") + ";" +
[System.Environment]::GetEnvironmentVariable("PATH","User")
# ── 2. Skip pending-reboot checks ───────────────────────────
Remove-Item "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending" `
-Recurse -ErrorAction SilentlyContinue
Remove-Item "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired" `
-Recurse -ErrorAction SilentlyContinue
Remove-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" `
-Name "PendingFileRenameOperations" -ErrorAction SilentlyContinue
# ── 3. Install SQL Server 2025 ───────────────────────────────
# Use Chocolatey if the package is available
choco install sql-server-2025 `
--params '"/INSTANCENAME=SQLEXPRESS /INSTANCEID=SQLEXPRESS /SECURITYMODE=SQL /SAPWD=Welcome@12345 /TCPENABLED=1 /IACCEPTSQLSERVERLICENSETERMS"' `
-y --no-progress
# Alternative: winget install (uncomment if Chocolatey package is unavailable)
# winget install Microsoft.SQLServer.2025.Developer
# ── 4. Install sqlcmd and ODBC Driver ────────────────────────
choco install sqlcmd -y --no-progress # Microsoft standalone sqlcmd
choco install sqlserver-odbcdriver -y --no-progress # ODBC Driver 18 (required dependency)
# Reload PATH so sqlcmd is found in this session
$env:PATH = [System.Environment]::GetEnvironmentVariable("PATH","Machine") + ";" +
[System.Environment]::GetEnvironmentVariable("PATH","User")
# ── 5. Enable TCP/IP via registry ───────────────────────────
# SQL Server 2025 uses version folder MSSQL17.SQLEXPRESS
$tcpPath = "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL17.SQLEXPRESS\MSSQLServer\SuperSocketNetLib\Tcp"
$ipAllPath = "$tcpPath\IPAll"
Set-ItemProperty -Path $tcpPath -Name "Enabled" -Value 1
Set-ItemProperty -Path $ipAllPath -Name "TcpPort" -Value "1433"
Set-ItemProperty -Path $ipAllPath -Name "TcpDynamicPorts" -Value "" # clear dynamic port
# ── 6. Restart SQL Server service ───────────────────────────
# Named instance service name: MSSQL$SQLEXPRESS (NOT "MSSQLSERVER")
Restart-Service -Name "MSSQL`$SQLEXPRESS" -Force -ErrorAction Stop
Start-Sleep -Seconds 10
# ── 7. Configure SQL Server Browser ─────────────────────────
Set-Service -Name "SQLBrowser" -StartupType Automatic
Start-Service -Name "SQLBrowser" -ErrorAction SilentlyContinue
# ── 8. Open Windows Firewall ports ──────────────────────────
New-NetFirewallRule -DisplayName "SQL Server TCP 1433" `
-Direction Inbound -Protocol TCP -LocalPort 1433 -Action Allow -ErrorAction SilentlyContinue
New-NetFirewallRule -DisplayName "SQL Server Browser UDP 1434" `
-Direction Inbound -Protocol UDP -LocalPort 1434 -Action Allow -ErrorAction SilentlyContinue
# ── 9. Enable SA login ───────────────────────────────────────
$saSetupSql = @"
ALTER LOGIN [sa] ENABLE;
ALTER LOGIN [sa] WITH PASSWORD = 'Welcome@12345';
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'remote access', 1; RECONFIGURE;
"@
# Use Windows Auth (-E) first — most reliable right after installation
sqlcmd -S "localhost\SQLEXPRESS" -E -Q $saSetupSql
# Verify SA login works
sqlcmd -S "localhost\SQLEXPRESS" -U sa -P "Welcome@12345" `
-Q "SELECT @@VERSION, GETDATE();" -l 10
# ── 10. SQL Server Agent (not available in Express) ──────────
$agentSvc = Get-Service -Name "SQLAgent`$SQLEXPRESS" -ErrorAction SilentlyContinue
if ($agentSvc) {
Set-Service -Name "SQLAgent`$SQLEXPRESS" -StartupType Automatic
Start-Service -Name "SQLAgent`$SQLEXPRESS"
} else {
Write-Warning "SQL Server Agent is not available in Express edition."
}
Write-Host "`n✅ SQL Server 2025 setup complete." -ForegroundColor Green
Write-Host " Connect: sqlcmd -S localhost\SQLEXPRESS -U sa -P 'Welcome@12345'" -ForegroundColor Cyan
Script Step Summary
| Step | Action | Key Detail |
|---|---|---|
| 1 | Install Chocolatey | Package manager for Windows |
| 2 | Clear reboot flags | Prevents installer from blocking |
| 3 | Install SQL Server 2025 | Named instance SQLEXPRESS, mixed-mode auth |
| 4 | Install sqlcmd + ODBC Driver 18 |
Required for command-line SQL access |
| 5 | Enable TCP/IP on port 1433 | Registry path: MSSQL17.SQLEXPRESS |
| 6 | Restart service | Service name: MSSQL$SQLEXPRESS |
| 7 | Configure SQL Browser | Resolves named instance connections |
| 8 | Open firewall ports | TCP 1433 and UDP 1434 |
| 9 | Enable SA login | Uses Windows Auth first, then verifies SA |
| 10 | SQL Server Agent | Skipped automatically on Express edition |
Sample SQL Queries
Once connected, run the following queries to create a test table, insert sample data, and verify the setup.
-- Create a sample DevOps projects table
CREATE TABLE DevOpsProjects (
ProjectID INT PRIMARY KEY IDENTITY(1,1),
ProjectName NVARCHAR(100) NOT NULL,
Environment NVARCHAR(50),
BuildStatus NVARCHAR(20),
DeploymentDate DATETIME DEFAULT GETDATE(),
LeadEngineer NVARCHAR(100)
);
-- Insert sample project records
INSERT INTO DevOpsProjects (ProjectName, Environment, BuildStatus, LeadEngineer)
VALUES
('Alpha-Portal', 'Production', 'Success', 'Jane Doe'),
('Beta-API', 'Staging', 'Success', 'John Smith'),
('Gamma-Auth', 'Development', 'Failed', 'Alice Wong'),
('Delta-Mobile', 'QA', 'In Progress', 'Bob Miller'),
('Epsilon-Data', 'Production', 'Success', 'Charlie Brown');
-- Retrieve all records
SELECT * FROM DevOpsProjects;
Expected output:
| ProjectID | ProjectName | Environment | BuildStatus | DeploymentDate | LeadEngineer |
|---|---|---|---|---|---|
| 1 | Alpha-Portal | Production | Success | (auto) | Jane Doe |
| 2 | Beta-API | Staging | Success | (auto) | John Smith |
| 3 | Gamma-Auth | Development | Failed | (auto) | Alice Wong |
| 4 | Delta-Mobile | QA | In Progress | (auto) | Bob Miller |
| 5 | Epsilon-Data | Production | Success | (auto) | Charlie Brown |
