A huge collection of 3400+ free website templates JAR theme com WP themes and more at the biggest community-driven free web design site
Home / App-V / WMI freatures PS

WMI freatures PS

We got a question on Twitter about an older function I has posted to get antivirus information via WMI. The function continues to work fine with Windows 10, although there’s always room for improvement. However, the question was that the function did not seem to work when querying a server running Windows Server 2016 or later. And that does appear to be the case. From what I can tell the WMI namespace my function is querying does not exist on Windows Server 2016 and later. I figured I needed to search to see if there were antivirus products anywhere else. So I wrote a function this morning to search all WMI namespaces for a class name.

My function, Find-CimClass, uses the CIM cmdlets to recursively search all namespaces on a computer (the default is the localhost) for a given class name. You can use wild cards for the class name. I also included an option for an Exclude pattern which can be a regular expression pattern. For example, I may search for a class name but want to exclude any of the Win32_Perf* classes. The function can be found as a gist on my GitHub repository.

#requires -version 4.0

#search WMI for a class
Function Find-CimClass {
[CmdletBinding()] [OutputType([Microsoft.Management.Infrastructure.CimClass])]

Param(
[Parameter(Position = 0, Mandatory, HelpMessage = «Enter the name of a CIM/WMI class. Wildcards are permitted.»)] [ValidateNotNullOrEmpty()] [string]$Classname,

[Parameter(HelpMessage = «Enter a pattern for class names to EXCLUDE from the results. You can use wildcards or regular expressions.»)] [string]$Exclude,

[Parameter(HelpMessage = «Enter the name of a computer to search.»)] [ValidateNotNullOrEmpty()] [string]$Computername = $env:COMPUTERNAME
)

Write-Verbose «Starting $($myinvocation.MyCommand)»

#define a hashtable of parameters to splat to Write-Progress
$progParams = @{
Activity = $myinvocation.MyCommand
PercentComplete = 0
Status = «Enumerating namespaces on $($Computername.ToUpper())»
CurrentOperation = «Creating temporary CIMSession»
}

Write-Progress @progParams
Write-Verbose «Creating a temporary CIMSession to $($Computername.ToUpper()).»

Try {
$cs = New-Cimsession -ComputerName $computername -ErrorAction Stop
}
Catch {
Write-Warning «Failed to connect to $($Computername.ToUpper())»
Write-Warning $_.exception.Message
#bail out of the function
return
}

$progParams.CurrentOperation = «Building namespace list»
#build a list of namespaces
Function _enumnamespace {
[cmdletbinding()] Param(
[string]$Namespace = «Root»,
[cimsession]$session
)

Get-CimInstance -Namespace $namespace -ClassName __Namespace -cimsession $session |
Foreach-object {
$n = Join-Path $Namespace $_.Name
#write the namespace path to the pipeline
$n
#recurse through each namespace
_enumnamespace -Namespace $n -session $session
}
}
#build a list of namespaces
$namespaces = _enumnamespace -session $CS | Sort-Object

#enumerate namespaces and search for the class
Write-Verbose «Searching for class $class»
if ($Exclude) {
Write-Verbose «Using an exclude pattern of $Exclude»
}
$i = 0
foreach ($ns in $namespaces) {
$i++
$pct = ($i / $namespaces.count) * 100
$progParams.PercentComplete = $pct
$progParams.Status = «Searching for class $classname in $($namespaces.count) namespaces»
$progParams.CurrentOperation = «processing \\$($computername.toUpper())\$ns»
Write-Progress @progparams
Write-Verbose $ns
Try {
$classes = Get-Cimclass -Namespace $ns -ClassName $classname -CimSession $cs -ErrorAction Stop
if ($classes -AND $Exclude) {
$classes.Where({$_.cimclassname -notmatch $Exclude }) | Sort-Object -Property CimClassName
}
else {
$classes | Sort-Object -Property CimClassName
}
}
Catch {
#ignore error if class not found
}
} #foreach ns

Write-Verbose «Removing tempory CIMSession»
$cs | Remove-CimSession

Write-Verbose «Ending $($myinvocation.MyCommand)»

} #close function
view rawFind-Cimclass.ps1 hosted with ❤ by GitHub

Because I’m making repeated queries, I create a temporary CIMSession. I don’t really need it when querying the local machine and could have added code to only create the CIMSession if the computername is remote. But for the sake of simplicity I create a temporary CIMSession regardless. The other scripting element you’ll see in the function is the use of Write-Progress. The function will take a little bit of time to complete and I wanted to provide feedback.


As you look through the code I hope you’ll realize that using Write-Progress is not that difficult. I think more scripters need to take advantage of this command.

With this tool in hand, I searched for anything antivirus related on a Windows Server 2016 box but with no results. I’ll be honest that I have not researched this issue in great deal, but is my searches thus far into WMI it appears Microsoft has removed any related namespaces and classes or changed them to something that I haven’t thought of or discovered.

Regardless, I now have another tool in my toolbox to easily discover things in WMI. I hope you’ll let me know what you think.

Update:

Shortly after publishing the original article and function, I realized the logic I was using to enumerate namespaces was incomplete. I was only getting the first 2 levels of namespaces. I ended up adding an internal function to recursively list all namespaces. Where I was search 57 before on my Windows 10 box, now I am searching 150. Unfortunately, this didn’t affect the search results for an antivirus class on Windows Server 2016.

Update #2:

After searching for anything I could think of I stumbled across the ProtectionTechnologyStatus class in the Root\Microsoft\SecurityClient namespace on Windows Server 2016. This appears to have all of the relevant information.

Sobre nosotros administrador

Check Also

¿Que es la virtualizacion? vMware

¿Qué es la virtualización? La virtualización es el proceso de creación de una representación de …

Deja un comentario