Install Instructions
The powershell script assumes you are running on a clean install of Windows Server 2016, and want to use Microsoft SQL Server Express 2017.
If you are using Microsoft SQL Standard, you will need to follow the Manual Setup instructions.
Visit the download page and download the OptiTune Management Server. It is packaged in a zip file. Extract the contents to a directory on your Windows 2016 Server (e.g. to "C:\otdownload").
To start the install script right click on "otinstall.ps1", and select "Run with Powershell". You can also open a PowerShell window (with admin privileges), and change directory (CD) into the directory with the script, and then type ".\otinstall.ps1" to execute the script.
The script can take a while to run, depending on your download speeds. If it fails, it can safely be run again to complete the installation.
You can also view the Manual Setup instructions to see step by step instructions for manually setting up the OptiTune Management Server on Windows Server 2016, which are the actions that the install script will perform.
Post Install
After the install script completes, you will need to do the following to complete the setup:
- Create a DNS entry that points to your server's IP4 address, e.g. "yourserver.company.com"
- Install an SSL certificate, and add the HTTPS binding to the optitune website in IIS Manager. You can navigate to http://localhost on the server, but the HTTP binding should be removed, and only the HTTPS (secure) website binding remain in a production server. To get a free SSL certificate that is valid for 3 months, visit https://ssl.comodo.com
- Modify the C:\optitune\web\web.config file with your DNS name, for the StaticContentUrl and DynamicContentUrl entries
- Register your first organization in OptiTune by visiting https://yourserver.company.com/register.aspx where you of course replace "yourserver.company.com" with your DNS name.
When registering your first organization on the self hosted management server (i.e. on the registration page), you can either use a paid registration code, free registration code, or leave it blank to setup monthly billing.
Script Reference
Here are the contents of the otinstall.ps1 powershell script.
############################################################
#
# Utility Function Definitions
#
############################################################
<#
Returns true if a program with the specified display name is installed.
This function will check both the regular Uninstall location as well as the
"Wow6432Node" location to ensure that both 32-bit and 64-bit locations are
checked for software installations.
@param String $program The name of the program to check for.
@return Booleam Returns true if a program matching the specified name is installed.
#>
function App-Installed( $program ) {
$x86 = ((Get-ChildItem "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall") |
Where-Object { $_.GetValue( "DisplayName" ) -like "*$program*" } ).Length -gt 0;
$x64 = ((Get-ChildItem "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall") |
Where-Object { $_.GetValue( "DisplayName" ) -like "*$program*" } ).Length -gt 0;
return $x86 -or $x64;
}
function New-TemporaryDirectory {
$parent = [System.IO.Path]::GetTempPath()
[string] $name = [System.Guid]::NewGuid()
New-Item -ItemType Directory -Path (Join-Path $parent $name)
}
function Download-File($url, $path){
$client = New-Object System.Net.WebClient
$client.DownloadFile($url, $path)
}
############################################################
#
# Main Script
#
############################################################
$ErrorActionPreference = 'Stop';
# Set Current Directory
$scriptDir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
Set-Location -Path $scriptDir
# Installing IIS Role
Write-Host "Installing IIS Server Role"
Install-WindowsFeature -ConfigurationFilePath 'iis.xml' | Out-Null
Write-Host "Installing SMTP Feature"
Install-WindowsFeature -ConfigurationFilePath 'smtp.xml' | Out-Null
# Copy Server Binaries
Write-Host "Copying Server Binaries"
$destDir = "C:\optitune"
$srcDir = Join-Path $scriptDir "optitune"
if ([System.IO.Directory]::Exists($destDir))
{
Write-Warning "$destDir already present"
}
else
{
[System.IO.Directory]::CreateDirectory($destDir) | Out-Null
copy-item "$srcDir\\*" $destDir -force -recurse
}
############################################################
#
# SQL Server and SSMS Install
#
############################################################
function Install-SqlServer {
if (App-Installed "Microsoft SQL Server")
{
Write-Warning "SQL Server is already installed"
return
}
Write-Host "Downloading SQL Server"
$url = 'https://download.microsoft.com/download/E/F/2/EF23C21D-7860-4F05-88CE-39AA114B014B/SQLEXPR_x64_ENU.exe'
$silentArgs = "/IACCEPTSQLSERVERLICENSETERMS /IACCEPTPYTHONLICENSETERMS /IACCEPTROPENLICENSETERMS /QS /ACTION=install /ROLE=AllFeatures_WithDefaults /FILESTREAMLEVEL=2 /FILESTREAMSHARENAME=MSSQLSERVER /SECURITYMODE=SQL /SAPWD=OptiTune123! /INSTANCEID=SQLEXPRESS /INSTANCENAME=SQLEXPRESS /UPDATEENABLED=FALSE"
$tempDir = New-TemporaryDirectory
$fileFullPath = "$tempDir\SQLEXPR.exe"
Download-File $url $fileFullPath
Write-Host "Extracting..."
$extractPath = "$tempDir\SQLEXPR"
Start-Process "$fileFullPath" "/Q /x:`"$extractPath`"" -Wait
Write-Host "Installing..."
Start-Process "$extractPath\setup.exe" $silentArgs -Wait
Write-Host "Removing extracted files..."
Remove-Item -Recurse "$tempDir"
}
function Install-SSMS {
if (App-Installed "SQL Server Management Studio")
{
Write-Warning "SQL Server Management Studio is already installed"
return
}
Write-Host "Downloading SQL Server Management Studio"
$url = 'https://download.microsoft.com/download/B/8/3/B839AD7D-DDC7-4212-9643-28E148251DC1/SSMS-Setup-ENU.exe'
$silentArgs = "/passive /install /norestart"
$tempDir = New-TemporaryDirectory
$fileFullPath = "$tempDir\SSMS-Setup-ENU.exe"
Download-File $url $fileFullPath
Write-Host "Installing..."
Start-Process $fileFullPath $silentArgs -Wait
Write-Host "Removing extracted files..."
Remove-Item -Recurse "$tempDir"
}
Install-SqlServer
Install-SSMS
############################################################
#
# Website Configuration
#
############################################################
Import-Module WebAdministration
function Install-OptiTune-Website {
if (Get-Website "Optitune")
{
Write-Warning "Optitune website is already present"
return
}
if (Get-Website "Default Web Site")
{
Write-Host "Deleting Default Web Site"
Remove-Website "Default Web Site"
}
#
# Create App Pool
#
Write-Host "Creating OptiTune app pool"
$poolName = 'optitune'
$poolPath = 'IIS:\AppPools\optitune'
$website = 'optitune'
New-WebAppPool $poolName
Set-ItemProperty -Path $poolPath -Name enable32BitAppOnWin64 -Value 'True'
Set-ItemProperty -Path $poolPath -Name startMode -Value 'AlwaysRunning'
Set-ItemProperty -Path $poolPath -Name processModel.idleTimeout -value 00:00:00
Set-ItemProperty -Path $poolPath -Name processModel.loadUserProfile -Value 'True'
Set-ItemProperty -Path $poolPath -Name recycling.disallowOverlappingRotation -Value 'True'
Set-ItemProperty -Path $poolPath -Name recycling.periodicRestart.time -Value 4.00:00:00
#
# Create Website
#
Write-Host "Creating OptiTune website"
New-Website -Name $website -ApplicationPool $poolName -Force -PhysicalPath "$destDir\web"
#
# Setup Permissions
#
Write-Host "Setting permissions"
$IISUser = "IIS AppPool\optitune"
$Acl = Get-Acl $destDir
$Ar = New-Object system.security.accesscontrol.filesystemaccessrule($IISUser,"Modify", "ContainerInherit,ObjectInherit", "None", "Allow")
$Acl.SetAccessRule($Ar)
Set-Acl $destDir $Acl
#
# Setup SMTP Service - grant 127.0.0.1 relay access
#
$SmtpConfig = Get-WMIObject -Namespace root/MicrosoftIISv2 -ComputerName localhost -Query "Select * From IisSmtpServerSetting"
$RelayIpList = @( 24, 0, 0, 128, 32, 0, 0, 128, 60, 0, 0, 128, 68, 0, 0, 128, 1, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 76, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 127, 0, 0, 1 )
$SmtpConfig.RelayIPList = $RelayIPList
$SmtpConfig.Put()
Set-Service "SMTPSVC" -StartupType Automatic -ErrorAction SilentlyContinue
Start-Service "SMTPSVC" -ErrorAction SilentlyContinue
}
Install-OptiTune-Website
############################################################
#
# Database Setup
#
############################################################
if (-Not (Get-Module -ListAvailable -Name SqlServer))
{
Write-Host "Installing SqlServer Powershell Module"
Install-PackageProvider -Name Nuget -Force
Install-Module -Name SqlServer -Force
}
Import-Module SqlServer
function Setup-OptiTune-Database {
$dbExists = $false;
try
{
Get-SqlDatabase -ServerInstance 'LOCALHOST\SQLEXPRESS' -Name optitune
$dbExists = $true;
}
catch
{
}
if ($dbExists)
{
Write-Warning "OptiTune database is already present"
return
}
Write-Host "Creating OptiTune database"
Invoke-Sqlcmd -ServerInstance 'LOCALHOST\SQLEXPRESS' -InputFile "$scriptDir\createdb.sql"
Invoke-Sqlcmd -ServerInstance 'LOCALHOST\SQLEXPRESS' -Database 'optitune' -InputFile "$scriptDir\optitune\optitune-schema.sql"
Write-Host "Importing Geo-Location Data`n This will take several minutes"
Invoke-Sqlcmd -ServerInstance 'LOCALHOST\SQLEXPRESS' -Database 'optitune' -Query "EXECUTE ImportAndCacheIP2Location" -QueryTimeout 0
}
Setup-OptiTune-Database
Write-Host "`nInstall finished, please do the following to complete the setup:`n" -ForegroundColor green
Write-Host "1) Customize '$destDir\web\Web.config':`n Modify the StaticContentUrl and DynamicContentUrl entries with the public https URL, e.g. https://manage.mycompany.com`n" -ForegroundColor green
Write-Host "2) Install an SSL certificate for the 'optitune' website" -ForegroundColor green
notepad C:\optitune\web\Web.config