PowerShell Port Forwarding For Utorrent/Qbittorrent/Other for new API

edited July 2017 in Windows VPN Setup
This is a new script for Port forwarding automation.  Currently it works for Utorrnet and Qbitorrent through powershell.  It requires Powershell 3.0 and above and windows 7 and above to work.

The script is now in the second post of this thread.

What this script does
  
When running this script it will connect to a pia server that you choose.  If available it will request a port forward and update your app to listen on that port.  It can also monitor the vpn and if it sees it disconnected it will reconnect and ask for a port forward again.


Known Problems
1. If using auto-check, Please turn off user account control or run as administrator.  It needs the privilege to start and stop the openvpn service.
2. Spaces in windows user names will cause the power shell script not to run if you have the script located on the desktop/documents/etc.  Read this for more info or work around.  This is not a problem with my script but a limitation of powershell.

The old script this is based on is here


Problems
Get it working first without Advance routing First


ENABLEAUTOCHECK
To enable this set  $ENABLEAUTOCHECK = $true
If you set openvpn to run as a service, and this is $true, it will check
every minute to make sure you are connected, if not it will try to
reconnect you every two minutes.

Go to this website for more info on openvpn service  http://vpnblog.info/openvpn-startup-windows.html.
Basically do this.

The Windows installer will set up a Service Wrapper, but leave it turned off by default. We need enable OpenVPN service and make sure it's set to Startup Type to manual. The script will start it and monitor it.

1) Open Control Panel -> Administrative Tools
2) Find and open Services
3) Find OpenVPN Service, right mouse click and Properties4) Set Startup type to Manual
5) When you started computer, the OpenVPN Service Wrapper will scan the \Program Files\OpenVPN\config ( for 64 bit OS \Program Files(x86)\OpenVPN\config ) folder for .ovpn configuration files and starting a separate OpenVPN process on each file( So only have one in there).

Once OpenVPN started as a service on Windows, the only way to control it is in Services, right mouse click on OpenVPN service and it gives start/stop control.

Advance Routing

To enable this set $EnabledAdvanceRouting = $true

What is Advance Routing, this is when you set your nic to a static ip address, and
don't assign a dns or gateway to the nic.  Basically your computer
doesn't know how to get to the internet.  What this does it adds a
temporary route to a dns server and looks up pia server address.  It
then remove the route to the dns server and adds a route to pia so your
computer knows how to connect to the pia server.  In then updates
openvpn connection file and adds the ip address and then openvpn is able
to connect.

Why this?  if your computer doesn't know how to
connect to the internet, apps can't leak your real ip address, ex
Utorrent.  so you can't get on the internet until openvpn connects,and
if the connection drops, your back to no internet.

Here the steps to get this to work.
1. install openvpn, (update the path $pathtoovpn if you installed the 64bit version)
2. copy one pia openvpn config to the config directory, rename it to pia
3. make an authpass.txt, first line your username, second line your password
4. edit pia.ovpn file add these three lines
auth-user-pass authpass.txt
route-metric 512
route 0.0.0.0 0.0.0.0

Your config directory needs at least these files
pass.txt
pia.ovpn

for standard encryption you need

ca.rsa.2048.crt
crl.rsa.2048.pem
 Get the Files from here https://www.privateinternetaccess.com/openvpn/openvpn-tcp.zip

For strong encryption you need these files also
ca.rsa.4096.crt
crl.rsa.4096.pem

Get the files from here https://www.privateinternetaccess.com/openvpn/openvpn-strong-tcp.zip
for Legacy encryption you need these files also
ca.crt
crl.pem

Get the files from here https://www.privateinternetaccess.com/openvpn/openvpn-ip-tcp.zip

The pass.txt looks like this
piausername
piapassword
The pia.opvn file looks like this
client
dev tun
proto udp
remote 172.98.67.44 1198
resolv-retry infinite
nobind
persist-key
persist-tun
cipher aes-128-cbc
auth sha256
tls-client
remote-cert-tls server
auth-user-pass pass.txt
comp-lzo
verb 1
reneg-sec 0
crl-verify crl.rsa.2048.pem
ca ca.rsa.2048.crt
disable-occ
route-metric 512
route 0.0.0.0 0.0.0.0

