Get Associated Application of a Disabled / Stopped Service - powershell

Problem
I am working with a PowerShell script to skim through a lists of known application services and, for any that are disabled, the script is expected to uninstall them. I have been researching how to get the application name/path of a target service, but failed to find anything suitable to my needs. I had tried working with Get-Service in hopes of that getting me what I need, but was not able to get the desired results.
Question
How do I get the associated application of a target service that is currently stopped or disabled using PowerShell?
PS: Please understand that PowerShell is a requirement of this.

The running state of the service shouldn't really impact what information you get back. However Get-Service doesn't give you all of the configuration info for a Service, in particular the Path of the process being invoked.
To get that you can use Get-WMIObject Win32_Service. For example:
Get-WMIObject win32_service | Where {$_.name -eq 'wuauserv'} | Select *
This returns a PathName property amongst others that I think you will find useful.

Related

Powershell 6.2 and Get-CimInstance to remotely stop/start/restart service issues

So I am at a big roadblock right now. I was working in PowerShell 5.1 and had the Get-WmiObject with the Win32_Service Class working perfectly fine to remotely stop/start/restart services remotely. However, I found out that the .StopService() method has been removed in PowerShell 6 (which I used this to bypass the dependencies issues I kept running in to). As well, I have found out that the -ComputerName variable has also been removed from a lot of the different commandlets.
Since the removed the -ComputerName from things like the Stop-Service commandlet, I am struggling to figure out how to properly handle the stopping of the service itself. I can retrieve the service or services I want without issue. I just can't seem to figure out how to handle stopping the service.
Tried being as detailed as I can. I know I am missing something stupidly small, but all of my Google searches appear to return everything with PowerShell 5, but so little on 6.
Thanks.
Ok, nevermind about this question. I decided to approach my Google searching another way and I stumbled upon the syntax I needed. For those of you wondering, you cannot run commands straight from the returned object. So for example, you could do "$service.StopService()" straight on the service previously. However, now you have to do an invoke of that StopService method by doing "Invoke-CimMethod -Name StopService" and that is only after you pipe the Get-CimInstance returned object to it. So the full syntax would look something like this.
get-ciminstance win32_service -filter "Name='spooler'" | Invoke-CimMethod -Name StartService
A really good website I found to explain and give really good examples of why and how the Cim Instances are they way they are.
https://4sysops.com/archives/managing-services-the-powershell-way-part-7

Get-EventLog not parsing Message when run by SYSTEM user

