Comparing the contents of edsaScriptText

I'm looking for a solution to let me keep all the ARS scripts in Git as well as use a decent editor.

The idea is that we keep all our scripts locally in Git and then push changes into ARS as we edit the scripts.

I've created a script that downloads all the current scripts (excluding builtin scripts):

$scriptModules = [adsi]"EDMS://CN=Script Modules,CN=Configuration"

function Export-Scripts {
    param (
        [System.DirectoryServices.DirectoryEntry]$dirEntry
    )
    Write-Information "Checking $($dirEntry.distinguishedName)" -InformationAction Continue
    $folders = @()
    switch ($dirEntry.ObjectClass) {
        'edsScriptModuleContainer' { 
            foreach ($child in $dirEntry.Children) {
                Write-Output "checking $($child.distinguishedName)"
                Export-Scripts -container $dirEntry $child
            }
            break
        }
        'edsScriptModule' {
            $scriptContent = $dirEntry.edsaScriptText[0]
            $scriptPath = "./"
            $folders = (($dirEntry.distinguishedName -replace "CN=", "") -split ",")
            [array]::Reverse($folders)
            foreach ($folder in $folders) {
                if ($folder -eq "Configuration") { continue }
                $scriptPath = $scriptPath + "/" + $folder
            }
            $scriptPath += ".ps1"
            if (-not(Test-Path -Path $scriptPath)) {
                New-Item -Path $scriptPath -ItemType File -Force | Out-Null
            }
            $scriptContent | Set-Content $scriptPath -Encoding Unicode
            break
        }
    }

}

foreach ($child in $scriptModules.Children) {
    if ($child.name -match ("Change Auditor Integration Script|Builtin")) { continue }
    Export-Scripts -dirEntry $child
}

Now I'm trying to create a script that checks for changes to the local file system and applies them in Active Roles, but I'm struggling to compare the contents of edsaScriptText:

$root = Resolve-Path "./"

$scripts = Get-ChildItem -Path "./Script Modules" -Recurse -File

function Get-DistinguisedName {
    param (
        [string]$path
    )
    $path = $path -replace ".ps1"
    $folders = $path -split "\\"
    [array]::Reverse($folders)
    $distinguishedName = $null
    foreach ($folder in $folders) {
        if($folder -eq "") { continue }
        $distinguishedName = $distinguishedName + "CN=$folder," 
    }
    $distinguishedName = $distinguishedName + "CN=Configuration"
    return $distinguishedName
}

foreach ($script in $scripts){
    $dn = Get-DistinguisedName -path (($script.FullName).Replace($root,""))
    $arsScript = [adsi]"EDMS://$dn"
    $scriptContent = $(Get-Content -Path $script.FullName -Raw)
    try {
        $arsScriptContent = $($arsScript.edsaScriptText[0])
    }
    catch {
        Write-Output "Unable to get content for $($dn)"
        continue
    }
    if ($arsScriptContent) {
        if ($arsScriptContent.Equals($scriptContent)) {
            Write-Output "we have a match"
        }
        else {
            Write-Output "something is different"
        }
    }
}

foreach ($child in $scriptModules.Children) {
    if ($child.name -match ("Change Auditor Integration Script|Builtin")) { continue }
    Export-Scripts -dirEntry $child
}

Even though the contents of the local script and edsaScriptText are identical, PowerShell always thinks there is a difference.  My guess is an issue with encoding but I'm not sure.

Anyone come across this before?

Worse case is I'll grab the contents of edsaScriptText and save it to a temp file so I can compare for differences, but this feels like overkill.

  • Well, that's annoying, it was all down to carriage returns at the end of the exported file.

    The following script fixes this and will update scripts in ARS:

    $root = Resolve-Path "./"
    
    $scripts = Get-ChildItem -Path "./Script Modules" -Recurse -File
    
    function Get-DistinguisedName {
        param (
            [string]$path
        )
        $path = $path -replace ".ps1"
        $folders = $path -split "\\"
        [array]::Reverse($folders)
        $distinguishedName = $null
        foreach ($folder in $folders) {
            if($folder -eq "") { continue }
            $distinguishedName = $distinguishedName + "CN=$folder," 
        }
        $distinguishedName = $distinguishedName + "CN=Configuration"
        return $distinguishedName
    }
    
    foreach ($script in $scripts){
        $dn = Get-DistinguisedName -path (($script.FullName).Replace($root,""))
        $arsScript = [adsi]"EDMS://$dn"
        $scriptContent = $(Get-Content -Path $script.FullName -Raw).TrimEnd()
        try {
            $arsScriptContent = $($arsScript.edsaScriptText[0]).TrimEnd()
        }
        catch {
            Write-Output "Creating $dn"
            $params = @{
                Name = $script.Name -replace "\.ps1", ""
                ParentContainer = Get-DistinguisedName -path (Split-Path -Path ($script.FullName).Replace($root, "") -Parent)
                Type = "edsScriptModule"
                ObjectAttributes = @{
                    edsaScriptText = $scriptContent
                    edsaScriptType = 0
                    edsaScriptLanguage = "powershell"
                }
                Proxy = $true
            }
            New-QADObject @params
            continue
        }
        if ($arsScriptContent) {
            if ($arsScriptContent -ne $scriptContent) {
                Write-Output "Updating $dn"
                $arsScript.Put("edsaScriptText",$scriptContent)
                $arsScript.SetInfo()
            }
        }
    }
    
    foreach ($child in $scriptModules.Children) {
        if ($child.name -match ("Change Auditor Integration Script|Builtin")) { continue }
        Export-Scripts -dirEntry $child
    }
    
    

    I'll look at options for deleting scripts from ARS soon, need to spend some time testing this first.