Public/Get-LnvUpdate.ps1
|
<#
.Synopsis Get-LnvUpdate finds and downloads updates for Lenovo machine type .Description This script allows users to search for updates that will be downloaded to a folder of their choice -Defaults to Windows 10 updates and a folder named c:\testrepo if you do not specify -Requires users to enter at least a machine type -Can be called without identifiers so long as you use the right order -If a repositoryfolder is specified that doesn't exist the script will create it -PackageType can be: 1: Application 2: Driver 3: Bios 4: Firmware -RebootType can be: 0: No reboot required 1: Forced reboot (update itself initiates the reboot) 3: Requires reboot (Thin Installer/System Update/CV initiates the reboot) 4: Forces shutdown (update itself initiates shutdown) 5: Delayed forced reboot (used for firmware, Thin Installer/System Update/CV will enforce reboot with dialog displaying count-down timer) -Severity can be: 1: Critical 2: Recommended 3: Optional Note: 9 can be used for these three parameters to represent 'All' .PARAMETER MachineType Mandatory : True .PARAMETER WindowsVersion .PARAMETER RepositoryFolder .PARAMETER PackageType .PARAMETER RebootType .PARAMETER Csv .PARAMETER Expand .Example Get-LnvUpdate -MachineType 20E4 -WindowsVersion 10 -RepositoryFolder "C:\repository" -PackageType 1 .Example Get-LnvUpdate 20E4 10 "C:\repository" .Example Get-LnvUpdate -MachineType "20E6" -RepositoryFolder "C:\repository" #> function Get-LnvUpdate { param ( [ValidateLength(4,4)][parameter(Mandatory = $true, position = 0)] [String] $MachineType, [parameter(position = 4, Mandatory = $false )][ValidateSet("10","11")] [String] $WindowsVersion = "10", [parameter(position = 2)][String] $RepositoryFolder = "c:\testrepo", [parameter(position = 3)][String] $PackageType = "9", [parameter(position = 4)][String] $RebootType = "9", [parameter(position = 5)][Switch] $Csv, [parameter(position = 6)][Switch] $Expand ) $url = "https://download.lenovo.com/catalog/" + $MachineType + "_win" + $WindowsVersion + ".xml" if ($Csv) { #Create table format to display information about the updates $tbl = New-Object System.Data.DataTable "Available Updates" $col0 = New-Object System.Data.DataColumn ID $col1 = New-Object System.Data.DataColumn Name #$col2 = New-Object System.Data.DataColumn Category $col3 = New-Object System.Data.DataColumn Version $col4 = New-Object System.Data.DataColumn PackageType $col5 = New-Object System.Data.DataColumn Reboot $col6 = New-Object System.Data.DataColumn Severity $col7 = New-Object System.Data.DataColumn Descriptor $col8 = New-Object System.Data.DataColumn PackageExe $tbl.Columns.Add($col0) $tbl.Columns.Add($col1) #$tbl.Columns.Add($col2) $tbl.Columns.Add($col3) $tbl.Columns.Add($col4) $tbl.Columns.Add($col5) $tbl.Columns.Add($col6) $tbl.Columns.Add($col7) $tbl.Columns.Add($col8) } #accesses the updates xml file for a system try { $systemUpdates = Get-LnvXmlFilePvt $url } catch { Write-Output $_ return } if($Expand) { if(-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { Write-Output "Not running in elevated session. Skipping expand." $Expand = $false } else { $hash = [hashtable]::Synchronized(@{}) $hash["RepoPath"] = $RepositoryFolder $initialSessionState = [InitialSessionState]::CreateDefault() $RunspacePool = [RunspaceFactory]::CreateRunspacePool($initialSessionState) [void]$RunspacePool.SetMaxRunspaces(2) $RunspacePool.Open() $Jobs = New-Object System.Collections.ArrayList $Worker = { param($Exe, $Fold) Start-Process -FilePath $Exe -ArgumentList "/VERYSILENT /DIR=`"$Fold`" /EXTRACT=`"YES`"" } } } #holds the urls for all the updates for a system $locations = $systemUpdates.packages.package.location $qnty = $systemUpdates.packages.count Write-Output -InputObject ("Total Updates Found: " + $qnty) #Create Repo & prepare to download #check if we have permissions if (-NOT (Test-Path $RepositoryFolder)) { new-item -ItemType directory -path $RepositoryFolder } #questionable code $RepositoryFolder += "\" $downloadCount = 0 #Loops the updates for a machine to download them in a folder with their readme and xml Foreach ($file in $locations) { try { $up1 = Get-LnvXmlFilePvt $file } catch { Write-Output $_ continue } #only get updates that match specified package type and/or reboot type $pkgType = $up1.Package.PackageType.type $rbType = $up1.Package.Reboot.type $pkgID = $up1.Package.id.ToString() if ((($PackageType -eq 9) -or ($PackageType -match $pkgType)) -and (($RebootType -eq 9) -or ($RebootType -match $rbType))) { #Create Folder for update if it does not already exst $innerFold = $RepositoryFolder.ToString() + $pkgID + "\" if (-NOT (Test-Path $innerFold)) { #Get Links; "$file" is the .xml #.xml $beg = $file.SubString(0, $file.LastIndexOf('/') + 1) #$end = $file.Substring($file.LastIndexOf('/') + 1) #.exe #grab crc as well to use Get-LnvFilePvt? $exeFile = $up1.Package.Files.Installer.File.Name $exeLink = $beg + $exeFile #.readme $readMeFile = $up1.Package.Files.Readme.File.Name $readMeLink = $beg + $readMeFile New-Item -ItemType directory -Path $innerFold #Download all parts of the update try { #$pathToExe = Join-Path -Path $innerFold -ChildPath $exeFile #(New-Object System.Net.WebClient).DownloadFile($exeLink, $innerFold + $exeFile); $dest = $innerFold + $exeFile Start-BitsTransfer -Source $exeLink -Destination $dest -ErrorAction Stop if ($Expand) { $PowerShell = [powershell]::Create() $PowerShell.RunspacePool = $RunspacePool $PowerShell.AddScript($Worker).AddArgument($innerFold + $exeFile).AddArgument("${RepositoryFolder}\${MachineType}_${WindowsVersion}\${pkgID}") | Out-Null $JobObj = New-Object -TypeName PSObject -Property @{ Runspace = $PowerShell.BeginInvoke() PowerShell = $PowerShell } $Jobs.Add($JobObj) | Out-Null } } catch { Write-Output -InputObject "Could not download EXE: $exeFile" } try { (New-Object System.Net.WebClient).DownloadFile($readMeLink, $innerFold + $readMeFile); } catch { Write-Output -InputObject "Could not download Readme: $readMeFile" } #count could be wrong $downloadCount += 1 if ($Csv) { $luPID = $up1.Package.id #$luCat = $categories_1[$counter] $luName = $up1.Package.Title.Desc.InnerText $luVer = $up1.Package.version $luTyp = $up1.Package.PackageType.type $luReb = $up1.Package.Reboot.type $luSev = $up1.Package.Severity.type $luXml = $file $luExe = $file.Substring(0, $file.LastIndexOf('/') + 1) + ($up1.Package.Files.Installer.File.Name) $row = $tbl.NewRow() $row.ID = $luPID $row.Name = $luName # $row.Category = $luCat $row.Version = $luVer $row.PackageType = $luTyp $row.Reboot = $luReb $row.Severity = $luSev $row.Descriptor = $luXml $row.PackageExe = $luExe $tbl.Rows.Add($row) } } else { Write-Output -InputObject ($up1.Package.id.ToString() + " exists in repository.") if ($Expand) { $beg = $file.SubString(0, $file.LastIndexOf('/') + 1) #$end = $file.Substring($file.LastIndexOf('/') + 1) #.exe #grab crc as well to use Get-LnvFilePvt? $exeFile = $up1.Package.Files.Installer.File.Name $exeLink = $beg + $exeFile $PowerShell = [powershell]::Create() $PowerShell.RunspacePool = $RunspacePool $PowerShell.AddScript($Worker).AddArgument($innerFold + $exeFile).AddArgument("${RepositoryFolder}\${MachineType}_${WindowsVersion}\${pkgID}") | Out-Null $JobObj = New-Object -TypeName PSObject -Property @{ Runspace = $PowerShell.BeginInvoke() PowerShell = $PowerShell } $Jobs.Add($JobObj) | Out-Null } } } } Write-Output -InputObject ("Downloaded Updates: " + $downloadCount) if ($Csv) { $csvFilePath = "${RepositoryFolder}\${MachineType}_${WindowsVersion}.csv" $tbl | Export-Csv -Path $csvFilePath } if($Expand) { while ($Jobs.Runspace.IsCompleted -contains $false) { Write-Output (Get-date).Tostring() "Still expanding packages..." Start-Sleep 1 } $RunspacePool.Dispose() } } # SIG # Begin signature block # MIItfQYJKoZIhvcNAQcCoIItbjCCLWoCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUqahiMrGiD4CMK3NKduUhPpN3 # /LqggialMIIFjTCCBHWgAwIBAgIQDpsYjvnQLefv21DiCEAYWjANBgkqhkiG9w0B # AQwFADBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD # VQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVk # IElEIFJvb3QgQ0EwHhcNMjIwODAxMDAwMDAwWhcNMzExMTA5MjM1OTU5WjBiMQsw # CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu # ZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQw # ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz # 7MKnJS7JIT3yithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS # 5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7 # bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfI # SKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jH # trHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14 # Ztk6MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2 # h4mXaXpI8OCiEhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt # 6zPZxd9LBADMfRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPR # iQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ER # ElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4K # Jpn15GkvmB0t9dmpsh3lGwIDAQABo4IBOjCCATYwDwYDVR0TAQH/BAUwAwEB/zAd # BgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wHwYDVR0jBBgwFoAUReuir/SS # y4IxLVGLp6chnfNtyA8wDgYDVR0PAQH/BAQDAgGGMHkGCCsGAQUFBwEBBG0wazAk # BggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEMGCCsGAQUFBzAC # hjdodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURS # b290Q0EuY3J0MEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0 # LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwEQYDVR0gBAowCDAGBgRV # HSAAMA0GCSqGSIb3DQEBDAUAA4IBAQBwoL9DXFXnOF+go3QbPbYW1/e/Vwe9mqyh # hyzshV6pGrsi+IcaaVQi7aSId229GhT0E0p6Ly23OO/0/4C5+KH38nLeJLxSA8hO # 0Cre+i1Wz/n096wwepqLsl7Uz9FDRJtDIeuWcqFItJnLnU+nBgMTdydE1Od/6Fmo # 8L8vC6bp8jQ87PcDx4eo0kxAGTVGamlUsLihVo7spNU96LHc/RzY9HdaXFSMb++h # UD38dglohJ9vytsgjTVgHAIDyyCwrFigDkBjxZgiwbJZ9VVrzyerbHbObyMt9H5x # aiNrIv8SuFQtJ37YOtnwtoeW/VvRXKwYw02fc7cBqZ9Xql4o4rmUMIIFkDCCA3ig # AwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBiMQswCQYDVQQG # EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl # cnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMTMw # ODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJVUzEVMBMGA1UE # ChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYD # VQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqGSIb3DQEBAQUA # A4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3yithZwuEppz1Y # q3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lX # FllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDVySAdYyktzuxe # TsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiODCu3T6cw2Vbu # yntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I # 9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/CNdaSaTC5qmg # Z92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCiEhtmmnTK3kse # 5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADMfRyVw4/3IbKy # Ebe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwh # HbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXKchYiCd98THU/ # Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t9dmpsh3lGwID # AQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4E # FgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQADggIBALth2X2p # bL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2SV1EY+CtnJYY # ZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd+SeuMIW59mdN # Oj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWcfFqK1qI4mfN4 # i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqasjYUegbyJLkJ # EVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9NcCOGDErcgdLM # MpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N0XWs0Mr7QbhD # parTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie4u1Ki7wb/UdK # Dd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mIr/OSmbaz5mEP # 0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1/YldvIViHTLS # oCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCmgKDWHrO8Dw9T # dSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+MIIGrjCCBJagAwIBAgIQBzY3tyRU # fNhHrP0oZipeWzANBgkqhkiG9w0BAQsFADBiMQswCQYDVQQGEwJVUzEVMBMGA1UE # ChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYD # VQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMjIwMzIzMDAwMDAwWhcN # MzcwMzIyMjM1OTU5WjBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQs # IEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEy # NTYgVGltZVN0YW1waW5nIENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC # AgEAxoY1BkmzwT1ySVFVxyUDxPKRN6mXUaHW0oPRnkyibaCwzIP5WvYRoUQVQl+k # iPNo+n3znIkLf50fng8zH1ATCyZzlm34V6gCff1DtITaEfFzsbPuK4CEiiIY3+va # PcQXf6sZKz5C3GeO6lE98NZW1OcoLevTsbV15x8GZY2UKdPZ7Gnf2ZCHRgB720RB # idx8ald68Dd5n12sy+iEZLRS8nZH92GDGd1ftFQLIWhuNyG7QKxfst5Kfc71ORJn # 7w6lY2zkpsUdzTYNXNXmG6jBZHRAp8ByxbpOH7G1WE15/tePc5OsLDnipUjW8LAx # E6lXKZYnLvWHpo9OdhVVJnCYJn+gGkcgQ+NDY4B7dW4nJZCYOjgRs/b2nuY7W+yB # 3iIU2YIqx5K/oN7jPqJz+ucfWmyU8lKVEStYdEAoq3NDzt9KoRxrOMUp88qqlnNC # aJ+2RrOdOqPVA+C/8KI8ykLcGEh/FDTP0kyr75s9/g64ZCr6dSgkQe1CvwWcZklS # UPRR8zZJTYsg0ixXNXkrqPNFYLwjjVj33GHek/45wPmyMKVM1+mYSlg+0wOI/rOP # 015LdhJRk8mMDDtbiiKowSYI+RQQEgN9XyO7ZONj4KbhPvbCdLI/Hgl27KtdRnXi # YKNYCQEoAA6EVO7O6V3IXjASvUaetdN2udIOa5kM0jO0zbECAwEAAaOCAV0wggFZ # MBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFLoW2W1NhS9zKXaaL3WMaiCP # nshvMB8GA1UdIwQYMBaAFOzX44LScV1kTN8uZz/nupiuHA9PMA4GA1UdDwEB/wQE # AwIBhjATBgNVHSUEDDAKBggrBgEFBQcDCDB3BggrBgEFBQcBAQRrMGkwJAYIKwYB # BQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBBBggrBgEFBQcwAoY1aHR0 # cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5j # cnQwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0Rp # Z2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcmwwIAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJ # YIZIAYb9bAcBMA0GCSqGSIb3DQEBCwUAA4ICAQB9WY7Ak7ZvmKlEIgF+ZtbYIULh # sBguEE0TzzBTzr8Y+8dQXeJLKftwig2qKWn8acHPHQfpPmDI2AvlXFvXbYf6hCAl # NDFnzbYSlm/EUExiHQwIgqgWvalWzxVzjQEiJc6VaT9Hd/tydBTX/6tPiix6q4XN # Q1/tYLaqT5Fmniye4Iqs5f2MvGQmh2ySvZ180HAKfO+ovHVPulr3qRCyXen/KFSJ # 8NWKcXZl2szwcqMj+sAngkSumScbqyQeJsG33irr9p6xeZmBo1aGqwpFyd/EjaDn # mPv7pp1yr8THwcFqcdnGE4AJxLafzYeHJLtPo0m5d2aR8XKc6UsCUqc3fpNTrDsd # CEkPlM05et3/JWOZJyw9P2un8WbDQc1PtkCbISFA0LcTJM3cHXg65J6t5TRxktcm # a+Q4c6umAU+9Pzt4rUyt+8SVe+0KXzM5h0F4ejjpnOHdI/0dKNPH+ejxmF/7K9h+ # 8kaddSweJywm228Vex4Ziza4k9Tm8heZWcpw8De/mADfIBZPJ/tgZxahZrrdVcA6 # KYawmKAr7ZVBtzrVFZgxtGIJDwq9gdkT/r+k0fNX2bwE+oLeMt8EifAAzV3C+dAj # fwAL5HYCJtnwZXZCpimHCUcr5n8apIUP/JiW9lVUKx+A+sDyDivl1vupL0QVSucT # Dh3bNzgaoSv27dZ8/DCCBrAwggSYoAMCAQICEAitQLJg0pxMn17Nqb2TrtkwDQYJ # KoZIhvcNAQEMBQAwYjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IElu # YzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQg # VHJ1c3RlZCBSb290IEc0MB4XDTIxMDQyOTAwMDAwMFoXDTM2MDQyODIzNTk1OVow # aTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMUEwPwYDVQQD # EzhEaWdpQ2VydCBUcnVzdGVkIEc0IENvZGUgU2lnbmluZyBSU0E0MDk2IFNIQTM4 # NCAyMDIxIENBMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANW0L0LQ # KK14t13VOVkbsYhC9TOM6z2Bl3DFu8SFJjCfpI5o2Fz16zQkB+FLT9N4Q/QX1x7a # +dLVZxpSTw6hV/yImcGRzIEDPk1wJGSzjeIIfTR9TIBXEmtDmpnyxTsf8u/LR1oT # pkyzASAl8xDTi7L7CPCK4J0JwGWn+piASTWHPVEZ6JAheEUuoZ8s4RjCGszF7pNJ # cEIyj/vG6hzzZWiRok1MghFIUmjeEL0UV13oGBNlxX+yT4UsSKRWhDXW+S6cqgAV # 0Tf+GgaUwnzI6hsy5srC9KejAw50pa85tqtgEuPo1rn3MeHcreQYoNjBI0dHs6EP # bqOrbZgGgxu3amct0r1EGpIQgY+wOwnXx5syWsL/amBUi0nBk+3htFzgb+sm+YzV # svk4EObqzpH1vtP7b5NhNFy8k0UogzYqZihfsHPOiyYlBrKD1Fz2FRlM7WLgXjPy # 6OjsCqewAyuRsjZ5vvetCB51pmXMu+NIUPN3kRr+21CiRshhWJj1fAIWPIMorTmG # 7NS3DVPQ+EfmdTCN7DCTdhSmW0tddGFNPxKRdt6/WMtyEClB8NXFbSZ2aBFBE1ia # 3CYrAfSJTVnbeM+BSj5AR1/JgVBzhRAjIVlgimRUwcwhGug4GXxmHM14OEUwmU// # Y09Mu6oNCFNBfFg9R7P6tuyMMgkCzGw8DFYRAgMBAAGjggFZMIIBVTASBgNVHRMB # Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBRoN+Drtjv4XxGG+/5hewiIZfROQjAfBgNV # HSMEGDAWgBTs1+OC0nFdZEzfLmc/57qYrhwPTzAOBgNVHQ8BAf8EBAMCAYYwEwYD # VR0lBAwwCgYIKwYBBQUHAwMwdwYIKwYBBQUHAQEEazBpMCQGCCsGAQUFBzABhhho # dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQQYIKwYBBQUHMAKGNWh0dHA6Ly9jYWNl # cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRSb290RzQuY3J0MEMGA1Ud # HwQ8MDowOKA2oDSGMmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRy # dXN0ZWRSb290RzQuY3JsMBwGA1UdIAQVMBMwBwYFZ4EMAQMwCAYGZ4EMAQQBMA0G # CSqGSIb3DQEBDAUAA4ICAQA6I0Q9jQh27o+8OpnTVuACGqX4SDTzLLbmdGb3lHKx # AMqvbDAnExKekESfS/2eo3wm1Te8Ol1IbZXVP0n0J7sWgUVQ/Zy9toXgdn43ccsi # 91qqkM/1k2rj6yDR1VB5iJqKisG2vaFIGH7c2IAaERkYzWGZgVb2yeN258TkG19D # +D6U/3Y5PZ7Umc9K3SjrXyahlVhI1Rr+1yc//ZDRdobdHLBgXPMNqO7giaG9OeE4 # Ttpuuzad++UhU1rDyulq8aI+20O4M8hPOBSSmfXdzlRt2V0CFB9AM3wD4pWywiF1 # c1LLRtjENByipUuNzW92NyyFPxrOJukYvpAHsEN/lYgggnDwzMrv/Sk1XB+JOFX3 # N4qLCaHLC+kxGv8uGVw5ceG+nKcKBtYmZ7eS5k5f3nqsSc8upHSSrds8pJyGH+PB # VhsrI/+PteqIe3Br5qC6/To/RabE6BaRUotBwEiES5ZNq0RA443wFSjO7fEYVgcq # LxDEDAhkPDOPriiMPMuPiAsNvzv0zh57ju+168u38HcT5ucoP6wSrqUvImxB+YJc # FWbMbA7KxYbD9iYzDAdLoNMHAmpqQDBISzSoUSC7rRuFCOJZDW3KBVAr6kocnqX9 # oKcfBnTn8tZSkP2vhUgh+Vc7tJwD7YZF9LRhbr9o4iZghurIr6n+lB3nYxs6hlZ4 # TjCCBrwwggSkoAMCAQICEAuuZrxaun+Vh8b56QTjMwQwDQYJKoZIhvcNAQELBQAw # YzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQD # EzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJTQTQwOTYgU0hBMjU2IFRpbWVTdGFtcGlu # ZyBDQTAeFw0yNDA5MjYwMDAwMDBaFw0zNTExMjUyMzU5NTlaMEIxCzAJBgNVBAYT # AlVTMREwDwYDVQQKEwhEaWdpQ2VydDEgMB4GA1UEAxMXRGlnaUNlcnQgVGltZXN0 # YW1wIDIwMjQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC+anOf9pUh # q5Ywultt5lmjtej9kR8YxIg7apnjpcH9CjAgQxK+CMR0Rne/i+utMeV5bUlYYSuu # M4vQngvQepVHVzNLO9RDnEXvPghCaft0djvKKO+hDu6ObS7rJcXa/UKvNminKQPT # v/1+kBPgHGlP28mgmoCw/xi6FG9+Un1h4eN6zh926SxMe6We2r1Z6VFZj75MU/HN # mtsgtFjKfITLutLWUdAoWle+jYZ49+wxGE1/UXjWfISDmHuI5e/6+NfQrxGFSKx+ # rDdNMsePW6FLrphfYtk/FLihp/feun0eV+pIF496OVh4R1TvjQYpAztJpVIfdNsE # vxHofBf1BWkadc+Up0Th8EifkEEWdX4rA/FE1Q0rqViTbLVZIqi6viEk3RIySho1 # XyHLIAOJfXG5PEppc3XYeBH7xa6VTZ3rOHNeiYnY+V4j1XbJ+Z9dI8ZhqcaDHOoj # 5KGg4YuiYx3eYm33aebsyF6eD9MF5IDbPgjvwmnAalNEeJPvIeoGJXaeBQjIK13S # lnzODdLtuThALhGtyconcVuPI8AaiCaiJnfdzUcb3dWnqUnjXkRFwLtsVAxFvGqs # xUA2Jq/WTjbnNjIUzIs3ITVC6VBKAOlb2u29Vwgfta8b2ypi6n2PzP0nVepsFk8n # lcuWfyZLzBaZ0MucEdeBiXL+nUOGhCjl+QIDAQABo4IBizCCAYcwDgYDVR0PAQH/ # BAQDAgeAMAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwIAYD # VR0gBBkwFzAIBgZngQwBBAIwCwYJYIZIAYb9bAcBMB8GA1UdIwQYMBaAFLoW2W1N # hS9zKXaaL3WMaiCPnshvMB0GA1UdDgQWBBSfVywDdw4oFZBmpWNe7k+SH3agWzBa # BgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNl # cnRUcnVzdGVkRzRSU0E0MDk2U0hBMjU2VGltZVN0YW1waW5nQ0EuY3JsMIGQBggr # BgEFBQcBAQSBgzCBgDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu # Y29tMFgGCCsGAQUFBzAChkxodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln # aUNlcnRUcnVzdGVkRzRSU0E0MDk2U0hBMjU2VGltZVN0YW1waW5nQ0EuY3J0MA0G # CSqGSIb3DQEBCwUAA4ICAQA9rR4fdplb4ziEEkfZQ5H2EdubTggd0ShPz9Pce4FL # Jl6reNKLkZd5Y/vEIqFWKt4oKcKz7wZmXa5VgW9B76k9NJxUl4JlKwyjUkKhk3aY # x7D8vi2mpU1tKlY71AYXB8wTLrQeh83pXnWwwsxc1Mt+FWqz57yFq6laICtKjPIC # YYf/qgxACHTvypGHrC8k1TqCeHk6u4I/VBQC9VK7iSpU5wlWjNlHlFFv/M93748Y # TeoXU/fFa9hWJQkuzG2+B7+bMDvmgF8VlJt1qQcl7YFUMYgZU1WM6nyw23vT6QSg # wX5Pq2m0xQ2V6FJHu8z4LXe/371k5QrN9FQBhLLISZi2yemW0P8ZZfx4zvSWzVXp # Ab9k4Hpvpi6bUe8iK6WonUSV6yPlMwerwJZP/Gtbu3CKldMnn+LmmRTkTXpFIEB0 # 6nXZrDwhCGED+8RsWQSIXZpuG4WLFQOhtloDRWGoCwwc6ZpPddOFkM2LlTbMcqFS # zm4cd0boGhBq7vkqI1uHRz6Fq1IX7TaRQuR+0BGOzISkcqwXu7nMpFu3mgrlgbAW # +BzikRVQ3K2YHcGkiKjA4gi4OA/kz1YCsdhIBHXqBzR0/Zd2QwQ/l4Gxftt/8wY3 # grcc/nS//TVkej9nmUYu83BDtccHHXKibMs/yXHhDXNkoPIdynhVAku7aRZOwqw6 # pDCCB1YwggU+oAMCAQICEAH2OVfKsi5/gxE0YVpt8UAwDQYJKoZIhvcNAQELBQAw # aTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMUEwPwYDVQQD # EzhEaWdpQ2VydCBUcnVzdGVkIEc0IENvZGUgU2lnbmluZyBSU0E0MDk2IFNIQTM4 # NCAyMDIxIENBMTAeFw0yNDAyMjgwMDAwMDBaFw0yNTA1MjQyMzU5NTlaMF4xCzAJ # BgNVBAYTAlVTMRcwFQYDVQQIEw5Ob3J0aCBDYXJvbGluYTEUMBIGA1UEBxMLTW9y # cmlzdmlsbGUxDzANBgNVBAoTBkxlbm92bzEPMA0GA1UEAxMGTGVub3ZvMIICIjAN # BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvQG1vNNHS34jqP4ExAKEkPeGrbyn # 0EAseZ0nI/OPSzjBWXtKkumwgsi6rqgRD7wCrxncDH5TtuW5pDbiYMffX3mwbM3Q # uzGPgyBcnd0eWr57yHKbPQ8j53QviIP6uX2C6H0HZujjVgWfjPwPkOfF8fqgl9dh # ZX8wVJvwJDUGLUzQMkyiIPV1/JmKUHnVi1ClEJBR4DSmv+6obQ01rlNaLK64RdeJ # iAnZmvnw+qo1N0bwG733A+OLEVhjMSvZ47/AhFvmLYPJ95mw4wa71a4E+2dGbR4i # N/3fX3Hr3+F4WCk1hy3F7RXTm5yr+IcNRwWtJ527jeRqxruWaWvJK8SPCwUcPWhg # qdzlGGzakCtwonIac0XC86ChEcau+3JYXuVD/fvXt0Gv9jXYEXN53P7QOhxyTpNz # p/ghLX3KSrK6pn4+niqb+cXPeyjbd+T29HjCQG9PGBwNRum7c8N5IcN68VHi8gdE # ecWjSmdPO9jguXQrHRuFkmEzf1wWHw5s9BR4TMwHT2O5D6PJZPcjAZakBoqehKPE # VAH0gMa2RICeTf1/ikuAOvFU9Q/in9F9jN0shDDz/SEoRU7OpD4C88gRGB8y0p0a # +EKCGFRT/drApdumRPmMQmMLREZDVOxNuN9irY3w5fql74cthz5bX6NkvvFpcJds # SD6M/bcEk6FKcyECAwEAAaOCAgMwggH/MB8GA1UdIwQYMBaAFGg34Ou2O/hfEYb7 # /mF7CIhl9E5CMB0GA1UdDgQWBBRagjd2MdLvV1XeyO0tkBGfG8YjWDA+BgNVHSAE # NzA1MDMGBmeBDAEEATApMCcGCCsGAQUFBwIBFhtodHRwOi8vd3d3LmRpZ2ljZXJ0 # LmNvbS9DUFMwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMIG1 # BgNVHR8Ega0wgaowU6BRoE+GTWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdp # Q2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEuY3Js # MFOgUaBPhk1odHRwOi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVk # RzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEzODQyMDIxQ0ExLmNybDCBlAYIKwYBBQUH # AQEEgYcwgYQwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBc # BggrBgEFBQcwAoZQaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0 # VHJ1c3RlZEc0Q29kZVNpZ25pbmdSU0E0MDk2U0hBMzg0MjAyMUNBMS5jcnQwCQYD # VR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAgEAvEuiwGr7vMBryz2z53c2L9ZEaZGT # YQfZrOy9/lpeYpHJ0ongWlyYmeGgl1vxHQP8+0xHctTtTC3ZaBVk6n/d8/53JYi2 # gmOJF6RHYnlGK+/r+Js3mm3Xu57fZkrqQciV0flPqjNlMZ5VYWtfhgbEeqM1Fnsa # rk9owJzhpWeBAVKXUG3dnxaNWJrH5ykCCphW0lCpZ18qezRTEB6PoNas9Y/wJuCB # 1jwuse5N9kJjbJxG01dblVm4vbQhtH2+fS6hB6+c/8rBR/vh0hubJkFCc0n0YoBe # JRtsYxiWk2hTDklF/rRyic+WDg+nsMUKTliBnbLWLyQYYk11uLBSXAabv/Aj8ywC # DiPsf/13l+CdBhtiDKEx+Jofkn4LTGblVSSiVbpgyuKVooUwNnH26nBKlzgAfS25 # rpLAHAxjEW9rq81jQyXBYxSuETciZjv/J2DKkK22dNOURX4RpvPrF4wUkhAj6gmj # bRzZmhEZwWBlW6L1ljuYFXLqlx549BTiTEGf3SsBphOLkTS/I3FbQXrFbetXg42A # znsVcor/ejFU2EL7wMBjC2lS4RZgfRixOzSiGBCbDm+yhOAPD5vAZWYsOiyzjtSG # CDOpXjJdTqKkcWgU9NU85+p/2rCYzHCl09KuGDnOoqLmpJAI+HyzCK79s4eAlsjo # uUwbomBag565bEMxggZCMIIGPgIBATB9MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQK # Ew5EaWdpQ2VydCwgSW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBD # b2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEzODQgMjAyMSBDQTECEAH2OVfKsi5/gxE0 # YVpt8UAwCQYFKw4DAhoFAKB4MBgGCisGAQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJ # KoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQB # gjcCARUwIwYJKoZIhvcNAQkEMRYEFHy5MhENByP38ZXYk6Njr64V855IMA0GCSqG # SIb3DQEBAQUABIICACYjeNhvEG15ZfWhNUiBTnzQAXJ8fyIrCz5IJtdgVKOjNFR9 # fAn5xDrJlCs9dcTdepnRmrjeNoE7d6YI7Epgj8zhOkmmZlHLfxRGWPNp7RuMvi4I # 8rTeD3szfyZTr4/Bb8RqffmqHnw+oUPuiOfxmpK88OyG+ZaZZM3vvZKglIvBLH6T # yeytA9xRbtYcGSGc6rplSnYRfRoDUuAjbS0B2uVJ+Vo94p3xpO1OvaP1+u+K+8iZ # kbOlN8/SKCVh1keq0fpEtff/O7SHLpKrIiDWzfa049VdC+/WRnVjLSSsl5iuYSRb # u/62O74uxoNaTMdno0lUgt/UYvIgCF2g+PE7VkVVljQM0r4r6BPVV4E0nMgccg9S # P2kuxWLxiGcs2Kf/K3z/3zHT7QcrONg3uASNQLgYjAKUcpLsl4VPP6V0WvyL6mUN # JpHPy7wF/AQL5ExssOC59roXHrXZ0NovY/fFYgvuSuOgWgGIiTAveE9Bi+tlpNPD # 2VeKCwe0Mn1mj2gwifYILq3Nsj3+eHmSm0OGHdducx2zYq8jLrNVhvs4YRP0kJol # uhQ1qyhQD1DZ3klXLoDjMKpQ+pSbopESxk7LUwK3v1P9B0YWsZDYD3h8HXqQjLql # hjFClhBzrH/Qd2X9EdBS9kyl7Dnz4l7fFz0lvSbc/43yHNYeFa8oi4gmQoijoYID # IDCCAxwGCSqGSIb3DQEJBjGCAw0wggMJAgEBMHcwYzELMAkGA1UEBhMCVVMxFzAV # BgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2VydCBUcnVzdGVk # IEc0IFJTQTQwOTYgU0hBMjU2IFRpbWVTdGFtcGluZyBDQQIQC65mvFq6f5WHxvnp # BOMzBDANBglghkgBZQMEAgEFAKBpMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEw # HAYJKoZIhvcNAQkFMQ8XDTI0MTIxMTE0MjIzNFowLwYJKoZIhvcNAQkEMSIEIHMP # hAYHcN313MM2vJS9exEDSmcP5bWGUWGJw9RI9bK8MA0GCSqGSIb3DQEBAQUABIIC # AKU/sgkGRMtsV5CDnATsJDuSAkm/RJFCwPxspu+2TNv8ru6BDUWlIwvdIl2eDZ6A # JfHWkcXTXPaqX+MecLczDtv49N2cxeQ/EcTWRMVKCOB3a2L7u0fR793pbCnvSUtv # KOM9wnNKIgcA5ARumxk+0OXAeB7Y6zGL7j0iUZtIwf0jabiJvkqLhpy74nrWLhkS # V25+B1i+5fjv3SpaSJ6tgkUsSwN8ZDI1q4FJjH/Ki+a2jXwj/ABzkj/HSWz6079s # BeeC8MtH3BOMD9x4gv7a787K7zlmrdK9iypTxI8bycv3P4OUPRt+Xd9ad6xOauG1 # B3UgCO6haf/o7o1I2IKWWxzOiNJB5J4jHO1u8RMR+hNZDMkvHY8IePy8BF826oak # TBWxnfNDxZRKRAONi1n93N/+PN44JybLHn7GJbu6/MVj6XnwzsCxxqkjpBoACuAa # RVavF4p0+p9DM1+1+dxRFleiGgW7FL6Q2gYWjbW7l6Y2dGW77KetELQCxL0S2FNf # IKKS6n9KQqJBiTFziYCneY6JBxIKGMVcCU+JxDt6bGGizhn93AM+h2Yb5DnBK24r # yopQSnQTAO5flERXD4ZO6kCmBSPaKOiBFB0T2bdjeRJ3yTAFdh0CJ4M0IfxcvOfx # TM2ca83VQjmI2ngL4Wp6drk6QKqNmzN87er8TVOCTsbR # SIG # End signature block |