Public/Get-VcList.ps1
Function Get-VcList { <# .SYNOPSIS Returns an object of Microsoft Visual C++ Redistributables for use with other VcRedist functions. .DESCRIPTION This function reads the Visual C++ Redistributables listed in an internal manifest (or an external JSON file) into an object that can be passed to other VcRedist functions. A complete listing of the supported and all known redistributables is included in the module. By default, Get-VcList will only return a list of the supported Visual C++ Redistributables. To return any of the unsupported Redistributables, the -Export parameter is required with the output filtered with Where-Object. The internal manifest can be exported with Export-VcManifest. .NOTES Author: Aaron Parker Twitter: @stealthpuppy .LINK https://stealthpuppy.com/VcRedist/get-vclist.html .PARAMETER Manifest The JSON file that contains the details about the Visual C++ Redistributables. This must be in the expected format. .PARAMETER Export Defines the list of Visual C++ Redistributables to export - All, Supported or Unsupported Redistributables. Defaults to exporting the Supported Redistributables. .PARAMETER Release Specifies the release (or version) of the redistributables to return. .PARAMETER Architecture Specifies the processor architecture to of the redistributables to return. Can be x86 or x64. .EXAMPLE Get-VcList Description: Return an object of the supported Visual C++ Redistributables from the embedded manifest. .EXAMPLE Get-VcList Description: Returns the supported 2010, 2012, 2013 and 2019, x86 and x64 versions of the supported Visual C++ Redistributables from the embedded manifest. .EXAMPLE Get-VcList -Export All Description: Returns a list of the all Visual C++ Redistributables from the embedded manifest, including unsupported versions. .EXAMPLE Get-VcList -Export Supported Description: Returns the full list of supported Visual C++ Redistributables from the embedded manifest. This is the same as running Get-VcList with no parameters. .EXAMPLE Get-VcList -Export Unsupported | Where-Object { $_.Release -eq "2008" } Description: Returns the full list of unsupported Visual C++ Redistributables from the embedded manifest and filters for the 2008 versions of the Redistributables. .EXAMPLE Get-VcList -Release 2013, 2019 -Architecture x86 Description: Returns the 2013 and 2019 x86 Visual C++ Redistributables from the list of supported Redistributables in the embedded manifest. .EXAMPLE Get-VcList -Path ".\VisualCRedistributables.json" Description: Returns a list of the Visual C++ Redistributables listed in the external manifest VisualCRedistributables.json. #> [OutputType([System.Management.Automation.PSObject])] [CmdletBinding(DefaultParameterSetName = 'Manifest', HelpURI = "https://stealthpuppy.com/VcRedist/get-vclist.html")] Param ( [Parameter(Mandatory = $False, Position = 0, ParameterSetName = 'Manifest')] [ValidateSet('2005', '2008', '2010', '2012', '2013', '2015', '2017', '2019')] [System.String[]] $Release = @("2010", "2012", "2013", "2019"), [Parameter(Mandatory = $False, Position = 1, ParameterSetName = 'Manifest')] [ValidateSet('x86', 'x64')] [System.String[]] $Architecture = @("x86", "x64"), [Parameter(Mandatory = $False, Position = 2, ValueFromPipeline, ParameterSetName = 'Manifest')] [ValidateNotNull()] [ValidateScript( { If (Test-Path -Path $_ -PathType 'Leaf' -ErrorAction "SilentlyContinue") { $True } Else { Throw "Cannot find file $_" } })] [Alias("Xml")] [System.String] $Path = (Join-Path -Path $MyInvocation.MyCommand.Module.ModuleBase -ChildPath "VisualCRedistributables.json"), [Parameter(Mandatory = $False, Position = 0, ParameterSetName = 'Export')] [ValidateSet('Supported', 'All', 'Unsupported')] [System.String] $Export = "Supported" ) Process { try { Write-Verbose -Message "$($MyInvocation.MyCommand): Reading JSON document [$Path]." $content = Get-Content -Raw -Path $Path -ErrorAction "SilentlyContinue" } catch [System.Exception] { Write-Warning -Message "$($MyInvocation.MyCommand): Unable to read manifest [$Path]." Throw $_.Exception.Message } try { # Convert the JSON content to an object Write-Verbose -Message "$($MyInvocation.MyCommand): Converting JSON." $json = $content | ConvertFrom-Json -ErrorAction "SilentlyContinue" } catch [System.Exception] { Write-Warning -Message "$($MyInvocation.MyCommand): Unable to convert manifest JSON to required object. Please validate the input manifest." Throw $_.Exception.Message } If ($Null -ne $json) { If ($PSBoundParameters.ContainsKey('Export')) { Switch ($Export) { "Supported" { Write-Verbose -Message "$($MyInvocation.MyCommand): Exporting supported VcRedists." [System.Management.Automation.PSObject] $output = $json.Supported } "All" { Write-Verbose -Message "$($MyInvocation.MyCommand): Exporting all VcRedists." Write-Warning -Message "$($MyInvocation.MyCommand): This list includes unsupported Visual C++ Redistributables." [System.Management.Automation.PSObject] $output = $json.Supported + $json.Unsupported } "Unsupported" { Write-Verbose -Message "$($MyInvocation.MyCommand): Exporting unsupported VcRedists." Write-Warning -Message "$($MyInvocation.MyCommand): This list includes unsupported Visual C++ Redistributables." [System.Management.Automation.PSObject] $output = $json.Unsupported } } } Else { # Filter the list for architecture and release If ($json | Get-Member -Name "Supported" -MemberType "Properties") { [System.Management.Automation.PSObject] $supported = $json.Supported } Else { [System.Management.Automation.PSObject] $supported = $json } [System.Management.Automation.PSObject] $output = $supported | Where-Object { $Release -contains $_.Release } | ` Where-Object { $Architecture -contains $_.Architecture } } # Get the count of items in $output; Because it's a PSCustomObject we can't use the .count property so need to measure th object # Grab a NoteProperty and count how many of those there are to get the object count try { $Property = $output | Get-Member -ErrorAction "SilentlyContinue" | Where-Object { $_.MemberType -eq "NoteProperty" } | Select-Object -ExpandProperty "Name" | Select-Object -First 1 $Count = $output.$Property.Count - 1 } catch { $Count = 0 } # Replace strings in the manifest Write-Verbose -Message "$($MyInvocation.MyCommand): Object count is: $($output.$Property.Count)." For ($i = 0; $i -le $Count; $i++) { try { $output[$i].SilentUninstall = $output[$i].SilentUninstall ` -replace "#Installer", $(Split-Path -Path $output[$i].Download -Leaf) ` -replace "#ProductCode", $output[$i].ProductCode } catch { Write-Verbose -Message "Failed to replace strings in: $($json[$i].Name)." } } Write-Output -InputObject $output } } } |