PSSystemProperties.ps1

Function Private:Initialize-PSSystemProperties {
    Function Private:Get-DotNetVersion {
        try {
            $Build = Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full' -Name 'Release'
            Switch ($Build)
            {
                378389 { Return 4.5 }
                {$_ -in 378675, 378758 } { Return 4.5.1 }
                379893 { Return 4.5.2 }
                {$_ -in 393295, 393297 } { Return 4.6.392395 }
                {$_ -in 394254, 394271 } { Return 4.6.1  }
                {$_ -in 394802, 394806 } { Return 4.6.2  }
                {$_ -in 460798, 460805 } { Return 4.7  }
                {$_ -in 461308, 461310 } { Return 4.7.1  }
                {$_ -in 461808, 461814 } { Return 4.7.2  }
                {$_ -in 528040, 528372, 528449, 528049 } { Return 4.8  }
                Default { throw '.Net 4.5+ installed, but unknown Build Number' }
            }
        } catch { Return $_.Exception }
    }

    Function Get-SystemPropertylibs {
        $DotNetVersion = (Get-DotNetVersion).Tostring().Replace('.','').Substring(0,2)
        if (-not $DotNetVersion -or -not ($DotNetVersion -as [int])) {throw 'Unable to detect DotNet version'}
        
        if (-not (Test-Path -Path "$PSScriptRoot\lib")) {
            New-Item -Path "$PSScriptRoot\temp" -ItemType Directory -Force
            $Pkg = Get-ChildItem -Path $PSScriptRoot | Where-Object {$_.Name -match '^microsoft-windowsapicodepack-(core|shell)(\.\d){3}\.nupkg$'}
            while ($Pkg.Count -ne 2) {
                try {
                    Invoke-WebRequest 'https://www.nuget.org/api/v2/package/Microsoft-WindowsAPICodePack-Core/1.1.4' -OutFile "$PSScriptRoot\microsoft-windowsapicodepack-core.1.1.4.nupkg"
                    Invoke-WebRequest 'https://www.nuget.org/api/v2/package/Microsoft-WindowsAPICodePack-Shell/1.1.4' -OutFile "$PSScriptRoot\microsoft-windowsapicodepack-shell.1.1.4.nupkg"
                    $Pkg = Get-ChildItem -Path $PSScriptRoot | Where-Object {$_.Name -match '^microsoft-windowsapicodepack-(core|shell)(\.\d){3}\.nupkg$'}
                }
                catch{Start-Sleep -Seconds 15}
            }
            if ($PSEdition -eq 'Desktop') {$Pkg = $Pkg | Foreach-Object {$_ | Copy-Item -Destination $_.FullName.Replace($_.Extension, '.zip') -PassThru}}
            try {
                $Pkg.foreach({Expand-Archive -Path $_.FullName -DestinationPath "$PSScriptRoot\temp\" -Force})
                Move-Item -Path "$PSScriptRoot\temp\lib\" -Destination $PSScriptRoot -Force
                Remove-Item -Path "$PSScriptRoot\temp\" -Recurse -Force
            }
            finally {if ($PSEdition -eq 'Desktop') {$Pkg | Remove-Item -Force}}
        }
        $Libraries = Get-ChildItem -Path "$PSScriptRoot\lib" -Recurse -Filter '*.dll' | Where-Object {$_.Directory.Name -match "net$DotNetVersion"} | Sort-Object -Property Name
        return $Libraries
    }

    try {$RequiredLibraries = Get-SystemPropertylibs}
    catch {throw ('Failed retrieving required DLLs: {0}' -f $_.Exception.Message)}
    
    ForEach ($Library in $RequiredLibraries) {
        try{Add-Type -Path $Library.FullName}
        catch {throw ('Failed importing required DLL: {0} - {1}' -f $Library.FullName, $_.Exception.Message)}
    }
    [void][Microsoft.WindowsAPICodePack.Shell.ShellObject]  
}
Initialize-PSSystemProperties