Problem
I am trying to schedule a job that monitors events on remote machines.
I wrote the script based on the Get-EventLog command and it works properly when run by my account. But when I run the Get-EventLog as SYSTEM user, the .Message attribute of the returned objects shows the following error:
The description for Event ID '4724' in Source 'Microsoft-Windows-Security-Auditing' cannot be found. The local computer may not have the necessary registry information or message DLL files to display the message, or you may not have permission to access them. The following information is part of the event: {somedata}
When I use the Get-WinEvent command as SYSTEM user, the problem does not appear and the .Message part displays properly.
I would stick with Get-WinEvent, especially since the data is much easier to parse (thanks to the ToXML() method), but the Get-EventLog happens to be terribly faster :(
Question
Does anyone have any idea why the Get-EventLog fails to render .Message when run by SYSTEM user and perhaps how to fix it?
To avoid obvious answers:
the COMPUTER$ account is member of DOMAIN\Event Log Readers group,
the COMPUTER$ account does have the read privileges over the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Security on remote machines,
obviously, the registry entries for Microsoft-Windows-Security-Auditing and related DLL's are identical on both the source and target computers.
Try:
Get-WinEvent -LogName “Microsoft-Windows-Security-Auditing” | where ID -eq 4724 | select-object -ExpandProperty Message

Powershell script check the status of the stopped services and send mail

I am pretty new to Powershell scripting and i have a requirement to check the status of the services, if the services are stopped ,capture the status into a separate text file and send the email status to the users that services got stopped. In my environment services runs on two different machines . How to achieve it using Get -service
Please help me.
Since it looks like you haven't started, I'll give you a few things to kick you off.
Get-Service | Where-Object {$_.status -eq "stopped"}
This is a way to retrieve all the stopped services. Get-Service gets all the services, Where-Object is like an if statement in programming, and the part in parenthesis is the condition to meet.
Here's a link where you can read more about that: https://technet.microsoft.com/en-us/library/ee176858.aspx
This is a line of code that will write processes to a text file:
Get-Process | Out-File c:\scripts\test.txt
You can see how combining different commands will get you the result you want. Search around the internet if you get stuck. PowerShell is pretty well documented.
Here's a link for some more research on writing to a file: https://technet.microsoft.com/en-us/library/ee176924.aspx

Distinguish Windows services with the same ProcessName

I am adjusting a monitoring system which checks if a service is running or not. It does that by checking the process name and it's memory consumption. Once it drops below 1 MB an alert is triggered. Also I use the memory usage value to display it in a graph. So checking and notifying is not the only purpose.
Currently I have 5 Windows services using the same ProcessName and I don't know how to make my script distinguish them. The ServiceName for each service is of course different and the path to the executable as well.
When I run get-process I see them all, but I don't see an option here distinguish them. Using get-service doesn't help much either, because it returns name, displayed name and status. Somehow I would love to combine the entries to see the memory usage by service name, not by process name.
You say that the path to executable is different - this way you can distinguish the processes by querying path property. Should they be equal, you can also query StartInfo object of a process to get Arguments property to discern from one another. But the best way to get correct process instances will be to query WMI objects of type Win32_Service to filter your services out, this way you can find if one of them is stopped as well, and then get the process by passing the ProcessId property of the WMI service object. For running services, the PID will be valid. An example (which only filters by service name):
gwmi win32_service | ? {$_.name -eq "wsearch"} | % {get-process -id $_.processid}
Note that there is a possibility that one process will handle more than a single service, this is called "Shared service process" and is visible in Get-Service output as ServiceType property of the returned service, the value Win32SharedProcess (0x20) indicated the underlying PID can be shared, although it's not always the case. The most known shared service process is svchost.exe which also has a sort of a namespace to determine which process should host a certain service, passed to it as a command line parameter.

Powershell - Refresh SNMP from registry or do a SNMPServiceResetEvent

I've written a powershell script that writes registry entries for network drivers to change DCB settings. Things like turning DCB on and off, defining traffic classes and bandwidth groups. After writing the values to registry sometimes you cannot see the changes with SNMP remotely. Though this is inconsistent.
I've scoured the web to see if there is a way to force SNMP to get its values from registry again. We have a script that sets the values in SNMP which automatically changes the registry. I'm trying to go the opposite way and set the values in the registry and have the MIB updated. I've tried reseting the SNMP service and network device in the script with no luck.
After modifying the registry, do a SetEvent on the global event named
"SNMPServiceResetEvent". (That is, do a CreateEvent to that named event and
then do a SetEvent). That should cause the agent to reintialize using the
current registry values.
Jeff Kelley
Microsoft / Windows CE Networking
The only thing I've found that sounds like what I need is the above quote, though futher research suggests he is talking about C++ or C#. Is there a way to do what he suggests in powershell? I found a New-Event commandlet though I'm unsure of its suitability to the current task. Code I've tried:
$snmpService = New-Event -sourceidentifier dcbScriptSnmpReset -sender SNMPServiceResetEvent -messagedata "Reset SNMP to refresh Registry"
Though there is no Set-Event commandlet and I don't know how to proceed.
Any help or leads would be much appreciated.
Thanks,
Marcus
Apparently I misunderstood how SNMP worked and now I can get it to update values entered into the registry by enabling and disabling the network adapter and stopping and starting the SNMP service:
Stop-Service $snmpService.Name
$adaptor = Get-WmiObject -Class Win32_NetworkAdapter | Where-Object {$_.DeviceID -eq $deviceID }
$adaptor.Disable()
$adaptor.Enable()
Start-Service $snmpService.Name