In this post, I’m going to avoid PowerShell for a simple reason: I’ve got to fix SCCM client issues and to do that, I will need to run a script on each one of these clients. As the number of client is in the hundreads, imagine trying to run a script that is compatible with many PS versions (and this is not the difficult part), when PowerShell is installed! I’m sure the support guys will have to run through a few XP machines .
Another issue wiht PS is that I would need to change the execution policy on each client. No thanks, for now at least.
If you didn’t hear enough excuses, here’s another one: yep I could run PS remotely using WMI but guess what? I need to work on stopping WMI and the services that depend on it.
I opted for a simple command line that will get a list of services that depend on the specified service:
sc enumdepend servicename
For instance, let’s try to run this against WMI (Windows Management Instrumentation – winmgmt):
sc enumdepend winmgmt
This is the result against one of my machines.
Now, I am a big fan of AutoIt, so I’ll be using it to capture the output from this command and have it to get a list of services that depend on the specified service, which in my case will be winmgmt. AutoIt gives me less troubles as in the end it’ll all be compiled in a single executable file. In the script below I kept a higher number of variables so that if you’re interested, you can just modify the script and start using the variable you like the most (for instance $temp_array in the script could be avoided). Normally I would have saved a couple of lines from it.
$service = "winmgmt" ;THE service!
$pid = Run('sc enumdepend '&$service, '', @SW_HIDE, 2)
Global $data ;This variable will contain an array with every line in the output
Global $service_names = "" ;This is a string that will contain the list of services split by a comma
Global $services ;This one will be the array when we split the string every comma at the end
;Get the output into $data
$data &= StdOutRead($pid)
;Make $data an array by splitting every line in a single entry in the array
$data = StringSplit($data, @CRLF,1)
;If there's no error, go through the array and when the string "SERVICE_NAME:" is found, add the name of the service
;into $temp_service. $service_names will be filled with the previous content (if it's the beginning of the line it'll be
;nothing) plus the service name plus a comma.
If Not @error Then
For $i = 1 To $data
If (StringInStr($data[$i],"SERVICE_NAME:")) Then
$temp_service = StringReplace($data[$i],"SERVICE_NAME: ","")
$service_names = $service_names&$temp_service&","
;If $service_names is empty, then there's no service that depends on WMI.
If Not $service_names Then
MsgBox(0,'No Services found','No services are dependant from the WMI service.')
;Removing the last char from the string which is a comma
$service_names = StringTrimRight ($service_names,1)
;$service_names now looks like this: service1,service2,service3
;Splitting $service_names at every comma so that we can have our array with data in it
$services = StringSplit($service_names,",")
;Now $services will looks like this:
I tried to comment as much as I could to make it as simple as possible. As you can see, you can now use the content from the array names $services and for instance, run through them all in a for cycle and stop all of these services.
I personally added this to another script that will basically will try to fix the issues with the SCCM clients in the environemt. I’ll probably write an article that’ll describe the steps to do that. Obviously in my case I removed any output (MsgBox) and wrote a log instead as I will need to have the Desktops team to run this remotely and silently.