The following script from Mark Cassidy is quick and easy to install Solr with Powershell.
Param(
$installFolder = "c:\solr",
$solrPort = "8662",
$solrHost = "solr",
$solrSSL = $true,
$solrVersion = "6.6.2",
$downloadFolder = "$PSScriptRoot"
)
$solrName = "solr-$solrVersion"
$solrPackage = "https://archive.apache.org/dist/lucene/solr/$solrVersion/$solrName.zip"
$solrRoot = "$installFolder\$solrName"
$nssmFolder = "c:\nssm"
$nssmVersion = "2.24"
$nssmPackage = "https://nssm.cc/release/nssm-$nssmVersion.zip"
$nssmRoot = "$nssmFolder\nssm-$nssmVersion"
$JavaOJDKBuildVersion = "1.8.0.201-1"
$JavaOJDKBuildZip = "java-1.8.0-openjdk-$JavaOJDKBuildVersion.b09.ojdkbuild.windows.x86_64.zip"
$JavaOJDKBuildPackage = "https://github.com/ojdkbuild/ojdkbuild/releases/download/$JavaOJDKBuildVersion/$JavaOJDKBuildZip"
$JavaOJDKBuildInstallFolder = "$env:ProgramFiles\ojdkbuild"
$JREPath = "$JavaOJDKBuildInstallFolder\java-1.8.0-openjdk-$JavaOJDKBuildVersion.b09.ojdkbuild.windows.x86_64"
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
## Verify elevated
## https://superuser.com/questions/749243/detect-if-powershell-is-running-as-administrator
$elevated = [bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).groups -match "S-1-5-32-544")
if($elevated -eq $false)
{
throw "In order to install services, please run this script elevated."
}
function downloadAndUnzipIfRequired
{
Param(
[string]$toolName,
[string]$toolFolder,
[string]$toolZip,
[string]$toolSourceFile,
[string]$installRoot,
[bool]$isSolr = $false,
[string]$solrFolder=""
)
if(!(Test-Path -Path $installRoot) -or ($isSolr -and !(Test-Path -Path $solrFolder)))
{
if(!(Test-Path -Path $toolZip))
{
Write-Host "Downloading $toolName..."
<#
Start-BitsTransfer -Source $toolSourceFile -Destination $toolZip
# github releases has issues with BitsTransfer
# Invoke-WebRequest is very slow in PowerShell 5.1 when showing progress bar
#>
$previousProgressPreference = $ProgressPreference
$ProgressPreference = 'SilentlyContinue'
Invoke-WebRequest -Uri $toolSourceFile -OutFile $toolZip
$ProgressPreference = $previousProgressPreference
}
if(!(Test-Path -Path $toolZip))
{
Write-Error "Unable to find $toolZip or download $toolSourceFile" -ErrorAction Stop
}
Write-Host "Extracting $toolName to $toolFolder..."
Expand-Archive $toolZip -DestinationPath $installRoot
}
}
if($env:JAVA_HOME -eq $null) {
# download & extract the java archive to the right folder
$javaZip = "$downloadFolder\$JavaOJDKBuildZip"
downloadAndUnzipIfRequired "Java" $JavaOJDKBuildInstallFolder $javaZip $JavaOJDKBuildPackage $JavaOJDKBuildInstallFolder -ErrorAction Stop
# Ensure Java environment variables
Write-Host "Setting JAVA_HOME environment variable"
[Environment]::SetEnvironmentVariable("JAVA_HOME", $JREPath, [EnvironmentVariableTarget]::Machine)
$env:JAVA_HOME = $JREPath
$oldPath = [Environment]::GetEnvironmentVariable("PATH", [EnvironmentVariableTarget]::Machine)
if(!$oldPath.Contains("$JREPath\bin")) {
$newPath = "$JREPath\bin;$oldPath"
Write-Host "Updating PATH: $newPath"
[Environment]::SetEnvironmentVariable("PATH", $newPath, [EnvironmentVariableTarget]::Machine)
$env:Path = $newPath
}
Write-Host "Verifying install ..."
Write-Host "java -version"
# Redirecting Stderr to Stdout and converting to string works around NativeCommandError.
# See https://stackoverflow.com/a/20950421
java.exe -version 2>&1 | %{ "$_" }
Write-Host "javac -version"
javac.exe -version 2>&1 | %{ "$_" }
}
# download & extract the solr archive to the right folder
$solrZip = "$downloadFolder\$solrName.zip"
downloadAndUnzipIfRequired "Solr" $solrRoot $solrZip $solrPackage $installFolder $true $solrRoot -ErrorAction Stop
# download & extract the nssm archive to the right folder
$nssmZip = "$downloadFolder\nssm-$nssmVersion.zip"
downloadAndUnzipIfRequired "NSSM" $nssmRoot $nssmZip $nssmPackage $nssmFolder -ErrorAction Stop
# if we're using HTTP
if($solrSSL -eq $false)
{
# Update solr cfg to use right host name
if(!(Test-Path -Path "$solrRoot\bin\solr.in.cmd.old"))
{
Write-Host "Rewriting solr config"
$cfg = Get-Content "$solrRoot\bin\solr.in.cmd"
Rename-Item "$solrRoot\bin\solr.in.cmd" "$solrRoot\bin\solr.in.cmd.old"
$newCfg = $newCfg | % { $_ -replace "REM set SOLR_HOST=192.168.1.1", "set SOLR_HOST=$solrHost" }
$newCfg | Set-Content "$solrRoot\bin\solr.in.cmd"
}
}
# Ensure the solr host name is in your hosts file
if($solrHost -ne "localhost")
{
$hostFileName = "c:\\windows\system32\drivers\etc\hosts"
$hostFile = [System.Io.File]::ReadAllText($hostFileName)
if(!($hostFile -like "*$solrHost*"))
{
Write-Host "Updating host file"
"`r`n127.0.0.1`t$solrHost" | Add-Content $hostFileName
}
}
# if we're using HTTPS
if($solrSSL -eq $true)
{
# Generate SSL cert
$certName = "$solrName-$solrHost"
$existingCert = Get-ChildItem Cert:\LocalMachine\Root | where FriendlyName -eq "$certName"
if($existingCert)
{
Write-Host "Removing the existing certificate to create a new one"
$existingCert | Remove-Item
}
Write-Host "Creating & trusting an new SSL Cert for $solrHost"
# Generate a cert
# https://docs.microsoft.com/en-us/powershell/module/pkiclient/new-selfsignedcertificate?view=win10-ps
$cert = New-SelfSignedCertificate -FriendlyName "$certName" -DnsName "$solrHost" -CertStoreLocation "cert:\LocalMachine" -NotAfter (Get-Date).AddYears(10)
# Trust the cert
# https://stackoverflow.com/questions/8815145/how-to-trust-a-certificate-in-windows-powershell
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store "Root","LocalMachine"
$store.Open("ReadWrite")
$store.Add($cert)
$store.Close()
# remove the untrusted copy of the cert
$cert | Remove-Item
# export the cert to pfx using solr's default password
if(!(Test-Path -Path "$solrRoot\server\etc\solr-ssl.keystore.pfx"))
{
Write-Host "Exporting cert for Solr to use"
$cert = Get-ChildItem Cert:\LocalMachine\Root | where FriendlyName -eq "$certName"
$certStore = "$solrRoot\server\etc\solr-ssl.keystore.pfx"
$certPwd = ConvertTo-SecureString -String "secret" -Force -AsPlainText
$cert | Export-PfxCertificate -FilePath $certStore -Password $certpwd | Out-Null
}
# Update solr cfg to use keystore & right host name
if(!(Test-Path -Path "$solrRoot\bin\solr.in.cmd.old"))
{
Write-Host "Rewriting solr config"
$cfg = Get-Content "$solrRoot\bin\solr.in.cmd"
Rename-Item "$solrRoot\bin\solr.in.cmd" "$solrRoot\bin\solr.in.cmd.old"
$newCfg = $cfg | % { $_ -replace "REM set SOLR_SSL_KEY_STORE=etc/solr-ssl.keystore.jks", "set SOLR_SSL_KEY_STORE=$certStore" }
$newCfg = $newCfg | % { $_ -replace "REM set SOLR_SSL_KEY_STORE_PASSWORD=secret", "set SOLR_SSL_KEY_STORE_PASSWORD=secret" }
$newCfg = $newCfg | % { $_ -replace "REM set SOLR_SSL_TRUST_STORE=etc/solr-ssl.keystore.jks", "set SOLR_SSL_TRUST_STORE=$certStore" }
$newCfg = $newCfg | % { $_ -replace "REM set SOLR_SSL_TRUST_STORE_PASSWORD=secret", "set SOLR_SSL_TRUST_STORE_PASSWORD=secret" }
$newCfg = $newCfg | % { $_ -replace "REM set SOLR_HOST=192.168.1.1", "set SOLR_HOST=$solrHost" }
$newCfg | Set-Content "$solrRoot\bin\solr.in.cmd"
}
}
# install the service & runs
$svc = Get-Service "$solrName" -ErrorAction SilentlyContinue
if(!($svc))
{
Write-Host "Installing Solr service"
&"$nssmRoot\win64\nssm.exe" install "$solrName" "$solrRoot\bin\solr.cmd" "-f" "-p $solrPort"
$svc = Get-Service "$solrName" -ErrorAction SilentlyContinue
}
if($svc.Status -ne "Running")
{
Write-Host "Starting Solr service"
Start-Service "$solrName"
}
# finally prove it's all working
$protocol = "http"
if($solrSSL -eq $true)
{
$protocol = "https"
}
Invoke-Expression "start $($protocol)://$($solrHost):$solrPort/solr/#/"
Copy the contents from the above script and paste it into a file naming “Install-Solr.ps1”.
Change the parameters in the top of the script:
$true
by default. Installs, and configures the solr instance with https. Change to $false
if https is not required.Run Powershell as Administrator.
Execute the below commands.
cd <path_to_the_folder_where_script_is_copied>
.\Install-Solr.ps1
The script will download the jre, nssm and solr installation files and install them. Also, it will configure https if solrSSL is marked as true.
Possible errors that you may face and solutions:
The below script from Diego Saavedra San Juan is very useful for uninstalling Solr instances:
Param(
$solrLocation="C:\Solr\solr-6.6.2",
$solrServiceName="solr-6.6.2"
)
# Uninstall Service
Write-Host "Checking if Solr service is installed"
$isSolrServiceInstalled = Get-Service | Where-Object {$_.Name -like "*$solrServiceName*"}
if ($null -ne $isSolrServiceInstalled)
{
Write-Host "Removing Solr service $solrServiceName" -ForegroundColor Cyan
# Stop the service
sc.exe stop $solrServiceName
sc.exe delete $solrServiceName
Start-Sleep 2
$isSolrServiceInstalled = sc.exe query $solrServiceName
if ( $isSolrServiceInstalled[0].Contains("1060") )
{
Write-Host "Removal of Solr service completed sucessfully" -ForegroundColor Green
}
else
{
Write-Host "Something went wrong removing Solr service named $solrServiceName" -ForegroundColor Red
exit 1
}
}
else
{
Write-Host "Solr service already removed, good" -ForegroundColor Green
}
# Remove folder
if ( Test-Path $solrLocation )
{
Remove-Item -Recurse $solrLocation
if ( -Not ( Test-Path $solrLocation ))
{
Write-Host "Correctly removed Solr directory at $solrLocation" -ForegroundColor Green
}
else
{
Write-Host "Something went wrong trying to remove the solr directory" -ForegroundColor Red
exit 1
}
}
else { Write-Host "Solr location $solrLocation already removed, good" -ForegroundColor Green }
Write-Host "Completed uninstallation of Solr" -ForegroundColor Green
Copy the contents from the above script and paste it into a file naming “Uninstall-Solr.ps1”.
Change the parameters in the top of the script:
Run Powershell as Administrator.
Run the below commands.
cd <path_to_folder_where_file_is_saved>
.\Uninstall-Solr.ps1
I hope these scripts will be helpful for you.
Please feel free to ask questions/drop suggestions in the comments.
Happy Sitecoring.