Comments

  • edited April 2020
    #Version 3.00 This combined Utorrent and qBittorent into one script and uses the new api.
    3.01  Fix to work on Windows 10, still works on 7+
    3.02 Clean up old code left over, that was not used
    3.03 Added options for Legacy,Standard, and Strong encryption
    3.10 Better detection when vpn connects, watch if the ip address changes, if so request new port, added option for qbittorrent to look for stalled qbittorrent.  Added fix for refer header for qbittorrent 3.3.14.  Cleaned up code on application connections.
    3.11 Fix screen issue, clear out old variables not used anymore.
    3.12 It will request port even if no application is running.
    3.13 It will update the port of the program if it couldn't before for some reason, example not running.
    3.14 Better support for Windows 10, script will prompt to run as admin  if advance features enabled.
    3.15  Correct Spelling, list version in title bar, added comment to this web address.
    3.2. Fixed logout failing of qbitorrent for 4.1
    3.3 Use Qbittorrent new api
    3.45 A lot of fixes.

    # More info at https://www.privateinternetaccess.com/forum/discussion/23542/
    $Ver ="Version 3.45"
    $WEBGUI_USER_ut="admin" #username for Utorrent
    $WEBGUI_PASS_ut="" #password for Utorrent
    $WEBGUI_PORT_ut=801 #port number for Utorrent
    $WEBGUI_USER_qb="admin" #username for qBittorrent
    $WEBGUI_PASS_qb="" #password for qBittorrent
    $WEBGUI_PORT_qb=802 #port number for Qbittorrent
    $Checkqbittorentstalled = $True # check if qbittorrent stalled
    $Checkqbittorentstalledtimer = 15 # check every 15 minites
    $checktime=60 # How often to check if still connected in seconds Default 60
    $waittime=0 #how long to wait before starting the script, useful if you need time for the vpn to connect default 0
    $ENABLEAUTOCHECK = $True # Set to $True to have the service restart to connect to vpn
    $EnabledAdvanceRouting = $True # Set to $true to use this when you have a static ip address and no dns or gateway assigned to your nic
    # EnabledAdvanceRouting only works if $Enableautocheck is is $true
    $disableportforwarduser=$False # if you don't want to enable port forwarding
    $defaultgateway = "10.23.179.3" # Part of Advance routing, change it to your router's ip address
    $Applist = @()
    $Applistnum = 1 #Default app list to select 0 = utorrent, 1 = qBittorrent, 2 = other
    $Applist += ,@("uTorrent","fnutorrent") # first varaible is name of program, second is function to call
    $Applist += ,@("qBittorrent", "fnqbittorrent")
    $Applist += ,@("Other", "fnother")
    $PIAservernum = 0 #default $PIAserver you wish to connect to Must enable AdvanceRouting
    $PIAserver = @() # List 10 servers to connect to.
    $PIAserver += ,@("ca-toronto.privateinternetaccess.com",$true) # First variable is server address, second does it support port forwarding
    $PIAserver += ,@("ca.privateinternetaccess.com",$true)
    $PIAserver += ,@("israel.privateinternetaccess.com",$true)
    $PIAserver += ,@("nl.privateinternetaccess.com",$true)
    $PIAserver += ,@("swiss.privateinternetaccess.com",$true)
    $PIAserver += ,@("sweden.privateinternetaccess.com",$true)
    $PIAserver += ,@("uk-london.privateinternetaccess.com",$false)
    $PIAserver += ,@("us-california.privateinternetaccess.com",$false)
    $PIAserver += ,@("us-midwest.privateinternetaccess.com",$false)
    $PIAserver += ,@("us-east.privateinternetaccess.com",$false)
    $PIAportsnum = 0 # set to 0 for UDP, 1 for TCP, default 0
    $PIAprotocal = @("udp","tcp")
    $PIAStrongEncryption = 1 # set to 2 for strong encryption
    $PIAcipher = @() #udp port,tcp port, ciper, certificate, revoke list, auth, description
    $PIAcipher += ,@(1194,443, "bf-cbc","ca.crt","crl.pem", "sha1" ,"Legacy Encryption ") #Legacy encryption
    $PIAcipher += ,@(1198,502, "aes-128-cbc","ca.rsa.2048.crt","crl.rsa.2048.pem", "sha1","Standard encryption") #Standard encryption
    $PIAcipher += ,@(1197,501, "aes-256-cbc","ca.rsa.4096.crt","crl.rsa.4096.pem", "sha256", "Strong encryption") #Strong encryption
    $DNSSERVER = "8.8.8.8" # part of Advance Routing, use any dns server, the default is google dns 8.8.8.8
    $pathtoovpn = "C:\Program Files\OpenVPN\config\pia.ovpn" # path to pia opvn file, this scripts edits the file and adds piaserver ip address, change to match yours ovpn location
    $disableportforward = $False # to temporary disable port forwarding when connected to a non-port forwarding server
    #Script below, be careful changing anything below this line
    $Windowswidth = 100
    $WindowsHeight = 26
    $host.ui.RawUI.WindowTitle = "PIA Port Forwarding for Utorrent/qBittorrent/Other $Ver"
    $rand = New-Object System.Random
    $chrstg = "abcdef1234567890"
    $servererror = $true
    $currentip=''
    $saveX = [console]::CursorLeft
    $saveY = 0
    $strmoving = '|','/','-','\'
    $startline = 1 #which line to start updating on based on function printsettings()
    $emptyspaces = ""
    $isprocessactive = $False
    $portupdatesuccessful = $False
    1..$Windowswidth | % {$emptyspaces += " " }

    Function clearscreen ($start, $fullclear = $false) {
    if ($fullclear) {
    clear;
    printsettings;
    [console]::SetCursorPosition($savex,$start)
    } else {
    [console]::SetCursorPosition($savex,$start)
    for ($i=$start; $i -le 11;$i++) {
    Write-host $emptyspaces
    if ([Console]::CursorTop -gt 13 ){break}
    }
    [console]::SetCursorPosition($savex,$start)
    }
    }
    Function printsettings(){
    write-host "Auto Check / Advance Routing are set to:"$ENABLEAUTOCHECK "/" $EnabledAdvanceRouting
    }
    Function isNumeric ($x) {
    $x2 = 0
    $isNum = [System.Int32]::TryParse($x, [ref]$x2)
    return $isNum
    }
    Function listservers{
    $SaveY=[Console]::CursorTop-1
    [console]::SetCursorPosition($saveX,$SaveY+4)
    for ($i = $PIAserver.getlowerbound(0);$i -le $PIAserver.getupperbound(0); $i++){
    $temp = " $i " + $PIAserver[$i][0] + $emptyspaces
    write-host $temp.substring(0,45) "Port Forwarding="$PIAserver[$i][1]
    }
    [console]::SetCursorPosition($saveX,$SaveY)
    }
    Function AdvanceRouting{
    write "Flushing DNS cache"
    ipconfig /flushdns
    write "Adding temporary route for DNS Server:$DNSSERVER by gateway:$defaultgateway"
    route add $DNSSERVER mask 255.255.255.255 $defaultgateway
    $FullAddressList = nslookup -type=a $PIAserver[$PIAservernum][0] $DNSSERVER
    write "Deleting temporary route to DNS Server:$DNSSERVER by gateway:$defaultgateway"
    route delete $DNSSERVER
    if (test-path $pathtoovpn) {
    foreach ($line in $FullAddressList) {
    $tempip = "$line" | %{ $_.Split(" ")[2] }
    $IsValid = ($tempip -As [IPAddress]) -As [Bool]
    if ($IsValid -and $tempip -ne $DNSSERVER){
    write "Adding temporary route for PIA Server:$tempip by gateway:$defaultgateway"
    route add $tempip mask 255.255.255.255 $defaultgateway
    (gc $pathtoovpn) -replace 'remote .*', "remote $tempip $($PIAcipher[$PIAStrongEncryption][$PIAportsnum]) " | sc $pathtoovpn
    (gc $pathtoovpn) -replace 'proto .*' , "proto $($PIAprotocal[$PIAportsnum])" | sc $pathtoovpn
    (gc $pathtoovpn) -replace 'cipher .*', "cipher $($PIAcipher[$PIAStrongEncryption][2])" | sc $pathtoovpn
    (gc $pathtoovpn) -replace 'ca .*', "ca $($PIAcipher[$PIAStrongEncryption][3])" | sc $pathtoovpn
    (gc $pathtoovpn) -replace 'crl-verify .*', "crl-verify $($PIAcipher[$PIAStrongEncryption][4])" | sc $pathtoovpn
    (gc $pathtoovpn) -replace 'auth .*', "auth $($PIAcipher[$PIAStrongEncryption][5])" | sc $pathtoovpn
    write "Updating File:$pathtoovpn to connect to PIA Server"
    write "with ip address:$tempip $($PIAprotocal[$PIAportsnum]) $($PIAcipher[$PIAStrongEncryption][$PIAportsnum]) $($PIAcipher[$PIAStrongEncryption][6])"
    return
    }
    }
    write "Not a valid DNS Server, or not a valid gateway, or not a valid PIA Server address"
    Start-Sleep -s 60
    } else {
    write-host "Not a valid path to openvpn config file:$pathtoovpn"
    Start-Sleep -s 60
    }
    }
    Function setwindowsize {
    $pshost = get-host
    $pswindow = $pshost.ui.rawui
    $psWindow.WindowSize = @{Width=1; Height=1}
    $psWindow.BufferSize = @{Width=$Windowswidth; Height=$WindowsHeight}
    $psWindow.WindowSize = @{Width=$Windowswidth; Height=$WindowsHeight}
    }
    Function resetadapter{
    $ip = ''
    $counter = 0
    while ($ip -eq '') {
    if (0 -eq $counter % 60) {
    Stop-Service OpenVPNService
    Write-Host $a.toshorttimestring() "Waiting for OpenVPNService to stop."
    Start-Sleep -s 5
    if ($EnabledAdvanceRouting) {
    clearscreen $startline $True
    if ($counter -ne 0){Write-Host $a.toshorttimestring() "Connection Failed, resetting adapter"}
    Write-Host $a.toshorttimestring() "Advance Routing Enabled, resetting up routes to connects to PIA server."
    AdvanceRouting
    }
    Start-Service OpenVPNService
    $SaveY=[Console]::CursorTop
    }

    try {
    $ip = (Get-WmiObject -Class Win32_NetworkAdapterConfiguration | Where-Object {$_.Description -like "TAP*"}).IPAddress[0]
    Write-Host "VPN Connected, waiting to finish"
    Start-Sleep -s 5
    }
    catch {
    clearscreen $SaveY
    $counter +=1
    Write-Host "Wating for VPN to connect" $counter
    Start-Sleep -s 1
    }
    }
    clearscreen $startline $True
    }
    Function fnutorrent{
    try {
    clearscreen ($startline + 1)
    $url="http://" + $ip + ":" + $WEBGUI_PORT_ut + "/gui/"
    $Credential = (New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $WEBGUI_USER_ut, ($WEBGUI_PASS_ut | ConvertTo-SecureString -AsPlainText -Force ))
    $response = Invoke-WebRequest -usebasicparsing -Uri $url"token.html" -Credential $Credential -SessionVariable my_session
    $token = ($response.tostring()).split('>')[2].split('<')[0]
    $response = Invoke-WebRequest -usebasicparsing -Uri $url"?action=setsetting&s=bind_port&v=$port&token=$token" -WebSession $my_session
    $response = (Invoke-WebRequest -usebasicparsing -Uri $url"?action=getsettings&token=$token" -WebSession $my_session).tostring()
    $response= ($Response.substring($Response.indexof("bind_port")-1)).substring(14)
    clearscreen ($startline + 1)
    Write-Host "Utorrent set to=" $response.Substring(0,$Response.indexof(","))
    return $True
    }
    catch [system.exception] {
    $a = get-date
    write-host $_.Exception.Message
    Write-Host $a.toshorttimestring() "Failed to update port via uTorrent WEBGUI."
    return $False
    }
    }
    Function fnqbittorrent{
    $a = get-date
    try {
    clearscreen ($startline + 1)
    Write-Host $a.toshorttimestring() " Trying to update Qbittorrent"
    $url="http://" + $ip + ":" + $WEBGUI_PORT_qb + "/api/v2/"
    $postParams = "username=$WEBGUI_USER_qb&password=$WEBGUI_PASS_qb"
    $response = Invoke-WebRequest -usebasicparsing -Uri $url"auth/login" -Method POST -Body $postParams -Headers @{"Referer"= $url } -SessionVariable my_session -TimeoutSec 15
    $postData = 'json={"listen_port":' + $port + '}'
    $Response = Invoke-WebRequest -usebasicparsing -Uri $url"app/setPreferences" -Method POST -Body $postData -Headers @{"Referer"= $url} -WebSession $my_session -TimeoutSec 15 |ConvertFrom-Json
    $Response = Invoke-WebRequest -usebasicparsing -Uri $url"app/preferences" -Headers @{"Referer"= $url} -WebSession $my_session -TimeoutSec 15 |ConvertFrom-Json
    Write-Host "qBitTorrent set to=" $Response.listen_port
    $Response = Invoke-WebRequest -usebasicparsing -Uri $url"auth/logout" -Method POST -Body $postParams -Headers @{"Referer"= $url} -WebSession $my_session -TimeoutSec 15
    return $True
    }
    catch [system.exception] {
    $a = get-date
    $theerror = $_.Exception.Message
    write-host $_.Exception.Message
    Write-Host $a.toshorttimestring() "Failed to update port via qbittorrent WEBGUI."
    $qbitorrentpath = Get-Process "qBittorrent" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Path
    Write-Host $theerror
    if($qbitorrentpath -ne $null) {
    Write-Host $a.toshorttimestring() "Trying to restart qbittorent"
    fnqbittorrenthardstalled
    } else {
    Write-Host $a.toshorttimestring() "Qbittorrent not running check the settings you gave the script for qBitTorrent"
    }
    return $False
    }

    }

    Function fnother{
    try{
    # $port is the varible for port write what you need here
    Write-Host $a.toshorttimestring() "you need to update function fnother to use another application"
    return $True
    }
    catch [system.exception] {
    $a = get-date
    Write-Host $a.toshorttimestring() "Failed to update Other"
    write-Host "Please check the information you've given this script for Other."
    Start-Sleep -s 60
    return $False
    }
    }
    Function setapp{
    try{
    return invoke-expression $Applist[$Applistnum][1]
    }
    catch [system.exception] {
    Write-Host $a.toshorttimestring() "Unable to call function script error. This is an unrecoverable error."
    $error[0].ToString() + $error[0].InvocationInfo.PositionMessage
    Start-Sleep -s 60
    return $False
    }

    }
    Function fnqbittorrentstalling{
    try {
    Write-Host "Checking if Qbittorrent is stalled"
    $url = "http://" + $ip + ":" + $WEBGUI_PORT_qb + "/api/v2/"
    $web = New-Object System.Net.WebClient
    $postParams = "username=$WEBGUI_USER_qb&password=$WEBGUI_PASS_qb"
    $Response = Invoke-WebRequest -usebasicparsing -Uri $url"auth/login" -Method POST -Body $postParams -Headers @{"Referer"= $url } -SessionVariable my_session -TimeoutSec 15
    $Response = Invoke-WebRequest -usebasicparsing -Uri $url"torrents/info?filter=downloading" -Headers @{"Referer"= $url} -WebSession $my_session |ConvertFrom-Json
    $Response1 = Invoke-WebRequest -usebasicparsing -Uri $url"transfer/info" -Headers @{"Referer"= $url} -WebSession $my_session |ConvertFrom-Json
    $i=0
    foreach ($state in $Response.state){ if ($state -eq "stalledDL") { $i+=1}}
    if (($i -gt 0) -and ($i -eq $Response.count) -and ($response1.total_peer_connections -eq 0))
    { Write-Host "Qbittorrent is stalled, restarting"
    $qbitorrentpath = Get-Process "qBittorrent" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Path
    if($qbitorrentpath -ne $null ) {
    $Response= Invoke-WebRequest -usebasicparsing -Uri $url"app/shutdown" -Headers @{"Referer"= $url} -WebSession $my_session
    $SaveY=[Console]::CursorTop
    for ($i = 1; $i -le 24; $i++) {
    [console]::SetCursorPosition($saveX,$SaveY)
    Write-Host "Waiting for qBittorent to close " $i
    Start-Sleep -s 1
    $isitclosed= Get-Process "qBittorrent" -ErrorAction SilentlyContinue
    if($isitclosed -eq $null ) {
    Write-Host "Restarting qBitTorrent"
    start-process $qbitorrentpath
    Start-Sleep -s 5
    [console]::SetCursorPosition($saveX,$SaveY)
    break
    }
    }
    } else {
    throw ("Error getting path")
    }
    } else {
    Write-Host "No problems found."
    }

    Start-Sleep -s 5
    }
    catch [system.exception] {
    $a = get-date
    try {
    write-host $_.Exception.Message
    fnqbittorrenthardstalled
    }
    catch [system.exception] {
    write-host $_.Exception.Message
    Write-Host $a.toshorttimestring() "Failed to check for stalled qbittorrent."
    Start-Sleep -s 60
    }
    }
    }

    Function fnqbittorrenthardstalled{
    Write-Host $a.toshorttimestring() "qBitTorrent not responding, trying to restart"
    $qbitorrentpath = Get-Process "qBittorrent" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Path
    if($qbitorrentpath -ne $null ) {
    Stop-process -name "qBittorrent" -Force
    for ($i = 1; $i -le 24; $i++) {
    [console]::SetCursorPosition($saveX,$SaveY)
    Write-Host "Waiting for qBittorent to close " $i
    Start-Sleep -s 1
    $isitclosed= Get-Process "qBittorrent" -ErrorAction SilentlyContinue
    if($isitclosed -eq $null ) {
    Write-Host "Restarting qBitTorrent"
    start-process $qbitorrentpath
    Start-Sleep -s 5
    [console]::SetCursorPosition($saveX,$SaveY)
    break
    }
    }
    Start-Sleep -s 5
    Write-Host "Trying to update qBitTorrent again"
    fnqbittorrent
    } else {
    Write-Host $a.toshorttimestring() "qBittorrent was not running, not starting"
    }
    }
    setwindowsize
    printsettings
    if ($waittime -gt 0) {
    Write-Host "Waiting $waittime seconds before continuing"
    Start-Sleep -s $waittime
    }
    if ($EnabledAdvanceRouting) {
    if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs; exit }
    If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(`
    [Security.Principal.WindowsBuiltInRole] "Administrator")){
    Write-Warning "You do not have Administrator rights to run this script!`nPlease re-run this script as an Administrator!"
    Start-Sleep -s 60
    Break
    }
    }
    $disableportforward = !$PIAserver[$PIAservernum][1]

    while($true) {
    try {
    $ip = (Get-WmiObject -Class Win32_NetworkAdapterConfiguration | Where-Object {$_.Description -like "TAP*"}).IPAddress[0]
    if(($ip -ne $currentip) -and (-not $servererror)){
    clearscreen ($startline)
    $servererror = $true
    Write-Host $a.toshorttimestring() "IP Address changed Detected"
    }
    $currentip = $ip
    $portupdatesuccessful = $false
    }
    catch [system.exception] {
    $a = get-date
    if ($ENABLEAUTOCHECK) {
    clearscreen $startline $True
    Write-Host $a.toshorttimestring() "VPN is not connected. Restarting the service."
    resetadapter
    } else {
    Write-Host $a.toshorttimestring() "VPN is not connected. Checking again in 1 minute."
    Start-Sleep -s 60
    }
    continue
    }
    $ProcessActive = Get-Process $Applist[$Applistnum][0] -ErrorAction SilentlyContinue
    if($ProcessActive -eq $null) {
    $isprocessactive = $False
    $portupdatesuccessful = $False
    } else {
    $isprocessactive = $True
    }
    if($disableportforward -or $disableportforwarduser) {
    clearscreen $startline
    $a= get-date
    $servererror = $false
    if ($disableportforward){
    Write-host $a.toshorttimestring() "Port forwarding is disabled on this server."
    } elseif ($disableportforwarduser ){
    Write-host $a.toshorttimestring() "You have disabled port forwarding."
    }
    } elseif ($servererror) {
    try {
    $a= get-date
    Write-Host $a.toshorttimestring() "Trying to connect to the PIA port server."
    $response = $null
    $CLIENT_ID = ""
    1..64 | % {$CLIENT_ID += $chrstg.substring($rand.next(0,$chrstg.length),1) }
    $response1 = Invoke-WebRequest -usebasicparsing -URI http://209.222.18.222:2000/?client_id=$CLIENT_ID
    $response = $response1.tostring()
    if ([string]::IsNullOrEmpty($response) ) {
    Write-Host $a.toshorttimestring() "Did not get a response from the server. Retrying in 1 minute."
    Write-Host $response
    } else {
    $port = $response.Substring($response.IndexOf(":")+1,$response.IndexOf("}")-$response.IndexOf(":")-1)
    if (isNumeric ($port) ) {
    clearscreen ($startline)
    Write-Host "Port given is $port"
    $servererror = $false
    } else {
    clearscreen ($startline)
    Write-Host $a.toshorttimestring() "Server returned an error, you must request the port within 2 minutes of connecting!"
    Write-host $a.toshorttimestring() "You are currently set to connect to PIA server" $PIAserver[$PIAservernum][0]"."
    }
    }
    if ($servererror) {Start-Sleep -s 10}
    }
    catch [system.exception] {
    $a= get-date
    if ($ENABLEAUTOCHECK) {
    $error[0].ToString() + $error[0].InvocationInfo.PositionMessage
    Write-Host $a.toshorttimestring() "Server returned an error, you must request the port within 2 minutes of connecting!"
    Write-Host $a.toshorttimestring() "Unable to connect to the PIA port server. Restarting service."
    Start-Sleep -s 10
    resetadapter
    $servererror = $true
    } else {
    Write-Host $a.toshorttimestring() "Unable to connect to the remote host. Retrying in 20 seconds."
    $error[0].ToString() + $error[0].InvocationInfo.PositionMessage
    Start-Sleep -s 20
    }
    continue
    }
    }
    if (!$portupdatesuccessful -and !$servererror -and !$disableportforwarduser) {
    if ($isprocessactive) {
    $portupdatesuccessful = setapp
    if ($portupdatesuccessful) {clearscreen ($startline)}

    } else {
    Write-host $a.toshorttimestring() $Applist[$Applistnum][0] "is not running."
    }
    }
    if ($Checkqbittorentstalled -and !$servererror){
    if ($isprocessactive){
    if ($Checkqbittorentstalledtime -eq $null) {
    $Checkqbittorentstalledtime = (get-date).Addminutes($Checkqbittorentstalledtimer).Addseconds(-1)
    write-host "Checking if qBittorrent is stalled at " $Checkqbittorentstalledtime.toshorttimestring()
    }else {
    if ($Checkqbittorentstalledtime -le (get-date)){
    fnqbittorrentstalling
    $Checkqbittorentstalledtime = (get-date).Addminutes($Checkqbittorentstalledtimer)
    Write-Host $a.toshorttimestring() "qBitTorrent is fine, check again at " $Checkqbittorentstalledtime.toshorttimestring()
    } Else {
    write-host "Checking if qBittorrent is stalled at " $Checkqbittorentstalledtime.toshorttimestring()
    }
    }
    } else {
    write-host $a.toshorttimestring() "qBittorrent is not active, can't check for stalled torrents"
    }
    }
    if ($ENABLEAUTOCHECK) {
    $saveY = [console]::CursorTop
    clearscreen $saveY $false
    $a= get-date
    Write-Host $a.toshorttimestring() "Checking to see if VPN is still active."
    $EnableAutoCheckrespone = ping -S $ip www.privateinternetaccess.com -n 3 -4 | Out-String
    if ($EnableAutoCheckrespone.indexof("Average") -lt 1) {
    Write-Host $a.toshorttimestring() "VPN is connected, but ping response was $EnableAutoCheckrespone , restarting service."
    Start-Sleep -s 10
    resetadapter
    $servererror = $true
    } else {
    $EnableAutoCheckrespone = $EnableAutoCheckrespone.substring($EnableAutoCheckrespone.indexof("Average"))
    $EnableAutoCheckrespone = $EnableAutoCheckrespone.substring(0,$EnableAutoCheckrespone.length -2)
    clearscreen $saveY $false
    Write-Host $a.toshorttimestring() "VPN is still active and ping $EnableAutoCheckrespone."
    }
    }
    $saveY = [console]::CursorTop
    if ($ENABLEAUTOCHECK) {$saveY -= 1 } #minus one for ping response
    if ($Checkqbittorentstalled) {$saveY -= 1 } #minus one for stalled qbittorent check
    if (!$isprocessactive) {$saveY -= 1 } #minus one for message torrent process not active
    if ($EnabledAdvanceRouting) {Write-host "You are currently connected to"$PIAserver[$PIAservernum][0] $PIAcipher[$PIAStrongEncryption][$PIAportsnum] ($PIAprotocal[$PIAportsnum]).ToUpper() $PIAcipher[$PIAStrongEncryption][6]}
    Write-host "Checking every $checktime seconds to see if you're connected."
    Write-Host "Press 'q' to quit, 'p' to enable/disabled port forwarding, 'c' to check if qBitTorrent is stalled,"
    Write-Host "'a' to cycle between Utorrent and qBittorrent, 'r' to stop and reconnect to PIA,"
    Write-Host "'l' to list PIA severs, '0-9' to connected to a specific PIA server,"
    Write-Host "'t' to change protocols, 'e' to increase encryption, or any other key to refresh."
    $counter = 0
    while(!$Host.UI.RawUI.KeyAvailable -and ($counter++ -le $checktime) -and !$servererror) {
    $strmoving | ForEach-Object {
    Write-Host -Object $_ -NoNewline
    [Threading.Thread]::Sleep( 200 )
    [console]::SetCursorPosition($saveX,[Console]::CursorTop)
    }
    }
    if ($Host.UI.RawUI.KeyAvailable) {
    $key = $host.UI.RawUI.ReadKey('NoEcho,IncludeKeyUp')
    if ($key.character -eq "Q") {break;}
    if ($key.character -eq "C") {fnqbittorrentstalling;}
    if ($key.character -eq "R") {
    resetadapter
    $servererror = $true
    }
    if ($key.character -eq "P") {
    $disableportforwarduser=!$disableportforwarduser
    if (!$disableportforwarduser){
    if (isNumeric ($port) ) {
    clearscreen ($startline)
    Write-Host "Port given before was $port"
    $portupdatesuccessful = setapp
    $savey +=1
    } else {
    $servererror = $true
    }
    }
    }
    if ($key.character -eq "A") {
    if ($Applistnum -eq 0) {
    $Applistnum = 1
    } else {
    $Applistnum = 0
    }
    Write-host "Changing app to update to" $Applist[$Applistnum][0]
    $portupdatesuccessful = setapp
    }
    if ($key.character -eq "T") {
    if ($EnabledAdvanceRouting) {
    if ($PIAportsnum -eq 0) {
    $PIAportsnum = 1
    } else {
    $PIAportsnum = 0
    }
    write-Host "Changing Protocol to" ($PIAprotocal[$PIAportsnum]).ToUpper()
    Start-Sleep -s 5
    resetadapter
    $servererror = $true
    } else {
    Write-host "Enable Advance Routing to use this"
    Start-Sleep -s 10
    }
    }
    if ($key.character -eq "E") {
    if ($EnabledAdvanceRouting) {
    if ($PIAStrongEncryption -eq $PIAcipher.getupperbound(0)) {
    $PIAStrongEncryption = 0
    } else {
    $PIAStrongEncryption += 1
    }
    write-Host "Changing Encryption to" $PIAcipher[$PIAStrongEncryption][6]
    Start-Sleep -s 5
    resetadapter
    $servererror = $true
    } else {
    Write-host "Enable Advance Routing to use this"
    Start-Sleep -s 10
    }
    }
    if (isnumeric($key.character)) {
    if ($EnabledAdvanceRouting) {
    $PIAservernum = [convert]::ToInt16($key.character, 10)
    write-Host "Changing Server to" $PIAserver[$PIAservernum][0]
    $disableportforward = !$PIAserver[$PIAservernum][1]
    Start-Sleep -s 5
    resetadapter
    $servererror = $true
    } else {
    Write-host "Enable Advance Routing to use this"
    Start-Sleep -s 10
    }
    }
    if ($key.character -eq "L" ) {listservers;}
    [Threading.Thread]::Sleep(500)
    $Host.UI.RawUI.FlushinputBuffer()
    }
    if ($servererror){
    clearscreen $startline
    } else {
    clearscreen $savey
    }
    }







  • Just wanted to say thanks for all the work you put into this script.  I was able to adapt it to Deluge and it works well.  I'm a beginner when it comes to Powershell and it was very instructive to see how you put together this script
  • BobP19454 said:
    Just wanted to say thanks for all the work you put into this script.  I was able to adapt it to Deluge and it works well.  I'm a beginner when it comes to Powershell and it was very instructive to see how you put together this script
    Give me the function and I'll add it to the script for people
  • This is script is pretty solid now.  Let me know if anyone is using it, so I know to update it with my local copy.
Sign In or Register to comment.