Skip to content

Instantly share code, notes, and snippets.

@chadbaldwin
Last active May 19, 2025 17:44
Show Gist options
  • Save chadbaldwin/1a486b4fbf48e9b0cd9551cb7e16382a to your computer and use it in GitHub Desktop.
Save chadbaldwin/1a486b4fbf48e9b0cd9551cb7e16382a to your computer and use it in GitHub Desktop.
Using Docker, create a SQL Server container, or start one of it already exists.
<# Docs:
https://hub.docker.com/_/microsoft-mssql-server
https://learn.microsoft.com/en-us/sql/linux/sql-server-linux-configure-environment-variables
#>
# Start SQL Server docker instance
Write-Verbose 'Creating function: Start-SQLServer'
function Start-SQLServer {
[CmdletBinding()]
param (
[Parameter()][string]$Tag = 'latest',
[Parameter()][string]$ContainerName = 'sqlserver',
[Parameter()][string]$Hostname,
[Parameter()][int]$Port = 1433,
[Parameter()][ValidateSet('Evaluation','Developer','Express','Web','Standard','EnterpriseCore')]
[string]$Edition,
[Parameter()][switch]$EnableSQLServerAgent,
[Parameter()][string]$ContainerTimeZone,
[Parameter()][switch]$Force
)
$sa_password = 'yourStrong(!)Password'
# If a container with that name already exists return an error unless -Force is specified, then we remove
if ($container_samename = docker container ls --filter "name=${ContainerName}" -q) {
$container_def = docker inspect $container_samename | ConvertFrom-Json
if ($Force) {
"`e[35mRemoving existing container '${ContainerName}'`e[0m`n"
docker rm -f $ContainerName | Out-Null
} else {
Write-Warning "Container '$($container_def.Name.TrimStart('/'))' already exists'. To replace, use -Force"
return
}
}
if ($container_sameport = docker container ls --filter "publish=${Port}/tcp" -q) {
$container_def = docker inspect $container_sameport | ConvertFrom-Json
Write-Warning "Container '$($container_def.Name.TrimStart('/'))' is already using port ${Port}. Specify a different port with -Port, or stop/remove the existing container."
return
}
# create & start
# Build params to use for docker run call
$params = (
'--name', $ContainerName,
'-p', "${Port}:1433"
)
# Optional params
if ($Hostname) { $params += '-h', $Hostname }
# Environment variables # https://learn.microsoft.com/en-us/sql/linux/sql-server-linux-configure-environment-variables
$params += '-e', 'ACCEPT_EULA=Y'
$params += '-e', "MSSQL_SA_PASSWORD=${sa_password}"
# Set the SQL Server edition - e.g. Developer, Standard, Enterprise, etc
if ($Edition) { $params += '-e', "MSSQL_PID=$Edition" }
# Enable SQL Server Agent
if ($EnableSQLServerAgent) { $params += '-e', "MSSQL_AGENT_ENABLED=${EnableSQLServerAgent}" }
# Set the time zone for the container # https://learn.microsoft.com/en-us/sql/linux/sql-server-linux-configure-time-zone
if ($ContainerTimeZone) { $params += '-e', "TZ=${ContainerTimeZone}" }
# Image version
$params += "mcr.microsoft.com/mssql/server:${Tag}"
"docker run -d ${params}"
docker run -d @params | Out-Null
"Container '${ContainerName}' has been created and started`n`nWaiting until database is available..."
while ($true) {
sleep 1
# Depending on the version of SQL Server, the path to sqlcmd is different. Testing both because I'm lazy
docker exec $ContainerName /opt/mssql-tools/bin/sqlcmd -U sa -P $sa_password -C -l 2 -t 2 -Q 'SELECT 1' *>&1 | Out-Null
if ($LASTEXITCODE -eq 0) { break }
docker exec $ContainerName /opt/mssql-tools18/bin/sqlcmd -U sa -P $sa_password -No -l 2 -t 2 -Q 'SELECT 1' *>&1 | Out-Null
if ($LASTEXITCODE -eq 0) { break }
# Commenting out - using docker exec instead to remove dependency on sqlcmd being installed locally
#sqlcmd -U sa -P $sa_password -S localhost -l 1 -t 1 -Q 'SELECT 1' *>&1 | Out-Null
#if ($LASTEXITCODE -eq 0) { break }
}
$container = docker inspect $ContainerName | ConvertFrom-Json
"`nImage: ${Tag}`n"
"SQL Server Version: $($container.Config.Labels.'com.microsoft.version')`n"
"Login credentials:`e[32m"
" Server: localhost$($Port -ne '1433' ? ",${Port}" : '')"
" Username: sa"
" Password: ${sa_password} `e[31m<-- DO NOT USE IN PRODUCTION`e[0m"
}
Write-Verbose 'Register ArgumentCompleter: Start-SQLServer:Tag'
Register-ArgumentCompleter -CommandName Start-SQLServer -ParameterName Tag -ScriptBlock {
(irm 'https://mcr.microsoft.com/v2/mssql/server/tags/list').tags | ? { $_ -match 'latest' }
}
@chadbaldwin
Copy link
Author

[reserving first comment]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment