Allows you to perform DirectAccess scripting using the XML file created by the DirectAccess Setup Wizard. This script requires both Windows PowerShell and the corresponding version of the .NET Framework.

PowerShell
Edit|Remove
#-----------------------------------------------------------------------
# <copyright file="engine.ps1" company="Microsoft">
#     Copyright (c) Microsoft Corporation.  All rights reserved.
# </copyright>
# <summary>This script can be used to configure DirectAccess.</summary>
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
# If the admin running this script wants to perform Group Policy operations (mode = gpsettingonly/ all),
# he/she would need permissions to create or edit Group Policy objects, 
# link the GPOs to the domain and modify security filtering on the GPO.
#-----------------------------------------------------------------------

param($mode, $data, $log)

function LogToFile ([string] $msg)
{
    Add-Content $logFile -Encoding Unicode -value $msg
}

function pscmdexec ([string[]] $msg)
{   
    $cmd = $msg[0]
    $desc = $msg[1]
    DebugPrint $desc
    $firstStep = [string][DateTime]::Now + " Step: " + $desc
    $secondStep = "`t" + "Executing: "
    $output = "`t" + "Output: "
    $cmd = $ExecutionContext.InvokeCommand.ExpandString($cmd) 
    $secondStep += $cmd
    LogToFile $firstStep
    LogToFile $secondStep
    
    trap 
    { 
        $output += $error[0];
    LogToFile $output
    ErrorPrint $error[0];
        ErrorPrint "DirectAccess Server configuration failed."
        exit 
    }

    $dummy = Invoke-Expression $cmd
    $output += "Success"
    LogToFile $output
}

function GPOExists([string] $GPOName)
{
    $dummy = Get-GPO "$GPOName" -ErrorAction 'silentlycontinue'
    if(-not $?)
    {
return $FALSE
    }
    else
    {
return $TRUE
    }
}

function ClearExistingLinkedSG([string] $gponame)
{
    $gpo = Get-GPO $gponame
    foreach($sec in $gpo.GetSecurityInfo())
    {
        if($sec.Permission -ieq "GpoApply")
        {
            switch ($sec.Trustee.SidType.value__)
            {
                1 {$TrusteeType="user"}
                2 {$TrusteeType="group"}
                5 {$TrusteeType="group"}
                9 {$TrusteeType="computer"}
            }

            $dummy = Set-GPPermissions -Name $gponame -TargetName $sec.Trustee.Name -TargetType $TrusteeType -PermissionLevel None
        }
    } 
}

function ClearNRPT()
{
    $ErrorActionPreference = "silentlycontinue"
    $subkeys = Get-GPRegistryValue -Name $ClientGPOName -Key "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient\DnsPolicyConfig"
    $ErrorActionPreference = "stop"
    if($NULL -ne $subkeys)
    {
        foreach($key in $subkeys)
        {
           $dummy = Remove-GPRegistryValue -Name $ClientGPOName -Key $key.FullKeyPath
        }
    }
}

function netshipseccmdexec ([string[]] $msg, [bool] $breakOnError = $TRUE)
{  
    $setstore = $msg[0]
    $cmd = $msg[1]
    $desc = $msg[2]
    DebugPrint $desc
    $firstStep = [string][DateTime]::Now + " Step: " + $desc
    $secondStep = "`t" + "Executing: "
    $output = "`t" + "Output: "
    $setstore = $ExecutionContext.InvokeCommand.ExpandString($setstore) 
    $cmd = $ExecutionContext.InvokeCommand.ExpandString($cmd) 
    $secondStep += $setstore
    LogToFile $firstStep
    LogToFile $secondStep
    LogToFile $cmd
    
    Set-Content -path "$env:temp\da.nsh" -value $setstore
    Add-Content -path "$env:temp\da.nsh" -value $cmd
    $exec = "netsh exec " + "$env:temp\da.nsh"
        
    $dummy = Invoke-Expression $exec
    Remove-Item -path "$env:temp\da.nsh"
    if($LastExitCode -gt 0)
    {
        $output += "Failure";
    LogToFile $output
        if ($breakOnError -eq $TRUE)
        {
            ErrorPrint $dummy;
            ErrorPrint "DirectAccess Server configuration failed."
            exit 
        }
    }
    else
    {
        $output += "Success"
        LogToFile $output
    }
}


function cmdexec ([string[]] $msg, [bool]$breakOnError = $TRUE, [int]$swallowErrorCode = 0)
{   
    $cmd = $msg[0]
    $desc = $msg[1]
    DebugPrint $desc
    $firstStep = [string][DateTime]::Now + " Step: " + $desc
    $secondStep = "`t" + "Executing: "
    $output = "`t" + "Output: "
    $cmd = $ExecutionContext.InvokeCommand.ExpandString($cmd) 
    $secondStep += $cmd
    LogToFile $firstStep
    LogToFile $secondStep
    
    $ret = Invoke-Expression $cmd
    if(($LastExitCode -gt 0) -and ($LastExitCode -ne $swallowErrorCode))
    {
        $output += $ret;
        LogToFile $output
        if ($breakOnError -eq $TRUE)
        {
            ErrorPrint $ret;
            ErrorPrint "DirectAccess Server configuration failed."
            exit 
        }
    }
    else
    {
        $output += "Success"
        LogToFile $output
    }
}

function DebugPrint ([string] $str)
{
    $host.UI.WriteLine("yellow", "black", "$str")
}

function ErrorPrint ([string] $str)
{
    $host.UI.WriteLine("red", "black", "$str")
}

function loadxml ([string] $xml = "$env:windir\DirectAccess\DirectAccessConfig.xml")
{
    $ErrorActionPreference="silentlycontinue"
    ($snapindata = [xml]"<root></root>").Load($xml)
    if(-not $?)
    {
        ErrorPrint "Couldn't load the xml file $str"
        ErrorPrint "Usage: .\engine.ps1 -mode <serveronly|gpsettingonly|all> [-data <XMLfilepath>] [-log <logfilepath>]"
        exit
    }

    if($($snapindata.root.State) -ine "Complete")
    {
        ErrorPrint "Script cannot be run on partially saved configuration."
        exit
    }
    
    if($($snapindata.root.Version) -ine "1.0")
    {
        ErrorPrint "Script cannot be run on the version of XML file given as input."
        exit
    }
    
    $ErrorActionPreference="stop"
}

function initLogFile([string] $log)
{
    $dummy = New-Item -path $log -type "file" -Force -ErrorAction silentlycontinue
    if(-not $?)
    {
        ErrorPrint "Couldn't open the log file $log"
        ErrorPrint "Usage: .\engine.ps1 -mode <serveronly|gpsettingonly|all> [-data <XMLfilepath>] [-log <logfilepath>]"
    }
}

# Function to insert breakpoint in scripts
function bp ([scriptblock] $condition)
{
    if($condition)
    {
        if(. $condition )
        {
            $host.ui.WriteLine("*break*")
            $host.EnterNestedPrompt()
        }
    } else {
        $host.UI.WriteLine("*break*")
    $host.EnterNestedPrompt()
    }
}

