Distinguish Windows services with the same ProcessName - powershell

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.

Related

windows service running under non-local admin user not able to get results from WMI agent

We have a windows service which is running under a account that is not part of local admin. With in the service we call a powershell file using processstartinfo. With in powershell file we call the WMI class
"$AVGCPU = Get-WmiObject win32_processor | Measure-Object -property LoadPercentage -Average | Select-object -expand Average"
The above code always returns 0. When i make the user as local admin then the cpu usage value is returned. Also when i run the same code in powershell launched under the same user account (without giving local admin privileges), i am able to get the value for CPU usage. Its only when the cmdlets is called from windows service i am getting this problem. Due to security restriction, i cannot make the user as local administrator. Any idea what rights should be given to the user that WMI class return value when called from windows service.

Get Associated Application of a Disabled / Stopped Service

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.

Using Powershell to get a vm's own name

The short question is; can a VM use powershell to get its own name?
I have an environment where I have 12 identical sets of VMs. Each set has one jump server, and the naming convention is ##_APP_SET#, where ## is a corresponding NAT device, and SET# tells me the set of VMs.
On this APP VM, I have created a menu that uses an account on the external vCenter to turn the VMs in the set on and off. So from within the VM, it is connecting to its parent vCenter and running an action on another VM in the set. The problem is that I have the VM names hard coded in the script. For example, if I'm on 01_APP_SET1, I have a bunch of entries for 01_MACHINENAME_SET1, and on 02_APP_SET2, I have entries for 02_MACHINENAME_SET2, etc.
I am currently managing 12 different scripts on the 12 different APP VMs. I am hoping to make the script more general where the VM calls a get-vm on itself and parses out the preceding ## and trailing SET#, but not having much luck beyond getting a list of systems called APP with get-vm APP.
I'm thinking the best way to tackle this would be to give each APP VM a hostname matching its name in vCenter, then parsing out the information that way.
Is there any sort of identifiable information that is unique to the APP VM such as a external facing IP to be able to log in to outside of the private networking for the Set?
Perhaps something like this would be helpful:
$ip = (ipconfig | Select-String "IPv4 Address" | Select-String "192.168.1").Line.Replace("IPv4 Address. . . . . . . . . . . :","")
$vm = get-vm | ?{$_.Guest.IPAddress -like $ip}
Or group the VMs with tags in VC and use Invoke-VMScript to poke around other guests as necessary.

How to obtain UNC drive info on "Disconnected Network Drive"

We run some processes in a distributed computing environment. Processes on one machine need to communicate information with processes on other machines. One of those piecies of information is the location of certain files. Thus, a process on one machine may have put information into a particular file on a particular network share, and it needs to communicate the location to a process on another machine.
We have no problem with the communication part. The problem is with determining the "location" information that a machine need to disseminate. File paths involving drive mappings are clearly useless: different machines will have differing drive mappings. Thus, what we need to communicate it the full UNC path name.
For the most part, we can obtain that information easily. One place where we are having problems is in a powershell script that needs to obtain this information. Currently, we use the following code:
$l_logicalDisk = Gwmi Win32_LogicalDisk -filter "DeviceID = '$l_currentDrive'"
if ( $l_logicalDisk.DriveType -eq 4 )
{
$l_base = $l_logicalDisk.ProviderName
}
and $l_base provides the \\computername\share information. However, in certain circumstances, this fails. At times, for some unknown reason, a mapped drive will appear as "Disconnected Network Drive" in Explorer.exe, even though the drive and all its files are accessible. (In fact, the script that is running is even located on the supposed "Disconnected Network Drive".) In this situation, the ProviderName field of the logical disk information is blank. Nothing seems to flip the status from "Disconnected Network Drive", nor have I found any way to update the ProviderName information.
So, does anyone know either (1) how to "reconnect" a disconnected network drive from within powershell or (2) how in Powershell to obtain the UNC path information for a directory in a more reliable method that outlined above? Thanks.
You can always ask the registry, this should work on disconnected drives (where $DrvLtr equals the desired network mapped drive letter such as Z or M):
Pushd
cd HKCU:
$UNC=(gci network|?{$_.Name -match "$DrvLtr"}|%{Get-ItemProperty -Path $_}).RemotePath
Popd
$UNC should then be a string with a value like "\Server01\FileShare$" which I think is what you're going for. Then you can just do a
$Path.Replace("$DrvLtr`:",$UNC)
And you're all set

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