How to stop a service in Windows 10 Pro 1903 with powershell - 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.

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.

Use PowerShell to install Windows Updates in vSphere

I have a cluster of vSphere windows clients approximately 100 that I want to remotely automate windows updates on weekly. I have listed all the windows machine out in text file on my desktop. I have run the PSWindowsUpdate module on my local windows10 machine with command:
Install-Module -Name PSWindowsUpdate and then executed the below script successful for my local machine to run windows updates.
#Import-Module PSWindowsUpdate
#Remove-Item -Path C:\Scripts\status.tx
#Start-Transcript -Path C:\Scripts\status.txt
#$Updates = "Critical Updates", "Security Updates"
#Get-WUInstall -AcceptALL- Verbose -IgnoreReboot -Category $Updates
#Write-Host "Done"
#Stop-Transcript
#Start-Sleep -s 120
#Restart-Computer -Force -Confirm:$false
-- after pc restarts run as PS As Administrator
#Get-WindowsUpdate
However, I am not a expert at PowerShell so, I do not know what to additionally script to accomplish the task of remotely updating 100 or so windows clients in vSphere.
Any suggestion would be appreciated.
You can try with the invoke-command. You can create a server list from a DC:
$Servers = Get-ADObject -Filter * -Properties Name,OperatingSystem | Where-Object OperatingSystem -like '*Server*'
And use this list with a loop like this
ForEach($_ in $Servers)
{
Invoke-Command -ScriptBlock {Get-WUInstall -AcceptALL- Verbose -IgnoreReboot -Category $Updates } -ComputerName $_.Name -ErrorAction SilentlyContinue
}

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"

Kill process by filename

I have 3 instances of application running from different places. All processes have similar names.
How can I kill process that was launched from specific place?
You can get the application path:
Get-Process | Where-Object {$_.Path -like "*something*"} | Stop-Process -WhatIf
That will work for the local machine only. To terminate remote processes:
Get-WmiObject Win32_Process -Filter "ExecutablePath LIKE '%something%'" -ComputerName server1 | Invoke-WmiMethod -Name Terminate
I would like to slightly improve Shay Levy's answer, as it didn't work work well on my setup (version 4 of powershell)
Get-Process | Where-Object {$_.Path -like "*something*"} | Stop-Process -Force -processname {$_.ProcessName}
You can take a look at the MainModule property inside of the Process class (which can be invoked via powershell).
foreach (Process process in Process.GetProcesses())
{
if (process.MainModule.FileName == location)
{
process.Kill();
}
}
I'd also consider the possible exceptions that can occur while calling this code. This might occur if you're trying to access processes that are no longer present (killed since the last time GetProcess was called) or processes for while you do not have permissions.
Try this:
http://technet.microsoft.com/en-us/library/ee177004.aspx
Stop-Process -processname notepad
The below command kills processes wherein "something" is part of the path or is a command line parameter. It also proves useful for terminating powershell scripts such as powershell -command c:\my-place\something.ps1 running something.ps1 from place c:\my-place:
gwmi win32_process | Where-Object {$_.CommandLine -like "*something*"} | % { "$(Stop-Process $_.ProcessID)" }
The solution works locally on my 64bit Windows 10 machine.