Enterprise.ps1
function getEnterprise { [KeeperSecurity.Authentication.IAuthentication] $auth = $Script:Context.Auth if (-not $auth) { Write-Error -Message "Not Connected" -ErrorAction Stop } if (-not $auth.AuthContext.IsEnterpriseAdmin) { Write-Error -Message "Not an Enterprise Administrator" -ErrorAction Stop } $enterprise = $Script:Context.Enterprise if (-not $enterprise) { $enterprise = New-Object Enterprise $enterprise.enterpriseData = New-Object KeeperSecurity.Enterprise.EnterpriseData $enterprise.roleData = New-Object KeeperSecurity.Enterprise.RoleData $enterprise.mspData = New-Object KeeperSecurity.Enterprise.ManagedCompanyData [KeeperSecurity.Enterprise.EnterpriseDataPlugin[]] $plugins = $enterprise.enterpriseData, $enterprise.roleData, $enterprise.mspData $enterprise.loader = New-Object KeeperSecurity.Enterprise.EnterpriseLoader($auth, $plugins) $enterprise.loader.Load().GetAwaiter().GetResult() | Out-Null if ($enterprise.enterpriseData.EnterpriseLicense.licenseStatus.StartsWith("msp")) { $enterprise.ManagedCompanies = @{} } $Script:Context.Enterprise = $enterprise $Script:Context.ManagedCompanyId = 0 } if ($Script:Context.ManagedCompanyId -gt 0) { if ($null -ne $enterprise.ManagedCompanies) { $enterpriseMc = $enterprise.ManagedCompanies[$Script:Context.ManagedCompanyId] if ($null -eq $enterpriseMc) { $authMc = New-Object KeeperSecurity.Enterprise.ManagedCompanyAuth $authMc.LoginToManagedCompany($Script:Context.Enterprise.loader, $Script:Context.ManagedCompanyId).GetAwaiter().GetResult() | Out-Null $enterpriseMc = New-Object Enterprise $enterpriseMc.enterpriseData = New-Object KeeperSecurity.Enterprise.EnterpriseData $enterpriseMc.roleData = New-Object KeeperSecurity.Enterprise.RoleData [KeeperSecurity.Enterprise.EnterpriseDataPlugin[]] $plugins = $enterpriseMc.enterpriseData, $enterpriseMc.roleData $enterpriseMc.loader = New-Object KeeperSecurity.Enterprise.EnterpriseLoader($authMc, $plugins) $enterpriseMc.loader.Load().GetAwaiter().GetResult() | Out-Null $enterprise.ManagedCompanies[$Script:Context.ManagedCompanyId] = $enterpriseMc } $enterprise = $enterpriseMc } else { $Script:Context.ManagedCompanyId = 0 } } return $enterprise } function Sync-KeeperEnterprise { <# .Synopsis Sync Keeper Enterprise Information #> [CmdletBinding()] [Enterprise]$enterprise = getEnterprise $task = $enterprise.loader.Load() $task.GetAwaiter().GetResult() | Out-Null } New-Alias -Name ked -Value Sync-KeeperEnterprise function Get-KeeperEnterpriseUser { <# .Synopsis Get a list of enterprise users #> [CmdletBinding()] [Enterprise]$enterprise = getEnterprise return $enterprise.enterpriseData.Users } New-Alias -Name keu -Value Get-KeeperEnterpriseUser function Get-KeeperEnterpriseTeam { <# .Synopsis Get a list of enterprise teams #> [CmdletBinding()] [Enterprise]$enterprise = getEnterprise return $enterprise.enterpriseData.Teams } New-Alias -Name ket -Value Get-KeeperEnterpriseTeam $Keeper_TeamNameCompleter = { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) $result = @() [Enterprise]$enterprise = $Script:Context.Enterprise if (-not $enterprise) { return $null } if ($wordToComplete) { $to_complete = $wordToComplete + '*' } else { $to_complete = '*' } foreach ($team in $enterprise.enterpriseData.Teams) { if ($team.Name -like $to_complete) { $teamName = $team.Name if ($teamName -match '[\s'']') { $teamName = $teamName -replace '''', '''''' $teamName = "'${teamName}'" } $result += $teamName } } if ($result.Count -gt 0) { return $result } else { return $null } } function Get-KeeperEnterpriseTeamUser { <# .Synopsis Get a list of enterprise users for team #> [CmdletBinding()] Param ( [Parameter(Position = 0, Mandatory = $true)]$Team ) [Enterprise]$enterprise = getEnterprise $enterpriseData = $enterprise.enterpriseData $uid = $null if ($Team -is [String]) { $uids = Get-KeeperEnterpriseTeam | Where-Object { $_.Uid -ceq $Team -or $_.Name -ieq $Team } | Select-Object -Property Uid if ($uids.Length -gt 1) { Write-Error -Message "Team name `"$Team`" is not unique. Use Team UID" -ErrorAction Stop } if ($null -ne $uids.Uid) { $uid = $uids.Uid } } elseif ($null -ne $Team.Uid) { $uid = $Team.Uid } if ($uid) { $team = $null if ($enterpriseData.TryGetTeam($uid, [ref]$team)) { foreach ($userId in $enterpriseData.GetUsersForTeam($uid)) { $user = $null foreach ($userId in $enterpriseData.TryGetUserById($userId, [ref]$user)) { $user } } } else { Write-Error -Message "Team `"$uid`" not found" -ErrorAction Stop } } else { Write-Error -Message "Team `"$Team`" not found" -ErrorAction Stop } } New-Alias -Name ketu -Value Get-KeeperEnterpriseTeamUser Register-ArgumentCompleter -CommandName Get-KeeperEnterpriseTeamUser -ParameterName Team -ScriptBlock $Keeper_TeamNameCompleter $Keeper_ActiveUserCompleter = { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) $result = @() [Enterprise]$enterprise = $Script:Context.Enterprise if (-not $enterprise) { return $null } if ($wordToComplete) { $to_complete = '*' + $wordToComplete + '*' } else { $to_complete = '*' } foreach ($user in $enterprise.enterpriseData.Users) { if ($user.UserStatus -in @([KeeperSecurity.Enterprise.UserStatus]::Active, [KeeperSecurity.Enterprise.UserStatus]::Disabled, [KeeperSecurity.Enterprise.UserStatus]::Blocked)) { if ($user.Email -like $to_complete) { $result += $user.Email } } } if ($result.Count -gt 0) { return $result } else { return $null } } function New-KeeperEnterpriseNode { <# .SYNOPSIS Creates Enterprise Node .PARAMETER ParentNode Parent Node name or ID .PARAMETER NodeName Node name #> [CmdletBinding()] Param ( [Parameter()][string] $ParentNode, [Parameter(Position = 0, Mandatory = $true)] $NodeName ) [Enterprise]$enterprise = getEnterprise [KeeperSecurity.Enterprise.EnterpriseNode] $parent = $null if ($ParentNode) { $parent = resolveSingleNode $ParentNode } $n = [KeeperSecurity.Enterprise.EnterpriseExtensions]::CreateNode($enterprise.enterpriseData, $NodeName, $parent).GetAwaiter().GetResult() Write-Information "Added node `"$($n.DisplayName)`"" } New-Alias -Name kena -Value New-KeeperEnterpriseNode function Add-KeeperEnterpriseUser { <# .SYNOPSIS Invites Enterprise Users .PARAMETER Node Node Name or ID .PARAMETER Email Email address to invite .PARAMETER Emails Extra email addresses to invite #> [CmdletBinding()] Param ( [Parameter()][string] $FullName, [Parameter()][string] $Node, [Parameter(Position = 0, Mandatory = $true)] $Email, [Parameter(ValueFromRemainingArguments = $true)] $Emails ) [Enterprise]$enterprise = getEnterprise [Int64] $nodeId = 0 if ($Node) { $n = resolveSingleNode $Node if ($n) { $nodeId = $n.Id } } $inviteOptions = New-Object KeeperSecurity.Enterprise.InviteUserOptions if ($nodeId -gt 0) { $inviteOptions.NodeId = $nodeId } if ($FullName) { $inviteOptions.FullName = $FullName } $user = $enterprise.enterpriseData.InviteUser($Email, $inviteOptions).GetAwaiter().GetResult() if ($user) { Write-Output "User `"$Email`" is invited" } $inviteOptions.FullName = $null foreach ($e in $Emails) { $user = $enterprise.enterpriseData.InviteUser($e, $inviteOptions).GetAwaiter().GetResult() if ($user) { Write-Output "User `"$e`" is invited" } } } New-Alias -Name invite-user -Value Add-KeeperEnterpriseUser function Lock-KeeperEnterpriseUser { <# .Synopsis Locks Enterprise User .Parameter User User email, enterprise Id, or instance. #> [CmdletBinding()] Param ( [Parameter(Position = 0, Mandatory = $true)]$User ) [Enterprise]$enterprise = getEnterprise $userObject = resolveUser $enterprise.enterpriseData $User if ($userObject) { $saved = $enterprise.enterpriseData.SetUserLocked($userObject, $true).GetAwaiter().GetResult() if ($saved) { Write-Output "User `"$($saved.Email)`" was locked" } } } Register-ArgumentCompleter -CommandName Lock-KeeperEnterpriseUser -ParameterName User -ScriptBlock $Keeper_ActiveUserCompleter New-Alias -Name lock-user -Value Lock-KeeperEnterpriseUser $Keeper_LockedUserCompleter = { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) $result = @() [Enterprise]$enterprise = $Script:Context.Enterprise if (-not $enterprise) { return $null } if ($wordToComplete) { $to_complete = '*' + $wordToComplete + '*' } else { $to_complete = '*' } foreach ($user in $enterprise.enterpriseData.Users) { if ($user.UserStatus -eq [KeeperSecurity.Enterprise.UserStatus]::Locked) { if ($user.Email -like $to_complete) { $result += $user.Email } } } if ($result.Count -gt 0) { return $result } else { return $null } } function Unlock-KeeperEnterpriseUser { <# .Synopsis Unlocks Enterprise User .Parameter User User email, enterprise Id, or instance. #> [CmdletBinding()] Param ( [Parameter(Position = 0, Mandatory = $true)]$User ) [Enterprise]$enterprise = getEnterprise $userObject = resolveUser $enterprise.enterpriseData $User if ($userObject) { $saved = $enterprise.enterpriseData.SetUserLocked($userObject, $false).GetAwaiter().GetResult() if ($saved) { Write-Output "User `"$($saved.Email)`" was unlocked" } } } Register-ArgumentCompleter -CommandName Unlock-KeeperEnterpriseUser -ParameterName User -ScriptBlock $Keeper_LockedUserCompleter New-Alias -Name unlock-user -Value Unlock-KeeperEnterpriseUser $Keeper_EnterpriseUserCompleter = { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) $result = @() [Enterprise]$enterprise = $Script:Context.Enterprise if (-not $enterprise) { return $null } if ($wordToComplete) { $to_complete = '*' + $wordToComplete + '*' } else { $to_complete = '*' } foreach ($user in $enterprise.enterpriseData.Users) { if ($user.Email -like $to_complete) { $result += $user.Email } } if ($result.Count -gt 0) { return $result } else { return $null } } function Move-KeeperEnterpriseUser { <# .Synopsis Transfers enterprise user account to another user .Parameter FromUser email or user ID to transfer vault from user .Parameter TargetUser email or user ID to transfer vault to user #> [CmdletBinding()] Param ( [Parameter(Position = 0, Mandatory = $true)]$FromUser, [Parameter(Position = 1, Mandatory = $true)]$TargetUser, [Switch] $Force ) [Enterprise]$enterprise = getEnterprise $fromUserObject = resolveUser $enterprise.enterpriseData $FromUser if (-not $fromUserObject) { return } $targetUserObject = resolveUser $enterprise.enterpriseData $TargetUser if (-not $targetUserObject) { return } if (-not $Force.IsPresent) { Write-Output "This action cannot be undone.`n" $answer = Read-Host -Prompt "Do you want to proceed with transferring $($fromUserObject.Email) account (Yes/No)? > " if ($answer -ne 'yes' -and $answer -ne 'y') { return } } $transferResult = $enterprise.enterpriseData.TransferUserAccount($enterprise.roleData, $fromUserObject, $targetUserObject).GetAwaiter().GetResult() if ($transferResult) { Write-Information "Successfully Transfered:" Write-Information " Records: $($transferResult.RecordsTransfered)" Write-Information " Shared Folders: $($transferResult.SharedFoldersTransfered)" Write-Information " Team: $($transferResult.TeamsTransfered)" if ($transferResult.RecordsCorrupted -gt 0 -or $transferResult.SharedFoldersCorrupted -gt 0 -or $transferResult.TeamsCorrupted -gt 0) { Write-Information "Failed to Transfer:" if ($transferResult.RecordsCorrupted -gt 0) { Write-Information " Records: $($transferResult.RecordsCorrupted)" } if ($transferResult.SharedFoldersCorrupted -gt 0) { Write-Information " Shared Folders: $($transferResult.SharedFoldersCorrupted)" } if ($transferResult.TeamsCorrupted -gt 0) { Write-Information " Team: $($transferResult.TeamsCorrupted)" } } } } Register-ArgumentCompleter -CommandName Move-KeeperEnterpriseUser -ParameterName FromUser -ScriptBlock $Keeper_LockedUserCompleter Register-ArgumentCompleter -CommandName Move-KeeperEnterpriseUser -ParameterName TargetUser -ScriptBlock $Keeper_ActiveUserCompleter New-Alias -Name transfer-user -Value Move-KeeperEnterpriseUser function Remove-KeeperEnterpriseUser { <# .Synopsis Removes Enterprise User .Parameter User User email, enterprise Id, or instance. #> [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact = 'High')] Param ( [Parameter(Position = 0, Mandatory = $true)]$User, [Switch] $Force ) [Enterprise]$enterprise = getEnterprise $userObject = resolveUser $enterprise.enterpriseData $User if ($userObject) { if (-not $Force.IsPresent) { Write-Output "`nDeleting a user will also delete any records owned and shared by this user." "Before you delete this user, we strongly recommend you lock their account" "and transfer any important records to other user.`n" "This action cannot be undone." if ($PSCmdlet.ShouldProcess($userObject.Email, "Removing Enterprise User")) { $enterprise.enterpriseData.DeleteUser($userObject).GetAwaiter().GetResult() | Out-Null Write-Output "User $($userObject.Email) has been deleted" } } } } Register-ArgumentCompleter -CommandName Remove-KeeperEnterpriseUser -ParameterName User -ScriptBlock $Keeper_EnterpriseUserCompleter New-Alias -Name delete-user -Value Remove-KeeperEnterpriseUser function resolveUser { Param ( $enterpriseData, $user ) [KeeperSecurity.Enterprise.EnterpriseUser] $u = $null if ($user -is [long]) { if ($enterpriseData.TryGetUserById($user, [ref]$u)) { return $u } } elseif ($user -is [string]) { if ($enterpriseData.TryGetUserByEmail($user, [ref]$u)) { return $u } } elseif ($user -is [KeeperSecurity.Enterprise.EnterpriseUser]) { if ($enterpriseData.TryGetUserById($user.Id, [ref]$u)) { return $u } } Write-Error "`"${user}`" cannot be resolved as enterprise user" -ErrorAction Stop } function resolveSingleNode { Param ($node) if ($node) { $nodes = Get-KeeperEnterpriseNode | Where-Object { $_.Id -eq $node } if ($nodes.Length -eq 0) { $nodes = Get-KeeperEnterpriseNode | Where-Object { $_.DisplayName -like $node + '*' } } if ($nodes.Length -eq 0) { Write-Error -Message "Node `"$node`" not found" -ErrorAction Stop } if ($nodes.Length -gt 1) { Write-Error -Message "Node name `"$node`" is not unique. Use Node ID." -ErrorAction Stop } $nodes[0] } } function Get-KeeperEnterpriseNode { <# .Synopsis Get a list of enterprise nodes #> [CmdletBinding()] [Enterprise]$enterprise = getEnterprise return $enterprise.enterpriseData.Nodes } New-Alias -Name ken -Value Get-KeeperEnterpriseNode function Get-KeeperEnterpriseRole { <# .Synopsis Get a list of enterprise roles #> [CmdletBinding()] [Enterprise]$enterprise = getEnterprise return $enterprise.roleData.Roles } New-Alias -Name ker -Value Get-KeeperEnterpriseRole # SIG # Begin signature block # MIIR1wYJKoZIhvcNAQcCoIIRyDCCEcQCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUbOoWmE7rH3D27u6w5OmwQokP # ZSeggg4jMIIGsDCCBJigAwIBAgIQCK1AsmDSnEyfXs2pvZOu2TANBgkqhkiG9w0B # AQwFADBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD # VQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVk # IFJvb3QgRzQwHhcNMjEwNDI5MDAwMDAwWhcNMzYwNDI4MjM1OTU5WjBpMQswCQYD # VQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lD # ZXJ0IFRydXN0ZWQgRzQgQ29kZSBTaWduaW5nIFJTQTQwOTYgU0hBMzg0IDIwMjEg # Q0ExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA1bQvQtAorXi3XdU5 # WRuxiEL1M4zrPYGXcMW7xIUmMJ+kjmjYXPXrNCQH4UtP03hD9BfXHtr50tVnGlJP # DqFX/IiZwZHMgQM+TXAkZLON4gh9NH1MgFcSa0OamfLFOx/y78tHWhOmTLMBICXz # ENOLsvsI8IrgnQnAZaf6mIBJNYc9URnokCF4RS6hnyzhGMIazMXuk0lwQjKP+8bq # HPNlaJGiTUyCEUhSaN4QvRRXXegYE2XFf7JPhSxIpFaENdb5LpyqABXRN/4aBpTC # fMjqGzLmysL0p6MDDnSlrzm2q2AS4+jWufcx4dyt5Big2MEjR0ezoQ9uo6ttmAaD # G7dqZy3SvUQakhCBj7A7CdfHmzJawv9qYFSLScGT7eG0XOBv6yb5jNWy+TgQ5urO # kfW+0/tvk2E0XLyTRSiDNipmKF+wc86LJiUGsoPUXPYVGUztYuBeM/Lo6OwKp7AD # K5GyNnm+960IHnWmZcy740hQ83eRGv7bUKJGyGFYmPV8AhY8gyitOYbs1LcNU9D4 # R+Z1MI3sMJN2FKZbS110YU0/EpF23r9Yy3IQKUHw1cVtJnZoEUETWJrcJisB9IlN # Wdt4z4FKPkBHX8mBUHOFECMhWWCKZFTBzCEa6DgZfGYczXg4RTCZT/9jT0y7qg0I # U0F8WD1Hs/q27IwyCQLMbDwMVhECAwEAAaOCAVkwggFVMBIGA1UdEwEB/wQIMAYB # Af8CAQAwHQYDVR0OBBYEFGg34Ou2O/hfEYb7/mF7CIhl9E5CMB8GA1UdIwQYMBaA # FOzX44LScV1kTN8uZz/nupiuHA9PMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAK # BggrBgEFBQcDAzB3BggrBgEFBQcBAQRrMGkwJAYIKwYBBQUHMAGGGGh0dHA6Ly9v # Y3NwLmRpZ2ljZXJ0LmNvbTBBBggrBgEFBQcwAoY1aHR0cDovL2NhY2VydHMuZGln # aWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcnQwQwYDVR0fBDwwOjA4 # oDagNIYyaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJv # b3RHNC5jcmwwHAYDVR0gBBUwEzAHBgVngQwBAzAIBgZngQwBBAEwDQYJKoZIhvcN # AQEMBQADggIBADojRD2NCHbuj7w6mdNW4AIapfhINPMstuZ0ZveUcrEAyq9sMCcT # Ep6QRJ9L/Z6jfCbVN7w6XUhtldU/SfQnuxaBRVD9nL22heB2fjdxyyL3WqqQz/WT # auPrINHVUHmImoqKwba9oUgYftzYgBoRGRjNYZmBVvbJ43bnxOQbX0P4PpT/djk9 # ntSZz0rdKOtfJqGVWEjVGv7XJz/9kNF2ht0csGBc8w2o7uCJob054ThO2m67Np37 # 5SFTWsPK6Wrxoj7bQ7gzyE84FJKZ9d3OVG3ZXQIUH0AzfAPilbLCIXVzUstG2MQ0 # HKKlS43Nb3Y3LIU/Gs4m6Ri+kAewQ3+ViCCCcPDMyu/9KTVcH4k4Vfc3iosJocsL # 6TEa/y4ZXDlx4b6cpwoG1iZnt5LmTl/eeqxJzy6kdJKt2zyknIYf48FWGysj/4+1 # 6oh7cGvmoLr9Oj9FpsToFpFSi0HASIRLlk2rREDjjfAVKM7t8RhWByovEMQMCGQ8 # M4+uKIw8y4+ICw2/O/TOHnuO77Xry7fwdxPm5yg/rBKupS8ibEH5glwVZsxsDsrF # hsP2JjMMB0ug0wcCampAMEhLNKhRILutG4UI4lkNbcoFUCvqShyepf2gpx8GdOfy # 1lKQ/a+FSCH5Vzu0nAPthkX0tGFuv2jiJmCG6sivqf6UHedjGzqGVnhOMIIHazCC # BVOgAwIBAgIQAnNTGQOIer82vZ1cJyDJDjANBgkqhkiG9w0BAQsFADBpMQswCQYD # VQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lD # ZXJ0IFRydXN0ZWQgRzQgQ29kZSBTaWduaW5nIFJTQTQwOTYgU0hBMzg0IDIwMjEg # Q0ExMB4XDTIyMDIwMjAwMDAwMFoXDTI1MDIwMTIzNTk1OVowcDELMAkGA1UEBhMC # VVMxETAPBgNVBAgTCElsbGlub2lzMRAwDgYDVQQHEwdDaGljYWdvMR0wGwYDVQQK # ExRLZWVwZXIgU2VjdXJpdHkgSW5jLjEdMBsGA1UEAxMUS2VlcGVyIFNlY3VyaXR5 # IEluYy4wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDNgTqmksdjUyKF # 5zWkDyghf0PLWJWdzG0TX2j8B4J55xwt+B17zd4Xc3n0dvmSVAyPQANeN+mP1chf # 4LTRn9h4jWb8Jsfn+JzyRhj/gYINYvBnpRpqoM0z7QC9Ebwj5T61Cogm9EKGcrG+ # Ujh+Z7pTqfSUrHD8NMXhDL/UpVn+w0Pb4qg7o7AH2o94n7u/qTlMGZCs+VCAvhNr # wPABxvFY07YGb9t5/IZlPE8vG3p1vw2SbgREgFWSEQFj6X2CIhSrbiFCW/766/Mq # EX6qm+RyF71fD4d3yShg39guaE9o+TBl1MqVCje4bK/wGoNxCho0I6Z1fBBKloyp # vlx3gPpU7tJJ+KpuIiel9R9dGQuscqKzehPtbRc9Abr9ThN/HrLg1sFFVMdn2oMR # 63QCUdz+B1NuS7Ap8Ti7XvAPJHzEuQDcdMcRbkIfllJVqrb9UXEFwOPzvRU2KrcQ # 42Jlnn4T+WenPx5Nr3o/o08WLhLTicEK1OacEowyRLBmih4Gxpdk3fUAVCEkdvmq # TSydQpl1Bk8V88dxCkB1wMZyFYLNcddBL4kUbwjso/z6f2TtfAVYs/iIRWqs7Xqt # 4F2BBqobOGMymwg6VgVjjzDIgJCZSbjpq2IoVTci5vli6vxgSoZ01fccSaKa4Izm # B7DbobIkIjLgPqpnCkqlHuJj5hQ9twIDAQABo4ICBjCCAgIwHwYDVR0jBBgwFoAU # aDfg67Y7+F8Rhvv+YXsIiGX0TkIwHQYDVR0OBBYEFCZd3/KEdT2t5WTIFb3TUaM4 # sTikMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzCBtQYDVR0f # BIGtMIGqMFOgUaBPhk1odHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRU # cnVzdGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEzODQyMDIxQ0ExLmNybDBToFGg # T4ZNaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0Q29k # ZVNpZ25pbmdSU0E0MDk2U0hBMzg0MjAyMUNBMS5jcmwwPgYDVR0gBDcwNTAzBgZn # gQwBBAEwKTAnBggrBgEFBQcCARYbaHR0cDovL3d3dy5kaWdpY2VydC5jb20vQ1BT # MIGUBggrBgEFBQcBAQSBhzCBhDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGln # aWNlcnQuY29tMFwGCCsGAQUFBzAChlBodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5j # b20vRGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEzODQyMDIx # Q0ExLmNydDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4ICAQAGyDM3Cbxq # Auhr8O2xwOoCSVKmFkXqicwlrugwLW44Y4WX+imvTrGfjj2S99k/4D5H8DgtW/u8 # tOxcCoehTOCIEwP5TLrieHppsqAR4jaJRcdAHOWiJ1bmwQBv/cBU9vaelL0oXxxf # TwD9oDaQNuyq6p+nIJMqbKv33b8AWGe3zq4JwblaFjRDL5lUDNhPx3g/pm7JhnbX # 7QTKydAJvpbuP5cqUH1GEeVMjc5vEELtGNy/fy7Ekm4dndX4IZcFXW5L0Lx8cReB # hIZwA+pzdzTWQYvfxgRMb/j2uY+Tkb6Wz2x9BBS1UXiP2qrs3rhQv8DZRkUSqnko # YD4uJP8gk8BXcIXIThgEF2YCq2hBiwna5Ijbwkmjn1lWwGv15SznTOTnrVApJqB1 # tB2s2ovUNV4CyKDPVr+9/CS6IQJfEZeHYcYLsIga2q5NZCrqZAasBfCwALVkALos # DIWhs33vYLfETMSuk5Hd5JC+hLjVM3ZJwslvnc/wec2r0GNAiZ3a1aweC7NYuzRz # 29Mi/eR/4ylmCltyZqYJ1JcC/g6eY2Q0xkdWc8P0yHfQ/3fe7+AKXXKNjfv858GW # lg1Ck2lvwPdLqJWqj1FwJPiGRCB+WulPe0csTyWnf+ed45TXx69tZ6BZr0Xr2jXu # ybBdJtg0NN0a62xxWrmX42CgsrzHzRm7OzGCAx4wggMaAgEBMH0waTELMAkGA1UE # BhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMUEwPwYDVQQDEzhEaWdpQ2Vy # dCBUcnVzdGVkIEc0IENvZGUgU2lnbmluZyBSU0E0MDk2IFNIQTM4NCAyMDIxIENB # MQIQAnNTGQOIer82vZ1cJyDJDjAJBgUrDgMCGgUAoHgwGAYKKwYBBAGCNwIBDDEK # MAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3 # AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU/Mqox8K6LMt+zb5y # FDz7djv90GIwDQYJKoZIhvcNAQEBBQAEggIAFb9vZnoV64T39RHD6Cgd25F7rFFu # mVl49fYlxFFLGDr1yh1ohRmhMShvh28UfKAf9r66pUWbKnAr6SovTXeYrddbmoz8 # jovB7Uv4P9DWXx2XwYmZbPM9vyq7kJALJyf3ShUHAqDqYRO2+VXICBEF6dfNLKX0 # kqS2yyj9UwSJ7bp8kI6MCNG5Xh2cy3x27CI/DSd9/vEIx7fBJbuUqRIjqJjX+VND # rB1dzQsPfRM5qAQH1m5gu6sRfJhM/89w9tAlvntaFr245UIgJ4noaPVnfy3skZZM # JAAQz+C19DXPyZQG/GckBU4w+yb9Xwtxh2OC2+I51BddI2ql3oOfvsvTcUsaLzO7 # aWlasyYcVcT8U3BSd32YNRj8xKTrj4CW+4ckRwS77aXkg3d9kpL4jz93LI4TqjaN # RTA6Y66yxtGDUW9q0f6SKJZ4hWTePnnZc7MEYVCB7fdCOLDw4ebdj4d9SC0Va3Tk # u5RnHr8qrZ8xTuPx2Fyxuwdoo/MlZnaCntZ9Pl1aab5oLfsYNfx4dlQ5G+BFRv9g # 2OBkrEuWIVdQsD/xGTc2JgrjykvRWC9tANrcUJu8MnOUwx8idwcMcJ0I5RbDHpgg # kVQI8IzWVGh9uut7R1K1CuNmu9Vawp51t1uMM9TPlO59tbE+eU2CCEMT8b6/sKZe # 74hs7gsIzaozuCg= # SIG # End signature block |