Install-SecureMFA_RDG_OTP_AuthenticationProvider.ps1

#Requires -RunAsAdministrator

<#
     .SYNOPSIS
        Installs SecureMFA RD Gateway OTP Authentication Provider.
    .DESCRIPTION
        SecureMFA RD Gateway OTP Authentication Provider plugin allows Microsoft RDS Gateway server to work with One-Time Pass codes which are elivered by RDP client as authentication cookie during user�s logon.
 
        Dependencies:
            * SecureMFA Tools COM extensions are required to be present on RDS gateway server to enable extraction of OTP codes for this service from SecureMFA database.
            * System which executes a script must have Microsoft Framework 4.6.1 and above installed.
            * SecureMFA_SupportTools.dll file must be present in script directory.
 
  
    .NOTES
        Version: 2.0.0.1
        Author: SecureMfa.com
        Creation Date: 15/07/2020
        Purpose/Change: Major changes
   
    .EXAMPLE
        C:\PS> Install-SecureMFA_RDG_OTP_AuthenticationProvider
 
        This command will install SecureMFA RD Gateway OTP Authentication Provider plugin on the server.
    
#>


$dllpath = (Join-Path -Path $PSScriptRoot -ChildPath sMFARDGAuthenticationProvider.dll)

#Check if windows events source for application log exist, if not create one.
if ([System.Diagnostics.EventLog]::SourceExists("SecureMFA_SupportTools") -eq $False) {New-EventLog -LogName "Application" -Source "SecureMFA_SupportTools" ; Write-Host "SecureMFA_SupportTools Log Source Created."}


