Functions/Set-DryADSchemaExtension.ps1

Using Namespace System.Management.Automation.Runspaces
Using Namespace System.Collections.Generic
# DryActiveDirectory is an AD config module for use with DryDeploy, or by itself.
#
# Copyright (C) 2021 Bjørn Henrik Formo (bjornhenrikformo@gmail.com)
# LICENSE: https://raw.githubusercontent.com/bjoernf73/DryActiveDirectory/main/LICENSE
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

<#
Type = $ADSchemaExtension.BaseName
                    SuccessCount = $ADSchemaExtJson.success_string_match_count
                    Content = $ADSchemaExtContent
                    Variables = $Variables
                    SchemaMaster = $DomainController #<-- Must be changed
#>

Function Set-DryADSchemaExtension  {
    [CmdletBinding(DefaultParameterSetName='Local')] 
    Param (
        [Parameter(Mandatory,HelpMessage='The Schema Extension type')]
        [String]
        $Type,

        [Parameter(Mandatory,HelpMessage='The number of times the success strings
        must be matched'
)]
        [Int]
        $SuccessCount,

        [Parameter(Mandatory,HelpMessage='The LDF Content')]
        [String]
        $Content,

        [Parameter(HelpMessage='Variables used for replacements in LDFs. Each
        `$var.name will be wrapped in trippel hashes (###$($var.name)###) and
        any match replaced with $var.value'
)]
        [List[PSObject]]
        $Variables,

        [Parameter(Mandatory,ParameterSetName='Remote',HelpMessage="PSSession
        to run the script blocks in"
)]
        [PSSession] 
        $PSSession,

        [Parameter(Mandatory,HelpMessage="The Domain Controller to use")]
        [String] 
        $Server
    )
    Try {
        ol v @('Execution Type',"$($PSCmdlet.ParameterSetName)")

        $SuccessStrings = @(
            'Entry modified successfully.',
            'Entry already exists, entry skipped',
            'Attribute or value exists, entry skipped.',
            'The command has completed successfully'
        )

        # Loop through variables and replace patterns in LDF Content
        If ($Variables) {
            ForEach ($Var in $Variables) {
                $Content = $Content -Replace "###$($Var.Name)###","$($Var.Value)"
            }
        }

        # Trim start of each line
        $Content = ($Content -Split "`n" | ForEach-Object { $_.TrimStart() } ) -join "`n"

        $ExtendSchemaArgumentList = @(
            $Content,
            $Server
        )
        $InvokeSchemaExtensionParams = @{
            ScriptBlock  = $DryAD_SB_SchemaExtension_Set
            ArgumentList = $ExtendSchemaArgumentList
            ErrorAction  = 'Stop'
        }
        If ($PSCmdlet.ParameterSetName -eq 'Remote') {
            $InvokeSchemaExtensionParams += @{
                Session = $PSSession
            }
        }
        $ExtendSchemaResult = Invoke-Command @InvokeSchemaExtensionParams
        
        If ($ExtendSchemaResult[0] -eq '') {
            $MatchCount = 0
            $ExtendSchemaResult[1].ForEach({ 
                $CurrentString = $_; 
                $SuccessStrings.ForEach({ 
                    If ($CurrentString -Match $_) { 
                        $MatchCount++
                    } 
                })
            })
            If ($MatchCount -eq $SuccessCount) {
                ol s "AD Schema is extended"
                ol i @('Successfully extended AD Schema of Type',$Type)
            }
            Else {
                ol f "AD Schema not extended"
                ol w @("Target successcount $SuccessCount, actual","$MatchCount")
                # Display thesult in debug
                $ExtendSchemaResult[1].ForEach({
                    ol d $_
                })
                Throw "Schema extension failed"
            }
        }
        Else {
            ol f "AD Schema not extended"
            ol e "Schema extension failed"
            Throw $ExtendSchemaResult[0]
        }  
    }
    Catch {
        $PSCmdlet.ThrowTerminatingError($_)
    }
}