Get-LatestAdobeReaderInstaller.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
<#PSScriptInfo
.VERSION 1.0.2
.GUID e4d9eb84-bf65-4985-a5b4-9bcbe20afb05
.AUTHOR NickolajA
.DESCRIPTION Get the latest Adobe Reader DC setup installation details from the official Adobe FTP server
.COMPANYNAME SCConfigMgr
.COPYRIGHT
.TAGS AdobeReader Intune ConfigMgr PowerShell FTP
.LICENSEURI
.PROJECTURI https://github.com/SCConfigMgr/Other/blob/master/Get-LatestAdobeReaderInstaller.ps1
.ICONURI
.EXTERNALMODULEDEPENDENCIES
.REQUIREDSCRIPTS
.EXTERNALSCRIPTDEPENDENCIES
.RELEASENOTES
#>

<#
.SYNOPSIS
    Get the latest Adobe Reader DC setup installation details from the official Adobe FTP server.
 
.DESCRIPTION
    Get the latest Adobe Reader DC setup installation details from the official Adobe FTP server.
 
.PARAMETER Type
    Specify the installer type, either EXE or MSP.
 
.PARAMETER Language
    Specify the desired language of the installer, e.g. 'en_US'.
 
.EXAMPLE
    # Retrieve the latest available Adobe Reader DC setup installer of type 'EXE' from the official Adobe FTP server:
    .\Get-LatestAdobeReaderInstaller.ps1 -Type EXE -Language en_US
 
    # Retrieve the latest available Adobe Reader DC patch installer of type 'MSP' from the official Adobe FTP server:
    .\Get-LatestAdobeReaderInstaller.ps1 -Type MSP
 
.NOTES
    FileName: Get-LatestAdobeReaderInstaller.ps1
    Author: Nickolaj Andersen
    Contact: @NickolajA
    Created: 2020-03-12
    Updated: 2020-04-22
     
    Version history:
    1.0.0 - (2020-03-12) Script created.
    1.0.1 - (2020-04-22) Fixed an issue where the SetupVersion was not interpretet correctly.
    1.0.2 - (2020-04-22) This time, it should work.
#>