Function Install-SecureMFA_RDG_OTP_AuthenticationProvider {
Param
(
    [Parameter(Mandatory=$false)][string]$anchordnsname = "adatum.labnet",
    [Parameter(Mandatory=$false)][string]$serialkey = "m000000",
    [Parameter(Mandatory=$false)][string]$subscriptionid = "1000000000000000000000001",
    [Parameter(Mandatory=$false)][string]$sqlserver = "asqlaol1.adatum.labnet",
    [Parameter(Mandatory=$false)][string]$sqldbname = "SecureMfaOTP",
    [Parameter(Mandatory=$false)][bool]$sqlintegratedsecurity = $true,
    [Parameter(Mandatory=$false)][string]$sqluseraccount = "sa",
    [Parameter(Mandatory=$false)][string]$sqluserpassword = "",
    [Parameter(Mandatory=$false)][bool]$data_encryption = $false,
    [Parameter(Mandatory=$false)][string]$data_encryption_passphrase = "d9GhT=7=Ox8-+LaZ",
    [Parameter(Mandatory=$false)][int]$timeout = 0,
    [Parameter(Mandatory=$false)][ValidateSet('0','1')][int]$timeoutaction = 0,
    [Parameter(Mandatory=$false)][int]$ui_login_failures = 0,
    [Parameter(Mandatory=$false)][int]$ui_lockout_minutes = 0,
    [Parameter(Mandatory=$false)][int]$totp_validity_seconds = 30,
    [Parameter(Mandatory=$false)][Switch]$NoServiceResart,
    [Parameter(Mandatory=$false)][Switch]$NoSamplePolicies,
    [Parameter(Mandatory=$false)][Switch]$Force
)
    
    #Check if TSGateway existi on the system
    if(((Get-Service tsgateway -ErrorAction SilentlyContinue).Status -eq $null) -and (!($Force))) {write-host "RD Gateway Authentication Provider requires RDS Gateway service to be installed. TS Gateway services doesn't exist on $env:COMPUTERNAME" -ForegroundColor Yellow; break}
    
    #Check if SecureMFA COM Extensions have been registered
    if((Test-Path -LiteralPath "HKLM:\SOFTWARE\Classes\SecureMFA_SupportTools.SecureMFACOM_Class") -ne $true) {  write-host "SecureMFA COM Extensions have not been installed on $env:COMPUTERNAME . Please use Install-SecureMFA_COM_Extensions command to register required COM extensions." -ForegroundColor Yellow; break };
     
    try
    {
        $Error.Clear()
        if (!(Test-Path $dllpath -Type Leaf) ) { throw "$dllpath does not exist" ; break}

        #Start deployment
        write-host "Creating SecureMFA RD Gateway OTPAuthentication Provider registry entries" -ForegroundColor Cyan

        if((Test-Path -LiteralPath "HKLM:\SOFTWARE\SecureMFA") -ne $true) {  New-Item "HKLM:\SOFTWARE\SecureMFA" -force -ea SilentlyContinue };
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'rds_sqlserver' -Value $sqlserver -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'rds_sqldbname' -Value $sqldbname -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'rds_sqlintegratedsecurity' -Value $sqlintegratedsecurity -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'rds_sqluseraccount' -Value $sqluseraccount -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'rds_sqluserpassword' -Value $sqluserpassword -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'rds_data_encryption' -Value ([Int32]$data_encryption) -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'rds_data_encryption_passphrase' -Value $data_encryption_passphrase -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'rds_ui_login_failures' -Value $ui_login_failures -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'rds_ui_lockout_minutes' -Value $ui_lockout_minutes -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'rds_totp_validity_seconds' -Value $totp_validity_seconds -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'rds_timeout' -Value $timeout -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'rds_timeoutaction' -Value $timeoutaction -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'rds_anchordnsname' -Value $anchordnsname -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'rds_serialkey' -Value $serialkey -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'rds_subscriptionid' -Value $subscriptionid -PropertyType String -Force -ea SilentlyContinue;

        write-host "Registering Authentication provider: $dllpath" -ForegroundColor Cyan

        #Set TS Gataway Authentication Plugin
        (get-WMIObject "Win32_TSGatewayServerSettings" -computer "." -Namespace "ROOT\CIMV2\TerminalServices").SetAuthenticationPluginAndRecycleRpcApplicationPools("SecureMFARdgAuthenticationProvider")
        
        #Register Authentication providers DLL
        $Result = Invoke-Command -ScriptBlock { regsvr32 /s $args[0] } -ArgumentList $dllpath        
        
        #Restart RDS Gateway service
        if((Get-Service tsgateway -ErrorAction SilentlyContinue).Status -ne $null -and (!($NoServiceResart))) {
        write-host "Restarting tsgateway service." -ForegroundColor Green
        Stop-Service tsgateway
        Start-Service tsgateway}


        if(!($NoServiceResart)){
        write-host "Configuring TS Gateway sample CAP and RAP policies." -ForegroundColor Green
        
        Import-Module RemoteDesktopServices
        $rds_gtw_CAP_name = 'CAP_Sample_All_Admins'
        $rds_gtw_RAP_name = 'RAP_Sample_All_Resources'

        if (!(Test-Path -Path "RDS:\GatewayServer\CAP\$rds_gtw_CAP_name") -and (!($NoSamplePolicies))) {
            #Create CAP for Administrators with passwrod authentication
            write-host "Creating: $rds_gtw_CAP_name" -ForegroundColor Green
            New-Item -Path "RDS:\GatewayServer\CAP" -Name $rds_gtw_CAP_name -UserGroups 'Administrators@BUILTIN' -AuthMethod 1

            #Enable session timeout (disconnect after 10h)
            set-item "RDS:\GatewayServer\CAP\$rds_gtw_CAP_name\SessionTimeout" -Value "600" -SessionTimeoutAction 0
            #Idle timeout sessions after 2h
            set-item "RDS:\GatewayServer\CAP\$rds_gtw_CAP_name\IdleTimeout" -Value "120"

            #Disable device redirections and allow only Clipboard copy.
            set-item "RDS:\GatewayServer\CAP\$rds_gtw_CAP_name\DeviceRedirection\DiskDrives" -Value 0
            set-item "RDS:\GatewayServer\CAP\$rds_gtw_CAP_name\DeviceRedirection\Printers" -Value 0
            set-item "RDS:\GatewayServer\CAP\$rds_gtw_CAP_name\DeviceRedirection\SerialPorts" -Value 0
            set-item "RDS:\GatewayServer\CAP\$rds_gtw_CAP_name\DeviceRedirection\PlugAndPlayDevices" -Value 0
            set-item "RDS:\GatewayServer\CAP\$rds_gtw_CAP_name\DeviceRedirection\Clipboard" -Value 1
        }
        ElseIf ($NoSamplePolicies) {write-host "$rds_gtw_CAP_name CAP rule creation skipping..." -ForegroundColor Yellow}
        else {write-host "$rds_gtw_CAP_name CAP rule exist skipping creation..." -ForegroundColor Yellow}

        if (!(Test-Path -Path "RDS:\GatewayServer\RAP\$rds_gtw_RAP_name") -and (!($NoSamplePolicies))) {
        #RAP Allow connections to any netwrok resource on port 3389
        write-host "Creating: $rds_gtw_RAP_name" -ForegroundColor Green
        New-Item -Path "RDS:\GatewayServer\RAP" -Name $rds_gtw_RAP_name -UserGroups 'Administrators@BUILTIN' -ComputerGroupType 2
        set-item "RDS:\GatewayServer\RAP\$rds_gtw_RAP_name\Description" -Value "Allow access to all resources"
        set-item "RDS:\GatewayServer\RAP\$rds_gtw_RAP_name\PortNumbers" -Value @("3389")
        }
        ElseIf  ($NoSamplePolicies) {write-host "$rds_gtw_RAP_name RAP rule creation skipping..." -ForegroundColor Yellow}
        else {write-host "$rds_gtw_RAP_name RAP rule exist skipping creation..." -ForegroundColor Yellow}

        };

        Write-host "RD Gateway Authentication Plugig has been configured: "(Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Terminal Server Gateway\Authentication plug-ins').'(default)' -ForegroundColor Cyan
        
    }
    catch
    {
        Write-Host "$($MyInvocation.InvocationName): $_" -ForegroundColor red
    }    


}