I have installed solr 7.5 using powershell script.
This script is able to install the solr but not able to start.solr is installing but in the start step it fails.
I have tried manually to start the service also it throws error. (unable to start solr. please contact your administrator)
i'm using java version 201 (note also i checked with 212).
I have added the script that I have used.
Param(
$solrVersion = "7.5.0",
$installFolder = "E:\solr\solr-7.5.0",
$solrPort = "8986",
$solrHost = "solr",
$solrSSL = $true,
$nssmVersion = "2.24",
$JREVersion = "1.8.0_201"
)
$JREPath = "C:\Program Files (x86)\Java\jre$JREVersion" ## Note that if you're running 32bit java, you will need to change this path
$solrName = "solr-$solrVersion"
$solrRoot = "$installFolder\$solrName"
$nssmRoot = "$installFolder\nssm-$nssmVersion"
$solrPackage = "https://archive.apache.org/dist/lucene/solr/$solrVersion/$solrName.zip"
$nssmPackage = "https://nssm.cc/release/nssm-$nssmVersion.zip"
$downloadFolder = "~\Downloads"
## 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
)
if(!(Test-Path -Path $toolFolder))
{
if(!(Test-Path -Path $toolZip))
{
Write-Host "Downloading $toolName..."
Start-BitsTransfer -Source $toolSourceFile -Destination $toolZip
}
Write-Host "Extracting $toolName to $toolFolder..."
Expand-Archive $toolZip -DestinationPath $installRoot
}
}
# download & extract the solr archive to the right folder
$solrZip = "$downloadFolder\$solrName.zip"
downloadAndUnzipIfRequired "Solr" $solrRoot $solrZip $solrPackage $installFolder
# download & extract the nssm archive to the right folder
$nssmZip = "$downloadFolder\nssm-$nssmVersion.zip"
downloadAndUnzipIfRequired "NSSM" $nssmRoot $nssmZip $nssmPackage $installFolder
# Ensure Java environment variable
$jreVal = [Environment]::GetEnvironmentVariable("JAVA_HOME", [EnvironmentVariableTarget]::Machine)
if($jreVal -ne $JREPath)
{
Write-Host "Setting JAVA_HOME environment variable"
[Environment]::SetEnvironmentVariable("JAVA_HOME", $JREPath, [EnvironmentVariableTarget]::Machine)
}
# 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
$existingCert = Get-ChildItem Cert:\LocalMachine\Root | where FriendlyName -eq "$solrName"
if(!($existingCert))
{
Write-Host "Creating & trusting an new SSL Cert for $solrHost"
# Generate a cert
# https://learn.microsoft.com/en-us/powershell/module/pkiclient/new-selfsignedcertificate?view=win10-ps
$cert = New-SelfSignedCertificate -FriendlyName "$solrName" -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 "$solrName"
$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"
&"$installFolder\nssm-$nssmVersion\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/#/"
Please find the screenshot
Set JAVA_HOME environment variable and try to start Solr manualy .
Need to verify the
Set the JAVA_Home environment variable or not.
Check JRE Path in the script file (jre$JREVersion", jre-$JREVersion").
Related
on a local Server I've got a bunch of sub-folders containing PowerShell-scripts, one of those is "sqlserver" folder contains Microsoft sqlserver module. I've got a daily task-scheduler job connecting a sql-server, there is a zip-file having the same sub-folder structure (with a folder: sqlserver) as on the local server.
The idea is to overwrite the local folder structure with the new structure from the zip-file.
The problem is the module "sqlserver" which I need to connect to sql server and get the zip file etc. Trying to overwrite it I get an error. I've tried to remove-module but it doesn't work as well.
The code:
try
{
[decimal]$lokaleVersion = 3.01 #
$deploymentVersion = 0
[string]$filetype = 'PS'
if($zipObject = Get-ZIPFile -lokaleAdminDBVersion $lokaleVersion -filetype $filetype -build 0)
{
$deploymentVersion = $zipObject.aktScriptVersion
if($deploymentVersion -gt $lokaleVersion)
{
Remove-Module -name sqlserver -Force
Unzip-File -zipObject $zipObject -zipname $filetype -modulePath $modulePath #error Access denied
$SubFolders = dir ($modulePath) | Where-Object {($_.PSIsContainer) -and ($_.Name -ne "sqlserver")} | ForEach-Object -Process {$_.FullName} -ErrorAction Stop
Import-Module -Name sqlserver -DisableNameChecking -Force
ForEach ($Folder in $SubFolders)
{
try
{
$a = (join-path -Path $modulePath -ChildPath ($folder.Split("\")[-1]) -Resolve) + "\" + "installer.ps1"
if(Test-Path ($a))
{
& $a
}
}
catch
{
Write-LogFile -Message $($Error[0].exception.message) -severity Fehler -modul $module
}
}
}
}
}
catch
{
if ($error[0].exception.message) {$message = $error[0].exception.message}
Write-LogFile -Message $message -severity Fehler -modul $module
}
It's important to overwrite the sub-folders (I'm updating the scripts) and the sqlserver-module should be updated regularly.
Thanks for your help.
Is there a faster way to get a specific registry value from a list of servers? I'm selecting a text file of computers with different flavors of windows and getting the OS product name. I'm finding that it's taking a couple seconds per computer to retrieve.
Current script:
Clear-Host
# Prompt for file containing list of target
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$myDialog = New-Object System.Windows.Forms.OpenFileDialog
$myDialog.Title = "Select File of Target Systems"
$myDialog.InitialDirectory = $PSScriptRoot
$myDialog.Filter = "TXT (*.txt) | *.txt"
$result = $myDialog.ShowDialog()
If ($result -eq "OK") {
$Computers = Get-Content $myDialog.FileName
}
Else {
Write-Host "`nCancelled by User`n"
}
$Array = #()
# Loop Through Computers
ForEach ($Computer in $Computers) {
Write-Warning "Processing $Computer"
# Get Registry Values
Try {
$OSVersion = Invoke-Command -ComputerName $Computer -ScriptBlock { (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" -Name ProductName).ProductName }
# Create a custom object
$ComplexObject = New-Object PSCustomObject
$ComplexObject | Add-Member -MemberType NoteProperty -Name "Server name" -Value $Computer
$ComplexObject | Add-Member -MemberType NoteProperty -Name "OS Version" -Value $OSVersion
# Add custom object to our array
$Array += $ComplexObject
}
Catch {
$_.Exception.Message
Break
}
}
# Results
If ($Array) {
# Display results in new window
$Array | Out-GridView -Title "OS Version Results"
# Display results in PS console
$Array
}
My end goal later on in the script is to do different things based on the OS version so I want to separate them into independent lists:
If (We have Win2008 servers) {
"Do This"
}
If (We have Win2012R2 servers) {
"Do This"
}
Clear-Host
# Prompt for file containing list of target
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$myDialog = [System.Windows.Forms.OpenFileDialog]::new()
$myDialog.Title = "Select File of Target Systems"
$myDialog.InitialDirectory = $PSScriptRoot
$myDialog.Filter = "TXT (*.txt) | *.txt"
$result = $myDialog.ShowDialog()
If ($result -eq "OK") {
$Computers = Get-Content $myDialog.FileName
}
Else {
Write-Host "`nCancelled by User`n"
}
# Get Registry Values
$Array = Try {
Invoke-Command -ComputerName $Computers -ScriptBlock {
(Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" -Name ProductName).ProductName
} -ErrorAction stop | Select-Object #{n="Server Name";e={$_.pscomputername}},
#{n="OS Version";e={$_}}
}
Catch {
write-warning $_.Exception.Message
break
}
# Results
If ($Array) {
# Display results in new window
$Array | Out-GridView -Title "OS Version Results"
# Display results in PS console
$Array
}
You can use Get-AdComputer like:
Get-ADComputer -Filter {(OperatingSystem -like "*windows*server*") -and (Enabled -eq "True")} -Properties OperatingSystem | Select -ExpandProperty OperatingSystem | ForEach {
If($_ -match "Windows Server 2008.*"){
# Server 2008
}
If($_ -match "Windows Server 2012.*"){
# Server 2012
}
# Add more like 2016,2019
}
Hi i am quite frustrated with powershell. i want to use my powershell script to call another powershell script inside it.
My powershell only do the first part which is download files and does not invoke the following powershell script...
Can not think the reason behind it.. Could anyone help me with that? Thanks!
The Program looks like :
$invocation = (Get-Variable MyInvocation).Value
$directorypath = Split-Path $invocation.MyCommand.Path
Set-Location $directorypath
if ($StepNumber -ne 2) {
$MyName = $MyInvocation.InvocationName
$LogFileName = ".\Logs\" + [System.IO.Path]::GetFileNameWithoutExtension($MyName) + [String]::Format("_{0:yyyy-MM-dd_HH-mm-ss}.Log", (Get-Date))
if (!(Test-Path ".\Logs")) {
$X = New-Item -path . -name Logs -ItemType directory
}
&PowerShell.exe -noProfile -File NSCCMPIDDownload.ps1 2 *>`&1 | Tee $LogFileName
exit
}
## ## ---- STEP2 ------------DownLoad the file from Website
$ErrorActionPreference = "Continue"
Write-Host Running NSCC-MPID-Download at $(Get-Date)
Write-Host ""
## Download the NSCC-MPID-Directory.xls from website
$datestr=$(Get-Date).ToString("yyyy-MM-dd")
$url="http://www.dtcc.com/~/media/Files/Downloads/client-center/NSCC/NSCC-MPID-Directory.xls"
$destination = $directorypath +"/NSCC-MPID-Directory"+"_"+$datestr+".xls"
## if destination does not exsist, creat a new one.
if (!(Test-Path $destination) ) {
New-Item $destination -type file -force
}
$client = new-object System.Net.WebClient
$client.DownloadFile( $url, $destination)
Write-Host Running NSCCMPIDInsertion.ps1
$cmd = "$directorypath\NSCCMPIDInsertion.ps1"
Invoke-Expression "$cmd"
Write-Host Running NSCCMPIDAfterParse.ps1
$cmd = "$directorypath\NSCCMPIDAfterParse.ps1"
Invoke-Expression "$cmd"
Write-Host --------------------------------------------------------------------------
Write-Host Process ended at $(Get-Date)
I am working on a disk space script for our clients in my off time. I just tested it using the ISE, and it looks like it was working until I checked the transcript.
There are sections during the first removal cycle around line 32 where it is removing files in C:\Windows\System32\, which of course I didn't want it to. I am sure I did something wrong, but I have checked for typos, and I do not understand how it can get %system32% from a users directory.
If (([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator))
{
$Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + ' (Elevated)'
$Host.UI.RawUI.BackgroundColor = 'DarkBlue'
Clear-Host
}
Else
{
$newProcess = New-Object Diagnostics.ProcessStartInfo 'PowerShell'
$newProcess.Arguments = "& '" + $script:MyInvocation.MyCommand.Path + "'"
$newProcess.Verb = 'runas'
[Diagnostics.Process]::Start($newProcess) | Out-Null
exit
}
If ((Test-Path "C:\DiskSpaceCleanupLog\") -eq $False)
{
New-Item -ItemType Directory -Path "C:\DiskSpaceCleanupLog\"
}
$Date = [string]::Format( "{0:dd-MM-yyyy}", [datetime]::Now.Date )
$LogName = "C:\DiskSpaceCleanupLog\" + $Date + "Log.txt"
Start-Transcript $LogName
$Path = #()
$Array = #(Get-ChildItem C:\Users | Select-Object Name)
Read-Host -Verbose "Removing User Account temp files..."
Foreach ($Name IN $Array)
{
$Path = ("C:\Users\" + $Name.Name + "\AppData\Local\Temp\")
}
Foreach ($Path IN $Array)
{
Get-ChildItem | Remove-Item -Recurse -WhatIf
}
Remove-Variable Path
Read-Host -Verbose "Removing User Account crash dumps..."
Foreach ($Name IN $Array)
{
$Path = ("C:\Users\" + $Name.Name + "\AppData\Local\CrashDumps\")
}
Foreach ($Path IN $Array)
{
Get-ChildItem | Remove-Item -Recurse -WhatIf
}
Remove-Variable Path
Read-Host -Verbose "Removing User Account reporting files..."
Foreach ($Name IN $Array)
{
$Path = ("C:\Users\" + $Name.Name + "\AppData\Local\Microsoft\Windows\WER\ReportArchive\")
}
Foreach ($Temp IN $Path)
{
Get-ChildItem | Remove-Item -Recurse -WhatIf
}
Remove-Variable Path
Read-Host -Verbose "Removing User Account temp files from Internet Explorer..."
Foreach ($Name IN $Array)
{
$Path = ("C:\Users\" + $Name.Name + "\AppData\Local\Microsoft\Windows\Temporary Internet Files\")
}
Foreach ($Temp IN $Path)
{
Get-ChildItem | Remove-Item -Recurse -WhatIf
}
Read-Host -Verbose "Removing Recycle Bin files..."
Remove-Item -LiteralPath 'C:\$Recycle.Bin\' -Recurse -WhatIf
Read-Host -Verbose "Removing global crash dumps..."
Remove-Item "C:\ProgramData\Microsoft\Windows\WER\ReportQueue" -Recurse -WhatIf
Remove-Item "C:\ProgramData\Microsoft\Windows\WER\ReportArchive" -Recurse -WhatIf
Read-Host -Verbose "Removing Windows Update cached files..."
Stop-Service -DisplayName 'Windows Update'
Remove-Item "C:\Windows\SoftwareDistribution\Download\*" -Recurse -WhatIf
Start-Service -DisplayName 'Windows Update'
Remove-Variable Array, Path
Read-Host -Verbose "Cleaning base image of update cache..."
DISM.exe /Online /Cleanup-Image /SPSuperseded
Read-Host -Verbose "Running Windows Clean Manager..."
$OSVersion = Get-WMIObject -Class Win32_OperatingSystem | Format-Table Version
If ($OSVersion -le 6.1)
{
cleanmgr.exe /verylowdisk
}
Read-Host -Verbose "Removal is complete. Sending logs..."
Stop-Transcript
$SecurePassword = ConvertTo-SecureString "InsertPasswordHere" -AsPlainText -Force
$emailcredential = New-Object System.Management.Automation.PSCredential ("email#domain.com", $SecurePassword)
Send-MailMessage -To "Name Here <email#domain.com>" -From "Name Here <email#domain.com>" -Subject ("Disk Space Cleanup Log - " + $Date) -Body "Attached is the log from the script." -Attachments $LogName -SmtpServer "smtp.office365.com" -Credential $emailcredential -UseSSL -Port "587" -DeliveryNotificationOption OnFailure
Line 32 is Get-ChildItem | Remove-Item -Recurse -WhatIf
The are several things that should be adjusted in your code but the issue that is befalling you now is that you have not specified a -Path. Therefore Get-ChildItem will be returning items from the working directory!
Get-ChildItem | Remove-Item -Recurse -WhatIf
Should be instead
Get-ChildItem $path | Remove-Item -Recurse -WhatIf
Like I said though there are several potential pitfalls and areas of improvement there to be addressed. You use the same loop 5 times. A couple are exactly the same.
I believe the issue is on line 23, where the code is not populating the array with full pathnames. See Get full path of the files in PowerShell for some advice on how to get the full pathnames instead.
I'm running the following code to pull data from SCOM 2012 and using an exported spreadsheet from SCCM 2012, output servers which are pending reboot along with their SCCM maintenance window for automated scheduled reboots.
The code takes around 5-8 minutes to run and I was wondering if there was any way to speed up the process. The code running under Begin Loop is the bottle neck.
Function Generate-RebootData{
IF(Get-Command Get-SCOMAlert -ErrorAction SilentlyContinue){}ELSE{Import-Module OperationsManager}
"Get Pend reboot servers from prod"
New-SCOMManagementGroupConnection -ComputerName ProdSrv
$AlertData = get-SCOMAlert -Criteria `
"Severity = 1 AND ResolutionState < 254 AND Name = 'Pending Reboot'" |
Select NetbiosComputerName
"Get Pend reboot servers from cert"
#For cert information
New-SCOMManagementGroupConnection -ComputerName CertSrv
$AlertData += Get-SCOMAlert -Criteria `
"Severity = 1 AND ResolutionState < 254 AND Name = 'Pending Reboot'" |
Select NetbiosComputerName
"Remove duplicates"
$AlertDataNoDupe = $AlertData | Sort NetbiosComputerName -Unique
"Create hash table"
$table = #{}
"Populate hash table"
Import-Csv D:\Scripts\servers2.csv | ForEach-Object {
$table[$_.Computername] = $_.'Collection Name'}
"Create final object"
$result = #{}
"Begin Loop"
$result = $AlertDataNoDupe | ForEach-Object { [PSCustomObject] #{
Server=$_.NetbiosComputerName
MaintenanceWindow=IF($table[$_.NetbiosComputerName]){$table[$_.NetbiosComputerName]}
ELSE{"Not found!"}
PingCheck=IF(Test-Connection -Count 1 $_.NetbiosComputerName -Quiet -EA SilentlyContinue)
{"Alive"}
ELSE{"Dead"}
LastReboot=Try{
$operatingSystem = Get-WmiObject Win32_OperatingSystem -ComputerName `
$_.NetbiosComputerName -ErrorAction Stop
[Management.ManagementDateTimeConverter]::ToDateTime(`
$operatingSystem.LastBootUpTime)}
Catch{"Access Denied!"}
} }
}
You should perform the PingCheck first, and only if that succeeds move on with the Get-WmiObject call - there's no need to contact a machine if you've just determined that it's "dead".
...
$result = $AlertDataNoDupe | ForEach-Object {
# Create hashtable
$Properties = #{
Server = $_.NetbiosComputerName
MaintenanceWindow = if($table[$_.NetbiosComputerName]){
= $_.NetbiosComputerName
} else {
'Not found!'
}
}
# Perform ping check, keep as boolean
$Properties['PingCheck'] = Test-Connection -Count 1 $_.NetbiosComputerName -Quiet -EA SilentlyContinue
$Properties['LastReboot'] = if($Properties['PingCheck'])
{
try
{
# Server seems to be online
$operatingSystem = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $_.NetbiosComputerName -ErrorAction Stop
[Management.ManagementDateTimeConverter]::ToDateTime($operatingSystem.LastBootUpTime)
}
catch
{
'Access Denied!'
}
}
else
{
# If server doesn't respond, declare it offline
'Computer offline!'
}
# create the object
New-Object -TypeName psobject -Property $Properties
}