Are You My Nano?

I’ve been diving a bit deeper into the Nano waters now that Windows Server 2016 is out the door. As I deployed a few servers I realized there was a potential long-term management issue. During the technical preview, Nano installations were recognized by their Tuva designation. But now, a Nano server is just another Windows Server 2016 installation. So how can I tell if a server is a Nano installation? Here’s the solution I came up with.

Continue reading

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

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

Creating CIM Scripts without Scripting

When Windows 8 and Windows Server 2012 came out, along with PowerShell 3.0, we got our hands on some terrific technology in the form of the CIM cmdlets. Actually, we got much more than people realize. One of the reasons there was a big bump in the number of shipping modules and cmdlets was CDXML. With some work and a properly formatted XML file, you could create your own commands based on WMI and CIM classes. Modules like SMBShare were built the same way. But creating a CDXML based module is not a task for someone just getting started with PowerShell.

So I decided to build a tool that just about anyone could use to create their own CIM-based commands, using relatively common PowerShell scripting techniques. You might find some of the things I do in my script just as interesting or useful. I was also motivated because I know that many IT Pros want to script but don’t have the time or feel they don’t have the skills. I hope what I’ve come up with will help jump start or accelerate the process.

My script, CIMScriptMaker.ps1, will guide you through identifying a WMI class and create an advanced function to get instances of that class. You can even add a filter and select which properties to display. You can then edit the function further if you want and end up with a practical tool that didn’t take a lot of time to write. Let me walk you through the process. The script works in either the console or the ISE. I’ll launch the script from the prompt.

The script defaults to the local computer, but you can specify a remote computer running PowerShell 3 or later. The script then enumerates the namespaces and presents a list using Out-Gridview. I use the title as a prompt.

I’ll select Root\CimV2 and click OK. My script then queries all the classes in that namespace and again displays a list using Out-Gridview. What’s nice is that you can use the filtering capability to quickly find a class you are interested in.

I’m going to select Win32_PageFileUsage and click OK. Using the Popup method from the old Wscript.Shell VBScript object I prompt if the user wants to test retrieving all instances of the selected class.

Naturally, I do. If there are results, they will be displayed in Out-Gridview again.

The script will wait for me to close the gridview. After which I’ll be prompted to continue.

Next the script will display a list of properties for the class and ask if I want to filter.

If you opt to filter, you’ll get a gridview with a list of operators to choose from. The default is =. Then you’ll get a Visual Basic message box asking you to enter in a value. For this demo I clicked Cancel to skip filtering.

Next I am prompted to select the properties. Clicking cancel will in essence give you the full CIM object. If you select properties then behind the scenes I’m generating code that is piping a Get-CimInstance command to Select-Object. I’ll select a few.

And that’s it! The script will generate an advanced function based on the selections you have made. The function defaults to a name using the Get verb and the noun is the class name. The function is copied to the clipboard so that you can paste it into your script editor and also saved to a global variable, $cimscript, just in case you accidentally overwrite the clipboard

If you are in the console, you can right-click to paste it right into your current session. The function includes comment based help. The function can take computer names or you can use CIMSessions.

Here’s what the generated code looks like.

Now I have a CIM based tool that just works or I can develop it further.

Right now, all my script does is generate a command to get WMI information using Get-CimInstance. With a little more work I could probably have it generate commands that do things as well using WMI class methods. But that’s for another day. In the mean time, here is my script.

What do you think?

Get PowerShell Version with WMI

With the release of PowerShell 4.0, it is possible you might end up with a mix of systems in your environment. I know I do because I do a lot of writing, testing and development that requires multiple versions in my test network. Recently I was doing some Group Policy work when I thought about WMI filters. A WMI filter is a way to limit Group Policy to machines that meet certain criteria. I thought it would be useful to have a WMI filter that could determine if the computer was running PowerShell 3 or 4. Why? Well one reason would be so that v4 machines would update help from a local v4 source and likewise for v3. So I started looking a developing a WMI query.

That led to the development of this:

This function uses WMI to retrieve the instance of the CIM_DATAFILE class for PowerShell.exe. I have found when querying for this class to be as specific in your query as you can. This runs pretty quickly and returns some useful information. I can even run it for a group of computers.

Which gives me this:
get-wmipshell

The first two machines are running PowerShell 2.0, the next 2 v3 and the last 2 v4. Now that I know this works, I can create a WMI filter with a query like this:

This should filter only for computers running PowerShell 3.0.

I wrote this function thinking I would add support for alternate credentials. But if you don’t need it, you can also get the same information using the [WMI] type accelerator.

I needed to test and develop a SELECT query which is why I ended up with the function I did. The date information is extra and if you use Get-CIMInstance, the dates are converted for you.

Yes, I know you can get this information with Test-WSMan as well and that is certainly a much easier way. Although if by chance you still have PowerShell 1.0 in use, I don’t think that will work. Anyway, there you have it. A quick way using WMI to find out the PowerShell version and a query you can use to build a WMI filter for Group Policy.

Enjoy.

UPDATE 11/14
I don’t know what I was thinking with my original query. It was much more complicated than it needed to be. I’ve updated my code samples with a better filter. Remember when using \ in any paths, it needs to be escaped which is why you see the name as you do.