Get Antivirus Product Status with PowerShell

I expect that most of you with enterprise wide antivirus installations probably have vendor tools for managing all of your clients. If so, don’t go away just yet. Even though I’m going to demonstrate how to get antivirus product status with PowerShell, the scripting techniques might still be useful. Or you might learn a bit more about WMI and the CIM cmdlets.  Let me start with a simple command to get antivirus information from your local computer, assuming you are running PowerShell 3.0 or later.

Continue reading “Get Antivirus Product Status with PowerShell”

The CIM-ple way with PowerShell and Event Logs

I’m always on the lookout for new ways to do things. Often I’m trying to find a way to create something that is easy to use without requiring a lot of PowerShell scripting.  I also like using the final result as teaching aids so even if you don’t need the end product, I hope you’ll pick up a trick or two that you can use in your own scripting projects. The task I had in mind today is a better way to get event log information. Not the events themselves, but rather the event log file. How many entries are in it? How big is it? How much of the configured log is being used? Here’s what I came up with.

Continue reading “The CIM-ple way with PowerShell and Event Logs”

Memory Reporting with PowerShell

I’ve started a new project and I’m hoping a few of you will give it a spin and let me know how it works for you. I’ve created a PowerShell module called MemoryTools that uses a few WMI classes and performance counters to provide insight into memory utilization and configuration on your servers. The module has several commands including one that skips the pipeline (exception to the rule!) and uses Write-Host to display memory status in living color.


The project is up on GitHub at if you’d like to give it a try. The Readme file should give you a overview of what to expect. Use GitHub to report any bugs or feature requests. I know I still need to add command help.

The module should work on any computer running v3 or later. Note that the Get-PhysicalMemory command, which queries the Win32_PhysicalMemory class, may not show results for some properties. There are a few new class properties that require Windows Server 2016 but I decided to include them anyway.

I look forward to hearing about your experiences.

The Power of Custom Properties

The other day fellow PowerShell MVP Adam Bertram published an article about using custom properties with Select-Object. It is a good article in that it gets you thinking about PowerShell in terms of objects and not simple text. But I want to take Adam’s article as a jumping off point and take his ideas a bit further. I’m going to use Adam’s same example as a learning tool. Don’t get distracted by other ways to get the same information. The process and techniques are what matter here.

Whenever I’m working with PowerShell, I’m always thinking about how I can use this at scale.  How can I get this same information for 10 or 100 servers? And of course,  at this point I need to make sure I include a computername in the results.  First, I’ll try something with a single computer.


Close but not quite. Get-CimInstance is writing multiple objects to the pipeline.  The server in question has 2  8GB sticks of memory which is what you see in the output. I need something more along Adam’s original idea to that this becomes 16GB.

What I really want is the Sum property from Measure-Object and to that I need to add a Computername property. I’ll turn things around a bit.


This works because I’m using the common PipelineVariable parameter introduced in PowerShell 4.  What happens is that the pipeline output from Get-CimInstance is stored in a variable, pv, which I can access later in the expression. In my case I’m defining a new property for the computername using $pv and adding it to the selected output from Measure-Object.

However, if I try this for multiple computer names, I don’t get the expected result.


That’s because I’m adding up the physical memory instances from all servers, which isn’t really what I want. Instead, this is a situation where I have to process each computer individually.


One thing to be careful of when using the ForEach enumerator is that you can’t pipe the output to another cmdlet like Export-CSV, unless you explicitly save the results to a variable.

Then you can pipe $data to other cmdlets. You can use ForEach-Object although it might be little harder to follow.

But this makes it easier if you need to pipe the output to something else.


To wrap this up let’s go all out and define a few more custom properties.


Even though I’m selecting a few properties from the output of Measure-Object, I’m defining several others which are calculated on the fly. There is so much you can do with this technique,  but if I lost you anywhere please let me know.

What Are You?

Here’s a quick way to tell whether a given machine is real or not: check the Win32_Baseboard class. You can use either Get-WmiObject or Get-CimInstance. Notice the results from a few physical machines.

Now see the result when querying a Hyper-V virtual machine:

I don’t have any VMware available so I don’t know what kind of result that would show. I also haven’t done extensive testing with items like a Microsoft Surface. I threw together this simple function you could use.

Have fun.