classes/WmiFilterList.psm1

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
using module .\WmiFilterObject.psm1

class WmiFilterList:System.Collections.Generic.List[WmiFilterObject] {

    WmiFilterList () {}

    WmiFilterList ( [string]$Filter ) {

        # if the filter begins with four groups of numbers the filter is from a
        # GPO and we have to parse off the number of filters first
        if ( $Filter -match '^(?:\d+;){4}\D.+' ) {

            [int]$FilterCount, $RemainingFilter  = $Filter.Split( ';', 2 )

        }
        
        # if the filter begins with only three groups of numbers it is a filter
        # created by New-WmiFilterObject and should be considered to be one
        # filter
        elseif ( $Filter -match '^(?:\d+;){3}\D.+' ) {

            [int]$FilterCount = 1
            $RemainingFilter  = $Filter

        }

        # finally, any other format is invalid
        else {

            throw 'Invalid WMI filter'

        }

        while ( $FilterCount -gt 0 ) {

            # each filter is a list of lengths and string sections
            # we use the substring length instead of just a split on ';' to ensure
            # semi-colons in the filter are properly captured

            [int]$LanguageLength, [int]$NameSpaceLength, [int]$FilterLength, $RemainingFilter = $RemainingFilter.Split( ';', 4 )

            $WmiFilterObject = [WmiFilterObject]@{
                Language    = $RemainingFilter.Substring( 0, $LanguageLength )
                NameSpace   = $RemainingFilter.Substring( $LanguageLength + 1, $NameSpaceLength )
                Filter      = $RemainingFilter.Substring( $LanguageLength + 1 + $NameSpaceLength + 1, $FilterLength )
            }
            
            $this.Add( $WmiFilterObject ) > $null

            $RemainingFilter = $RemainingFilter.Substring( $LanguageLength + 1 + $NameSpaceLength + 1 + $FilterLength + 1 )

            $FilterCount --

        }

    }
    
    WmiFilterList ( [WmiFilterObject[]] $WmiFilterObject ) {

        $this.AddRange( $WmiFilterObject ) > $null

    }

    [string] ToString () {

        return ( [string]$this.Count + ';' + -join( $this | ForEach-Object { $_.ToString() } ) )

    }

}