functions/Set-GPWmiFilterAssignment.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
130
131
132
133
134
135
136
137
138
139
140
141
function Set-GPWmiFilterAssignment
{
<#
    .SYNOPSIS
        Assigns WMI Filters to GPOs.
     
    .DESCRIPTION
        Assigns WMI Filters to GPOs.
     
    .PARAMETER Policy
        The Group Policy Object to modify.
     
    .PARAMETER Filter
        The Filter to Apply.
     
    .PARAMETER Server
        The server to contact.
        Specify the DNS Name of a Domain Controller.
     
    .PARAMETER Credential
        The credentials to use to contact the targeted server.
     
    .PARAMETER EnableException
        This parameters disables user-friendly warnings and enables the throwing of exceptions.
        This is less user friendly, but allows catching exceptions in calling scripts.
     
    .EXAMPLE
        PS C:\> Get-GPO -Name '01_A_OU_1' | Set-GPWmiFilterAssignment -Filter 'Windows 10'
     
        Assigns the WMI Filter "WIndows 10" to the GPO "01_A_OU_1"
#>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")]
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('Id', 'DisplayName')]
        $Policy,
        
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        $Filter,
        
        [string]
        $Server = $env:USERDNSDOMAIN,
        
        [System.Management.Automation.PSCredential]
        $Credential,
        
        [switch]
        $EnableException
    )
    
    begin
    {
        #region Resolve Server
        try { $PSBoundParameters.Server = Get-DomainController -Server $Server -Credential $Credential }
        catch
        {
            Stop-PSFFunction -String 'Set-GPWmiFilterAssignment.FailedADAccess' -StringValues $Server -EnableException $EnableException -ErrorRecord $_
            return
        }
        #endregion Resolve Server
        
        $adParameters = $PSBoundParameters | ConvertTo-PSFHashtable -Include Server, Credential
        $domainName = (Get-ADDomain @adParameters).DNSRoot
        
        #region Handle Explicit Filter input
        $filterExplicit = $false
        if (Test-PSFParameterBinding -Mode Explicit -ParameterName 'Filter')
        {
            if ($Filter.PSObject.TypeNames -eq 'GroupPolicy.WMIFilter')
            {
                $filterObject = $Filter
            }
            elseif ($Filter -as [System.Guid])
            {
                $filterObject = Get-GPWmiFilter @adParameters -Guid $Filter
            }
            else { $filterObject = Get-GPWmiFilter @adParameters -Name $Filter }
            
            if (-not $filterObject)
            {
                Stop-PSFFunction -String 'Set-GPWmiFilterAssignment.NoFilter' -StringValues $Filter -EnableException $EnableException
                return
            }
            if ($filterObject.Count -gt 1)
            {
                Stop-PSFFunction -String 'Set-GPWmiFilterAssignment.TooManyFilter' -StringValues $Filter -EnableException $EnableException
                return
            }
            $filterExplicit = $true
            $filterString = '[{0};{{{1}}};0]' -f $domainName, $filterObject.ID.ToString().ToUpper()
        }
        #endregion Handle Explicit Filter input
    }
    process
    {
        if (Test-PSFFunctionInterrupt) { return }
        
        #region Piped Filter Input
        if (-not $filterExplicit)
        {
            if ($Filter.PSObject.TypeNames -eq 'GroupPolicy.WMIFilter')
            {
                $filterObject = $Filter
            }
            elseif ($Filter -as [System.Guid])
            {
                $filterObject = Get-GPWmiFilter @adParameters -Guid $Filter
            }
            else { $filterObject = Get-GPWmiFilter @adParameters -Name $Filter }
            
            if (-not $filterObject)
            {
                Stop-PSFFunction -String 'Set-GPWmiFilterAssignment.NoFilter' -StringValues $Filter -EnableException $EnableException
                return
            }
            if ($filterObject.Count -gt 1)
            {
                Stop-PSFFunction -String 'Set-GPWmiFilterAssignment.TooManyFilter' -StringValues $Filter -EnableException $EnableException
                return
            }
            $filterString = '[{0};{{{1}}};0]' -f $domainName, $filterObject.ID.ToString().ToUpper()
        }
        #endregion Piped Filter Input
        
        foreach ($policyItem in ($Policy | Resolve-PolicyName))
        {
            $gpoObject = Get-ADObject @adParameters -LDAPFilter "(&(objectClass=groupPolicyContainer)(|(cn=$($policyItem))(cn={$($policyItem)})(displayName=$($policyItem))))"
            
            if (-not $gpoObject)
            {
                Write-PSFMessage -Level Warning -String 'Set-GPWmiFilterAssignment.GPONotFound' -StringValues $policyItem
                continue
            }
            
            Invoke-PSFProtectedCommand -ActionString 'Set-GPWmiFilterAssignment.UpdatingGPO' -ActionStringValues $filterObject.Name, $policyItem, $gpoObject -Target $policyItem -ScriptBlock {
                $gpoObject | Set-ADObject @adParameters -Replace @{ gPCWQLFilter = $filterString }
            } -Continue -PSCmdlet $PSCmdlet -EnableException $EnableException.ToBool()
        }
    }
}