Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Function Test-DownloadUri {
<#
.SYNOPSIS
Tests that a url is valid
.DESCRIPTION
Returns a status code from an http request of a url. Used to verify that download links work.
.PARAMETER Uri
The url that we are checking is valid
.INPUTS
N/A
.OUTPUTS
Status code from an http response or null if link is invalid
.EXAMPLE
$uri = "www.google.com"
$status = Test-DownloadUri -uri $uri
if ($status -ne 200)
{Write-Error "oh dear"}
.NOTES
N/A
#>
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[string] $uri
)
$httpRequest = [System.Net.WebRequest]::Create($uri)
try {
$httpResponse = $httpRequest.GetResponse()
$httpStatus = $httpResponse.StatusCode
If ($httpStatus -eq 200) {
Write-Verbose "Download link is OK." -Verbose
}
Else {
Write-Error "Download link no longer works."
}
$httpResponse.Close()
Return $httpStatus
}
catch {
Write-Error "Download link no longer works."
Return $null
}
}
Function Install-NuGet {
<#
.SYNOPSIS
Installs NuGet from the web.
.DESCRIPTION
Checks that NuGet is installed in given folder location. If it isn't it is downloaded from the web.
.PARAMETER WorkingFolder
Location that Nuget.exe is/isn't.
.PARAMETER NugetInstalluri
The url used to download Nuget.
.INPUTS
N/A
.OUTPUTS
NugetExe: the path to Nuget, irrespective of whether it was downloaded or already existed.
.EXAMPLE
$NuGetPath = Install-NuGet -WorkingFolder $PsScriptRoot -NuGetInstallUri "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
.NOTES
N/A
#>
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[string] $WorkingFolder,
[Parameter(Mandatory = $true)]
[string] $NuGetInstallUri
)
Write-Verbose "Working Folder : $WorkingFolder" -Verbose
$NugetExe = "$WorkingFolder\nuget.exe"
if (-not (Test-Path $NugetExe)) {
Write-Verbose "Cannot find nuget at path $WorkingFolder\nuget.exe" -Verbose
If (($LinkStatus = Test-DownloadUri -uri $NuGetInstallUri) -ne 200) {
Throw "It appears that download Nuget link no longer works. "
}
$sourceNugetExe = $NuGetInstallUri
Write-Verbose "$sourceNugetExe -OutFile $NugetExe" -Verbose
Invoke-WebRequest $sourceNugetExe -OutFile $NugetExe
if (-not (Test-Path $NugetExe)) {
Throw "It appears that the nuget download hasn't worked."
}
Else {
Write-Verbose "Nuget Downloaded!" -Verbose
}
}
Return $NugetExe
}
Function Get-LocalDb2016NuGet {
<#
.SYNOPSIS
Get Microsoft SQL Server 2016 LocalDB from Nuget.
.DESCRIPTION
Downloads Microsoft SQL Server 2016 LocalDB from Nuget. This Nuget package is not official release from Microsoft.
Before we use Nuget, we use the function "Install-Nuget" to check is Nuget is installed in local folder.
.PARAMETER WorkingFolder
Location that Nuget.exe is/isn't.
Location that we want to download Nuget package to.
Mandatory
.PARAMETER NugetInstalluri
The url used to download Nuget.
mandatory
.PARAMETER targetVersion
The version of the Nuget package we want to get.
Not mandatory - will download the latest if not included.
.INPUTS
N/A
.OUTPUTS
targetMsi: the path to Microsoft SQL Server 2016 LocalDB msi, irrespective of whether it was downloaded or already existed.
.EXAMPLE
$targetMsi = Get-LocalDb2016NuGet -WorkingFolder $PsScriptRoot -NugetInstallUri "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" -targetVersion "13.1.4001.0"
.NOTES
N/A
#>
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[string] $WorkingFolder,
[Parameter(Mandatory = $true)]
[string] $NugetInstallUri,
[Parameter(Mandatory = $false)]
[string] $targetVersion
)
$NuGetPath = Install-NuGet -WorkingFolder $WorkingFolder -NuGetInstallUri $NugetInstallUri
$nugetInstallLocalDb = "&$NuGetPath install Microsoft.SQL.Server.2016.LocalDB -ExcludeVersion -OutputDirectory $WorkingFolder"
if ($targetVersion) {
$nugetInstallLocalDb += " -version $targetVersion"
}
else {
Write-Verbose "As no version target version of Microsoft SQL Server 2016 LocalDB, the latest version will be downloaded." -Verbose
}
Write-Verbose $nugetInstallLocalDb -Verbose
Invoke-Expression $nugetInstallLocalDb | Out-Null
$localDbInstallFolder = "$WorkingFolder\Microsoft.SQL.Server.2016.LocalDB"
if (-not (Test-Path $localDbInstallFolder)) {
Throw "It appears that the nuget install hasn't worked, check output above to see whats going on"
}
$targetMsi = Join-Path $localDbInstallFolder "SqlLocalDB.msi"
Return $targetMsi
}
Function Get-LocalDb2016 {
<#
.SYNOPSIS
Get Microsoft SQL Server 2016 LocalDB from Microsoft website.
.DESCRIPTION
Downloads Microsoft SQL Server 2016 LocalDB from Microsoft website. The url was obtained by running Fiddler with https requests on when using SQL Server 2016 Express Installer.
Thisi s becauseMicrosoft have not published the download link anywhere.
.PARAMETER WorkingFolder
Location of where we want to download Microsoft SQL Server 2016 LocalDB msi
Mandatory
.PARAMETER checkNuget
A switch that can be used to check Nuget for package if the url does not work. See notes for more details.
.PARAMETER targetVersion
The version of the Nuget package we want to get.
Not mandatory - will download the latest if not included.
.PARAMETER NugetInstalluri
The url used to download Nuget.
Not mandatory because we may not want to/be able to use Nuget.
.INPUTS
N/A
.OUTPUTS
targetMsi: the path to Microsoft SQL Server 2016 LocalDB msi, irrespective of whether it was downloaded or already existed.
.EXAMPLE
$tv = "13.1.4001.0"
$NugetUri = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
$localDB = "https://download.microsoft.com/download/9/0/7/907AD35F-9F9C-43A5-9789-52470555DB90/ENU/SqlLocalDB.msi"
$msi = Get-LocalDb2016 -WorkingFolder $PSScriptroot -downloadLocalDbUri $localDB -targetVersion $tv -checkNuget -NugetInstallUri $NugetUri -Verbose
.NOTES
Because the url from Microsoft is not official, it amy change from time to time, leading current known url invalid.
To anticiapte this we can check Nuget for a version that we can then download.
#>
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[string] $WorkingFolder,
[Parameter(Mandatory = $true)]
[string] $downloadLocalDbUri,
[switch] $checkNuget,
[Parameter(Mandatory = $false)]
[string] $targetVersion,
[Parameter(Mandatory = $false)]
[string] $NugetInstallUri
)
Write-Verbose "Working Folder : $WorkingFolder" -Verbose
Write-Verbose "Target Version : $targetVersion" -Verbose
$targetMsi = Join-Path $WorkingFolder "Microsoft.SQL.Server.2016.LocalDB"
if (-not (Test-Path $targetMsi)) {
New-Item $targetMsi -type directory | Out-Null
}
[string]$targetMsi = Join-Path $targetMsi "SqlLocalDB.msi"
if (-not (Test-Path $targetMsi)) {
If (($LinkStatus = Test-DownloadUri -uri $downloadLocalDbUri) -ne 200) {
Write-Verbose "It appears that the download link is no longer working..." -Verbose
If ($CheckNuget) {
Write-Verbose "Checking Nuget for Microsoft SQL Server 2016 LocalDB msi..."
$targetMsi = Get-LocalDb2016NuGet -WorkingFolder $WorkingFolder -NugetInstallUri $NugetInstallUri -targetVersion $targetVersion
}
Else {
Throw "Cannot download Microsoft SQL Server 2016 LocalDB msi. Either add -CheckNuget switch or find the working url to download Microsoft SQL Server 2016 LocalDB msi."
}
}
Else{
try {
Write-Verbose "Downloading Microsoft SQL Server 2016 LocalDB msi..." -Verbose
Invoke-WebRequest -Uri $downloadLocalDbUri -OutFile $targetMsi -Verbose
}
catch {
Throw $_.Exception
}
}
}
Else {
Write-Verbose "Microsoft SQL Server 2016 LocalDB msi already downloaded." -Verbose
}
Return $targetMsi
}
Function Install-LocalDb2016 {
<#
.SYNOPSIS
Install Microsoft SQL Server 2016 LocalDB on machine.
.DESCRIPTION
Checks to see if Microsoft SQL Server 2016 LocalDB is installed. If not will install.
If installed, will check version installed, and if it is less than the version we want to install, will install it.
.PARAMETER LocalDbMsiPath
Location of Microsoft SQL Server 2016 LocalDB msi.
Mandatory
.PARAMETER targetVersion
The version we want to install.
mandatory
.INPUTS
N/A
.OUTPUTS
N/A
.EXAMPLE
$tv = "13.1.4001.0"
$NugetUri = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
$localDB = "https://download.microsoft.com/download/9/0/7/907AD35F-9F9C-43A5-9789-52470555DB90/ENU/asdf/SqlLocalDB.msi"
$msi = Get-LocalDb2016 -WorkingFolder $PSScriptRoot -downloadLocalDbUri $localDB -targetVersion $tv -checkNuget -NugetInstallUri $NugetUri -Verbose
Install-LocalDb2016 -LocalDbMsiPath $msi -targetVersion $tv
.NOTES
N/A
#>
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[string] $LocalDbMsiPath,
[Parameter(Mandatory = $true)]
[string] $targetVersion
)
$registryPath = "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL13E.LOCALDB\MSSQLServer\CurrentVersion"
if ( -not (Test-Path $registryPath)) {
Write-Verbose "Microsoft SQL Server 2016 LocalDB not installed." -Verbose
$install = $true
}
else {
$registryProperties = Get-ItemProperty $registryPath
$sourceVersion = $registryProperties.CurrentVersion
if ($sourceVersion -lt $targetVersion) {
Write-Verbose "Microsoft SQL Server 2016 LocalDB requires upgrading." -Verbose
$install = $true
}
}
if ($install -eq $true) {
try {
Write-Verbose "Installing Microsoft SQL Server 2016 LocalDB..." -Verbose
Start-Process -FilePath "msiexec.exe" -ArgumentList "/i $LocalDbMsiPath /q IACCEPTSQLLOCALDBLICENSETERMS=YES" -Wait | Out-Null
}
catch {
Throw "It appears LocalDB has not installed properly."
}
if ( -not (Test-Path $registryPath)) {
Write-Verbose "It appears that LocalDB has not installed." -Verbose
}
else {
Write-Verbose "SQL Server LocalDB Installed Successfully." -Verbose
}
}
else {
Write-Verbose "Microsoft SQL Server 2016 LocalDB already Installed." -Verbose
}
}
$loc = $PSScriptRoot
$tv = "13.1.4001.0"
$NugetUri = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
$localDB = "https://download.microsoft.com/download/9/0/7/907AD35F-9F9C-43A5-9789-52470555DB90/ENU/SqlLocalDB.msi"
$msi = Get-LocalDb2016 -WorkingFolder $loc -downloadLocalDbUri $localDB -targetVersion $tv -checkNuget -NugetInstallUri $NugetUri -Verbose
Install-LocalDb2016 -LocalDbMsiPath $msi -targetVersion $tv
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment