Get-SystemInfo.ps1
<#PSScriptInfo
.VERSION 1.0.0 .GUID 21f7b5b3-f9bd-4611-a846-9372c3a89275 .AUTHOR asheroto .COMPANYNAME asheroto .TAGS PowerShell Windows get system info information hardware firmware details disk memory network pending reboot usage shutdown event last .PROJECTURI https://github.com/asheroto/Get-SystemInfo .RELEASENOTES [Version 1.0.0] - Initial Release. #> <# .SYNOPSIS Gathers detailed system diagnostics, including configuration, hardware, network, and OS status. .DESCRIPTION This script provides a complete overview of system information, hardware specifications, network details, and pending reboot status. It is useful for IT professionals who need to quickly retrieve in-depth diagnostics on Windows systems. .EXAMPLE Get-SystemInfo Runs the script to display detailed system information. .PARAMETER CheckForUpdate Checks if an update is available for this script. .PARAMETER UpdateSelf Updates the script to the latest version from PSGallery. .PARAMETER Version Displays the current version of the script. .PARAMETER Help Shows detailed help information for the script. .NOTES Version : 1.0.0 Created by : asheroto .LINK Project Site: https://github.com/asheroto/Get-SystemInfo #> [CmdletBinding()] param ( [switch]$CheckForUpdate, [switch]$UpdateSelf, [switch]$Version, [switch]$Help ) # Script information $CurrentVersion = '1.0.0' $RepoOwner = 'asheroto' $RepoName = 'Get-SystemInfo' $PowerShellGalleryName = 'Get-SystemInfo' # Preferences $ProgressPreference = 'SilentlyContinue' # Suppress progress bar (makes downloading super fast) $ConfirmPreference = 'None' # Suppress confirmation prompts # Display version if -Version is specified if ($Version.IsPresent) { $CurrentVersion exit 0 } # Display full help if -Help is specified if ($Help) { Get-Help -Name $MyInvocation.MyCommand.Source -Full exit 0 } # Display $PSVersionTable and Get-Host if -Verbose is specified if ($PSBoundParameters.ContainsKey('Verbose') -and $PSBoundParameters['Verbose']) { $PSVersionTable Get-Host } # Set debug preferences if -Debug is specified if ($PSBoundParameters.ContainsKey('Debug') -and $PSBoundParameters['Debug']) { $DebugPreference = 'Continue' $ConfirmPreference = 'None' } function Get-GitHubRelease { <# .SYNOPSIS Fetches the latest release information of a GitHub repository. .DESCRIPTION This function uses the GitHub API to get information about the latest release of a specified repository, including its version and the date it was published. .PARAMETER Owner The GitHub username of the repository owner. .PARAMETER Repo The name of the repository. .EXAMPLE Get-GitHubRelease -Owner "asheroto" -Repo "Get-SystemInfo" This command retrieves the latest release version and published datetime of the Get-SystemInfo repository owned by asheroto. #> [CmdletBinding()] param ( [string]$Owner, [string]$Repo ) try { $url = "https://api.github.com/repos/$Owner/$Repo/releases/latest" $response = Invoke-RestMethod -Uri $url -ErrorAction Stop $latestVersion = $response.tag_name $publishedAt = $response.published_at # Convert UTC time string to local time $UtcDateTime = [DateTime]::Parse($publishedAt, [System.Globalization.CultureInfo]::InvariantCulture, [System.Globalization.DateTimeStyles]::RoundtripKind) $PublishedLocalDateTime = $UtcDateTime.ToLocalTime() [PSCustomObject]@{ LatestVersion = $latestVersion PublishedDateTime = $PublishedLocalDateTime } } catch { Write-Error "Unable to check for updates.`nError: $_" exit 1 } } function CheckForUpdate { param ( [string]$RepoOwner, [string]$RepoName, [version]$CurrentVersion, [string]$PowerShellGalleryName ) $Data = Get-GitHubRelease -Owner $RepoOwner -Repo $RepoName Write-Output "" Write-Output ("Repository: {0,-40}" -f "https://github.com/$RepoOwner/$RepoName") Write-Output ("Current Version: {0,-40}" -f $CurrentVersion) Write-Output ("Latest Version: {0,-40}" -f $Data.LatestVersion) Write-Output ("Published at: {0,-40}" -f $Data.PublishedDateTime) if ($Data.LatestVersion -gt $CurrentVersion) { Write-Output ("Status: {0,-40}" -f "A new version is available.") Write-Output "`nOptions to update:" Write-Output "- Download latest release: https://github.com/$RepoOwner/$RepoName/releases" if ($PowerShellGalleryName) { Write-Output "- Run: $RepoName -UpdateSelf" Write-Output "- Run: Install-Script $PowerShellGalleryName -Force" } } else { Write-Output ("Status: {0,-40}" -f "Up to date.") } exit 0 } function UpdateSelf { try { # Get PSGallery version of script $psGalleryScriptVersion = (Find-Script -Name $PowerShellGalleryName).Version # If the current version is less than the PSGallery version, update the script if ($CurrentVersion -lt $psGalleryScriptVersion) { Write-Output "Updating script to version $psGalleryScriptVersion..." # Install NuGet PackageProvider if not already installed if (-not (Get-PackageProvider -Name NuGet -ErrorAction SilentlyContinue)) { Install-PackageProvider -Name "NuGet" -Force } # Trust the PSGallery if not already trusted $psRepoInstallationPolicy = (Get-PSRepository -Name 'PSGallery').InstallationPolicy if ($psRepoInstallationPolicy -ne 'Trusted') { Set-PSRepository -Name 'PSGallery' -InstallationPolicy Trusted | Out-Null } # Update the script Install-Script $PowerShellGalleryName -Force # If PSGallery was not trusted, reset it to its original state if ($psRepoInstallationPolicy -ne 'Trusted') { Set-PSRepository -Name 'PSGallery' -InstallationPolicy $psRepoInstallationPolicy | Out-Null } Write-Output "Script updated to version $psGalleryScriptVersion." exit 0 } else { Write-Output "Script is already up to date." exit 0 } } catch { Write-Output "An error occurred: $_" exit 1 } } # ============================================================================ # # Initial checks # ============================================================================ # # First heading Write-Output "Get-SystemInfo $CurrentVersion" # Check for updates if -CheckForUpdate is specified if ($CheckForUpdate) { CheckForUpdate -RepoOwner $RepoOwner -RepoName $RepoName -CurrentVersion $CurrentVersion -PowerShellGalleryName $PowerShellGalleryName } # Update the script if -UpdateSelf is specified if ($UpdateSelf) { UpdateSelf } # Heading Write-Output "To check for updates, run Get-SystemInfo -CheckForUpdate" function Get-SystemInfo { function Write-Header { param ( [string]$Header, [string]$Value ) Write-Host "${Header}: " -ForegroundColor Green -NoNewline Write-Output $Value } # System Information Write-Section "System Information" $hostname = $env:COMPUTERNAME $os = Get-CimInstance -ClassName Win32_OperatingSystem $cs = Get-CimInstance -ClassName Win32_ComputerSystem $bios = Get-CimInstance -ClassName Win32_BIOS Write-Header "Hostname" $hostname # Hardware and Firmware Details Write-Section "Hardware and Firmware Details" Write-Header "Make/Model" "$($cs.Manufacturer) $($cs.Model)" Write-Header "Serial Number" $bios.SerialNumber Write-Header "Firmware Manufacturer" $bios.Manufacturer Write-Header "Firmware Version" $bios.SMBIOSBIOSVersion # OS Details Write-Section "OS Details" $uptime = (Get-Date) - $os.LastBootUpTime $displayVersion = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" -Name DisplayVersion).DisplayVersion Write-Header "OS Version" $os.Caption Write-Header "OS Display Version" $displayVersion Write-Header "OS Architecture" $os.OSArchitecture Write-Header "OS Install Date" $os.InstallDate Write-Header "OS Last Boot Time" $os.LastBootUpTime Write-Header "System Uptime" "$([math]::Floor($uptime.TotalDays)) days, $($uptime.Hours) hours, $($uptime.Minutes) minutes" # CPU Details Write-Section "CPU Details" $cpu = Get-CimInstance -ClassName Win32_Processor $cpuSpeedGHz = [math]::Round($cpu.MaxClockSpeed / 1000, 2) Write-Header "CPU Make/Model" $cpu.Name Write-Header "CPU Speed" "$cpuSpeedGHz GHz" Write-Header "CPU Usage" "$(($cpu | Measure-Object -Property LoadPercentage -Average).Average)%" Write-Header "CPU Cores" $cpu.NumberOfCores Write-Header "CPU Threads (Logical Processors)" $cpu.NumberOfLogicalProcessors # Memory details Write-Section "Memory Details" # Total memory summary $totalRAM = [math]::Round($cs.TotalPhysicalMemory / 1GB, 2) $freeMem = [math]::Round($os.FreePhysicalMemory / 1MB, 2) $usedMem = $totalRAM - $freeMem $memUsage = [math]::Round(($usedMem / $totalRAM) * 100, 2) Write-Header "Total RAM (GB)" $totalRAM Write-Header "Used RAM (GB)" $usedMem Write-Header "Free RAM (GB)" $freeMem Write-Header "Memory Usage (%)" $memUsage # Collect RAM DIMM information for table display $dimmDetails = Get-CimInstance -ClassName Win32_PhysicalMemory | ForEach-Object { # Remove "Controller" from DeviceLocator for DIMM Number and Controller $dimmSlot = $_.DeviceLocator -replace "Controller", "" $controller = if ($dimmSlot -match "(\d+)-") { $matches[1] } else { "N/A" } $slot = if ($dimmSlot -match "-(DIMM\w+)") { $matches[1] } else { $dimmSlot } # Determine size and model details $dimmSizeGB = [math]::Round($_.Capacity / 1GB, 2) $makeModel = if ($_.Model) { $_.Model } elseif ($_.PartNumber) { $_.PartNumber } else { "Unknown" } # Output each DIMM detail as a custom object [PSCustomObject]@{ "DIMM Number" = $dimmSlot "Controller" = $controller "Slot" = $slot "RAM (GB)" = $dimmSizeGB "Model/Part" = $makeModel } } # Display the table $dimmDetails | Format-Table -AutoSize # Disk usage in table format Write-Section "Disk Usage" $diskInfo = Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DriveType=3" | ForEach-Object { $totalSizeGB = [math]::Round($_.Size / 1GB, 2) $freeSpaceGB = [math]::Round($_.FreeSpace / 1GB, 2) $usedSpaceGB = $totalSizeGB - $freeSpaceGB $driveUsage = [math]::Round(($usedSpaceGB / $totalSizeGB) * 100, 2) # Retrieve associated physical disk information $physicalDisk = Get-CimInstance -Query "ASSOCIATORS OF {Win32_LogicalDisk.DeviceID='$($_.DeviceID)'} WHERE AssocClass=Win32_LogicalDiskToPartition" | ForEach-Object { Get-CimInstance -Query "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='$($_.DeviceID)'} WHERE AssocClass=Win32_DiskDriveToDiskPartition" } $makeModel = if ($physicalDisk.Model) { $physicalDisk.Model } else { "Unknown" } # Create a custom object for each disk [PSCustomObject]@{ Drive = $_.DeviceID "Volume Label" = $_.VolumeName "Total Size (GB)" = $totalSizeGB "Free Space (GB)" = $freeSpaceGB "Used Space (GB)" = $usedSpaceGB "Usage (%)" = $driveUsage "Make/Model" = $makeModel } } # Display the table $diskInfo | Format-Table -AutoSize # Network Adapter Details Write-Section "Network Adapter Details" # Retrieve network adapter information and format it as a table $networkInfo = Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration | Where-Object { $_.IPEnabled -eq $true } | ForEach-Object { $adapterName = $_.Description $macAddress = $_.MACAddress $ipAddresses = $_.IPAddress -join ", " $subnetMasks = $_.IPSubnet -join ", " $defaultGateway = if ($_.DefaultIPGateway) { $_.DefaultIPGateway -join ", " } else { "N/A" } # Create a custom object for each network adapter [PSCustomObject]@{ "Adapter" = $adapterName "MAC Address" = $macAddress "IP Address(es)" = $ipAddresses "Subnet Mask(s)" = $subnetMasks "Default Gateway" = $defaultGateway } } # Display the table $networkInfo | Format-Table -AutoSize } function Get-LastShutdownEvents { Write-Section "Last Shutdown Events" try { $shutdownEvents = Get-WinEvent -FilterHashtable @{LogName = 'System'; ID = 1074 } -ErrorAction SilentlyContinue | Select-Object -Property TimeCreated, Message | Sort-Object -Property TimeCreated -Descending | Select-Object -First 5 if ($shutdownEvents) { $shutdownEvents | ForEach-Object { Write-Output "$($_.TimeCreated): $($_.Message)" } } else { Write-Output "No shutdown events found." } } catch { Write-Output "An error occurred while retrieving shutdown events: $_" } } function Get-PendingRebootReasons { Write-Section "Pending Reboot Check" $PendingRebootReasons = @() if (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired") { $PendingRebootReasons += "Windows Update" } if (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending") { $PendingRebootReasons += "Component-Based Servicing" } if ((Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager").PendingFileRenameOperations) { $PendingRebootReasons += "Pending File Rename Operations" } if (Test-Path "HKLM:\SOFTWARE\Microsoft\Cluster\PendingReboot") { $PendingRebootReasons += "Cluster Pending Reboot" } if ($PendingRebootReasons.Count -gt 0) { Write-Output "Pending reboot reasons:" $PendingRebootReasons | ForEach-Object { Write-Output "- $_" } } else { Write-Output "No pending reboot." } } function Write-Section($text) { Write-Output "" Write-Output ("#" * ($text.Length + 4)) Write-Output "# $text #" Write-Output ("#" * ($text.Length + 4)) Write-Output "" } # Main execution Get-SystemInfo Get-PendingRebootReasons Get-LastShutdownEvents # SIG # Begin signature block # MIIhEgYJKoZIhvcNAQcCoIIhAzCCIP8CAQExDzANBglghkgBZQMEAgIFADCBiQYK # KwYBBAGCNwIBBKB7MHkwNAYKKwYBBAGCNwIBHjAmAgMBAAAEEB/MO2BZSwhOtyTS # xil+81ECAQACAQACAQACAQACAQAwQTANBglghkgBZQMEAgIFAAQwx3SMsWfWgXtE # 1XonxaIhOT3JtBQZN/hqzFsV9qtAJ+PpSWAgnT4ViZSrquKRSuw5oIIHZDCCA1kw # ggLfoAMCAQICEA+4p0C5FY0DUUO8WdnwQCkwCgYIKoZIzj0EAwMwYTELMAkGA1UE # BhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2lj # ZXJ0LmNvbTEgMB4GA1UEAxMXRGlnaUNlcnQgR2xvYmFsIFJvb3QgRzMwHhcNMjEw # NDI5MDAwMDAwWhcNMzYwNDI4MjM1OTU5WjBkMQswCQYDVQQGEwJVUzEXMBUGA1UE # ChMORGlnaUNlcnQsIEluYy4xPDA6BgNVBAMTM0RpZ2lDZXJ0IEdsb2JhbCBHMyBD # b2RlIFNpZ25pbmcgRUNDIFNIQTM4NCAyMDIxIENBMTB2MBAGByqGSM49AgEGBSuB # BAAiA2IABLu0rCelSA2iU1+PLoE+L1N2uAiUopqqiouYtbHw/CoVu7mzpSIv/WrA # veJVaGBrlzTBZlNxI/wa1cogDwJAoqNKWkajkVMrlfID6aum04d2L+dkn541UfzD # YzV4duT4d6OCAVcwggFTMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFJtf # sDa6nQauGSe9wKAiwIuLOHftMB8GA1UdIwQYMBaAFLPbSKT5ocXYrjZBzBFjaWIp # vEvGMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB2BggrBgEF # BQcBAQRqMGgwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBA # BggrBgEFBQcwAoY0aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0 # R2xvYmFsUm9vdEczLmNydDBCBgNVHR8EOzA5MDegNaAzhjFodHRwOi8vY3JsMy5k # aWdpY2VydC5jb20vRGlnaUNlcnRHbG9iYWxSb290RzMuY3JsMBwGA1UdIAQVMBMw # BwYFZ4EMAQMwCAYGZ4EMAQQBMAoGCCqGSM49BAMDA2gAMGUCMHi9SZVlcQHQRldo # ZQ5oqdw2CMHu/dSO20BlPw3/k6/CrmOGo37LtJFaeOwHA2cHfAIxAOefH/EHW6w0 # xji8taVQzubqOH4+eZDkpFurAg3oB/xWplqK3bNQst3y+mZ0ntAWYzCCBAMwggOJ # oAMCAQICEAExw+sKUABDj0yZt5afTZQwCgYIKoZIzj0EAwMwZDELMAkGA1UEBhMC # VVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTwwOgYDVQQDEzNEaWdpQ2VydCBH # bG9iYWwgRzMgQ29kZSBTaWduaW5nIEVDQyBTSEEzODQgMjAyMSBDQTEwHhcNMjQw # MzA3MDAwMDAwWhcNMjUwMzA4MjM1OTU5WjBvMQswCQYDVQQGEwJVUzERMA8GA1UE # CBMIT2tsYWhvbWExETAPBgNVBAcTCE11c2tvZ2VlMRwwGgYDVQQKExNBc2hlciBT # b2x1dGlvbnMgSW5jMRwwGgYDVQQDExNBc2hlciBTb2x1dGlvbnMgSW5jMHYwEAYH # KoZIzj0CAQYFK4EEACIDYgAExsP0nyCZ1QtY7aXin+tdZVcF0uPHJJjRpjVVgUmb # 3iKJeKapvWBSAbroBouKIP9+Qoz197aNbZCSOBQsWX53SUyTu1Trvwku7ksL+eQh # bJvnRJ20UqF566z5KbniyLrAo4IB8zCCAe8wHwYDVR0jBBgwFoAUm1+wNrqdBq4Z # J73AoCLAi4s4d+0wHQYDVR0OBBYEFNdgDYHKEBunNDYgivfxKeS4YX0/MD4GA1Ud # IAQ3MDUwMwYGZ4EMAQQBMCkwJwYIKwYBBQUHAgEWG2h0dHA6Ly93d3cuZGlnaWNl # cnQuY29tL0NQUzAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMw # gasGA1UdHwSBozCBoDBOoEygSoZIaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0Rp # Z2lDZXJ0R2xvYmFsRzNDb2RlU2lnbmluZ0VDQ1NIQTM4NDIwMjFDQTEuY3JsME6g # TKBKhkhodHRwOi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRHbG9iYWxHM0Nv # ZGVTaWduaW5nRUNDU0hBMzg0MjAyMUNBMS5jcmwwgY4GCCsGAQUFBwEBBIGBMH8w # JAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBXBggrBgEFBQcw # AoZLaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0R2xvYmFsRzND # b2RlU2lnbmluZ0VDQ1NIQTM4NDIwMjFDQTEuY3J0MAkGA1UdEwQCMAAwCgYIKoZI # zj0EAwMDaAAwZQIxAJHtFqbIBTSZ6AiYEyHsjjlZ7treTZfTSPiyyr8KAKBPKVXt # B2859Jj8A3c9lEXrLgIwGTu2YV8DhFy9OqIDwkCZfoYH8oMo1LRtYhYZtVzkr3WF # er8mkmAdOyNbW/DI0pZPMYIY8zCCGO8CAQEweDBkMQswCQYDVQQGEwJVUzEXMBUG # A1UEChMORGlnaUNlcnQsIEluYy4xPDA6BgNVBAMTM0RpZ2lDZXJ0IEdsb2JhbCBH # MyBDb2RlIFNpZ25pbmcgRUNDIFNIQTM4NCAyMDIxIENBMQIQATHD6wpQAEOPTJm3 # lp9NlDANBglghkgBZQMEAgIFAKCBjDAQBgorBgEEAYI3AgEMMQIwADAZBgkqhkiG # 9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIB # FTA/BgkqhkiG9w0BCQQxMgQwyoh39mwT3iZqgLHPRwzslWpnOLZRt/UR0vqrkRGM # ZKjHV9gSTdNICQTjeIW7Brn6MAsGByqGSM49AgEFAARmMGQCMB4rVaPZ3mJv0y2r # P6QBk502RLjO6FkmOGx3UnQhAO5tOof1GgltvwFk4jyevPwIHAIwNHJDqMT/1+JW # NkSTGKzX+ylr7PmIPVJmMl+bwiv5l2IE7o1gpZM3aXGHuUQkEnVkoYIXWzCCF1cG # CisGAQQBgjcDAwExghdHMIIXQwYJKoZIhvcNAQcCoIIXNDCCFzACAQMxDzANBglg # hkgBZQMEAgIFADCBiAYLKoZIhvcNAQkQAQSgeQR3MHUCAQEGCWCGSAGG/WwHATBB # MA0GCWCGSAFlAwQCAgUABDAvhHQtpWiIoSCkjXzc23i0YXf/vNg/zXVtRZZpG/ra # h1BCEECHmFT98HxI9r7JXIwCEQDA9sU77cxp5POerE14I/UPGA8yMDI0MTAzMDA1 # MTcyMlqgghMDMIIGvDCCBKSgAwIBAgIQC65mvFq6f5WHxvnpBOMzBDANBgkqhkiG # 9w0BAQsFADBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4x # OzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYgVGlt # ZVN0YW1waW5nIENBMB4XDTI0MDkyNjAwMDAwMFoXDTM1MTEyNTIzNTk1OVowQjEL # MAkGA1UEBhMCVVMxETAPBgNVBAoTCERpZ2lDZXJ0MSAwHgYDVQQDExdEaWdpQ2Vy # dCBUaW1lc3RhbXAgMjAyNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB # AL5qc5/2lSGrljC6W23mWaO16P2RHxjEiDtqmeOlwf0KMCBDEr4IxHRGd7+L660x # 5XltSVhhK64zi9CeC9B6lUdXM0s71EOcRe8+CEJp+3R2O8oo76EO7o5tLuslxdr9 # Qq82aKcpA9O//X6QE+AcaU/byaCagLD/GLoUb35SfWHh43rOH3bpLEx7pZ7avVnp # UVmPvkxT8c2a2yC0WMp8hMu60tZR0ChaV76Nhnj37DEYTX9ReNZ8hIOYe4jl7/r4 # 19CvEYVIrH6sN00yx49boUuumF9i2T8UuKGn9966fR5X6kgXj3o5WHhHVO+NBikD # O0mlUh902wS/Eeh8F/UFaRp1z5SnROHwSJ+QQRZ1fisD8UTVDSupWJNstVkiqLq+ # ISTdEjJKGjVfIcsgA4l9cbk8Smlzddh4EfvFrpVNnes4c16Jidj5XiPVdsn5n10j # xmGpxoMc6iPkoaDhi6JjHd5ibfdp5uzIXp4P0wXkgNs+CO/CacBqU0R4k+8h6gYl # dp4FCMgrXdKWfM4N0u25OEAuEa3JyidxW48jwBqIJqImd93NRxvd1aepSeNeREXA # u2xUDEW8aqzFQDYmr9ZONuc2MhTMizchNULpUEoA6Vva7b1XCB+1rxvbKmLqfY/M # /SdV6mwWTyeVy5Z/JkvMFpnQy5wR14GJcv6dQ4aEKOX5AgMBAAGjggGLMIIBhzAO # BgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEF # BQcDCDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwHwYDVR0jBBgw # FoAUuhbZbU2FL3MpdpovdYxqII+eyG8wHQYDVR0OBBYEFJ9XLAN3DigVkGalY17u # T5IfdqBbMFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNv # bS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5j # cmwwgZAGCCsGAQUFBwEBBIGDMIGAMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5k # aWdpY2VydC5jb20wWAYIKwYBBQUHMAKGTGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0 # LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdD # QS5jcnQwDQYJKoZIhvcNAQELBQADggIBAD2tHh92mVvjOIQSR9lDkfYR25tOCB3R # KE/P09x7gUsmXqt40ouRl3lj+8QioVYq3igpwrPvBmZdrlWBb0HvqT00nFSXgmUr # DKNSQqGTdpjHsPy+LaalTW0qVjvUBhcHzBMutB6HzeledbDCzFzUy34VarPnvIWr # qVogK0qM8gJhh/+qDEAIdO/KkYesLyTVOoJ4eTq7gj9UFAL1UruJKlTnCVaM2UeU # UW/8z3fvjxhN6hdT98Vr2FYlCS7Mbb4Hv5swO+aAXxWUm3WpByXtgVQxiBlTVYzq # fLDbe9PpBKDBfk+rabTFDZXoUke7zPgtd7/fvWTlCs30VAGEsshJmLbJ6ZbQ/xll # /HjO9JbNVekBv2Tgem+mLptR7yIrpaidRJXrI+UzB6vAlk/8a1u7cIqV0yef4uaZ # FORNekUgQHTqddmsPCEIYQP7xGxZBIhdmm4bhYsVA6G2WgNFYagLDBzpmk9104WQ # zYuVNsxyoVLObhx3RugaEGru+SojW4dHPoWrUhftNpFC5H7QEY7MhKRyrBe7ucyk # W7eaCuWBsBb4HOKRFVDcrZgdwaSIqMDiCLg4D+TPVgKx2EgEdeoHNHT9l3ZDBD+X # gbF+23/zBjeCtxz+dL/9NWR6P2eZRi7zcEO1xwcdcqJsyz/JceENc2Sg8h3KeFUC # S7tpFk7CrDqkMIIGrjCCBJagAwIBAgIQBzY3tyRUfNhHrP0oZipeWzANBgkqhkiG # 9w0BAQsFADBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkw # FwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVz # dGVkIFJvb3QgRzQwHhcNMjIwMzIzMDAwMDAwWhcNMzcwMzIyMjM1OTU5WjBjMQsw # CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRp # Z2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYgVGltZVN0YW1waW5nIENB # MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxoY1BkmzwT1ySVFVxyUD # xPKRN6mXUaHW0oPRnkyibaCwzIP5WvYRoUQVQl+kiPNo+n3znIkLf50fng8zH1AT # CyZzlm34V6gCff1DtITaEfFzsbPuK4CEiiIY3+vaPcQXf6sZKz5C3GeO6lE98NZW # 1OcoLevTsbV15x8GZY2UKdPZ7Gnf2ZCHRgB720RBidx8ald68Dd5n12sy+iEZLRS # 8nZH92GDGd1ftFQLIWhuNyG7QKxfst5Kfc71ORJn7w6lY2zkpsUdzTYNXNXmG6jB # ZHRAp8ByxbpOH7G1WE15/tePc5OsLDnipUjW8LAxE6lXKZYnLvWHpo9OdhVVJnCY # Jn+gGkcgQ+NDY4B7dW4nJZCYOjgRs/b2nuY7W+yB3iIU2YIqx5K/oN7jPqJz+ucf # WmyU8lKVEStYdEAoq3NDzt9KoRxrOMUp88qqlnNCaJ+2RrOdOqPVA+C/8KI8ykLc # GEh/FDTP0kyr75s9/g64ZCr6dSgkQe1CvwWcZklSUPRR8zZJTYsg0ixXNXkrqPNF # YLwjjVj33GHek/45wPmyMKVM1+mYSlg+0wOI/rOP015LdhJRk8mMDDtbiiKowSYI # +RQQEgN9XyO7ZONj4KbhPvbCdLI/Hgl27KtdRnXiYKNYCQEoAA6EVO7O6V3IXjAS # vUaetdN2udIOa5kM0jO0zbECAwEAAaOCAV0wggFZMBIGA1UdEwEB/wQIMAYBAf8C # AQAwHQYDVR0OBBYEFLoW2W1NhS9zKXaaL3WMaiCPnshvMB8GA1UdIwQYMBaAFOzX # 44LScV1kTN8uZz/nupiuHA9PMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggr # BgEFBQcDCDB3BggrBgEFBQcBAQRrMGkwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3Nw # LmRpZ2ljZXJ0LmNvbTBBBggrBgEFBQcwAoY1aHR0cDovL2NhY2VydHMuZGlnaWNl # cnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcnQwQwYDVR0fBDwwOjA4oDag # NIYyaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RH # NC5jcmwwIAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJYIZIAYb9bAcBMA0GCSqGSIb3 # DQEBCwUAA4ICAQB9WY7Ak7ZvmKlEIgF+ZtbYIULhsBguEE0TzzBTzr8Y+8dQXeJL # Kftwig2qKWn8acHPHQfpPmDI2AvlXFvXbYf6hCAlNDFnzbYSlm/EUExiHQwIgqgW # valWzxVzjQEiJc6VaT9Hd/tydBTX/6tPiix6q4XNQ1/tYLaqT5Fmniye4Iqs5f2M # vGQmh2ySvZ180HAKfO+ovHVPulr3qRCyXen/KFSJ8NWKcXZl2szwcqMj+sAngkSu # mScbqyQeJsG33irr9p6xeZmBo1aGqwpFyd/EjaDnmPv7pp1yr8THwcFqcdnGE4AJ # xLafzYeHJLtPo0m5d2aR8XKc6UsCUqc3fpNTrDsdCEkPlM05et3/JWOZJyw9P2un # 8WbDQc1PtkCbISFA0LcTJM3cHXg65J6t5TRxktcma+Q4c6umAU+9Pzt4rUyt+8SV # e+0KXzM5h0F4ejjpnOHdI/0dKNPH+ejxmF/7K9h+8kaddSweJywm228Vex4Ziza4 # k9Tm8heZWcpw8De/mADfIBZPJ/tgZxahZrrdVcA6KYawmKAr7ZVBtzrVFZgxtGIJ # Dwq9gdkT/r+k0fNX2bwE+oLeMt8EifAAzV3C+dAjfwAL5HYCJtnwZXZCpimHCUcr # 5n8apIUP/JiW9lVUKx+A+sDyDivl1vupL0QVSucTDh3bNzgaoSv27dZ8/DCCBY0w # ggR1oAMCAQICEA6bGI750C3n79tQ4ghAGFowDQYJKoZIhvcNAQEMBQAwZTELMAkG # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp # Z2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNzdXJlZCBJRCBSb290IENB # MB4XDTIyMDgwMTAwMDAwMFoXDTMxMTEwOTIzNTk1OVowYjELMAkGA1UEBhMCVVMx # FTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNv # bTEhMB8GA1UEAxMYRGlnaUNlcnQgVHJ1c3RlZCBSb290IEc0MIICIjANBgkqhkiG # 9w0BAQEFAAOCAg8AMIICCgKCAgEAv+aQc2jeu+RdSjwwIjBpM+zCpyUuySE98orY # WcLhKac9WKt2ms2uexuEDcQwH/MbpDgW61bGl20dq7J58soR0uRf1gU8Ug9SH8ae # FaV+vp+pVxZZVXKvaJNwwrK6dZlqczKU0RBEEC7fgvMHhOZ0O21x4i0MG+4g1ckg # HWMpLc7sXk7Ik/ghYZs06wXGXuxbGrzryc/NrDRAX7F6Zu53yEioZldXn1RYjgwr # t0+nMNlW7sp7XeOtyU9e5TXnMcvak17cjo+A2raRmECQecN4x7axxLVqGDgDEI3Y # 1DekLgV9iPWCPhCRcKtVgkEy19sEcypukQF8IUzUvK4bA3VdeGbZOjFEmjNAvwjX # WkmkwuapoGfdpCe8oU85tRFYF/ckXEaPZPfBaYh2mHY9WV1CdoeJl2l6SPDgohIb # Zpp0yt5LHucOY67m1O+SkjqePdwA5EUlibaaRBkrfsCUtNJhbesz2cXfSwQAzH0c # lcOP9yGyshG3u3/y1YxwLEFgqrFjGESVGnZifvaAsPvoZKYz0YkH4b235kOkGLim # dwHhD5QMIR2yVCkliWzlDlJRR3S+Jqy2QXXeeqxfjT/JvNNBERJb5RBQ6zHFynIW # IgnffEx1P2PsIV/EIFFrb7GrhotPwtZFX50g/KEexcCPorF+CiaZ9eRpL5gdLfXZ # qbId5RsCAwEAAaOCATowggE2MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOzX # 44LScV1kTN8uZz/nupiuHA9PMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3z # bcgPMA4GA1UdDwEB/wQEAwIBhjB5BggrBgEFBQcBAQRtMGswJAYIKwYBBQUHMAGG # GGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBDBggrBgEFBQcwAoY3aHR0cDovL2Nh # Y2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNydDBF # BgNVHR8EPjA8MDqgOKA2hjRodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNl # cnRBc3N1cmVkSURSb290Q0EuY3JsMBEGA1UdIAQKMAgwBgYEVR0gADANBgkqhkiG # 9w0BAQwFAAOCAQEAcKC/Q1xV5zhfoKN0Gz22Ftf3v1cHvZqsoYcs7IVeqRq7IviH # GmlUIu2kiHdtvRoU9BNKei8ttzjv9P+Aufih9/Jy3iS8UgPITtAq3votVs/59Pes # MHqai7Je1M/RQ0SbQyHrlnKhSLSZy51PpwYDE3cnRNTnf+hZqPC/Lwum6fI0POz3 # A8eHqNJMQBk1RmppVLC4oVaO7KTVPeix3P0c2PR3WlxUjG/voVA9/HYJaISfb8rb # II01YBwCA8sgsKxYoA5AY8WYIsGyWfVVa88nq2x2zm8jLfR+cWojayL/ErhULSd+ # 2DrZ8LaHlv1b0VysGMNNn3O3AamfV6peKOK5lDGCA4YwggOCAgEBMHcwYzELMAkG # A1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdp # Q2VydCBUcnVzdGVkIEc0IFJTQTQwOTYgU0hBMjU2IFRpbWVTdGFtcGluZyBDQQIQ # C65mvFq6f5WHxvnpBOMzBDANBglghkgBZQMEAgIFAKCB4TAaBgkqhkiG9w0BCQMx # DQYLKoZIhvcNAQkQAQQwHAYJKoZIhvcNAQkFMQ8XDTI0MTAzMDA1MTcyMlowKwYL # KoZIhvcNAQkQAgwxHDAaMBgwFgQU29OF7mLb0j575PZxSFCHJNWGW0UwNwYLKoZI # hvcNAQkQAi8xKDAmMCQwIgQgdnafqPJjLx9DCzojMK7WVnX+13PbBdZluQWTmEOP # mtswPwYJKoZIhvcNAQkEMTIEMOtSV++LxNS12Orb5WKoRPgY5Fhsq8Ck2EsSPhWS # SkDbL9riSmBp84BE6vJCkRdBfDANBgkqhkiG9w0BAQEFAASCAgAlOONS/6zgXTcj # 6QMT09VAWR5MByT9VCqsdMTzK63UCFoiRL3MLOjgO4xHhSWDEXAGPi7q3mGrjex3 # T5aSgrsKKFCT2ECWcwNMIxpGhckHSFbLCDGYgyVZM+JL9856E+nCUS1xFOLAON08 # CcwQoh7dU3cOKqeIpQolagJi5pO/CHAF0FigPVHl1eJvDNWQ6z5gPLFETDX7nTTh # MxaNEvx7Lj+EGlYIA4yRaS610qg+tVY3oYUZY1CGO600Wh8nq+B/nu1yfRIrzOtT # 4kP8WBMwBj5e/lyl7v2EXpnBVRYUbFAhS3MkA57EH3kbW5UyPpFrg+brcf8gyYXA # EXHBdK54FUrQM4mWOtnx+r5rR0ybTYPOUwGGNT9DAjlBvBtbf5Kj5yQxuUM7DOpU # ylJdZ2re/qGndo6ezA3Os3OJHRqEIstJfpKo1qSSefhFBo60DcYW9e6/qorYarKc # lGEqXxWQrE8Fs7ddTb9OVutyO9a6uIsykAje1uKA6g4zmEsaeOdVi2GRvkRT5x+4 # XG4V1aKcTfyPUdZmWEBC6qlNJ3Ds9eP8oZyo0W4ZSve6mqBNaSKcIIqGa4BUF93W # oYu+UrKPpa2f2bm/5XC04XLjCfzRwBmXH5OBResowUv83zU2EyJCkLeBnZQJyX4m # hDnM5K9X6HxGKjK/b/45ZaNByPIL5A== # SIG # End signature block |