[CmdletBinding(SupportsShouldProcess = $true)]
param(
    [parameter(Mandatory = $false, HelpMessage = "Specify the installer type, either EXE or MSP.")]
    [ValidateNotNullOrEmpty()]
    [ValidateSet("EXE", "MSP")]
    [string]$Type = "EXE",

    [parameter(Mandatory = $false, HelpMessage = "Specify the desired language of the installer, e.g. 'en_US'.")]
    [ValidateNotNullOrEmpty()]
    [ValidateSet("en_US", "de_DE", "es_ES", "fr_FR", "ja_JP")]
    [string]$Language = "en_US"
)
Process {
    # Set script error action preference
    $ErrorActionPreference = "Stop"

    # Functions
    function Get-AdobeReaderFTPItem {
        [CmdletBinding(SupportsShouldProcess = $true)]
        param(
            [parameter(Mandatory = $false, HelpMessage = "Specify the directory path, e.g. 'ftp://ftp.adobe.com/pub/adobe/reader/win/AcrobatDC'.")]
            [ValidateNotNullOrEmpty()]
            [string]$Path = "ftp://ftp.adobe.com/pub/adobe/reader/win/AcrobatDC"
        )
        Process {
            # Construct anonymous credentials to use when connecting to Adobe's FTP
            $FTPCredentials = ([System.Management.Automation.PSCredential]::new("anonymous", ("password" | ConvertTo-SecureString -AsPlainText -Force)))
       
            # Construct WebRequest object for recieving FTP data stream
            [System.Net.FtpWebRequest]$WebRequest = [System.Net.WebRequest]::Create($Path)
            $WebRequest.Method = [System.Net.WebRequestMethods+FTP]::ListDirectoryDetails
            $WebRequest.Credentials = $FTPCredentials
            $WebRequest.Timeout = 90000
            $WebRequest.KeepAlive = $false
            $WebRequest.UseBinary = $false
            $WebRequest.UsePassive = $true
    
            try {
                # Get FTP response data stream
                $FTPResponse = $WebRequest.GetResponse()
                $FTPResponseStream = $FTPResponse.GetResponseStream()
                $FTPStreamReader = New-Object -TypeName System.IO.StreamReader -ArgumentList $FTPResponseStream

                # Read each line of the stream and add it a list
                $StreamList = New-Object -TypeName System.Collections.ArrayList
                while ($ListItem = $FTPStreamReader.ReadLine()) {
                    # Split directory listing string into objects (borrowed from PSFTP module from PSGallery: https://www.powershellgallery.com/packages/PSFTP)
                    $null, $null, $null, $null, $null, $null, $null, [string]$Date, [string]$Name = [regex]::Split($ListItem, '^([d-])([rwxt-]{9})\s+(\d{1,})\s+([.@A-Za-z0-9-]+)\s+([A-Za-z0-9-]+)\s+(\d{1,})\s+(\w+\s+\d{1,2}\s+\d{1,2}:?\d{2})\s+(.+?)\s?$', "SingleLine,IgnoreCase,IgnorePatternWhitespace")
                    
                    # Parse date string into date object (borrowed from PSFTP module from PSGallery: https://www.powershellgallery.com/packages/PSFTP)
                    $DatePart = $Date -split "\s+"
                    $NewDateString = "$($DatePart[0]) $('{0:D2}' -f [int]$DatePart[1]) $($DatePart[2])"
                    if($DatePart[2] -match ":") {
                        $Month = ([DateTime]::ParseExact($DatePart[0],"MMM" ,[System.Globalization.CultureInfo]::InvariantCulture)).Month
                        if((Get-Date).Month -ge $Month) {
                            $NewDate = [DateTime]::ParseExact($NewDateString, "MMM dd HH:mm", [System.Globalization.CultureInfo]::InvariantCulture)
                        }
                        else {
                            $NewDate = ([DateTime]::ParseExact($NewDateString, "MMM dd HH:mm", [System.Globalization.CultureInfo]::InvariantCulture)).AddYears(-1)
                        }
                    } 
                    else {
                        $NewDate = [DateTime]::ParseExact($NewDateString, "MMM dd yyyy", [System.Globalization.CultureInfo]::InvariantCulture)
                    }

                    # Construct custom object to be added to array list
                    $PSObject = [PSCustomObject]@{
                        Path = -join@($Path, "/", $Name.Trim())
                        Date = $NewDate
                        Name = $Name.Trim()
                    }

                    # Filter out unwanted objects and add everything else to array list
                    if ($Name -notlike "misc") {
                        $StreamList.Add($PSObject) | Out-Null
                    }
                }

                # Handle return value from function
                Write-Output -InputObject ($StreamList | Sort-Object -Property Date)
            }
            catch [System.Exception] {
                throw $_.Exception.Message; break
            }
        }
        End {
            # Perform cleanup and disconnect FTP connection
            $FTPResponse.Close()
            $FTPResponse.Dispose()
        }
    }

    function Get-LatestAdobeReaderInstallerItem {
        $FTPDirectoryItem = Get-AdobeReaderFTPItem | Select-Object -Skip $LatestCount -Last 1
        if ($FTPDirectoryItem -ne $null) {
            $FTPDirectoryItems = Get-AdobeReaderFTPItem -Path $FTPDirectoryItem.Path
            if ($FTPDirectoryItems -ne $null) {
                switch ($Type) {
                    "EXE" {
                        $FTPSetupInstaller = $FTPDirectoryItems | Where-Object { ($_.Name -match $FTPDirectoryItem.Name) -and ($_.Name -match $Language) -and ($_.Name -match $Type.ToLower()) }
                    }
                    "MSP" {
                        $FTPSetupInstaller = $FTPDirectoryItems | Where-Object { ($_.Name -match $FTPDirectoryItem.Name) -and ($_.Name -match $Type.ToLower()) }
                    }
                }
                
                if ($FTPSetupInstaller -ne $null) {
                    foreach ($FTPSetupInstallerItem in $FTPSetupInstaller) {
                        $PSObject = [PSCustomObject]@{
                            FileName = $FTPSetupInstallerItem.Name
                            SetupVersion = -join@($FTPDirectoryItem.Name.SubString(0, 2), ".", $FTPDirectoryItem.Name.SubString(2, 3), ".", $FTPDirectoryItem.Name.SubString(5, 5))
                            URL = $FTPSetupInstallerItem.Path
                            Date = $FTPSetupInstallerItem.Date
                        }
                        Write-Output -InputObject $PSObject
                    }
                }
                else {
                    $LatestCount++
                    Get-LatestAdobeReaderInstallerItem
                }
            }
        }
    }

    # Retrieve the latest setup installer based on parameter input
    $LatestCount = 0
    Get-LatestAdobeReaderInstallerItem
}