Public/Get-WmiProperty.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#region Function Get-WmiProperty
Function Get-WmiProperty {
<#
.SYNOPSIS
    This function is used to get the properties of a WMI class.
.DESCRIPTION
    This function is used to get one or more properties of a WMI class.
.PARAMETER Namespace
    Specifies the namespace where to search for the WMI class. Default is: 'ROOT\cimv2'.
.PARAMETER ClassName
    Specifies the class name for which to get the properties.
.PARAMETER PropertyName
    Specifies the propery name to search for. Supports wildcards. Default is: '*'.
.PARAMETER PropertyValue
    Specifies the propery value or values to search for. Supports wildcards.(Optional)
.PARAMETER QualifierName
    Specifies the property qualifier name to match. Supports wildcards.(Optional)
.PARAMETER Property
    Matches property Name, Value and CimType. Can be piped. If this parameter is specified all other search parameters will be ignored.(Optional)
    Supported format:
        [PSCustomobject]@{
            'Name' = 'Website'
            'Value' = $null
            'CimType' = 'String'
        }
.EXAMPLE
    Get-WmiProperty -Namespace 'ROOT' -ClassName 'SCCMZone'
.EXAMPLE
    Get-WmiProperty -Namespace 'ROOT' -ClassName 'SCCMZone' -PropertyName 'WebsiteSite' -QualifierName 'key'
.EXAMPLE
    Get-WmiProperty -Namespace 'ROOT' -ClassName 'SCCMZone' -PropertyName '*Site'
.EXAMPLE
    $Property = [PSCustomobject]@{
        'Name' = 'Website'
        'Value' = $null
        'CimType' = 'String'
    }
    Get-WmiProperty -Namespace 'ROOT' -ClassName 'SCCMZone' -Property $Property
    $Property | Get-WmiProperty -Namespace 'ROOT' -ClassName 'SCCMZone'
.NOTES
    This is a module function and can typically be called directly.
.LINK
    https://sccm-zone.com
.LINK
    https://github.com/JhonnyTerminus/SCCM
#>

    [CmdletBinding()]
    Param (
        [Parameter(Mandatory=$false,Position=0)]
        [ValidateNotNullorEmpty()]
        [string]$Namespace = 'ROOT\cimv2',
        [Parameter(Mandatory=$true,Position=1)]
        [ValidateNotNullorEmpty()]
        [string]$ClassName,
        [Parameter(Mandatory=$false,Position=2)]
        [ValidateNotNullorEmpty()]
        [string]$PropertyName = '*',
        [Parameter(Mandatory=$false,Position=3)]
        [ValidateNotNullorEmpty()]
        [string]$PropertyValue,
        [Parameter(Mandatory=$false,Position=4)]
        [ValidateNotNullorEmpty()]
        [string]$QualifierName,
        [Parameter(Mandatory=$false,ValueFromPipeline,Position=5)]
        [ValidateNotNullorEmpty()]
        [PSCustomObject]$Property = @()
    )

    Begin {
        ## Get the name of this function and write header
        [string]${CmdletName} = $PSCmdlet.MyInvocation.MyCommand.Name
        Write-FunctionHeaderOrFooter -CmdletName ${CmdletName} -CmdletBoundParameters $PSBoundParameters -Header
    }
    Process {
        Try {

            ## Check if class exists
            $ClassTest = Get-WmiClass -Namespace $Namespace -ClassName $ClassName -ErrorAction 'SilentlyContinue'

            ## If no class is found, write debug message and optionally throw error if -ErrorAction 'Stop' is specified
            If (-not $ClassTest) {
                $ClassNotFoundErr = "No class [$ClassName] found in namespace [$Namespace]."
                Write-Log -Message $ClassNotFoundErr -Severity 2 -Source ${CmdletName} -DebugMessage
                Write-Error -Message $ClassNotFoundErr -Category 'ObjectNotFound'
            }

            ## Get class properties
            $WmiProperty = (Get-WmiClass -Namespace $Namespace -ClassName $ClassName -ErrorAction 'SilentlyContinue' | Select-Object *).CimClassProperties | Where-Object -Property Name -like $PropertyName

            ## Get class property based on specified parameters
            If ($Property) {

                # Compare all specified properties and return only properties that match Name, Value and CimType.
                $GetProperty = Compare-Object -ReferenceObject $Property -DifferenceObject $WmiProperty -Property Name, Value, CimType -IncludeEqual -ExcludeDifferent -PassThru

            }
            ElseIf ($PropertyValue -and $QualifierName) {
                $GetProperty = $WmiProperty | Where-Object { ($_.Value -like $PropertyValue) -and ($_.Qualifiers.Name -like $QualifierName) }
            }
            ElseIf ($PropertyValue) {
                $GetProperty = $WmiProperty | Where-Object -Property Value -like $PropertyValue
            }
            ElseIf ($QualifierName) {
                $GetProperty = $WmiProperty | Where-Object { $_.Qualifiers.Name -like $QualifierName }
            }
            Else {
                $GetProperty = $WmiProperty
            }

            ## If no matching properties are found, write debug message and optionally throw error if -ErrorAction 'Stop' is specified
            If (-not $GetProperty) {
                $PropertyNotFoundErr = "No property [$PropertyName] found for class [$Namespace`:$ClassName]."
                Write-Log -Message $PropertyNotFoundErr -Severity 2 -Source ${CmdletName} -DebugMessage
                Write-Error -Message $PropertyNotFoundErr -Category 'ObjectNotFound'
            }
        }
        Catch {
            Write-Log -Message "Failed to retrieve wmi class [$Namespace`:$ClassName] properties. `n$(Resolve-Error)" -Severity 3 -Source ${CmdletName}
            Break
        }
        Finally {
            Write-Output -InputObject $GetProperty
        }
    }
    End {
        Write-FunctionHeaderOrFooter -CmdletName ${CmdletName} -Footer
    }
}
#endregion