Since you're talking of 15,000 hosts, querying each of them from the network is going to be highly inefficient.
The Right Thing To Do™ then is to have a watchdog running on each host to make sure the appropriate software is installed and running. This watchdog might be a piece of software running as a service, a scheduled script or even hardware-based if you use something like Intel vPro.
To verify if an AV software is installed, you could use the following PowerShell command --
$avSoftware = get-wmiobject -class "Win32_Product" -namespace "root\cimv2" `
-computername "." -filter "Name like '%antivirus%'"
Note that at the end you have a filter
argument that you can customize to make sure you're looking at the right product.
After playing a bit with the like
operator, you should be able to nail the antivirus description and minor variations here and there. Note that my example above (anything containing the word "antivirus") is pretty simplistic. You should instead look for specific patterns matching your approved antivirus software (e.g. "Trend Micro Antivirus%")
Anyway, the command above will return a collection of installed products that match your filter
statement. From here you can test whether $avSoftware.Count
is greater than zero, in which case you have antivirus software installed. The example below lists all the installed antivirus software --
if ($avSoftware.Count -gt 0) {
foreach ($av in $avSoftware) {
write-host $p.Name
}
} else {
write-host "No AV software found"
}
Instead of just printing a message saying that no AV has been found, you should obviously do something more useful, e.g.
- Notify an admin
- Install an AV from the network
You also said you'd like to get the version of the installed AV. To do that, you can use the Version
property of the Win32_Process
. Let's modify the above code like this to also print the version numbers for the installed software --
$avSoftware = get-wmiobject -class "Win32_Product" -namespace "root\cimv2" `
-computername "." -filter "Name like '%antivirus%'"
foreach ($av in $avSoftware) {
write-host $av.Name, $av.Version
}
As for the version of the installed virus definition files, you'd have to rely on each specific AV WMI interface. You'll have to consult the vendor's documentation for that.
One more thing to remember. It's probably not enough to know that the host has AV installed if the AV isn't running. After checking which AV is installed, you should make sure its process is running. To do that, you'll have to know what the appropriate process for each of your AV software is and look for them like this --
$processes = get-wmiobject -class "Win32_Process" -namespace "root\cimv2" `
-computername "." -filter "Name = 'TeaTimer.exe'"
if ($processes.Count -gt 0) {
foreach ($p in $processes) {
write-host $p.Name
} else {
# AV not running. Launch it here or notify someone
}
The above example looks for the Spybot process (not exactly AV, but you get the picture), which is called "TeaTimer.exe". Modify it to look for your process instead.
Now, all of that said, if you're dealing with thousands of hosts like that, you should probably invest in some management tool (e.g. LANdesk, Microsoft System Center or Level Platforms.) These tools would make your life a whole lot easier.
This can also be done via an elevated command prompt using the sc
command. The syntax is:
sc config [service name] depend= <Dependencies(separated by / (forward slash))>
Note: There is a space after the equals sign, and there is not one before it.
Warning: depend=
parameter will overwrite existing dependencies list, not append. So for example, if ServiceA already depends on ServiceB and ServiceC, if you run depend= ServiceD
, ServiceA will now depend only on ServiceD. (Thanks Matt!)
Examples
Dependency on one other service:
sc config ServiceA depend= ServiceB
Above means that ServiceA will not start until ServiceB has started. If you stop ServiceB, ServiceA will stop automatically.
Dependency on multiple other services:
sc config ServiceA depend= ServiceB/ServiceC/ServiceD/"Service Name With Spaces"
Above means that ServiceA will not start until ServiceB, ServiceC, and ServiceD have all started. If you stop any of ServiceB, ServiceC, or ServiceD, ServiceA will stop automatically.
To remove all dependencies:
sc config ServiceA depend= /
To list current dependencies:
sc qc ServiceA
Best Answer
This is possible with a PowerShell one-liner, you just need an easy way to identify that cert (I'm using the cert's ThumbPrint).
If you already have a known machine that you know definitely has the cert installed (easiest way to check interactively is by just using
certmgr.msc
) then you can use that machine to find the cert's thumbprint.The following PowerShell command will list all certs installed in the Trusted Publisher store in the local machine context:
Obviously the path above can be modified, to list other cert stores, or you can view (a long list of) all locally installed certs using:
The first command should give you an output something like this:
Once you've found the Thumbprint of the cert that you're looking for, you can use that to filter the results like this:
That should return the details of the cert if it's installed, and nothing if it's not. Amongst other uses, this Powershell one-liner can be used as a Custom Script Detection method in an SCCM 2012 Application.
(Resources used: Use PowerShell to Find Certificates that are About to Expire | PowerTip: Use PowerShell to Discover Certificate Thumbprints | Using the Where-Object Cmdlet)