Powershell/Private/FileAssociations/Get-ProtocolTypeAssociation.ps1

# MIT License

# Copyright © 2022, Danysys
# Modified by JumpCloud

# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:

# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
function Get-ProtocolTypeAssociation {
    [OutputType([System.Collections.ArrayList])]
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true, HelpMessage = 'The SID of the user to capture file type associations')]
        [System.String]
        $UserSid,
        [Parameter(HelpMessage = 'Use the _admu path (true) or the regular path (false). Defaults to true.')]
        [System.Boolean]
        $UseAdmuPath = $true

    )
    begin {
        $manifestList = [System.Collections.ArrayList]::new()
        $hiveRoot = if ($UseAdmuPath) {
            "$($UserSid)_admu"
        } else {
            $UserSid
        }
        $urlAssociationsPath = "$hiveRoot\Software\Microsoft\Windows\Shell\Associations\UrlAssociations"
    }
    process {
        # Use disposable .NET RegistryKey handles — PowerShell provider access leaves
        # open handles that block REG UNLOAD of manually loaded profile hives.
        $urlKey = $null
        try {
            $urlKey = [Microsoft.Win32.Registry]::Users.OpenSubKey($urlAssociationsPath, $false)
            if ($null -eq $urlKey) {
                # Do not return $manifestList here — end still runs and would emit it twice.
                return
            }

            foreach ($extension in $urlKey.GetSubKeyNames()) {
                $userChoiceKey = $null
                try {
                    $userChoiceKey = $urlKey.OpenSubKey("$extension\UserChoice", $false)
                    if ($null -eq $userChoiceKey) {
                        continue
                    }
                    $progId = $userChoiceKey.GetValue("ProgId")
                    if ( ( -NOT [System.String]::IsNullOrEmpty($extension) ) -AND ( -NOT [System.String]::IsNullOrEmpty($progId) ) ) {
                        $manifestList.Add([PSCustomObject]@{
                                extension = $extension
                                programId = $progId
                            }) | Out-Null
                    }
                } finally {
                    if ($null -ne $userChoiceKey) {
                        $userChoiceKey.Close()
                        $userChoiceKey.Dispose()
                    }
                }
            }
        } finally {
            if ($null -ne $urlKey) {
                $urlKey.Close()
                $urlKey.Dispose()
            }
        }
    }
    end {
        return $manifestList
    }
}
##### END MIT License #####