function initDefaults
{
    $ClientGPOName = "$($snapindata.root.GPO.ClientPolicies.GPOName)"
    $ServerGPOName = "$($snapindata.root.GPO.ServerPolicies.GPOName)"
    $AppServerGPOName = "$($snapindata.root.GPO.AppServerPolicies.GPOName)"
    
    $NCSIKey = "HKLM\Software\Policies\Microsoft\Windows\NetworkConnectivityStatusIndicator\CorporateConnectivity"
    $NRPTKey = "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient\DnsPolicyConfig"
    $NRPTOptions = "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient"
    $v6TransitionKey = "HKLM\SOFTWARE\Policies\Microsoft\Windows\TCPIP\v6Transition"
    $IpHttpsInterface = $v6TransitionKey + "\iphttps\iphttpsinterface"
    $SetStoreClientGPO = "advfirewall set store GPO=```"$($snapindata.root.GPO.Common.DomainName)\$ClientGPOName```""
    $SetStoreServerGPO = "advfirewall set store GPO=```"$($snapindata.root.GPO.Common.DomainName)\$ServerGPOName```""
    $SetStoreAppServerGPO = "advfirewall set store GPO=```"$($snapindata.root.GPO.Common.DomainName)\$AppServerGPOName```""
    
    $corpConnectivityDnsProbeHostName = "directaccess-corpConnectivityHost"
    $corpConnectivityDnsProbeHostAddress = "::1"
    $dnsProbeHostFQDN =  $corpConnectivityDnsProbeHostName + "." + $($snapindata.root.GPO.Common.DomainName)
    
    [bool]$appcmdpresent = [System.IO.File]::Exists($env:windir + "\system32\inetsrv\appcmd.exe")
    if($appcmdpresent)
    {
        $env:path += ";$env:SystemRoot\system32\inetsrv\"
        $IISRootPhysicalPath = appcmd.exe LIST VDIR "Default Web Site/" /text:physicalpath
        $IISRootPhysicalPath = [System.Environment]::ExpandEnvironmentVariables($IISRootPhysicalPath)
    }
    
    $iphttpsprefix = $($snapindata.root.ServerData.IPHttps.IpHttpsPrefix).Split("/")[0]
    $corpprefix = $($snapindata.root.ServerData.CorpPrefix).Split("/")[0]
    
    foreach($address in $snapindata.root.GPO.Common.AppServers.Address)
    {
        $AppServers = $AppServers + $address + ","
    }
    
    $AppServers = $AppServers.Trim(",")
    
    foreach($address in $snapindata.root.GPO.Common.DnsServers.Address)
    {
        $DnsServers = $DnsServers + $address + ","
    }
    
    $DnsServers = $DnsServers.Trim(",")
    
    foreach($address in $snapindata.root.GPO.Common.MgmtServers.Address)
    {
        $MgmtServers = $MgmtServers + $address + ","
    }
    
    $MgmtServers = $MgmtServers.Trim(",")
    
    
    [bool]$dnscmdpresent = [System.IO.File]::Exists($env:windir + "\system32\dnscmd.exe")
}

#--------------------------------------------------------------------------------------------------------------------------------------------
#                                                                   Starting the script
#--------------------------------------------------------------------------------------------------------------------------------------------

$ErrorActionPreference = "stop"

# Check mode
if($mode)
{
    if(($mode -ine "serveronly") -and ($mode -ine "gpsettingonly") -and ($mode -ine "all"))
    {
        ErrorPrint "Incorrect mode $mode specified. Valid modes are serveronly,gpsettingonly or all"
        ErrorPrint "Usage: .\engine.ps1 -mode <serveronly|gpsettingonly|all> [-data <XMLfilepath>] [-log <logfilepath>]"
        exit
    }
}
else
{
    ErrorPrint "Mode not specified";
    ErrorPrint "Usage: .\engine.ps1 -mode <serveronly|gpsettingonly|all> [-data <XMLfilepath>] [-log <logfilepath>]"
    exit
}

# Load the data xml
if($data)
{
    . loadxml $data
}
else
{
    . loadxml
}

# Initialize the log file
if($log)
{
    $logFile = $log
}
else
{
    $logFile = ".\DirectAccess_log.txt"
}
initLogFile $logfile

. initDefaults

#--------------------------------------------------------------------------------------------------------------------------------------------
#                                                                Starting command execution
#--------------------------------------------------------------------------------------------------------------------------------------------

# Always create this path
pscmdexec("New-Item -Path HKLM:\System\CurrentControlSet\Services\iphlpsvc -name DirectAccess -ErrorAction silentlycontinue", "Creating registry key HKLM:\System\CurrentControlSet\Services\iphlpsvc\DirectAccess")

if(($mode -ieq "serveronly") -or ($mode -ieq "all"))
{
    # Clearing the DaServerEnabled RegistryValue
    pscmdexec("New-ItemProperty -Path HKLM:\System\CurrentControlSet\Services\iphlpsvc\DirectAccess -name DaServerEnabled -value 0 -PropertyType DWORD -Force", "Clearing HKLM:\System\CurrentControlSet\Services\iphlpsvc\DirectAccess\DaServerEnabled")

    # Enabling Transition technologies

    cmdexec("netsh interface ipv6 set interface ```"$($snapindata.root.ServerData.InternetInterface.Name)```" forwarding=enabled", "Enable forwarding on internet interface.") $FALSE
    if($($snapindata.root.ServerData.IsV6Deployed) -ieq "True")
    {
        cmdexec("netsh interface ipv6 set interface ```"$($snapindata.root.ServerData.InternalNetworkInterface.Name)```" forwarding=enabled", "Enable forwarding on intranet interface.")
    }
    else
    {
        cmdexec("netsh interface isatap set state enabled", "Enable isatap")
        cmdexec("netsh interface isatap set router $($snapindata.root.ServerData.TransitionTechnologies.ISATAP.IsatapRouterName) enabled", "Enable isatap router")
        cmdexec("netsh interface ipv6 set interface ```"$($snapindata.root.ServerData.TransitionTechnologies.ISATAP.IsatapInterfaceName)```" forwarding=enabled advertise=enabled advertisedefaultroute=enabled", "Enable forwarding and advertising defaultroute on isatap interface")
        cmdexec("netsh interface ipv6 delete route $($snapindata.root.ServerData.CorpPrefix) ```"$($snapindata.root.ServerData.TransitionTechnologies.ISATAP.IsatapInterfaceName)```"", "Deleting old route on isatap interface") $FALSE
        cmdexec("netsh interface ipv6 add route $($snapindata.root.ServerData.CorpPrefix) ```"$($snapindata.root.ServerData.TransitionTechnologies.ISATAP.IsatapInterfaceName)```" publish=yes", "Route creation on isatap interface")
    }
        
    cmdexec("netsh interface teredo set state server servername=$($snapindata.root.ServerData.TransitionTechnologies.Teredo.FirstInternetGlobalAddress)", "Enable teredo")
    cmdexec("netsh interface ipv6 set interface ```"Teredo Tunneling Pseudo-Interface```" forwarding=enabled", "Enable forwarding on teredo interface")
    cmdexec("netsh interface 6to4 set state enabled", "Enable 6to4")
    cmdexec("netsh interface ipv6 set interface ```"6TO4 Adapter```" forwarding=enabled", "Enable forwarding on 6To4 interface")
    cmdexec("netsh interface httpstunnel delete interface", "Delete IpHttps interface if already present.") $FALSE
    cmdexec("netsh interface httpstunnel add interface server $($snapindata.root.ServerData.IPHttps.IpHttpsServerURL) enabled certificates", "Enable IpHttps")
    cmdexec("netsh interface ipv6 set interface IPHTTPSInterface forwarding=enabled advertise=enabled", "Enable forwarding and advertising on IpHttps interface")
    cmdexec("netsh interface ipv6 delete route $($snapindata.root.ServerData.IPHttps.IpHttpsPrefix) IPHTTPSInterface", "Delete old route on IpHttps interface") $FALSE
    cmdexec("netsh interface ipv6 add route $($snapindata.root.ServerData.IPHttps.IpHttpsPrefix) IPHTTPSInterface publish=yes", "Route creation on IpHttps interface")

    # Dosp Configuration
    cmdexec("netsh ipsecdosprotection delete interface ```"$($snapindata.root.ServerData.InternalNetworkInterface.Name)```"", "Deleting existing settings for IPsec DOS Protection.") $FALSE
    cmdexec("netsh ipsecdosprotection delete interface ```"$($snapindata.root.ServerData.InternetInterface.Name)```"", "Deleting existing settings for IPsec DOS Protection.") $FALSE

    cmdexec("netsh ipsecdosprotection add interface ```"$($snapindata.root.ServerData.InternalNetworkInterface.Name)```" internal", "Configuring IPsec DOS Protection intranet interface")
    cmdexec("netsh ipsecdosprotection add interface ```"$($snapindata.root.ServerData.InternetInterface.Name)```" public", "Configuring IPsec DOS Protection internet interface")
    $rate = $($snapindata.root.ServerData.DOSPConfig.IPsecUnauthenticatedPerIPRate)
    if($rate -eq "0")
    {
        $rate = "disable"
    }
    
    cmdexec("netsh ipsecdosprotection set ratelimit ipsecunauthenticatedperip $rate", "Configuring IPsec DOS Protection intranet interface")
    $rate = $($snapindata.root.ServerData.DOSPConfig.IPsecAuthenticatedRate)
    if($rate -eq "0")
    {
        $rate = "disable"
    }
    
    cmdexec("netsh ipsecdosprotection set ratelimit ipsecauthenticated $rate", "Configuring IPsec DOS Protection intranet interface")
    $rate = $($snapindata.root.ServerData.DOSPConfig.ICMPv6Rate)
    if($rate -eq "0")
    {
        $rate = "disable"
    }
    
    cmdexec("netsh ipsecdosprotection set ratelimit icmpv6 $rate", "Configuring IPsec DOS Protection intranet interface")

    # Isatap Registration
    if($dnscmdpresent -and ($($snapindata.root.ServerData.IsV6Deployed) -ine "True"))
    {
        cmdexec("dnscmd.exe /RecordDelete $($snapindata.root.GPO.Common.DomainName) isatap A $($snapindata.root.ServerData.TransitionTechnologies.ISATAP.CorpV4Address) /f", "Isatap de-registration.") $FALSE
        cmdexec("dnscmd.exe /RecordAdd $($snapindata.root.GPO.Common.DomainName) isatap A $($snapindata.root.ServerData.TransitionTechnologies.ISATAP.CorpV4Address)", "Isatap registration.")
    }

    # IIS Operation
    cmdexec("netsh http delete sslcert ipport=0.0.0.0:443", "IIS: Delete '*' binding.") $FALSE
    if($appcmdpresent)
    {
        cmdexec("appcmd.exe set config  -section:system.applicationHost/sites /-```"[name=```'Default Web Site```'].bindings.[protocol=```'https```',bindingInformation=```'*:443:```']```" /commit:apphost", "IIS: Delete '*' binding.") $FALSE
    }

    if($($snapindata.root.GPO.ClientPolicies.NID.NidCertHash) -eq $null)
    {
        cmdexec("netsh http add sslcert ipport=0.0.0.0:443 certhash=$($snapindata.root.ServerData.IPHttps.IpHttpsCertHash) appid=```"{5d8e2743-ef20-4d38-8751-7e400f200e65}```" dsmapperusage=enable", "IIS: Add '*' binding.")
    }
    else
    {
        foreach($address in $snapindata.root.IIS.IpHttpsAddresses.Address)
        {
            if($address.Contains(":") -eq $TRUE)
            {
                $address = "[" + $address + "]"
            }

            cmdexec("netsh http delete sslcert ipport=`"$address`":443", "IIS: Delete old binding.") $FALSE
            cmdexec("netsh http add sslcert ipport=`"$address`":443 certhash=$($snapindata.root.ServerData.IPHttps.IpHttpsCertHash) appid=```"{4dc3e181-e14b-4a21-b022-59fc669b0914}```" dsmapperusage=enable", "IIS: Add IpHttps binding.")
            if($appcmdpresent)
            {
                cmdexec("appcmd.exe set config  -section:system.applicationHost/sites /+```"[name=```'Default Web Site```'].bindings.[protocol=```'https```',bindingInformation=```'`"$address`":443:```']```" /commit:apphost", "IIS: Add IpHttps binding.") -swallowErrorCode 183
            }
        }
        
        foreach($address in $($snapindata.root.IIS.InOutAddresses.Address))
        {
            if($address.Contains(":") -eq $TRUE)
            {
                $address = "[" + $address + "]"
            }

            cmdexec("netsh http delete sslcert ipport=`"$address`":443", "IIS: Delete old binding.") $FALSE
            cmdexec("netsh http add sslcert ipport=`"$address`":443 certhash=$($snapindata.root.GPO.ClientPolicies.NID.NidCertHash) appid=```"{4dc3e181-e14b-4a21-b022-59fc669b0914}```"", "IIS: Add InOut binding.")
            if($appcmdpresent)
            {
                cmdexec("appcmd.exe set config  -section:system.applicationHost/sites /+```"[name=```'Default Web Site```'].bindings.[protocol=```'https```',bindingInformation=```'`"$address`":443:```']```" /commit:apphost", "IIS: Add InOut binding.") -swallowErrorCode 183
            }
        }
    }

    if($($snapindata.root.GPO.ClientPolicies.NID.NidCertHash))
    {
        pscmdexec("New-Item -Path $IISRootPhysicalPath\insideoutside -Type Directory -Force", "IIS: Create Inside outside virtual directory, physical path.")
        pscmdexec("Copy-Item $IISRootPhysicalPath\iisstart.htm $IISRootPhysicalPath\insideoutside\", "IIS: Copying iisstart.htm.")
        pscmdexec("Copy-Item $IISRootPhysicalPath\welcome.png $IISRootPhysicalPath\insideoutside\", "IIS: Copying welcome.png.")
        if($appcmdpresent) 
        {       
            cmdexec("appcmd.exe add VDIR /app.name:```"Default Web Site/```" /path:/insideoutside /physicalPath:$IISRootPhysicalPath\insideoutside /commit:apphost", "IIS: Create Inside outside virtual directory.") -swallowErrorCode 183
            ## Add IIS Filtering.
            cmdexec("appcmd.exe set config ```"Default Web Site/insideoutside```" -section:system.webServer/security/ipSecurity /allowUnlisted:```"false```"  /commit:apphost", "IIS Filtering: Setting allowUnlisted to false")
            cmdexec("appcmd.exe set config ```"Default Web Site/insideoutside```" -section:system.webServer/security/ipSecurity /+```"[ipAddress=```'`"$iphttpsprefix`"```',subnetMask=```'ffff:ffff:ffff:ffff::```',allowed=```'false```']```"  /commit:apphost", "IIS Filtering: Set filter for IpHttps Prefix") -swallowErrorCode 183
            cmdexec("appcmd.exe set config ```"Default Web Site/insideoutside```" -section:system.webServer/security/ipSecurity /+```"[ipAddress=```'`"$corpprefix`"```',subnetMask=```'ffff:ffff:ffff::```',allowed=```'true```']```"  /commit:apphost", "IIS Filtering: Set filter for Corp Prefix") -swallowErrorCode 183
            cmdexec("appcmd.exe set config ```"Default Web Site/insideoutside```" -section:system.webServer/security/ipSecurity /+```"[ipAddress=```'0.0.0.0```',subnetMask=```'0.0.0.0```',allowed=```'true```']```"  /commit:apphost", "IIS Filtering: Set filter for all IPv4 addresses") -swallowErrorCode 183
        }
    }
    elseif($appcmdpresent)
    {
        pscmdexec("Remove-Item -Path $IISRootPhysicalPath\insideoutside -Recurse -ErrorAction silentlycontinue", "IIS: Deleting Inside outside virtual directory, physical path.")
        cmdexec("appcmd.exe delete VDIR ```"Default Web Site/insideoutside```" /commit:apphost", "IIS: Delete Inside outside virtual directory.") -swallowErrorCode 50
    }

    # Creating local registries
    DebugPrint "Creating Local Registry Settings."
    LogToFile "Setting Registry values"
    pscmdexec("New-ItemProperty -Path HKLM:\System\CurrentControlSet\Services\iphlpsvc\DirectAccess -name DaInternetFacingNic -value ```"$($snapindata.root.ServerData.InternetInterface.Id)```" -Force", "Setting HKLM:\System\CurrentControlSet\Services\iphlpsvc\DirectAccess\DaInternetFacingNic")
    pscmdexec("New-ItemProperty -Path HKLM:\System\CurrentControlSet\Services\iphlpsvc\DirectAccess -name DaIntranetFacingNic -value ```"$($snapindata.root.ServerData.InternalNetworkInterface.Id)```" -Force", "Setting HKLM:\System\CurrentControlSet\Services\iphlpsvc\DirectAccess\DaIntranetFacingNic")
    pscmdexec("New-ItemProperty -Path HKLM:\System\CurrentControlSet\Services\iphlpsvc\DirectAccess -name TeredoRelayEnabled -value 1 -PropertyType DWORD -Force", "Setting HKLM:\System\CurrentControlSet\Services\iphlpsvc\DirectAccess\TeredoRelayEnabled")
    pscmdexec("New-ItemProperty -Path HKLM:\System\CurrentControlSet\Services\iphlpsvc\DirectAccess -name NidUrl -value $($snapindata.root.GPO.ClientPolicies.NID.NidURL) -Force", "Setting HKLM:\System\CurrentControlSet\Services\iphlpsvc\DirectAccess\NidUrl")
    pscmdexec("New-ItemProperty -Path HKLM:\System\CurrentControlSet\Services\iphlpsvc\DirectAccess -name NcsiRrName -value $dnsProbeHostFQDN -Force", "Setting HKLM:\System\CurrentControlSet\Services\iphlpsvc\DirectAccess\NcsiRrName")
    pscmdexec("New-ItemProperty -Path HKLM:\System\CurrentControlSet\Services\iphlpsvc\DirectAccess -name NcsiRrIp -value $corpConnectivityDnsProbeHostAddress -Force", "Setting HKLM:\System\CurrentControlSet\Services\iphlpsvc\DirectAccess\NcsiRrIp")

    $regValue = Get-ItemProperty -Path HKLM:\System\CurrentControlSet\Services\Netlogon\Parameters
    if($regValue.MaxConcurrentApi -ne 5)
    {
        pscmdexec("New-ItemProperty -Path HKLM:\System\CurrentControlSet\Services\Netlogon\Parameters -name MaxConcurrentApi -value 5 -PropertyType DWORD -Force", "Setting multiple concurrent NTLM authentication value to 5")
        pscmdexec("Restart-Service netlogon", "Restarting Netlogon service")
    }

    if($mode -ieq "serveronly" -and ($($snapindata.root.ServerData.IsV6Deployed) -ine "True") -and (-not $dnscmdpresent))
    {
        LogToFile "ISATAP Registration needs to be done manually."
        $host.UI.WriteLine("magenta", "black", "ISATAP Registration needs to be done manually.")
    }
}

if(($mode -ieq "gpsettingonly") -or ($mode -ieq "all"))
{
    # Load GroupPolicy module.
    pscmdexec("Import-Module GroupPolicy","Load GroupPolicy module.")

    # Client GPO 
    LogToFile("---DA Client GPO operations---")
    $exists = GPOExists($ClientGPOName)
    if($exists -ne $TRUE) 
    {
        pscmdexec("New-GPO ```"$ClientGPOName```"", "Creating Client GPO")
    }
    else
    {
        $ErrorActionPreference = "silentlycontinue"
        $dummy = Remove-GPLink -Name "$ClientGPOName" -Target "$($snapindata.root.GPO.Common.DistinguishedDomainName)"
        $ErrorActionPreference = "stop"
        netshipseccmdexec($SetStoreClientGPO, "advfirewall consec delete rule name=```"$($snapindata.root.GPO.ClientPolicies.ClientToDnsPolicy)```"", "Deleting existing ClientToDnsPolicy") $FALSE
        netshipseccmdexec($SetStoreClientGPO, "advfirewall consec delete rule name=```"$($snapindata.root.GPO.ClientPolicies.ClientToCorpPolicy)```"", "Deleting existing ClientToCorpPolicy") $FALSE
        netshipseccmdexec($SetStoreClientGPO, "advfirewall consec delete rule name=```"$($snapindata.root.GPO.ClientPolicies.ClientToMgmtPolicy)```"", "Deleting existing ClientToMgmtPolicy") $FALSE
        netshipseccmdexec($SetStoreClientGPO, "advfirewall consec delete rule name=```"$($snapindata.root.GPO.ClientPolicies.ClientToApplicationServerPolicy)```"", "Deleting existing ClientToApplicationServerPolicy") $FALSE
        netshipseccmdexec($SetStoreClientGPO, "advfirewall consec delete rule name=```"$($snapindata.root.GPO.ClientPolicies.ClientToApplicationServerExemptPolicy)```"", "Deleting existing ClientToApplicationServerExemptPolicy") $FALSE
        netshipseccmdexec($SetStoreClientGPO, "advfirewall consec delete rule name=```"$($snapindata.root.GPO.ClientPolicies.ClientToNlaExemptPolicy)```"", "Deleting existing ClientToNlaExemptPolicy") $FALSE
        netshipseccmdexec($SetStoreClientGPO, "advfirewall firewall delete rule name=```"$($snapindata.root.GPO.ClientPolicies.IpHttpsOutRuleName)```"", "Deleting existing outbound IPHTTPS rule.") $FALSE
    }

    pscmdexec("New-GPLink -Name ```"$ClientGPOName```" -Target ```"$($snapindata.root.GPO.Common.DistinguishedDomainName)```"","Link Client GPO to domain")
    ClearExistingLinkedSG($ClientGPOName)

    # Link security group to Client GPO
    foreach($n in $snapindata.root.GPO.ClientPolicies.SecurityGroups.SecurityGroup)
    {
        if($n)
        {
            pscmdexec("Set-GPPermissions -TargetName ```"$($n.Name)```" -Name ```"$ClientGPOName```" -PermissionLevel GpoApply -TargetType $($n.Type)","Link security group to Client GPO")
        }
    }

    # NCSI Settings
    
    pscmdexec("Set-GPRegistryValue -Name ```"$ClientGPOName```" -Key $NCSIKey -ValueName DnsProbeHost -Value $dnsProbeHostFQDN -Type String","Set DnsProbeHost")
    pscmdexec("Set-GPRegistryValue -Name ```"$ClientGPOName```" -Key $NCSIKey -ValueName DnsProbeContent -Value $corpConnectivityDnsProbeHostAddress -Type String","Set DnsProbeContent")
    pscmdexec("Set-GPRegistryValue -Name ```"$ClientGPOName```" -Key $NCSIKey -ValueName SitePrefixes -Value $($snapindata.root.GPO.Common.CorpV6) -Type String","Set SitePrefixes")
    pscmdexec("Set-GPRegistryValue -Name ```"$ClientGPOName```" -Key $NCSIKey -ValueName DomainLocationDeterminationUrl -Value $($snapindata.root.GPO.ClientPolicies.NID.NidURL) -Type String","Set DomainLocationDeterminationUrl")

    # NRPT Settings
    # This is to set the DNS option for fallback
    if($($snapindata.root.GPO.ClientPolicies.DnsFallBackOptions) -ieq "DnsFallbackValueNameDoesNotExist")    
    {
        pscmdexec("Set-GPRegistryValue -Name ```"$ClientGPOName```" -Key ```"$NRPTOptions```" -ValueName DnsSecureNameQueryFallback -Value 0 -Type Dword","Set DnsSecureNameQueryFallback")
    }
    elseif($($snapindata.root.GPO.ClientPolicies.DnsFallBackOptions) -ieq "DnsAlwaysFallbackPrivateOnly")
    {
        pscmdexec("Set-GPRegistryValue -Name ```"$ClientGPOName```" -Key ```"$NRPTOptions```" -ValueName DnsSecureNameQueryFallback -Value 2 -Type Dword","Set DnsSecureNameQueryFallback")
    }
    elseif($($snapindata.root.GPO.ClientPolicies.DnsFallBackOptions) -ieq "DnsAlwaysFallbackForAnyError")
    {
        pscmdexec("Set-GPRegistryValue -Name ```"$ClientGPOName```" -Key ```"$NRPTOptions```" -ValueName DnsSecureNameQueryFallback -Value 1 -Type Dword","Set DnsSecureNameQueryFallback")
    }

    # Clear old NRPT settings first
    ClearNRPT
    
    foreach($n in $snapindata.root.GPO.ClientPolicies.NRPT.entry)
    {
        pscmdexec("Set-GPRegistryValue -Name ```"$ClientGPOName```" -Key ```"$NRPTKey\$($n.PolicyName)```" -ValueName Version -Value 1 -Type DWord","Set Dns Policy Version")
        pscmdexec("Set-GPRegistryValue -Name ```"$ClientGPOName```" -Key ```"$NRPTKey\$($n.PolicyName)```" -ValueName ConfigOptions -Value 4 -Type DWord","Set Dns Policy Config options")
        $name = "@(```"$($n.Name)```")"
        pscmdexec("Set-GPRegistryValue -Name ```"$ClientGPOName```" -Key ```"$NRPTKey\$($n.PolicyName)```" -ValueName Name -Value $name -Type MultiString","Set Dns Policy Name")
        pscmdexec("Set-GPRegistryValue -Name ```"$ClientGPOName```" -Key ```"$NRPTKey\$($n.PolicyName)```" -ValueName DirectAccessDNSServers -Value ```"$($n.DirectAccessDNSServers)```" -Type String","Set DirectAccessDNSServers")
        pscmdexec("Set-GPRegistryValue -Name ```"$ClientGPOName```" -Key ```"$NRPTKey\$($n.PolicyName)```" -ValueName DirectAccessQueryIPSECRequired -Value 0 -Type DWord","Set DirectAccessQueryIPSECEncryption")
        pscmdexec("Set-GPRegistryValue -Name ```"$ClientGPOName```" -Key ```"$NRPTKey\$($n.PolicyName)```" -ValueName DirectAccessQueryIPSECEncryption -Value 0 -Type DWord","Set DirectAccessQueryIPSECEncryption")
        pscmdexec("Set-GPRegistryValue -Name ```"$ClientGPOName```" -Key ```"$NRPTKey\$($n.PolicyName)```" -ValueName IPSECCARestriction -Value ```"$($snapindata.root.GPO.Common.RootCert)```" -Type String","Set IPSECCARestriction")
        pscmdexec("Set-GPRegistryValue -Name ```"$ClientGPOName```" -Key ```"$NRPTKey\$($n.PolicyName)```" -ValueName DirectAccessProxyName -Value ```"```" -Type String","Set DirectAccessProxyName")
        pscmdexec("Set-GPRegistryValue -Name ```"$ClientGPOName```" -Key ```"$NRPTKey\$($n.PolicyName)```" -ValueName DirectAccessProxyType -Value 0 -Type DWord","Set DirectAccessProxyType")
        
        if($($n.DirectAccessDNSServers))
        {
            $dnsServerAddresses = $dnsServerAddresses + $($n.DirectAccessDNSServers) + ","
        }
    }

    # Set v6Transition settings on client gpo
        pscmdexec("Set-GPRegistryValue -Name ```"$ClientGPOName```" -Key $v6TransitionKey -ValueName Teredo_ServerName -Value $($snapindata.root.ServerData.TransitionTechnologies.Teredo.FirstInternetGlobalAddress) -Type String","Set Teredo Server Name")
        pscmdexec("Set-GPRegistryValue -Name ```"$ClientGPOName```" -Key $v6TransitionKey -ValueName Teredo_DefaultQualified -Value Enabled -Type String","Set Teredo default qualified value.")
        pscmdexec("Set-GPRegistryValue -Name ```"$ClientGPOName```" -Key $v6TransitionKey -ValueName 6to4_RouterName -Value $($snapindata.root.ServerData.TransitionTechnologies.Teredo.FirstInternetGlobalAddress) -Type String","Set 6to4 Router Name")
        pscmdexec("Set-GPRegistryValue -Name ```"$ClientGPOName```" -Key $IpHttpsInterface -ValueName IpHttps_ClientURL -Value $($snapindata.root.ServerData.IPHttps.IpHttpsServerURL) -Type String","Set IpHttps Client URL")
        pscmdexec("Set-GPRegistryValue -Name ```"$ClientGPOName```" -Key $IpHttpsInterface -ValueName InterfaceRole -Value 0 -Type DWord","Set IpHttps interface role")
        pscmdexec("Set-GPRegistryValue -Name ```"$ClientGPOName```" -Key $IpHttpsInterface -ValueName IPHTTPS_ClientState -Value 0 -Type DWord","Set IpHttps State")    
        
    # Connection Security Rules in GPO

    netshipseccmdexec($SetStoreClientGPO, "advfirewall set global ipsec defaultexemptions icmp", "Set the ICMP exemption for the Client GPO")
    netshipseccmdexec($SetStoreClientGPO, "advfirewall set global mainmode mmkeylifetime 60min,0sess", "Setting Phase1CryptoSet")
    netshipseccmdexec($SetStoreClientGPO, "advfirewall set global mainmode mmsecmethods dhgroup2:aes128-sha256,dhgroup2:aes128-sha1,dhgroup2:3des-sha1", "Setting Phase1CryptoSet")
    netshipseccmdexec($SetStoreClientGPO, "advfirewall consec add rule name=```"$($snapindata.root.GPO.ClientPolicies.ClientToDnsPolicy)```" description=```"Policies to enable the Corp Access Over IPSEC and V6 remotely```" mode=tunnel action=requireinrequireout profile=private,public remotetunnelendpoint=$($snapindata.root.GPO.Common.TunnelEndpointDnsDcMgmt) endpoint1=any endpoint2=$DnsServers auth1=computercert auth1ca=```"$($snapindata.root.GPO.Common.RootCertNetshFormatted) catype:$($snapindata.root.GPO.Common.CertType)```" auth2=userntlm qmsecmethods=ESP:SHA1-AES192+60min+100000kb,ESP:SHA1-AES128+60min+100000kb", "Client to DNS,DC policy")
    netshipseccmdexec($SetStoreClientGPO, "advfirewall consec add rule name=```"$($snapindata.root.GPO.ClientPolicies.ClientToCorpPolicy)```" description=```"Policies to enable the Corp Access Over IPSEC and V6 remotely```" mode=tunnel action=requireinrequireout profile=private,public remotetunnelendpoint=$($snapindata.root.GPO.Common.TunnelEndpointCorp) endpoint1=any endpoint2=$($snapindata.root.GPO.Common.CorpV6) auth1=computercert auth1ca=```"$($snapindata.root.GPO.Common.RootCertNetshFormatted) catype:$($snapindata.root.GPO.Common.CertType)```" auth2=userkerb qmsecmethods=ESP:SHA1-AES192+60min+100000kb,ESP:SHA1-AES128+60min+100000kb", "Client to Corp policy")
    netshipseccmdexec($SetStoreClientGPO, "advfirewall consec add rule name=```"$($snapindata.root.GPO.ClientPolicies.ClientToNlaExemptPolicy)```" description=```"Policies to exempt for NLA bootstrapping Over IPSEC```" mode=tunnel action=noauthentication profile=private,public port2=443 protocol=tcp endpoint1=```"$($snapindata.root.GPO.Common.CorpV6)```" endpoint2=```"$($snapindata.root.GPO.ClientPolicies.NID.NidAddress)```"", "Client to NLA Exempt policy")

    if($MgmtServers)
    {
        netshipseccmdexec($SetStoreClientGPO, "advfirewall consec add rule name=```"$($snapindata.root.GPO.ClientPolicies.ClientToMgmtPolicy)```" description=```"Policies to enable the Corp Access Over IPSEC and V6 remotely```" mode=tunnel action=requireinrequireout profile=private,public remotetunnelendpoint=$($snapindata.root.GPO.Common.TunnelEndpointDnsDcMgmt) endpoint1=any endpoint2=$MgmtServers auth1=computercert auth1ca=```"$($snapindata.root.GPO.Common.RootCertNetshFormatted) catype:$($snapindata.root.GPO.Common.CertType)```" auth2=userntlm qmsecmethods=ESP:SHA1-AES192+60min+100000kb,ESP:SHA1-AES128+60min+100000kb", "Client to Mgmt policy")
    }

    if($($snapindata.root.GPO.AppServerPolicies.AuthenticationOption) -ine "NoAuthentication")
    {
        if($($snapindata.root.GPO.AppServerPolicies.AuthenticationOption) -ieq "SelectedServerEndToEnd")
        {
            netshipseccmdexec($SetStoreClientGPO, "advfirewall consec add rule name=```"$($snapindata.root.GPO.ClientPolicies.ClientToApplicationServerPolicy)```" description=```"Policies to enable the Corp Access Over IPSEC and V6 remotely```" mode=transport action=requestinrequestout profile=private,public endpoint1=any endpoint2=$AppServers auth1=computercert,computerkerb auth1ca=```"$($snapindata.root.GPO.Common.RootCertNetshFormatted) catype:$($snapindata.root.GPO.Common.CertType)```" auth2=userkerb qmsecmethods=ESP:SHA256-None+60min+100000kb,AH:SHA256+60min+100000kb,AuthNoEncap:SHA256+60min+100000kb", "Client to AppServer policy")
        }
        else
        {
            netshipseccmdexec($SetStoreClientGPO, "advfirewall consec add rule name=```"$($snapindata.root.GPO.ClientPolicies.ClientToApplicationServerPolicy)```" description=```"Policies to enable the Corp Access Over IPSEC and V6 remotely```" mode=transport action=requireinrequireout profile=private,public endpoint1=any endpoint2=$($snapindata.root.GPO.Common.CorpV6) auth1=computercert,computerkerb auth1ca=```"$($snapindata.root.GPO.Common.RootCertNetshFormatted) catype:$($snapindata.root.GPO.Common.CertType)```" auth2=userkerb qmsecmethods=ESP:SHA256-None+60min+100000kb,AH:SHA256+60min+100000kb,AuthNoEncap:SHA256+60min+100000kb", "Client to AppServer policy")
            if($MgmtServers)
            {
                netshipseccmdexec($SetStoreClientGPO, "advfirewall consec add rule name=```"$($snapindata.root.GPO.ClientPolicies.ClientToApplicationServerExemptPolicy)```" description=```"Policies to enable the Corp Access Over IPSEC and V6 remotely```" mode=transport action=noauthentication profile=private,public endpoint1=any endpoint2=```"$DnsServers,$MgmtServers```"", "Client to AppServer Exempt policy")
            }
            else
            {
                netshipseccmdexec($SetStoreClientGPO, "advfirewall consec add rule name=```"$($snapindata.root.GPO.ClientPolicies.ClientToApplicationServerExemptPolicy)```" description=```"Policies to enable the Corp Access Over IPSEC and V6 remotely```" mode=transport action=noauthentication profile=private,public endpoint1=any endpoint2=$DnsServers", "Client to AppServer Exempt policy")
            }
        }
    }

    # Server GPO
    LogToFile("---DA Server GPO operations---")
    $exists = GPOExists($ServerGPOName)
    if($exists -ne $TRUE) 
    {
        pscmdexec("New-GPO ```"$ServerGPOName```"", "Creating Server GPO")
    }
    else
    {
        $ErrorActionPreference = "silentlycontinue"
        $dummy = Remove-GPLink -Name "$ServerGPOName" -Target "$($snapindata.root.GPO.Common.DistinguishedDomainName)"
        $ErrorActionPreference = "stop"
        netshipseccmdexec($SetStoreServerGPO, "advfirewall consec delete rule name=```"$($snapindata.root.GPO.ServerPolicies.ServerToDnsPolicy)```"", "Deleting existing ServerToDnsPolicy") $FALSE
        netshipseccmdexec($SetStoreServerGPO, "advfirewall consec delete rule name=```"$($snapindata.root.GPO.ServerPolicies.ServerToCorpPolicy)```"", "Deleting existing ServerToCorpPolicy") $FALSE
        netshipseccmdexec($SetStoreServerGPO, "advfirewall consec delete rule name=```"$($snapindata.root.GPO.ServerPolicies.ServerToMgmtPolicy)```"", "Deleting existing ServerToMgmtPolicy") $FALSE
        netshipseccmdexec($SetStoreServerGPO, "advfirewall firewall delete rule name=```"$($snapindata.root.GPO.ServerPolicies.IpHttpsInRuleName)```"", "Deleting existing inbound IPHTTPS rule.") $FALSE
        netshipseccmdexec($SetStoreServerGPO, "advfirewall set global ipsec authzusergrp none", "Clearing authorized users setting.")
    }

    pscmdexec("New-GPLink -Name ```"$ServerGPOName```" -Target ```"$($snapindata.root.GPO.Common.DistinguishedDomainName)```"","Link Server GPO to domain")
    ClearExistingLinkedSG($ServerGPOName)

    # Link security group to Server GPO
    foreach($n in $snapindata.root.GPO.ServerPolicies.SecurityGroups.SecurityGroup)
    {
        if($n)
        {
            pscmdexec("Set-GPPermissions -TargetName ```"$($n.Name)```" -Name ```"$ServerGPOName```" -PermissionLevel GpoApply -TargetType $($n.Type)","Link security group to Server GPO")
        }
    }

    netshipseccmdexec($SetStoreServerGPO, "advfirewall set global ipsec defaultexemptions icmp", "Set the ICMP exemption for the Server GPO")
    netshipseccmdexec($SetStoreServerGPO, "advfirewall set global mainmode mmkeylifetime 60min,0sess", "Setting Phase1CryptoSet")
    netshipseccmdexec($SetStoreServerGPO, "advfirewall set global mainmode mmsecmethods dhgroup2:aes128-sha256,dhgroup2:aes128-sha1,dhgroup2:3des-sha1", "Setting Phase1CryptoSet")
    netshipseccmdexec($SetStoreServerGPO, "advfirewall set global ipsec strongcrlcheck 1", "Enable the strong certificate CRL check.")
    
    if($($snapindata.root.GPO.Common.SmartCard.Option) -ieq "RemoteSmartCard")
    {
        netshipseccmdexec($SetStoreServerGPO, "advfirewall consec add rule name=```"$($snapindata.root.GPO.ServerPolicies.ServerToDnsPolicy)```" mode=tunnel action=requireinrequireout profile=private,public localtunnelendpoint=$($snapindata.root.GPO.Common.TunnelEndpointDnsDcMgmt) endpoint1=$DnsServers endpoint2=any auth1=computercert auth1ca=```"$($snapindata.root.GPO.Common.RootCertNetshFormatted) catype:$($snapindata.root.GPO.Common.CertType)  certmapping:yes```" auth2=userntlm qmsecmethods=ESP:SHA1-AES192+60min+100000kb,ESP:SHA1-AES128+60min+100000kb", "Server to DNS,DC policy")
        netshipseccmdexec($SetStoreServerGPO, "advfirewall consec add rule name=```"$($snapindata.root.GPO.ServerPolicies.ServerToCorpPolicy)```" mode=tunnel action=requireinrequireout profile=private,public localtunnelendpoint=$($snapindata.root.GPO.Common.TunnelEndpointCorp) endpoint1=$($snapindata.root.GPO.Common.CorpV6) endpoint2=any auth1=computercert auth1ca=```"$($snapindata.root.GPO.Common.RootCertNetshFormatted) catype:$($snapindata.root.GPO.Common.CertType) certmapping:yes```" auth2=userkerb applyauthz=yes qmsecmethods=ESP:SHA1-AES192+60min+100000kb,ESP:SHA1-AES128+60min+100000kb", "Server to Corp policy")
        if($MgmtServers)
        {
            netshipseccmdexec($SetStoreServerGPO, "advfirewall consec add rule name=```"$($snapindata.root.GPO.ServerPolicies.ServerToMgmtPolicy)```" mode=tunnel action=requireinrequireout profile=private,public localtunnelendpoint=$($snapindata.root.GPO.Common.TunnelEndpointDnsDcMgmt) endpoint1=$MgmtServers endpoint2=any auth1=computercert auth1ca=```"$($snapindata.root.GPO.Common.RootCertNetshFormatted) catype:$($snapindata.root.GPO.Common.CertType)  certmapping:yes```" auth2=userntlm qmsecmethods=ESP:SHA1-AES192+60min+100000kb,ESP:SHA1-AES128+60min+100000kb", "Server to Mgmt policy")
        }
    }
    else
    {
netshipseccmdexec($SetStoreServerGPO, "advfirewall consec add rule name=```"$($snapindata.root.GPO.ServerPolicies.ServerToDnsPolicy)```" mode=tunnel action=requireinrequireout profile=private,public localtunnelendpoint=$($snapindata.root.GPO.Common.TunnelEndpointDnsDcMgmt) endpoint1=$DnsServers endpoint2=any auth1=computercert auth1ca=```"$($snapindata.root.GPO.Common.RootCertNetshFormatted) catype:$($snapindata.root.GPO.Common.CertType)```" auth2=userntlm qmsecmethods=ESP:SHA1-AES192+60min+100000kb,ESP:SHA1-AES128+60min+100000kb", "Server to DNS,DC policy")
        netshipseccmdexec($SetStoreServerGPO, "advfirewall consec add rule name=```"$($snapindata.root.GPO.ServerPolicies.ServerToCorpPolicy)```" mode=tunnel action=requireinrequireout profile=private,public localtunnelendpoint=$($snapindata.root.GPO.Common.TunnelEndpointCorp) endpoint1=$($snapindata.root.GPO.Common.CorpV6) endpoint2=any auth1=computercert auth1ca=```"$($snapindata.root.GPO.Common.RootCertNetshFormatted) catype:$($snapindata.root.GPO.Common.CertType)```" auth2=userkerb qmsecmethods=ESP:SHA1-AES192+60min+100000kb,ESP:SHA1-AES128+60min+100000kb", "Server to Corp policy")
        if($MgmtServers)
        {
            netshipseccmdexec($SetStoreServerGPO, "advfirewall consec add rule name=```"$($snapindata.root.GPO.ServerPolicies.ServerToMgmtPolicy)```" mode=tunnel action=requireinrequireout profile=private,public localtunnelendpoint=$($snapindata.root.GPO.Common.TunnelEndpointDnsDcMgmt) endpoint1=$MgmtServers endpoint2=any auth1=computercert auth1ca=```"$($snapindata.root.GPO.Common.RootCertNetshFormatted) catype:$($snapindata.root.GPO.Common.CertType)```" auth2=userntlm qmsecmethods=ESP:SHA1-AES192+60min+100000kb,ESP:SHA1-AES128+60min+100000kb", "Server to Mgmt policy")
        }
    }

    if($($snapindata.root.GPO.Common.SmartCard.Option) -ieq "RemoteSmartCard")
    {
        netshipseccmdexec($SetStoreServerGPO, "advfirewall set global ipsec authzusergrp $($snapindata.root.GPO.Common.SmartCard.SDDLString)", "Configure the users that are authorized to establish tunnel mode connections.")
    }

    # Application Server GPO
    LogToFile("---Application Server GPO operations---")
    $exists = GPOExists($AppServerGPOName)
    if($exists -ne $TRUE) 
    {
        if($($snapindata.root.GPO.AppServerPolicies.AuthenticationOption) -ine "NoAuthentication")
    {
            pscmdexec("New-GPO ```"$AppServerGPOName```"", "Creating Application Server GPO")
        }
    }
    else
    {
        $ErrorActionPreference = "silentlycontinue"
        $dummy = Remove-GPLink -Name "$AppServerGPOName" -Target "$($snapindata.root.GPO.Common.DistinguishedDomainName)"
        $ErrorActionPreference = "stop"
        netshipseccmdexec($SetStoreAppServerGPO, "advfirewall consec delete rule name=```"$($snapindata.root.GPO.AppServerPolicies.ApplicationServerToClientPolicy)```"", "Deleting existing ApplicationServerToClientPolicy") $FALSE
        netshipseccmdexec($SetStoreAppServerGPO, "advfirewall consec delete rule name=```"$($snapindata.root.GPO.AppServerPolicies.ApplicationServerToIpHttpsClientPolicy)```"", "Deleting existing ApplicationServerToIpHttpsClientPolicy") $FALSE
    }

    if($($snapindata.root.GPO.AppServerPolicies.AuthenticationOption) -ine "NoAuthentication")
    {
        pscmdexec("New-GPLink -Name ```"$AppServerGPOName```" -Target ```"$($snapindata.root.GPO.Common.DistinguishedDomainName)```"","Link App Server GPO to domain")
        ClearExistingLinkedSG($AppServerGPOName)

        # Link security group to Server GPO
        foreach($n in $snapindata.root.GPO.AppServerPolicies.SecurityGroups.SecurityGroup)
        {
            if($n)
            {
               pscmdexec("Set-GPPermissions -TargetName ```"$($n.Name)```" -Name ```"$AppServerGPOName```" -PermissionLevel GpoApply -TargetType $($n.Type)","Link security group to Application Server GPO")
        }
        }

        netshipseccmdexec($SetStoreAppServerGPO, "advfirewall set global ipsec defaultexemptions icmp", "Set the ICMP exemption for the App server GPO")
        netshipseccmdexec($SetStoreAppServerGPO, "advfirewall set global mainmode mmkeylifetime 60min,0sess", "Setting Phase1CryptoSet")
        netshipseccmdexec($SetStoreAppServerGPO, "advfirewall set global mainmode mmsecmethods dhgroup2:aes128-sha256,dhgroup2:aes128-sha1,dhgroup2:3des-sha1", "Setting Phase1CryptoSet")

    if($($snapindata.root.GPO.AppServerPolicies.EndToEndIPsecCompatibilityMode) -ieq "False")
    {
    netshipseccmdexec($SetStoreAppServerGPO, "advfirewall consec add rule name=```"$($snapindata.root.GPO.AppServerPolicies.ApplicationServerToClientPolicy)```" mode=transport action=requireinrequireout profile=domain endpoint1=any endpoint2=$($snapindata.root.GPO.Common.NonCorpV6) auth1=computercert,computerkerb auth1ca=```"$($snapindata.root.GPO.Common.RootCertNetshFormatted) catype:$($snapindata.root.GPO.Common.CertType)```" auth2=userkerb qmsecmethods=ESP:SHA256-None+60min+100000kb,AH:SHA256+60min+100000kb", "AppServer to Client policy")
    netshipseccmdexec($SetStoreAppServerGPO, "advfirewall consec add rule name=```"$($snapindata.root.GPO.AppServerPolicies.ApplicationServerToIpHttpsClientPolicy)```" mode=transport action=requireinrequireout profile=domain endpoint1=any endpoint2=$($snapindata.root.ServerData.IPHttps.IpHttpsPrefix) auth1=computercert,computerkerb auth1ca=```"$($snapindata.root.GPO.Common.RootCertNetshFormatted) catype:$($snapindata.root.GPO.Common.CertType)```" auth2=userkerb qmsecmethods=ESP:SHA256-None+60min+100000kb,AH:SHA256+60min+100000kb", "AppServer to Remote Client policy")
    }
    else
    {
    netshipseccmdexec($SetStoreAppServerGPO, "advfirewall consec add rule name=```"$($snapindata.root.GPO.AppServerPolicies.ApplicationServerToClientPolicy)```" mode=transport action=requireinrequireout profile=domain endpoint1=any endpoint2=$($snapindata.root.GPO.Common.NonCorpV6) auth1=computercert,computerkerb auth1ca=```"$($snapindata.root.GPO.Common.RootCertNetshFormatted) catype:$($snapindata.root.GPO.Common.CertType)```" auth2=userkerb qmsecmethods=AuthNoEncap:SHA256+60min+100000kb,ESP:SHA256-None+60min+100000kb,AH:SHA256+60min+100000kb", "AppServer to Client policy")
    netshipseccmdexec($SetStoreAppServerGPO, "advfirewall consec add rule name=```"$($snapindata.root.GPO.AppServerPolicies.ApplicationServerToIpHttpsClientPolicy)```" mode=transport action=requireinrequireout profile=domain endpoint1=any endpoint2=$($snapindata.root.ServerData.IPHttps.IpHttpsPrefix) auth1=computercert,computerkerb auth1ca=```"$($snapindata.root.GPO.Common.RootCertNetshFormatted) catype:$($snapindata.root.GPO.Common.CertType)```" auth2=userkerb qmsecmethods=AuthNoEncap:SHA256+60min+100000kb,ESP:SHA256-None+60min+100000kb,AH:SHA256+60min+100000kb", "AppServer to Remote Client policy")
    }
    }

    # Creating outbound IpHttps allow rule for client
    netshipseccmdexec($SetStoreClientGPO, "advfirewall firewall add rule name=```"$($snapindata.root.GPO.ClientPolicies.IpHttpsOutRuleName)```" dir=out action=allow program=%SystemRoot%\system32\svchost.exe description=```"Outbound TCP rule to allow IpHttps tunneling technology to provide connectivity across HTTP proxies and firewalls.```" profile=public,private protocol=tcp remoteport=iphttps", "Creating outbound IpHttps allow rule for client")

    # Creating inbound IpHttps allow rule for server
    netshipseccmdexec($SetStoreServerGPO, "advfirewall firewall add rule name=```"$($snapindata.root.GPO.ServerPolicies.IpHttpsInRuleName)```" dir=in action=allow program=%SystemRoot%\system32\svchost.exe description=```"Inbound TCP rule to allow IpHttps tunneling technology to provide connectivity across HTTP proxies and firewalls.```" profile=public,private protocol=tcp localport=iphttps", "Creating inbound IpHttps allow rule for server")

    # Creating DnsServerAddresses registrykey.
    $dnsServerAddresses = $dnsServerAddresses.Trim(",")
    pscmdexec("New-ItemProperty -Path HKLM:\System\CurrentControlSet\Services\iphlpsvc\DirectAccess -name DnsServerAddresses -value $dnsServerAddresses -PropertyType MultiString -Force", "Setting HKLM:\System\CurrentControlSet\Services\iphlpsvc\DirectAccess\DnsServerAddresses")

    if($dnscmdpresent)
    {
        cmdexec("dnscmd.exe /RecordDelete $($snapindata.root.GPO.Common.DomainName) $corpConnectivityDnsProbeHostName AAAA $corpConnectivityDnsProbeHostAddress /f", "directaccess-corpConnectivityHost de-registration.") $FALSE
        cmdexec("dnscmd.exe /RecordAdd $($snapindata.root.GPO.Common.DomainName) $corpConnectivityDnsProbeHostName AAAA $corpConnectivityDnsProbeHostAddress", "directaccess-corpConnectivityHost registration.")
    }
    else
    {
        LogToFile "DNS registration for directaccess-corpConnectivityHost needs to be done manually."
        $host.UI.WriteLine("magenta", "black", "DNS registration for directaccess-corpConnectivityHost needs to be done manually.")
            
        if($mode -ieq "all" -and ($($snapindata.root.ServerData.IsV6Deployed) -ine "True"))
        {
            LogToFile "ISATAP registration needs to be done manually."
            $host.UI.WriteLine("magenta", "black", "ISATAP registration needs to be done manually.")
        }
    }
    
    LogToFile "GPO's configured successfully."
    $host.UI.WriteLine("green", "black", "Group Policy configurations completed successfully.")
}

if($mode -ieq "all" -or $mode -ieq "serveronly")
{
    pscmdexec("New-ItemProperty -Path HKLM:\System\CurrentControlSet\Services\iphlpsvc\DirectAccess -name DaServerEnabled -value 1 -PropertyType DWORD -Force", "Setting HKLM:\System\CurrentControlSet\Services\iphlpsvc\DirectAccess\DaServerEnabled")
    LogToFile "DirectAccess Server configured successfully."
    $host.UI.WriteLine("green", "black", "DirectAccess Server configured successfully.")
}