functions/get-d365sqloptionsfrombacpacmodelfile.ps1


<#
    .SYNOPSIS
        Get the SQL Server options from the bacpac model.xml file
         
    .DESCRIPTION
        Extract the SQL Server options that are listed inside the model.xml file originating from a bacpac file
         
    .PARAMETER Path
        Path to the extracted model.xml file that you want to work against
         
    .EXAMPLE
        PS C:\> Get-D365SqlOptionsFromBacpacModelFile -Path "C:\Temp\model.xml"
         
        This will display all the SQL Server options configured in the bacpac file.
         
    .EXAMPLE
        PS C:\> Export-d365ModelFileFromBacpac -Path "C:\Temp\AxDB.bacpac" -OutputPath "C:\Temp\model.xml" | Get-D365SqlOptionsFromBacpacModelFile
         
        This will display all the SQL Server options configured in the bacpac file.
        First it will export the model.xml from the "C:\Temp\AxDB.bacpac" file, using the Export-d365ModelFileFromBacpac function.
        The output from Export-d365ModelFileFromBacpac will be piped into the Get-D365SqlOptionsFromBacpacModelFile function.
         
    .NOTES
        Tags: Bacpac, Servicing, Data, SqlPackage, Sql Server Options, Collation
         
        Author: Mötz Jensen (@Splaxi)
#>


function Get-D365SqlOptionsFromBacpacModelFile {
    [CmdletBinding(DefaultParameterSetName = 'ImportTier1')]
    param (
        [Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('ModelFile')]
        [Alias('File')]
        [string] $Path
    )

    process {
        Invoke-TimeSignal -Start

        if (-not (Test-PathExists -Path $Path -Type Leaf)) { return }

        $reader = [System.Xml.XmlReader]::Create($Path)

        $break = $false
        while ($reader.read() -and -not ($break)) {
            switch ($reader.NodeType) {
                ([System.Xml.XmlNodeType]::Element) {
                    if ($reader.Name -eq "Element") {
                        if ($reader.GetAttribute("Type") -eq "SqlDatabaseOptions") {
                            if ($reader.ReadToDescendant("Property")) {
                                do {
                                    [PSCustomObject]@{OptionName = $reader.GetAttribute("Name")
                                        OptionValue              = $reader.GetAttribute("Value")
                                    }

                                } while ($reader.ReadToNextSibling("Property"))

                            }

                            $break = $true
                            break
                        }
                    }

                    break
                }
            }
        }

        Invoke-TimeSignal -End
    }
}