starting Windows services with powershell - powershell

I need to check service status of remote computer
If it is stopped, then I have to check whether the service is related to OS or Application.
If it is OS, then check for dependent services and then check it is configured with local system account only.
If it satisfies all the conditions then service has to be started
If service is configured with service account then it has to be started with the respective service account only.
If service is related to App but not OS, then send email to server owner and application team to start service.

Okay, let's start to break this down.
First of all, you want to check the services of another computer. For this task, there are multiple ways to do it. One could be the Invoke-Command. You could also first connect to the computer and then execute the commands. Herefore you can use the Enter-PSSession.
Let's go to the other parts. You want to check if a service is running. You can use the Get-Service command for this. The services you get back have different properties. One you should look for is the property "status". As you may see if you just use the command Get-Service you get every Service on your (or remote) machine. You can filter the results by using the | (Data pipe) and the Where-Object command.
You want to filter for all services which aren't running anymore.
This could look like this:
Get-Service | Where-Object {$_.status -eq "stopped"}
Now we have all Services which are not running. We need to extend our filter more to get the services that are from the user "LocalSystem".
Get-Service | Where-Object {$_.status -eq "stopped" -and $_.UserName -eq "LocalSystem"}
Last but not least we just want services which are from the OS. The property "ServiceType" determines whether the service is "Win32OwnProcess" or "Win32ShareProcess". So we filter for "Win32OwnProcess".
Get-Service | Where-Object {$_.status -eq "stopped" -and $_.UserName -eq "LocalSystem" -and $_.ServiceType -eq "Win32OwnProcess"}
Sadly I didn't really understand what you need the dependent services for, but you can have a look at them and extend this oneliner to your own needs.
Get-Service | Where-Object {$_.status -eq "stopped" -and $_.UserName -eq "LocalSystem" -and $_.ServiceType -eq "Win32OwnProcess"} | ft -Property Name, DependentServices
I think that's a good start for you to finish the rest of it by yourself.
You may need IF Statements, and the Send-MailMessage if you want to send an e-mail to the server owner. For restarting a service you can use the Start-Service command.
You can use the data pipe for this again. First filter for all the services you are looking for as I did earlier this post and then use the data pipe and the Start-Service command.
This could like this:
Get-Service | Where-Object {$_.status -eq "stopped" -and $_.StartType -eq "automatic"} | Start-Service
This would restart all services which aren't running and have as start type "automatic".

Related

Is there a way to query Server Manager using PowerShell

Part of our daily process is to RDP to a remote machine and check the services are running. We have to check “File and Storage Services”, “IIS”, “Local Server”, and “All Servers” (see image).
Can I do this remotely through PowerShell? I have a script (Get-Service -ComputerName [remote computer name]), but which services do I list to check these 4 main areas are running?
Server Manager
Tried:
get-service -Name "LanmanServer", "LanmanWorkstation" -ComputerName [computername]
get-service -ComputerName [computername] | Where-Object {$.Status -ne "Running"}
get-service -ComputerName [computername] | Where-Object {$.Status -eq "Running"}
So I can list the services, and if they're running or not, but this doesn't tell me what I need

How to stop Windows Services via Powershell with AutomaticDelayed start type?

I was able to write a Powershell 2.0 script that that stops certain running services, which I use in an Ansible script. The Ansible script reboots the VM first, then runs the script.
# Get a list of running XYZ_* services and store them in an array.
$runningExaServices = Get-Service | Where-Object {$_.Name -like "*XYZ_*"} | Where-Object {$_.Status -eq "Running"}
# Iterate throgh the services and stop all of them except EXA_Web,
# EXA_Web_APIs, EXA_Nginx, EXA_Redis. We'll stop those separately
Foreach($service in $runningExaServices) {
Write-Host "Stopping: "$service.name
Stop-Service -Name $service.name -Force
$svc = Get-Service | Where-Object {$_.Name -eq $service.name}
Write-Host $svc.name: $svc.status
}
The XYZZ_* services will indeed stop. However, the services with Automatic (Delayed Start) would start running again. What's the secret to keeping them stopped? TIA
Since Get-Service doesn't expose the "Automatic (Delayed start)" configuration, you'll have to rely on just the Automatic value for StartType. If you want them to stay stopped, switch the starttype value to "Manual":
# Get a list of running XYZ_* services and store them in an array.
$runningExaServices = Get-Service -Name "*XYZ_*" | Where-Object {$_.Status -eq "Running"} #| Stop-Service -PassThru
Foreach($service in $runningExaServices) {
#Write-Host "Stopping: $($service.name)"
if ($service.StartType -eq "Automatic") {
$Serice | Set-Service -StartupType 'Manual'
}
Stop-Service -Name $service.name -Force -PassThru
# Write-Host "$($svc.name): $($svc.status)"
}
I'm not too sure when these cmdlets were introduced but, I will go ahead and take a guess that Set-Service was released at the same time as Get-Service; i.e. PowerShell 2.0.
With that said, a simple if condition/statement can check for the starttype value and proceed accordingly by setting it to "Manual". Then, stopping the service(s).
Couple of side notes:
You don't need the loop if you pipe directly to Set-Service, and Stop-Service given the following circumstances:
You don't care about setting the starttype to "Manual"
You don't care about the iteration process, and just having them all stop at once with a -PassThru switch provided; which in turn outputs the object with the new status of "Stopped".
Lastly, - referring back to the 2nd sub-bullet point above - -PassThru is what I would suggest rather than stating what current service object you're on and re-querying the same object for the new status.

