Skip to content

Instantly share code, notes, and snippets.

@SkipToTheEndpoint
Created April 15, 2024 11:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SkipToTheEndpoint/806892e1a013698e1acbb6fbf9ddbbe8 to your computer and use it in GitHub Desktop.
Save SkipToTheEndpoint/806892e1a013698e1acbb6fbf9ddbbe8 to your computer and use it in GitHub Desktop.
HardwareConfigurationRemediateScript
#=============================================================================================================================
#
# Script Name: HardwareConfigurationRemediateScript.ps1
# Description: Purpose of this script is to remediate HardwareConfiguration policy.
#
#=============================================================================================================================
# Define Variables
param(
[Parameter(Mandatory=$true)]
[string]
$fileName,
[Parameter(Mandatory=$true)]
[string]
$newPolicyVersion,
[Parameter(Mandatory=$true)]
[string]
$policyId,
[Parameter(Mandatory=$true)]
[string]
$fileToWriteContent
)
$fileName = $fileName.Trim("`"'")
$newPolicyVersion = $newPolicyVersion.Trim("`"'")
$policyId = $policyId.Trim("`"'")
$newPolicyVersionInt = [int]$newPolicyVersion
$fileToWriteContent = $fileToWriteContent.Trim("`"'")
$intuneHardwareConfigPolicyVersionPath = "HKLM:\SOFTWARE\Microsoft\IntuneManagementExtension\HardwareConfig"
$statusValueName = "Status"
$versionName = "PolicyVersion"
$agentMsgName = "AgentErrMsg"
$destPathName = "ConfigFileDropPath"
$biosLockedStateName = "IsBiosLocked"
$biosLockedPasswordKeyName = "BiosLockedPasswordGuidKey"
$metadataChangeDetectedName = "IsMetadataChangeDetected"
$destinationPath = "$Env:WinDir\IMECache\HardwareConfiguration"
$sourcePath = "$Env:WinDir\IMECache\HealthScripts"
#####COMMON HELPER FUNCTIONS#####
function Test-RegPathExists
{
param(
[Parameter(Mandatory=$true)]
[string]
$RegPath
)
if(Test-Path -Path $RegPath -PathType Container)
{
return $true
}
else
{
return $false
}
}
function Test-RegValueExists
{
param(
[Parameter(Mandatory=$true)]
[string]
$RegPath,
[Parameter(Mandatory=$true)]
[string]
$ValueName
)
if(Test-RegPathExists -RegPath $RegPath)
{
$propertyList = Get-ItemProperty -Path $RegPath
if($propertyList)
{
if(Get-Member -InputObject $propertyList -Name $ValueName)
{
return $true
}
}
}
return $false
}
function Test-AgentInstalled
{
param(
[Parameter(Mandatory=$true)]
[string]
$RegPath,
[Parameter(Mandatory=$true)]
[string]
$ValueName,
[Parameter(Mandatory=$false)]
[string]
$ExpectedValue
)
if(Test-RegValueExists -RegPath $RegPath -ValueName $ValueName)
{
if($ExpectedValue)
{
$value = Get-ItemPropertyValue -Path $RegPath -Name $ValueName
if($value -eq $ExpectedValue)
{
return $true
}
}
else
{
return $true
}
}
return $false
}
function ExitWithStatus
{
param(
[Parameter(Mandatory=$true)]
[int]
$ExitCode
)
#$host.SetShouldExit($ExitCode) #non-zero means remediation needed
exit $ExitCode #TODO: uncomment when ready to use
}
#####END COMMON HELPER FUNCTIONS#####
$hardwareConfigPolicyVersionFullPath = (Join-Path -Path $intuneHardwareConfigPolicyVersionPath -ChildPath $policyId).ToString()
if (Test-RegValueExists -RegPath $hardwareConfigPolicyVersionFullPath -ValueName $statusValueName)
{
$currentStatus = Get-ItemPropertyValue -Path $hardwareConfigPolicyVersionFullPath -Name $statusValueName
}
#$filePresent = (Get-ChildItem $destinationPath -File | MeasureObject).Count -ne 0
$curVersion = -1
if (Test-RegValueExists -RegPath $hardwareConfigPolicyVersionFullPath -ValueName $versionName)
{
$curVersion = Get-ItemPropertyValue -Path $hardwareConfigPolicyVersionFullPath -Name $versionName
}
$isMetadataChangeDetected = "false"
if(Test-RegValueExists -RegPath $intuneHardwareConfigPolicyVersionPath -ValueName $metadataChangeDetectedName)
{
$isMetadataChangeDetected = Get-ItemPropertyValue -Path $intuneHardwareConfigPolicyVersionPath -Name $metadataChangeDetectedName
}
#private function decls
function CopyConfigFilesAndVersion()
{
# copy config and metadata files under policyid subdirectory
# We always keep latest version of config and metadata files in the shared folder
$fileDestinationPath = (Join-Path -Path $destinationPath -ChildPath $policyId).ToString()
#ensure target directory exists
if ((Test-Path -Path $fileDestinationPath -PathType Container) -eq $false)
{
New-Item -ItemType Directory -Path $fileDestinationPath
$destAcl = Get-Acl -Path $fileDestinationPath
$sysRule = New-Object System.Security.AccessControl.FileSystemAccessRule("NT AUTHORITY\SYSTEM","Modify","Allow")
$usrRule = New-Object System.Security.AccessControl.FileSystemAccessRule("BUILTIN\Users","ReadData","Allow")
$destAcl.SetAccessRule($sysRule)
$usrDeny = New-Object System.Security.AccessControl.FileSystemAccessRule("BUILTIN\Users","ReadAndExecute","Allow")
$destAcl.RemoveAccessRule($usrDeny)
$destAcl.SetAccessRule($usrRule)
$destAcl.SetAccessRuleProtection($true, $false)
Set-Acl -Path $fileDestinationPath -AclObject $destAcl
}
else
{
# if the files already exists in the policy folder (That means, OEM Agent not processed previous version files),
# then delete old version files.
Get-ChildItem -Path $fileDestinationPath -File | Remove-Item -Verbose
}
$prefix = [System.IO.Path]::GetRandomFileName().Substring(0,8)
# copy metadata
$folderName = $policyId + "_" + $newPolicyVersion
$uniqueMetadataFileName = ($prefix + "_metadata.json")
$metadataDestinationfile = (Join-Path -Path $fileDestinationPath -ChildPath $uniqueMetadataFileName).ToString()
Copy-Item -Path([IO.Path]::Combine($sourcePath, $folderName, "metadata.json")).ToString() -Destination $metadataDestinationfile
#write blob
$fileNameToWrite = $prefix + "_" + $fileName
$contentsToWrite = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($fileToWriteContent))
$destinationfile = (Join-Path -Path $fileDestinationPath -ChildPath $fileNameToWrite).ToString()
Set-Content -Path $destinationfile -Value $contentsToWrite -NoNewline
#registry flag settings
if (Test-RegValueExists -RegPath $hardwareConfigPolicyVersionFullPath -ValueName $versionName)
{
Set-ItemProperty -Path $hardwareConfigPolicyVersionFullPath -Name $versionName -Value $newPolicyVersion -Force
Set-ItemProperty -Path $hardwareConfigPolicyVersionFullPath -Name $destPathName -Value $fileDestinationPath -Force
}
else
{
if ((Test-RegPathExists -RegPath $hardwareConfigPolicyVersionFullPath) -eq $false)
{
New-Item -Path $hardwareConfigPolicyVersionFullPath -Force
}
New-ItemProperty -Path $hardwareConfigPolicyVersionFullPath -Name $versionName -Value $newPolicyVersion -PropertyType Dword -Force
New-ItemProperty -Path $hardwareConfigPolicyVersionFullPath -Name $destPathName -Value $fileDestinationPath -PropertyType String -Force
}
}
function SetState()
{
param(
[Parameter(Mandatory =$false)]
[string]
$newVal
)
if (Test-RegValueExists -RegPath $hardwareConfigPolicyVersionFullPath -ValueName $statusValueName)
{
Set-ItemProperty -Path $hardwareConfigPolicyVersionFullPath -Name $statusValueName -Value $newVal -Force
#reset the flag to false.
Set-ItemProperty -Path $intuneHardwareConfigPolicyVersionPath -Name $metadataChangeDetectedName -Value "false" -Force
}
else
{
if ((Test-RegPathExists -RegPath $hardwareConfigPolicyVersionFullPath) -eq $false)
{
New-Item -Path $hardwareConfigPolicyVersionFullPath -Force
}
New-ItemProperty -Path $hardwareConfigPolicyVersionFullPath -Name $statusValueName -Value $newVal -PropertyType String -Force
}
#Create bios locked state registry value if it doesn't exist.
if(!(Test-RegValueExists -RegPath $intuneHardwareConfigPolicyVersionPath -ValueName $biosLockedStateName))
{
New-ItemProperty -Path $intuneHardwareConfigPolicyVersionPath -Name $biosLockedStateName -Value "false" -PropertyType String -Force
}
#Create bios locked password key registry value if it doesn't exist.
if(!(Test-RegValueExists -RegPath $intuneHardwareConfigPolicyVersionPath -ValueName $biosLockedPasswordKeyName))
{
New-ItemProperty -Path $intuneHardwareConfigPolicyVersionPath -Name $biosLockedPasswordKeyName -Value "" -PropertyType String -Force
}
#Create metadata change detect registry value if it doesn't exist.
if(!(Test-RegValueExists -RegPath $intuneHardwareConfigPolicyVersionPath -ValueName $metadataChangeDetectedName))
{
New-ItemProperty -Path $intuneHardwareConfigPolicyVersionPath -Name $metadataChangeDetectedName -Value "false" -PropertyType String -Force
}
}
#only need to update if version is newer or metadata has changed or current state is failed
if ((($currentStatus -eq "Failed") -or ($currentStatus -eq "Error")) -and ($newPolicyVersionInt -ge $curVersion))
{
# Clear agent error message
if (Test-RegValueExists -RegPath $hardwareConfigPolicyVersionFullPath -ValueName $agentMsgName)
{
Set-ItemProperty -Path $hardwareConfigPolicyVersionFullPath -Name $agentMsgName -Value "" -Force
}
# retry policy
if ($newPolicyVersionInt -ge $curVersion)
{
CopyConfigFilesAndVersion
SetState("Pending");
}
}
elseif(($newPolicyVersionInt -gt $curVersion) -or $isMetadataChangeDetected -eq "true")
{
CopyConfigFilesAndVersion
SetState("Pending");
}
ExitWithStatus -ExitCode 0
# SIG # Begin signature block
# MIIn5gYJKoZIhvcNAQcCoIIn1zCCJ9MCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCLHpKZI3U0AA7J
# ujxOQSZ6Z6dIF2fBy1Jb0DWiU/ZSIqCCDYUwggYDMIID66ADAgECAhMzAAADri01
# UchTj1UdAAAAAAOuMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
# bmcgUENBIDIwMTEwHhcNMjMxMTE2MTkwODU5WhcNMjQxMTE0MTkwODU5WjB0MQsw
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
# AQD0IPymNjfDEKg+YyE6SjDvJwKW1+pieqTjAY0CnOHZ1Nj5irGjNZPMlQ4HfxXG
# yAVCZcEWE4x2sZgam872R1s0+TAelOtbqFmoW4suJHAYoTHhkznNVKpscm5fZ899
# QnReZv5WtWwbD8HAFXbPPStW2JKCqPcZ54Y6wbuWV9bKtKPImqbkMcTejTgEAj82
# 6GQc6/Th66Koka8cUIvz59e/IP04DGrh9wkq2jIFvQ8EDegw1B4KyJTIs76+hmpV
# M5SwBZjRs3liOQrierkNVo11WuujB3kBf2CbPoP9MlOyyezqkMIbTRj4OHeKlamd
# WaSFhwHLJRIQpfc8sLwOSIBBAgMBAAGjggGCMIIBfjAfBgNVHSUEGDAWBgorBgEE
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUhx/vdKmXhwc4WiWXbsf0I53h8T8w
# VAYDVR0RBE0wS6RJMEcxLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJh
# dGlvbnMgTGltaXRlZDEWMBQGA1UEBRMNMjMwMDEyKzUwMTgzNjAfBgNVHSMEGDAW
# gBRIbmTlUAXTgqoXNzcitW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8v
# d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIw
# MTEtMDctMDguY3JsMGEGCCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDov
# L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDEx
# XzIwMTEtMDctMDguY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB
# AGrJYDUS7s8o0yNprGXRXuAnRcHKxSjFmW4wclcUTYsQZkhnbMwthWM6cAYb/h2W
# 5GNKtlmj/y/CThe3y/o0EH2h+jwfU/9eJ0fK1ZO/2WD0xi777qU+a7l8KjMPdwjY
# 0tk9bYEGEZfYPRHy1AGPQVuZlG4i5ymJDsMrcIcqV8pxzsw/yk/O4y/nlOjHz4oV
# APU0br5t9tgD8E08GSDi3I6H57Ftod9w26h0MlQiOr10Xqhr5iPLS7SlQwj8HW37
# ybqsmjQpKhmWul6xiXSNGGm36GarHy4Q1egYlxhlUnk3ZKSr3QtWIo1GGL03hT57
# xzjL25fKiZQX/q+II8nuG5M0Qmjvl6Egltr4hZ3e3FQRzRHfLoNPq3ELpxbWdH8t
# Nuj0j/x9Crnfwbki8n57mJKI5JVWRWTSLmbTcDDLkTZlJLg9V1BIJwXGY3i2kR9i
# 5HsADL8YlW0gMWVSlKB1eiSlK6LmFi0rVH16dde+j5T/EaQtFz6qngN7d1lvO7uk
# 6rtX+MLKG4LDRsQgBTi6sIYiKntMjoYFHMPvI/OMUip5ljtLitVbkFGfagSqmbxK
# 7rJMhC8wiTzHanBg1Rrbff1niBbnFbbV4UDmYumjs1FIpFCazk6AADXxoKCo5TsO
# zSHqr9gHgGYQC2hMyX9MGLIpowYCURx3L7kUiGbOiMwaMIIHejCCBWKgAwIBAgIK
# YQ6Q0gAAAAAAAzANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNV
# BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv
# c29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlm
# aWNhdGUgQXV0aG9yaXR5IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEw
# OTA5WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE
# BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYD
# VQQDEx9NaWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG
# 9w0BAQEFAAOCAg8AMIICCgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+la
# UKq4BjgaBEm6f8MMHt03a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc
# 6Whe0t+bU7IKLMOv2akrrnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4D
# dato88tt8zpcoRb0RrrgOGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+
# lD3v++MrWhAfTVYoonpy4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nk
# kDstrjNYxbc+/jLTswM9sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6
# A4aN91/w0FK/jJSHvMAhdCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmd
# X4jiJV3TIUs+UsS1Vz8kA/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL
# 5zmhD+kjSbwYuER8ReTBw3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zd
# sGbiwZeBe+3W7UvnSSmnEyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3
# T8HhhUSJxAlMxdSlQy90lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS
# 4NaIjAsCAwEAAaOCAe0wggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRI
# bmTlUAXTgqoXNzcitW2oynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAL
# BgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBD
# uRQFTuHqp8cx0SOJNDBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jv
# c29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf
# MDNfMjIuY3JsMF4GCCsGAQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3
# dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf
# MDNfMjIuY3J0MIGfBgNVHSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEF
# BQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1h
# cnljcHMuaHRtMEAGCCsGAQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkA
# YwB5AF8AcwB0AGEAdABlAG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn
# 8oalmOBUeRou09h0ZyKbC5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7
# v0epo/Np22O/IjWll11lhJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0b
# pdS1HXeUOeLpZMlEPXh6I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/
# KmtYSWMfCWluWpiW5IP0wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvy
# CInWH8MyGOLwxS3OW560STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBp
# mLJZiWhub6e3dMNABQamASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJi
# hsMdYzaXht/a8/jyFqGaJ+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYb
# BL7fQccOKO7eZS/sl/ahXJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbS
# oqKfenoi+kiVH6v7RyOA9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sL
# gOppO6/8MO0ETI7f33VtY5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtX
# cVZOSEXAQsmbdlsKgEhr/Xmfwb1tbWrJUnMTDXpQzTGCGbcwghmzAgEBMIGVMH4x
# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt
# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01p
# Y3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTECEzMAAAOuLTVRyFOPVR0AAAAA
# A64wDQYJYIZIAWUDBAIBBQCggcYwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQw
# HAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIJh/
# rj3w9OwUJLAXx8zC18rgAoqQXrWZUFjyRsIQmJUBMFoGCisGAQQBgjcCAQwxTDBK
# oCyAKgBNAGkAYwByAG8AcwBvAGYAdAAgAEMAbwByAHAAbwByAGEAdABpAG8AbqEa
# gBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEBBQAEggEASlY9
# 6zU3GK872cE/xab3jeES+ezwUIOTbsbdfpMud1YXQQdXfAMO52WFX/9rqRQRpIFh
# bSGqhY1H6pgB3FGZbqD4kAwFcAX3x1cYYi4ERYtIVhNlm8h5Ail3VPR2HCfujhvo
# ZKR5pGAMqDfDxPcloY4pcW8Z+VWkXXTxXdScedZ7MGFljetSqlTv0G5y1jKwd3oZ
# SV3sq3qKDYpxF1Yl/N5tVypS6zod6B4b9+DxRbJA8sw8kcbde/Ij03MvshKdjokb
# d1ikD+bzdJ26c/oFUg5LtoOd7vw7ahEzAuQOCajVYb4RDdDKwnO4HxWUJN7ndwq3
# CqXfBlvu20v/JNDpnKGCFykwghclBgorBgEEAYI3AwMBMYIXFTCCFxEGCSqGSIb3
# DQEHAqCCFwIwghb+AgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFZBgsqhkiG9w0BCRAB
# BKCCAUgEggFEMIIBQAIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFlAwQCAQUABCDd
# 0KY+hDc2gu1vL6WGstCTXTc+tnntkUHjwZm+KwK0jAIGZdXhbeDUGBMyMDI0MDIy
# OTIxMzAwNC42NzhaMASAAgH0oIHYpIHVMIHSMQswCQYDVQQGEwJVUzETMBEGA1UE
# CBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9z
# b2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVy
# YXRpb25zIExpbWl0ZWQxJjAkBgNVBAsTHVRoYWxlcyBUU1MgRVNOOjJBRDQtNEI5
# Mi1GQTAxMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNloIIR
# eDCCBycwggUPoAMCAQICEzMAAAHenkielp8oRD0AAQAAAd4wDQYJKoZIhvcNAQEL
# BQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcT
# B1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UE
# AxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwHhcNMjMxMDEyMTkwNzEy
# WhcNMjUwMTEwMTkwNzEyWjCB0jELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp
# bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw
# b3JhdGlvbjEtMCsGA1UECxMkTWljcm9zb2Z0IElyZWxhbmQgT3BlcmF0aW9ucyBM
# aW1pdGVkMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjoyQUQ0LTRCOTItRkEwMTEl
# MCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZTCCAiIwDQYJKoZI
# hvcNAQEBBQADggIPADCCAgoCggIBALSB9ByF9UIDhA6xFrOniw/xsDl8sSi9rOCO
# XSSO4VMQjnNGAo5VHx0iijMEMH9LY2SUIBkVQS0Ml6kR+TagkUPbaEpwjhQ1mprh
# RgJT/jlSnic42VDAo0en4JI6xnXoAoWoKySY8/ROIKdpphgI7OJb4XHk1P3sX2pN
# Z32LDY1ktchK1/hWyPlblaXAHRu0E3ynvwrS8/bcorANO6DjuysyS9zUmr+w3H3A
# EvSgs2ReuLj2pkBcfW1UPCFudLd7IPZ2RC4odQcEPnY12jypYPnS6yZAs0pLpq0K
# RFUyB1x6x6OU73sudiHON16mE0l6LLT9OmGo0S94Bxg3N/3aE6fUbnVoemVc7FkF
# Lum8KkZcbQ7cOHSAWGJxdCvo5OtUtRdSqf85FklCXIIkg4sm7nM9TktUVfO0kp6k
# x7mysgD0Qrxx6/5oaqnwOTWLNzK+BCi1G7nUD1pteuXvQp8fE1KpTjnG/1OJeehw
# KNNPjGt98V0BmogZTe3SxBkOeOQyLA++5Hyg/L68pe+DrZoZPXJaGU/iBiFmL+ul
# /Oi3d83zLAHlHQmH/VGNBfRwP+ixvqhyk/EebwuXVJY+rTyfbRfuh9n0AaMhhNxx
# g6tGKyZS4EAEiDxrF9mAZEy8e8rf6dlKIX5d3aQLo9fDda1ZTOw+XAcAvj2/N3DL
# VGZlHnHlAgMBAAGjggFJMIIBRTAdBgNVHQ4EFgQUazAmbxseaapgdxzK8Os+naPQ
# EsgwHwYDVR0jBBgwFoAUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXwYDVR0fBFgwVjBU
# oFKgUIZOaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9z
# b2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAoMSkuY3JsMGwGCCsGAQUFBwEB
# BGAwXjBcBggrBgEFBQcwAoZQaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9w
# cy9jZXJ0cy9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENBJTIwMjAxMCgxKS5j
# cnQwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAOBgNVHQ8B
# Af8EBAMCB4AwDQYJKoZIhvcNAQELBQADggIBAOKUwHsXDacGOvUIgs5HDgPs0LZ1
# qyHS6C6wfKlLaD36tZfbWt1x+GMiazSuy+GsxiVHzkhMW+FqK8gruLQWN/sOCX+f
# GUgT9LT21cRIpcZj4/ZFIvwtkBcsCz1XEUsXYOSJUPitY7E8bbldmmhYZ29p+XQp
# IcsG/q+YjkqBW9mw0ru1MfxMTQs9MTDiD28gAVGrPA3NykiSChvdqS7VX+/LcEz9
# Ubzto/w28WA8HOCHqBTbDRHmiP7MIj+SQmI9VIayYsIGRjvelmNa0OvbU9CJSz/N
# fMEgf2NHMZUYW8KqWEjIjPfHIKxWlNMYhuWfWRSHZCKyIANA0aJL4soHQtzzZ2Mn
# NfjYY851wHYjGgwUj/hlLRgQO5S30Zx78GqBKfylp25aOWJ/qPhC+DXM2gXajIXb
# l+jpGcVANwtFFujCJRdZbeH1R+Q41FjgBg4m3OTFDGot5DSuVkQgjku7pOVPtldE
# 46QlDg/2WhPpTQxXH64sP1GfkAwUtt6rrZM/PCwRG6girYmnTRLLsicBhoYLh+EE
# FjVviXAGTk6pnu8jx/4WPWu0jsz7yFzg82/FMqCk9wK3LvyLAyDHN+FxbHAxtgwa
# d7oLQPM0WGERdB1umPCIiYsSf/j79EqHdoNwQYROVm+ZX10RX3n6bRmAnskeNhi0
# wnVaeVogLMdGD+nqMIIHcTCCBVmgAwIBAgITMwAAABXF52ueAptJmQAAAAAAFTAN
# BgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0
# b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh
# dGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9y
# aXR5IDIwMTAwHhcNMjEwOTMwMTgyMjI1WhcNMzAwOTMwMTgzMjI1WjB8MQswCQYD
# VQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEe
# MBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3Nv
# ZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC
# AgoCggIBAOThpkzntHIhC3miy9ckeb0O1YLT/e6cBwfSqWxOdcjKNVf2AX9sSuDi
# vbk+F2Az/1xPx2b3lVNxWuJ+Slr+uDZnhUYjDLWNE893MsAQGOhgfWpSg0S3po5G
# awcU88V29YZQ3MFEyHFcUTE3oAo4bo3t1w/YJlN8OWECesSq/XJprx2rrPY2vjUm
# ZNqYO7oaezOtgFt+jBAcnVL+tuhiJdxqD89d9P6OU8/W7IVWTe/dvI2k45GPsjks
# UZzpcGkNyjYtcI4xyDUoveO0hyTD4MmPfrVUj9z6BVWYbWg7mka97aSueik3rMvr
# g0XnRm7KMtXAhjBcTyziYrLNueKNiOSWrAFKu75xqRdbZ2De+JKRHh09/SDPc31B
# mkZ1zcRfNN0Sidb9pSB9fvzZnkXftnIv231fgLrbqn427DZM9ituqBJR6L8FA6PR
# c6ZNN3SUHDSCD/AQ8rdHGO2n6Jl8P0zbr17C89XYcz1DTsEzOUyOArxCaC4Q6oRR
# RuLRvWoYWmEBc8pnol7XKHYC4jMYctenIPDC+hIK12NvDMk2ZItboKaDIV1fMHSR
# lJTYuVD5C4lh8zYGNRiER9vcG9H9stQcxWv2XFJRXRLbJbqvUAV6bMURHXLvjflS
# xIUXk8A8FdsaN8cIFRg/eKtFtvUeh17aj54WcmnGrnu3tz5q4i6tAgMBAAGjggHd
# MIIB2TASBgkrBgEEAYI3FQEEBQIDAQABMCMGCSsGAQQBgjcVAgQWBBQqp1L+ZMSa
# voKRPEY1Kc8Q/y8E7jAdBgNVHQ4EFgQUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXAYD
# VR0gBFUwUzBRBgwrBgEEAYI3TIN9AQEwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3
# dy5taWNyb3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMBMGA1Ud
# JQQMMAoGCCsGAQUFBwMIMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud
# DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjR
# PZSQW9fOmhjEMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0
# LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNy
# bDBaBggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93d3cubWljcm9z
# b2Z0LmNvbS9wa2kvY2VydHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3J0MA0G
# CSqGSIb3DQEBCwUAA4ICAQCdVX38Kq3hLB9nATEkW+Geckv8qW/qXBS2Pk5HZHix
# BpOXPTEztTnXwnE2P9pkbHzQdTltuw8x5MKP+2zRoZQYIu7pZmc6U03dmLq2HnjY
# Ni6cqYJWAAOwBb6J6Gngugnue99qb74py27YP0h1AdkY3m2CDPVtI1TkeFN1JFe5
# 3Z/zjj3G82jfZfakVqr3lbYoVSfQJL1AoL8ZthISEV09J+BAljis9/kpicO8F7BU
# hUKz/AyeixmJ5/ALaoHCgRlCGVJ1ijbCHcNhcy4sa3tuPywJeBTpkbKpW99Jo3QM
# vOyRgNI95ko+ZjtPu4b6MhrZlvSP9pEB9s7GdP32THJvEKt1MMU0sHrYUP4KWN1A
# PMdUbZ1jdEgssU5HLcEUBHG/ZPkkvnNtyo4JvbMBV0lUZNlz138eW0QBjloZkWsN
# n6Qo3GcZKCS6OEuabvshVGtqRRFHqfG3rsjoiV5PndLQTHa1V1QJsWkBRH58oWFs
# c/4Ku+xBZj1p/cvBQUl+fpO+y/g75LcVv7TOPqUxUYS8vwLBgqJ7Fx0ViY1w/ue1
# 0CgaiQuPNtq6TPmb/wrpNPgkNWcr4A245oyZ1uEi6vAnQj0llOZ0dFtq0Z4+7X6g
# MTN9vMvpe784cETRkPHIqzqKOghif9lwY1NNje6CbaUFEMFxBmoQtB1VM1izoXBm
# 8qGCAtQwggI9AgEBMIIBAKGB2KSB1TCB0jELMAkGA1UEBhMCVVMxEzARBgNVBAgT
# Cldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29m
# dCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMkTWljcm9zb2Z0IElyZWxhbmQgT3BlcmF0
# aW9ucyBMaW1pdGVkMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjoyQUQ0LTRCOTIt
# RkEwMTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZaIjCgEB
# MAcGBSsOAwIaAxUAaKBSisy4y86pl8Xy22CJZExE2vOggYMwgYCkfjB8MQswCQYD
# VQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEe
# MBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3Nv
# ZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIFAOmK66kwIhgP
# MjAyNDAyMjkxOTQwMjVaGA8yMDI0MDMwMTE5NDAyNVowdDA6BgorBgEEAYRZCgQB
# MSwwKjAKAgUA6YrrqQIBADAHAgEAAgIO4zAHAgEAAgIRljAKAgUA6Yw9KQIBADA2
# BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIBAAIDB6EgoQowCAIB
# AAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBACHo0aG9p0Bd+CEBEQ2uwBj757S4KFlX
# eqQU+NiyLL8IUg0KuUY6q19sQpnAGduj8esuo6wJzPHlkAAiHJUXo3zQLXnai5h7
# Xyky4oVQL8oPM/shuM8C698dlEsuKN8ubHY+qkMJkIMRQLFZWEKdRJ06bMEbxsew
# lbW1ReXoybKwMYIEDTCCBAkCAQEwgZMwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
# Cldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29m
# dCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENB
# IDIwMTACEzMAAAHenkielp8oRD0AAQAAAd4wDQYJYIZIAWUDBAIBBQCgggFKMBoG
# CSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQxIgQgE2IG7Zt/
# x0Mte5l2lZtDniaspSYgV3w7iZygRklnGlIwgfoGCyqGSIb3DQEJEAIvMYHqMIHn
# MIHkMIG9BCCOPiOfDcFeEBBJAn/mC3MgrT5w/U2z81LYD44Hc34dezCBmDCBgKR+
# MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS
# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMT
# HU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAB3p5InpafKEQ9AAEA
# AAHeMCIEIHiD7bQdyLeEP623nbSdp9QBmPBTEgT/V7z+oreQ219vMA0GCSqGSIb3
# DQEBCwUABIICAB7DYreqNfDYqxdX2AqnsE9ZLpkj6tx0xDGbRTNTJKwXxBcrQ6nz
# UfZCeCAkysOshmtV/gsTjQZ5za9rq6EfDCVs+TPnxXyRVvx9xAYtTRU35wXCEeYZ
# hvKdbCpwWRMx9fxjG5E4f+gcXQXtk0lFRkCzZl4VXW6OUgpVWcwfnc9ZxJZWozWw
# ueguIFqQ4kJUmi+YhxCYpS40AoK8QaKBu2dWmnvY+GPeFZOLbJeVL14ZqtlBVsnW
# qdSZQUBseXb+LFC327og4E5KTePWlzNkNS/J8Y3ytlZjM6lUVOyh1d7evS6Y1JlO
# XDJSY1Bp97PWjlm59mkbKK9GsGWmsePbtM3DTP7zSUrhBp4xtyB1UPZVa/RJLYFh
# fd2D+IWVVZYjpdxdUubK8bOYUxk5lOApqHCEjh+7GRTNgXRLYxANz1l2iOWP8MYq
# TvjiUsuev9+lehMG6RqThRuGd64yyNvN7LfjtluvVYdLszWHBNrX8Igjsc5cKICk
# ammIyK93pbqext2j+Q4HdxIwS/w202GwO0UvuEQgF7bP1lK/9S6A/6+8KGN6wpI6
# SxLvJOGOB5yZjyYGBJU4fr2vJ3ZnnTEQnhgK1sRXWJv1wSyGtvL7wgFEyIMxf6YC
# Y2JZ+eCChIqTbbYPT3l6jnO4AhMbi1tS955nLs48YoTnZ1EUfkY+JweE
# SIG # End signature block
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment