Hopefully my title isn’t too vague. I’ve put together a simple script that does a WMI query on anything in the domain with a “Server” OS, and then checks to see if it is physical or virtual. It outputs to a CSV file, and I can sort by the ‘version’ column to determine if it’s physical or virtual. Here’s a sample of the code:
What I’d like to accomplish is to have it write something simple like “Physical” if the version doesn’t match the conditions for VMware or Hyper-V, or “Virtual” if it does. I run this to just get physical servers:
This works, but I’d like to do it as listed in the first example and just get a simple output that lists server name and whether it is physical or virtual. Any ideas?
So, the trick is just to add another custom property to your Select-Object property list. You’ve got one for IPAddress already; just add another. Call it “MachineType” or something. In the expression portion, put all your logic. That can include an entire sub-script, with if constructs and whatever. Whatever you “Write-Output” from the expression will become the value of the “MachineType” property.
This is exactly what I was looking for. Thanks! I was close… I was just over-thinking it, I guess. Also, good tip about using ‘n’ instead of ‘l’ for custom properties. It’s much easier to read that way.
So I’m trying to apply the same logic to a query to determine whether or not SNMP is enabled on all servers running any variation of 2008 Server. This is my code:
This works, but it’s only returning a value for servers that have SNMP installed. It’s skipping over the ones that don’t have it installed. I suspect that this is because the WMI query is returning a null value, but I thought that my ‘if ($_.Name -ne “”)’ statement would catch that.
On servers without SNMP, WMI is probably not returning anything. So, there’s nothing to pipe to Select-Object, so it doesn’t execute. WMI isn’t returning NULL, it’s returning nothing. There’s not really a way to handle that in a one-liner - you’d need to capture the WMI query to a variable, and then test it using a standalone if construct to see if it contains an object or not.
One-liners are great, but they don’t really do logical branching well.
Dave, this worked perfectly! Thank you. I didn’t think to separate the name and WMI query out into two different components like you’re doing here. Thanks again!
Dave, I have a followup question. Again, this worked, but I’m a bit confused. According to the help files, Get-WMIObject does not accept pipeline input for the ‘computername’ property, but it appears that we’re passing the name through from the ‘get-adcomputer’ cmdlet. How is this working? Doe it behave differently if you store it in an array first?
You’re not piping anything directly to Get-WmiObject, in that example. It’s Select-Object that accepts the pipeline input. When you use a constructed property, the Expression is a script block that gets executed for each of the input objects that Select-Object is processing (referred to by the $_ automatic variable inside the expression), and that script block’s return value is what gets assigned to the resulting property.
They both get you PSObjects with the same properties, but I prefer how the pipeline looks when there’s not a big ForEach-Object loop stuck in the middle of it.