How to stop a service in Windows 10 Pro 1903 with powershell

In Powershell I would like to stop a service:
Stop-Service -Name "StateRepository" -Force
The service won't stop. It doesn't make any difference how long I wait. I'm signed on with the user Administrator in Windows 10 Pro 1903. I don't get any errors. When I look in services.msc the service is not stopped.
If Stop-Service -Force isn't working, I'm not sure what's going on here. However, you can use WMI/CIM to get the current PID of the service and kill it that way (note that this can be an unsafe operation):
$service = Get-CimInstance Win32_Service | Where-Object { $_.Name -eq "StateRepository" } | Select -First 1 Name, ProcessId
Write-Warning "Killing process $($service.ProcessId) for service $($service.Name)"
Stop-Process -Force $service.ProcessId
This said, it's always better to look into why a service won't stop, as this technique would be more of a last resort.

How to get all Windows service names starting with a common word?

There are some windows services hosted whose display name starts with a common name (here NATION). For example:
NATION-CITY
NATION-STATE
NATION-Village
Is there some command to get all the services like 'NATION-'. Finally I need to stop, start and restart such services using the command promt.
sc queryex type= service state= all | find /i "NATION"
use /i for case insensitive search
the white space after type=is deliberate and required
Using PowerShell, you can use the following
Get-Service | Where-Object {$_.displayName.StartsWith("NATION-")} | Select name
This will show a list off all services which displayname starts with "NATION-".
You can also directly stop or start the services;
Get-Service | Where-Object {$_.displayName.StartsWith("NATION-")} | Stop-Service
Get-Service | Where-Object {$_.displayName.StartsWith("NATION-")} | Start-Service
or simply
Get-Service | Where-Object {$_.displayName.StartsWith("NATION-")} | Restart-Service
Another way of doing it, if you don't like the old PowerShell version.
# Create an array of all services running
$GetService = get-service
# Iterate throw each service on a host
foreach ($Service in $GetService)
{
# Get all services starting with "MHS"
if ($Service.DisplayName.StartsWith("MHS"))
{
# Show status of each service
Write-Host ($Service.DisplayName, $Service.Status, $Service.StartType) -Separator "`t`t`t`t`t|`t"
# Check if a service is service is RUNNING.
# Restart all "Automatic" services that currently stopped
if ($Service.StartType -eq 'Automatic' -and $Service.status -eq 'Stopped' )
{
Restart-Service -Name $Service.DisplayName
Write-Host $Service.DisplayName "|`thas been restarted!"
}
}
}
Save it as a .ps1 file and then execute
powershell -file "path\to your\start stop nation service command file.ps1"

Filter services when calling Get-Service

I did this in the past, and can't remember the correct command (I think I was using instring or soemthign?)
I want to list all the windows services running that have the word 'sql' in them.
Listing all the windows services is:
Get-Service
Is there a instring function that does this?
Get-Service -Name *sql*
A longer alternative would be:
Get-Service | where-object {$_.name -like '*sql*'}
Many cmdlets offer built in filtering and support wildcards. If you check the help files (Get-Help Get-Service -full), you will see
-name <string[]>
Specifies the service names of services to be retrieved. Wildcards are
permitted. By default, Get-Service gets all of the services on the comp
uter.
Required? false
Position? 1
Default value *
Accept pipeline input? true (ByValue, ByPropertyName)
Accept wildcard characters? true
Usually if filtering is built in to the cmdlet, that is the preferred way to go, since it is often faster and more efficient.
In this case, there might not be too much of a performance benefit, but in V2, where you could be pulling services from a remote computer and filtering there would be the preferred method (less data to send back to the calling computer).
You can get all the services that are running and having words sql.
Get-Service | Where-Object {$_.Status -eq "Running"} | Where-Object {$_.Name -like "*sql*"}
If you want more information, see this (not much difference)
http://nisanthkv.blog.com/2012/06/29/get-services-using-powershell
Hope it helps...
Please enter below command:
Get-Service -Name '*<search string>*'
Above answers are great, but this is more useful:
Get-WmiObject -ComputerName <INSERT COMPUTER NAME> -Class Win32_Service | where-object {$_.name -like '*sql*'}
It allows for this query on remote computers.
The Search String might be in either Display Name or Service Name (e.g. searching Service Name for "*SQL*" does not include the SQL Integration Services ...) so I filter both:
get-service | Where-Object {$_.DisplayName -like "*MySearchString*" -or $_.ServiceName -like "*MySearchString*"}