diff --git a/Get.Software/Get.Software.json b/Get.Software/Get.Software.json new file mode 100644 index 00000000..b7dd7dc8 --- /dev/null +++ b/Get.Software/Get.Software.json @@ -0,0 +1,14 @@ +{ + "Applications" : { + "AdobeAcrobatReaderDC" : { + "Uri": "https://armmf.adobe.com/arm-manifests/mac/AcrobatDC/reader/current_version.txt", + "ContentType" : "text/plain; charset=utf-8", + "Languages" : [ + "en_US", "de_DE", "es_ES", "fr_FR", "ja_JP" + ] + } + }, + "Preferences" : { + "ErrorAction" : "SilentlyContinue" + } +} diff --git a/Get.Software/Get.Software.psd1 b/Get.Software/Get.Software.psd1 index 982bd9df..1bfdcabb 100644 --- a/Get.Software/Get.Software.psd1 +++ b/Get.Software/Get.Software.psd1 @@ -69,7 +69,7 @@ PowerShellVersion = '3.0' # NestedModules = @() # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. -FunctionsToExport = @('Get-AdobeReaderUri', 'Get-AdobeReaderVersion', +FunctionsToExport = @('Get-AdobeAcrobatReaderDC', 'Get-CitrixReceiverVersion', 'Get-ControlUpAgentUri', 'Get-ControlUpAgentVersion', 'Get-GoogleChromeUri', 'Get-GoogleChromeVersion', 'Get-GreenshotUri', 'Get-GreenshotVersion', diff --git a/Get.Software/Get.Software.psm1 b/Get.Software/Get.Software.psm1 index 840d58cd..b18dca3c 100644 --- a/Get.Software/Get.Software.psm1 +++ b/Get.Software/Get.Software.psm1 @@ -1,6 +1,15 @@ -# Get public and private function definition files -$Public = @( Get-ChildItem -Path $PSScriptRoot\Public\*.ps1 -ErrorAction SilentlyContinue ) -$Private = @( Get-ChildItem -Path $PSScriptRoot\Private\*.ps1 -ErrorAction SilentlyContinue ) +<# + .SYNOPSIS + LatestUpdate script to initiate the module +#> +[CmdletBinding()] +Param () + +#region Get public and private function definition files +$publicRoot = Join-Path -Path $PSScriptRoot -ChildPath "Public" +$privateRoot = Join-Path -Path $PSScriptRoot -ChildPath "Private" +$public = @( Get-ChildItem -Path (Join-Path $publicRoot "*.ps1") -ErrorAction SilentlyContinue ) +$private = @( Get-ChildItem -Path (Join-Path $privateRoot "*.ps1") -ErrorAction SilentlyContinue ) # Dot source the files ForEach ($import in @($Public + $Private)) { @@ -12,5 +21,9 @@ ForEach ($import in @($Public + $Private)) { } } -# Export the Public modules -Export-ModuleMember -Function $Public.Basename +# Export the public modules and aliases +Export-ModuleMember -Function $public.Basename -Alias * +#endregion + +# Get module strings +$script:resourceStrings = Get-ModuleResource diff --git a/Get.Software/Private/ConvertTo-Hashtable.ps1 b/Get.Software/Private/ConvertTo-Hashtable.ps1 new file mode 100644 index 00000000..b9545a77 --- /dev/null +++ b/Get.Software/Private/ConvertTo-Hashtable.ps1 @@ -0,0 +1,52 @@ +Function ConvertTo-Hashtable { + <# + .SYNOPSIS + Converts a PSCustomObject into a hashtable for Windows PowerShell + + .NOTES + Author: Adam Bertram + Link: https://4sysops.com/archives/convert-json-to-a-powershell-hash-table + #> + [OutputType([System.Collections.Hashtable])] + [CmdletBinding()] + Param ( + [Parameter(Mandatory = $True, Position = 0, ValueFromPipeline)] + $InputObject + ) + + Process { + ## Return null if the input is null. This can happen when calling the function + ## recursively and a property is null + If ($Null -eq $InputObject) { + Return $Null + } + + ## Check if the input is an array or collection. If so, we also need to convert + ## those types into hash tables as well. This function will convert all child + ## objects into hash tables (if applicable) + If ($InputObject -is [System.Collections.IEnumerable] -and $InputObject -isnot [string]) { + $collection = @( + ForEach ($object in $InputObject) { + ConvertTo-Hashtable -InputObject $object + } + ) + + ## Return the array but don't enumerate it because the object may be pretty complex + Write-Output -NoEnumerate -InputObject $collection + } + ElseIf ($InputObject -is [psobject]) { + ## If the object has properties that need enumeration + ## Convert it to its own hash table and return it + $hash = @{ } + ForEach ($property in $InputObject.PSObject.Properties) { + $hash[$property.Name] = ConvertTo-Hashtable -InputObject $property.Value + } + $hash + } + Else { + ## If the object isn't an array, collection, or other object, it's already a hash table + ## So just return it. + $InputObject + } + } +} diff --git a/Get.Software/Private/Get-ModuleResource.ps1 b/Get.Software/Private/Get-ModuleResource.ps1 new file mode 100644 index 00000000..93135bd5 --- /dev/null +++ b/Get.Software/Private/Get-ModuleResource.ps1 @@ -0,0 +1,41 @@ +Function Get-ModuleResource { + <# + .SYNOPSIS + Reads the module strings from the JSON file and returns a hashtable. + #> + [OutputType([System.Management.Automation.PSObject])] + [CmdletBinding()] + Param ( + [Parameter(Mandatory = $False, Position = 0)] + [ValidateNotNull()] + [ValidateScript( { If (Test-Path -Path $_ -PathType 'Leaf') { $True } Else { Throw "Cannot find file $_" } })] + [System.String] $Path = (Join-Path -Path $MyInvocation.MyCommand.Module.ModuleBase -ChildPath "Get.Software.json") + ) + + try { + Write-Verbose -Message "$($MyInvocation.MyCommand): read module resource strings from [$Path]" + $content = Get-Content -Path $Path -Raw -ErrorAction SilentlyContinue + } + catch [System.Exception] { + Write-Warning -Message "$($MyInvocation.MyCommand): failed to read from: $Path." + Throw $_.Exception.Message + } + + try { + If (Test-PSCore) { + $script:resourceStringsTable = $content | ConvertFrom-Json -AsHashtable -ErrorAction SilentlyContinue + } + Else { + $script:resourceStringsTable = $content | ConvertFrom-Json -ErrorAction SilentlyContinue | ConvertTo-Hashtable + } + } + catch [System.Exception] { + Write-Warning -Message "$($MyInvocation.MyCommand): failed to convert strings to required object." + Throw $_.Exception.Message + } + finally { + If ($Null -ne $script:resourceStringsTable) { + Write-Output -InputObject $script:resourceStringsTable + } + } +} diff --git a/Get.Software/Private/Invoke-WebContent.ps1 b/Get.Software/Private/Invoke-WebContent.ps1 new file mode 100644 index 00000000..f4d98e57 --- /dev/null +++ b/Get.Software/Private/Invoke-WebContent.ps1 @@ -0,0 +1,48 @@ +Function Invoke-WebContent { + <# + .SYNOPSIS + Return content from Invoke-WebRequest. + #> + [OutputType([Microsoft.PowerShell.Commands.WebResponseObject])] + [CmdletBinding()] + Param( + [Parameter(Mandatory = $True, Position = 0)] + [ValidateNotNullOrEmpty()] + [System.String] $Uri, + + [Parameter(Mandatory = $True, Position = 0)] + [ValidateNotNullOrEmpty()] + [System.String] $ContentType + ) + + If ($Null -ne $script:resourceStrings) { + try { + $params = @{ + Uri = $Uri + ContentType = $ContentType + UserAgent = [Microsoft.PowerShell.Commands.PSUserAgent]::Chrome + UseBasicParsing = $True + ErrorAction = $script:resourceStrings.Preferences.ErrorAction + } + $Request = Invoke-WebRequest @params + } + catch [System.Net.WebException] { + Write-Warning -Message ($($MyInvocation.MyCommand)) + Write-Warning -Message ([string]::Format("Error : {0}", $_.Exception.Message)) + } + catch [System.Exception] { + Write-Warning -Message "$($MyInvocation.MyCommand): failed to invoke request to: $Uri." + Throw $_.Exception.Message + } + + If ($Request.StatusCode -eq "200") { + Write-Output -InputObject $Request.Content + } + Else { + Write-Warning -Message "$($MyInvocation.MyCommand): no valid response." + } + } + Else { + Write-Warning -Message "$($MyInvocation.MyCommand): unable to retrieve: $Uri." + } +} diff --git a/Get.Software/Private/Test-PSCore.ps1 b/Get.Software/Private/Test-PSCore.ps1 new file mode 100644 index 00000000..32bf0d47 --- /dev/null +++ b/Get.Software/Private/Test-PSCore.ps1 @@ -0,0 +1,21 @@ +Function Test-PSCore { + <# + .SYNOPSIS + Returns True if running on PowerShell Core. + #> + [CmdletBinding()] + [OutputType([Boolean])] + Param ( + [Parameter(Mandatory = $False, Position = 0)] + [ValidateNotNullOrEmpty()] + [System.String] $Version = '6.0.0' + ) + + # Check whether current PowerShell environment matches or is higher than $Version + If (($PSVersionTable.PSVersion -ge [Version]::Parse($Version)) -and ($PSVersionTable.PSEdition -eq "Core")) { + Write-Output -InputObject $True + } + Else { + Write-Output -InputObject $False + } +} diff --git a/Get.Software/Public/Get-AdobeAcrobatReaderDC.ps1 b/Get.Software/Public/Get-AdobeAcrobatReaderDC.ps1 new file mode 100644 index 00000000..5a6ec572 --- /dev/null +++ b/Get.Software/Public/Get-AdobeAcrobatReaderDC.ps1 @@ -0,0 +1,103 @@ +Function Get-AdobeAcrobatReaderDC { + <# + .SYNOPSIS + Gets the download URLs for Adobe Reader DC Continuous track installers. + + .DESCRIPTION + Gets the download URLs for Adobe Reader DC Continuous track installers for the latest version for Windows and macOS. + + .NOTES + Author: Aaron Parker + Twitter: @stealthpuppy + + .LINK + https://github.com/aaronparker/Get.Software + + .PARAMETER Platform + Return downloads for Windows or macOS platforms. Use "win" or "mac" or specify both to return downloads for both platforms. + + .EXAMPLE + Get-AdobeReaderUri -Platform + + Description: + Returns an array with installer type, language and download URL for Windows. + + .EXAMPLE + Get-AdobeReaderUri -Platform win, mac + + Description: + Returns an array with installer type, language and download URL for both Windows and macOS. + #> + [CmdletBinding()] + Param ( + [Parameter()] + [ValidateSet("win", "mac")] + [System.String[]] $Platform = "win" + ) + + # Get current version + $Content = Invoke-WebContent -Uri $script:resourceStrings.Applications.AdobeAcrobatReaderDC.Uri ` + -ContentType $script:resourceStrings.Applications.AdobeAcrobatReaderDC.ContentType + $version = $Content.Replace(".", "") + + # Construct download list + If ($Null -ne $version) { + ForEach ($plat in $Platform) { + Switch ($plat) { + "win" { + $ftpUrl = "ftp://ftp.adobe.com/pub/adobe/reader/$plat/AcrobatDC/" + ForEach ($lang in $script:resourceStrings.Applications.AdobeAcrobatReaderDC.Languages) { + $PSObject = [PSCustomObject] @{ + Platform = "Windows" + Type = "Installer" + Language = $lang + URL = "$($ftpUrl)$($version)/AcroRdrDC$($version)_$($lang).exe" + } + Write-Output -InputObject $PSObject + } + $PSObject = [PSCustomObject] @{ + Platform = "Windows" + Type = "Updater" + Language = "Neutral" + URL = "$($ftpUrl)$($version)/AcroRdrDC$($version).msp" + } + Write-Output -InputObject $PSObject + $PSObject = [PSCustomObject] @{ + Platform = "Windows" + Type = "Updater" + Language = "Multi" + URL = "$($ftpUrl)$($version)/AcroRdrDC$($version)_MUI.msp" + } + Write-Output -InputObject $PSObject + } + "mac" { + $ftpUrl = "ftp://ftp.adobe.com/pub/adobe/reader/$plat/AcrobatDC/" + $PSObject = [PSCustomObject] @{ + Platform = "macOS" + Type = "Installer" + Language = "Multi" + URL = "$($ftpUrl)$($version)/AcroRdrDC_$($version)_MUI.dmg" + } + Write-Output -InputObject $PSObject + $PSObject = [PSCustomObject] @{ + Platform = "macOS" + Type = "Updater" + Language = "Multi" + URL = "$($ftpUrl)$($version)/AcroRdrDCUpd$($version)_MUI.dmg" + } + Write-Output -InputObject $PSObject + $PSObject = [PSCustomObject] @{ + Platform = "macOS" + Type = "Updater" + Language = "Multi" + URL = "$($ftpUrl)$($version)/AcroRdrDCUpd$($version)_MUI.pkg" + } + Write-Output -InputObject $PSObject + } + } + } + } + Else { + Write-Warning -Message "$($MyInvocation.MyCommand): unable to find Adobe Acrobat Reader DC version." + } +} diff --git a/Get.Software/Public/Get-AdobeReaderUri.ps1 b/Get.Software/Public/Get-AdobeReaderUri.ps1 deleted file mode 100644 index 77707c83..00000000 --- a/Get.Software/Public/Get-AdobeReaderUri.ps1 +++ /dev/null @@ -1,96 +0,0 @@ -Function Get-AdobeReaderUri { - <# - .SYNOPSIS - Gets the download URLs for Adobe Reader DC Continuous track installers. - - .DESCRIPTION - Gets the download URLs for Adobe Reader DC Continuous track installers for the latest version for Windows and macOS. - - .NOTES - Author: Aaron Parker - Twitter: @stealthpuppy - - .LINK - https://github.com/aaronparker/Get.Software - - .PARAMETER Platform - Return downloads for Windows or macOS platforms. Use 'win' or 'mac' or specify both to return downloads for both platforms. - - .EXAMPLE - Get-AdobeReaderUri -Platform - - Description: - Returns an array with installer type, language and download URL for Windows. - - .EXAMPLE - Get-AdobeReaderUri -Platform win, mac - - Description: - Returns an array with installer type, language and download URL for both Windows and macOS. - #> - [CmdletBinding()] - Param ( - [Parameter(Mandatory = $False)] - [ValidateSet('win', 'mac')] - [string[]] $Platform = "win" - ) - - # Get current version - $version = (Get-AdobeReaderVersion).Replace('.', '') - - # Variables, URLs and languages for download - $languages = @('en-US', 'de_DE', 'es_ES', 'fr_FR', 'ja_JP') - $object = @() - - # Construct download list - ForEach ($plat in $Platform) { - Switch ($plat) { - "win" { - $ftpUrl = "ftp://ftp.adobe.com/pub/adobe/reader/$plat/AcrobatDC/" - ForEach ($lang in $languages) { - $item = New-Object PSCustomObject - $item | Add-Member -Type NoteProperty -Name 'Platform' -Value 'Windows' - $item | Add-Member -Type NoteProperty -Name 'Type' -Value 'Installer' - $item | Add-Member -Type NoteProperty -Name 'Language' -Value $lang - $item | Add-Member -Type NoteProperty -Name 'URL' -Value "$($ftpUrl)$($version)/AcroRdrDC$($version)_$($lang).exe" - $object += $item - } - $item = New-Object PSCustomObject - $item | Add-Member -Type NoteProperty -Name 'Platform' -Value 'Windows' - $item | Add-Member -Type NoteProperty -Name 'Type' -Value 'Updater' - $item | Add-Member -Type NoteProperty -Name 'Language' -Value 'Neutral' - $item | Add-Member -Type NoteProperty -Name 'URL' -Value "$($ftpUrl)$($version)/AcroRdrDC$($version).msp" - $object += $item - $item = New-Object PSCustomObject - $item | Add-Member -Type NoteProperty -Name 'Platform' -Value 'Windows' - $item | Add-Member -Type NoteProperty -Name 'Type' -Value 'Updater' - $item | Add-Member -Type NoteProperty -Name 'Language' -Value 'Multi' - $item | Add-Member -Type NoteProperty -Name 'URL' -Value "$($ftpUrl)$($version)/AcroRdrDC$($version)_MUI.msp" - $object += $item - } - "mac" { - $ftpUrl = "ftp://ftp.adobe.com/pub/adobe/reader/$plat/AcrobatDC/" - $item = New-Object PSCustomObject - $item | Add-Member -Type NoteProperty -Name 'Platform' -Value 'macOS' - $item | Add-Member -Type NoteProperty -Name 'Type' -Value 'Installer' - $item | Add-Member -Type NoteProperty -Name 'Language' -Value 'Multi' - $item | Add-Member -Type NoteProperty -Name 'URL' -Value "$($ftpUrl)$($version)/AcroRdrDC_$($version)_MUI.dmg" - $object += $item - $item = New-Object PSCustomObject - $item | Add-Member -Type NoteProperty -Name 'Platform' -Value 'macOS' - $item | Add-Member -Type NoteProperty -Name 'Type' -Value 'Updater' - $item | Add-Member -Type NoteProperty -Name 'Language' -Value 'Multi' - $item | Add-Member -Type NoteProperty -Name 'URL' -Value "$($ftpUrl)$($version)/AcroRdrDCUpd$($version)_MUI.dmg" - $object += $item - $item = New-Object PSCustomObject - $item | Add-Member -Type NoteProperty -Name 'Platform' -Value 'macOS' - $item | Add-Member -Type NoteProperty -Name 'Type' -Value 'Updater' - $item | Add-Member -Type NoteProperty -Name 'Language' -Value 'Multi' - $item | Add-Member -Type NoteProperty -Name 'URL' -Value "$($ftpUrl)$($version)/AcroRdrDCUpd$($version)_MUI.pkg" - $object += $item - } - } - } - - Write-Output ($object | Sort-Object -Property Platform, Type) -} diff --git a/Get.Software/Public/Get-AdobeReaderVersion.ps1 b/Get.Software/Public/Get-AdobeReaderVersion.ps1 deleted file mode 100644 index 187848c1..00000000 --- a/Get.Software/Public/Get-AdobeReaderVersion.ps1 +++ /dev/null @@ -1,30 +0,0 @@ -Function Get-AdobeReaderVersion { - <# - .SYNOPSIS - Gets the current Adobe Reader DC Continuous track release version. - - .DESCRIPTION - Gets the current Adobe Reader DC Continuous track release version sourced from the Adobe site and returns a version string. - - .NOTES - Author: Aaron Parker - Twitter: @stealthpuppy - - .LINK - https://github.com/aaronparker/Get.Software - - .EXAMPLE - Get-AdobeReaderVersion - - Description: - Returns the version number string for the latest Adobe Reader DC release. - #> - [CmdletBinding()] - Param ( - [Parameter(Mandatory = $False)] - [string] $Uri = "https://armmf.adobe.com/arm-manifests/mac/AcrobatDC/reader/current_version.txt" - ) - - # Get current version - Write-Output ((Invoke-WebRequest -uri $Uri).Content) -}