functions/CimMember.ps1
Function Get-CimClassProperty { [cmdletbinding(DefaultParameterSetName = 'property')] [OutputType('CimClassProperty')] Param( [Parameter( Position = 0, Mandatory, ValueFromPipeline, HelpMessage = 'Specify a CIM Class' )] [ArgumentCompleter({ #argument completer uses local classes to populate the list param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) if ($fakeBoundParameters.NameSpace -match '^root') { (Get-CimClass -Namespace $fakeBoundParameters.NameSpace ).Where({ $_.CimClassName -notMatch '^__' }).CimClassName | Where-Object { $_ -like "*$wordToComplete*" } } else { (Get-CimClass -Namespace 'Root\Cimv2').Where({ $_.CimClassName -notMatch '^__' }).CimClassName | Where-Object { $_ -like "*$wordToComplete*" } } })] [ValidateNotNullOrEmpty()] [string]$ClassName, [Parameter(HelpMessage = 'Specify the class namespace beginning with ROOT')] [ValidateNotNullOrEmpty()] [ValidatePattern('^Root\\')] [Alias('NS')] [string]$Namespace = 'Root\Cimv2', [Parameter(ParameterSetName = 'property', HelpMessage = 'Specify a property name. Wildcards are permitted.')] [ValidateNotNullOrEmpty()] [SupportsWildcards()] [string]$Property = '*', [Parameter(ParameterSetName = 'key', HelpMessage = 'Only show Key properties')] [switch]$KeyOnly, [Parameter(ValueFromPipeline, HelpMessage = 'Specify a computer name or an existing CimSession object.')] [ValidateNotNullOrEmpty()] [Alias('CN')] [CimSession]$CimSession = $ENV:COMPUTERNAME ) Begin { Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Starting $($MyInvocation.MyCommand)" Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Running under PowerShell version $($PSVersionTable.PSVersion)" #initialize a list for output. I want to write sorted output to the pipeline. $out = [System.Collections.Generic.List[object]]::new() #initialize variables for the CimSession connection New-Variable -Name ci New-Variable -Name ce } #begin Process { if ($CimSession.TestConnection([ref]$ci, [ref]$ce)) { Try { Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Querying properties for $ClassName on $($CimSession.ComputerName.ToUpper())" $rawClass = $CimSession.GetClass($Namespace, $ClassName) } Catch { Throw $_ } if ($PSCmdlet.ParameterSetName -eq 'property') { Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Filtering by property $Property" $rawProperties = ($rawClass.CimClassProperties).Where({ $_.name -like $Property }) } else { Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Filtering by key property" $rawProperties = ($rawClass.CimClassProperties).Where({ $_.flags -match 'Key' }) } Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Found $($rawProperties.count) matching properties" foreach ($item in $rawProperties) { $isKey = $item.Flags -match 'Key' If (($KeyOnly -AND $IsKey) -OR (-Not $KeyOnly)) { $result = [PSCustomObject]@{ PSTypeName = 'CimClassProperty' Namespace = $rawClass.CimSystemProperties.Namespace ClassName = $rawClass.CimSystemProperties.ClassName Property = $item.Name ValueType = $item.CimType IsKey = $isKey #hidden in default table format Flags = $item.Flags } $out.Add($result) } #if } #foreach item } else { Write-Warning "Unable to connect to $($CimSession.ComputerName.ToUpper()). $($ce.Message)" } } #process End { if ($out.Count -gt 0) { $out | Sort-Object -Property Property } else { Write-Verbose "[$((Get-Date).TimeOfDay) END ] No matching properties detected" } Write-Verbose "[$((Get-Date).TimeOfDay) END ] Ending $($MyInvocation.MyCommand)" } #end } #close Get-CimClassProperty Function Get-CimClassPropertyQualifier { [cmdletbinding()] [OutputType('cimClassPropertyQualifier')] Param( [Parameter( Position = 0, Mandatory, ValueFromPipeline, HelpMessage = 'Specify a CIM Class' )] [ArgumentCompleter({ param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) if ($fakeBoundParameters.NameSpace -match '^root') { (Get-CimClass -Namespace $fakeBoundParameters.NameSpace ).Where({ $_.CimClassName -notMatch '^__' }).CimClassName | Where-Object { $_ -like "$wordToComplete*" } } else { (Get-CimClass -Namespace 'Root\Cimv2').Where({ $_.CimClassName -notMatch '^__' }).CimClassName | Where-Object { $_ -like "$wordToComplete*" } } })] [ValidateNotNullOrEmpty()] [string]$ClassName, [Parameter(HelpMessage = 'Specify a property name. Wildcards are permitted.')] [ValidateNotNullOrEmpty()] [SupportsWildcards()] [string]$Property = "*", [Parameter(HelpMessage = 'Specify the class namespace beginning with ROOT')] [ValidateNotNullOrEmpty()] [ValidatePattern('^Root\\')] [Alias('NS')] [string]$Namespace = 'Root\Cimv2', [Parameter(ValueFromPipeline, HelpMessage = 'Specify a computer name or an existing CimSession object.')] [ValidateNotNullOrEmpty()] [Alias('CN')] [CimSession]$CimSession = $ENV:COMPUTERNAME ) Begin { Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Starting $($MyInvocation.MyCommand)" Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Running under PowerShell version $($PSVersionTable.PSVersion)" #initialize variables for the CimSession connection New-Variable -Name ci New-Variable -Name ce } #begin Process { if ($CimSession.TestConnection([ref]$ci, [ref]$ce)) { Try { Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Getting property information from $ClassName on $($CimSession.ComputerName.ToUpper())" $rawClass = $CimSession.GetClass($Namespace, $ClassName) $rawProperty = $CimSession.GetClass($Namespace, $ClassName).CimClassProperties.Where({$_.Name -like $Property}) } Catch { Throw $_ } If ($null -eq $rawProperty) { $msg = 'Failed to find a property called {0} on {1}:{2}' -f $property, $Namespace, $ClassName.ToUpper() Write-Warning $msg } else { Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Found $($rawProperty.count) matching properties" Foreach ($item in $rawProperty) { Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Found $($item.Qualifiers.count) qualifiers for $($item.Name)" foreach ($q in $item.Qualifiers) { [PSCustomObject]@{ PSTypeName = 'cimClassPropertyQualifier' Namespace = $rawClass.CimSystemProperties.Namespace ClassName = $rawClass.CimClassName Property = $item.Name Name = $q.Name Value = $q.Value CimType = $q.CimType Flags = $q.Flags } } #foreach q } #foreach item } } else { Write-Warning "Unable to connect to $($CimSession.ComputerName.ToUpper()). $($ce.Message)" } } #process End { Write-Verbose "[$((Get-Date).TimeOfDay) END ] Ending $($MyInvocation.MyCommand)" } #end } #close Get-CimClassPropertyQualifier Function Get-CimClassMethod { [cmdletbinding()] [OutputType('CimClassMethod')] Param( [Parameter( Position = 0, Mandatory, ValueFromPipeline, HelpMessage = 'Specify a CIM Class' )] [ArgumentCompleter({ param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) if ($fakeBoundParameters.NameSpace -match '^root') { (Get-CimClass -Namespace $fakeBoundParameters.NameSpace ).Where({ $_.CimClassName -notMatch '^__' }).CimClassName | Where-Object { $_ -like "$wordToComplete*" } } else { (Get-CimClass -Namespace 'Root\Cimv2').Where({ $_.CimClassName -notMatch '^__' }).CimClassName | Where-Object { $_ -like "$wordToComplete*" } } })] [ValidateNotNullOrEmpty()] [string]$ClassName, [Parameter(HelpMessage = 'Specify a method name. Wildcards are permitted.')] [ValidateNotNullOrEmpty()] [SupportsWildcards()] [alias('Name')] [string]$Method = '*', [Parameter(HelpMessage = 'Specify the class namespace beginning with ROOT')] [ValidateNotNullOrEmpty()] [ValidatePattern('^Root\\')] [Alias('NS')] [string]$Namespace = 'Root\Cimv2', [Parameter(ValueFromPipeline, HelpMessage = 'Specify a computer name or an existing CimSession object.')] [ValidateNotNullOrEmpty()] [Alias('CN')] [CimSession]$CimSession = $ENV:COMPUTERNAME ) Begin { Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Starting $($MyInvocation.MyCommand)" Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Running under PowerShell version $($PSVersionTable.PSVersion)" #initialize a list for output. I want to write sorted output to the pipeline. $out = [System.Collections.Generic.List[object]]::new() #initialize variables for the CimSession connection New-Variable -Name ci New-Variable -Name ce } #begin Process { if ($CimSession.TestConnection([ref]$ci, [ref]$ce)) { Try { Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Processing CimClass $($PSBoundParameters['ClassName']) from $Namespace on $($CimSession.ComputerName.ToUpper())" $rawClass = $CimSession.GetClass($Namespace, $PSBoundParameters['ClassName']) $Methods = ($rawClass.CimClassMethods).where({ $_.Name -like $Method }) if ($methods.count -gt 0) { Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Found $($methods.count) methods" foreach ($methodItem in $Methods) { $result = [PSCustomObject]@{ PSTypeName = 'CimClassMethod' Namespace = $rawClass.CimSystemProperties.Namespace ClassName = $rawClass.CimSystemProperties.ClassName Name = $methodItem.Name ResultType = $methodItem.ReturnType Parameters = $methodItem.Parameters } $out.Add($result) } #foreach methodItem } #if methods.count > 0 else { $msg = 'No methods found for {0}:{1}' -f $Namespace, $PSBoundParameters['ClassName'].ToString().ToUpper() Write-Warning $msg } } #Try Catch { Throw $_ } } #if connected else { Write-Warning "Unable to connect to $($CimSession.ComputerName.ToUpper()). $($ce.Message)" } } #process End { if ($out.Count -gt 0) { $out | Sort-Object -Property Name } Write-Verbose "[$((Get-Date).TimeOfDay) END ] Ending $($MyInvocation.MyCommand)" } #end } #close Get-CimClassMethod Function Get-CimNamespace { [cmdletbinding()] [OutputType([System.String])] Param( [Parameter( Position = 0, HelpMessage = 'Specify the root namespace to query. The default is ROOT.' )] [ValidateNotNullOrEmpty()] [string]$Namespace = 'Root', [Parameter(HelpMessage = 'Only list the top-level namespaces under the specified namespace.')] [switch]$TopLevelOnly, [Parameter(ValueFromPipeline, HelpMessage = 'Specify a computer name or an existing CimSession object.')] [ValidateNotNullOrEmpty()] [Alias('CN')] [CimSession]$CimSession = $ENV:COMPUTERNAME ) Begin { Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Starting $($MyInvocation.MyCommand)" #define a private function to do the heavy lifting function _enumspace { [cmdletbinding()] Param( [CimSession]$CimSession, [string]$Namespace, [switch]$TopLevelOnly ) $CimSession.EnumerateInstances($Namespace, '__Namespace') | ForEach-Object { $child = Join-Path -Path $Namespace -ChildPath $_.Name if ($child) { $child if (-Not $TopLevelOnly) { Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Recursing to $child" $PSBoundParameters.namespace = $child _enumspace @PSBoundParameters } } } #foreach-object } #close function New-Variable -Name ci New-Variable -Name ce } #begin Process { if ($CimSession.TestConnection([ref]$ci, [ref]$ce)) { Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Querying namespaces under $Namespace on $($CimSession.ComputerName.ToUpper())." #invoke the private helper function$ _enumspace -CimSession $CimSession -Namespace $Namespace -TopLevelOnly:$TopLevelOnly } else { Write-Warning "Unable to connect to $($CimSession.ComputerName.ToUpper()). $($ce.Message)" } } #process End { Write-Verbose "[$((Get-Date).TimeOfDay) END ] Ending $($MyInvocation.MyCommand)" } #end } #close function Function Get-CimMember { [cmdletbinding(DefaultParameterSetName = 'property')] [OutputType('CimClassProperty', ParameterSetName = 'property')] [OutputType('CimClassMethod', ParameterSetName = 'method')] [Alias('cmm')] Param( [Parameter( Mandatory, ValueFromPipelineByPropertyName, HelpMessage = 'Specify a CIM Class' )] [Parameter(ParameterSetName = 'property', Position = 0)] [Parameter(ParameterSetName = 'method', Position = 0)] [ArgumentCompleter({ param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) if ($fakeBoundParameters.NameSpace -match '^root') { (Get-CimClass -Namespace $fakeBoundParameters.NameSpace ).Where({ $_.CimClassName -notMatch '^__' }).CimClassName | Where-Object { $_ -like "$wordToComplete*" } } else { (Get-CimClass -Namespace 'Root\Cimv2').Where({ $_.CimClassName -notMatch '^__' }).CimClassName | Where-Object { $_ -like "$wordToComplete*" } } })] [Alias('CimClassName')] [ValidateNotNullOrEmpty()] [string]$ClassName, [Parameter(ParameterSetName = 'property', HelpMessage = 'Specify a property name. Wildcards are permitted.')] [ValidateNotNullOrEmpty()] [SupportsWildcards()] [string]$Property = '*', [Parameter(Mandatory, ParameterSetName = 'method', HelpMessage = 'Specify a method name. Wildcards are permitted.')] [ValidateNotNullOrEmpty()] [SupportsWildcards()] [alias('Name')] [string]$Method, [Parameter(HelpMessage = 'Specify the class namespace beginning with ROOT')] [ValidateNotNullOrEmpty()] [ValidatePattern('^Root\\')] [Alias('NS')] [string]$Namespace = 'Root\Cimv2', [Parameter(ValueFromPipeline, HelpMessage = 'Specify a computer name or an existing CimSession object.')] [ValidateNotNullOrEmpty()] [Alias('CN')] [CimSession]$CimSession = $ENV:COMPUTERNAME ) Begin { Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Starting $($MyInvocation.MyCommand)" Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Running under PowerShell version $($PSVersionTable.PSVersion)" } #begin Process { Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Processing parameter set $($PSCmdlet.ParameterSetName)" Switch ($PSCmdlet.ParameterSetName) { 'property' { Get-CimClassProperty -Namespace $Namespace -ClassName $ClassName -Property $Property -CimSession $CimSession } 'method' { Get-CimClassMethod -Namespace $Namespace -ClassName $ClassName -Method $Method -CimSession $CimSession } } #switch $PSCmdlet.ParameterSetName } #process End { Write-Verbose "[$((Get-Date).TimeOfDay) END ] Ending $($MyInvocation.MyCommand)" } #end } #close Get-CimMember Function Get-CimClassListing { [cmdletbinding()] [OutputType('cimClassListing')] Param( [Parameter(Position = 0,HelpMessage = 'Enter a pattern for class names. You can use wildcards.')] [SupportsWildcards()] [ValidateNotNullOrEmpty()] [string]$Name="*", [Parameter(HelpMessage = 'Specify the class namespace beginning with Root')] [ValidateNotNullOrEmpty()] [ValidatePattern('^Root\\')] [Alias('NS')] [string]$Namespace = 'Root\Cimv2', [Parameter(HelpMessage = 'Enter a pattern for class names to EXCLUDE from the results. You can use wildcards.')] [SupportsWildcards()] [ValidateNotNullOrEmpty()] [string]$Exclude, [Parameter(ValueFromPipeline, HelpMessage = 'Specify a computer name or an existing CimSession object.')] [ValidateNotNullOrEmpty()] [Alias('CN')] [CimSession]$CimSession = $ENV:COMPUTERNAME ) Begin { Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Starting $($MyInvocation.MyCommand)" Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Running under PowerShell version $($PSVersionTable.PSVersion)" #initialize variables for the CimSession connection New-Variable -Name ci New-Variable -Name ce $opt = [Microsoft.Management.Infrastructure.Options.CimOperationOptions]::new() $opt.ClassNamesOnly = $True } #begin Process { if ($CimSession.TestConnection([ref]$ci, [ref]$ce)) { $CimSession.EnumerateClasses($Namespace,"").where({($_.CimClassName -Like $Name) -AND ($_.CimClassName -notmatch "^__") -AND $_.CimClassName -NotLike $Exclude}) | ForEach-Object { [PSCustomObject]@{ PSTypeName = 'cimClassListing' Namespace = $_.CimSystemProperties.Namespace ClassName = $_.CimClassName } } | Sort-Object -Property ClassName } else { Write-Warning "Unable to connect to $($CimSession.ComputerName.ToUpper()). $($ce.Message)" } } #process End { Write-Verbose "[$((Get-Date).TimeOfDay) END ] Ending $($MyInvocation.MyCommand)" } #end } #close Get-CimClassListing #ArgumentCompleters #enum all namespaces when this script is dot-sources and save to temp text file #using a threadjob when the module is imported to speed up the process Start-ThreadJob { #this is a stripped down version of the private function _enumspace Function _enumNamespace { [cmdletbinding()] Param( [string]$Namespace = 'Root', [string]$ClassName = '__Namespace' ) $splat = @{ Namespace = $Namespace ClassName = $ClassName } Get-CimInstance @splat | ForEach-Object { $child = Join-Path -Path $Namespace -ChildPath $_.Name if ($child) { $child $splat.namespace = $child _enumNamespace @splat } } #foreach-object } #close function _enumNamespace | Out-File $env:TEMP\CimNamespaceList.txt } | Out-Null Register-ArgumentCompleter -CommandName Get-CimMember,Get-CimClassMethod, Get-CimClassProperty, Get-CimClassPropertyQualifier,Get-CimClassListing -ParameterName Namespace -ScriptBlock { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) $CimNamespaceList = Get-Content $env:TEMP\CimNamespaceList.txt #PowerShell code to populate $wordToComplete ($CimNamespaceList).Where({ $_ -like "*$wordToComplete*" }) | ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) } } |