I've now created 3 Powershell scripts.
The first is used to extract the tunnel info automatically from tunnelbroker.net using the API
<#
GetTunnelInfo.ps1 (c) 2014 Timothy Dutton
Function to retreive the info of the first tunnel interface found on
a users account.
Many thanks to Hurricane Electric who provided the API that is used
to make this script work.
#>
function Get-TunnelInfo
{
# Prompt for Tunnelbroker user details
Param(
[Parameter(Mandatory=$true, Position=0, Helpmessage="Tunnelbroker Username: ")]
$Username,
[Parameter(Mandatory=$true, Position=0, Helpmessage="Enter Password: ")]
[SecureString]$Password
)
# Password was obtained using a secure string so now we decode it
$pw=[Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.Interopservices.Marshal]::SecureStringToBSTR($Password))
$ErrorActionPreference="Stop"
# Now obtain the Tunnel info
$url="https://tunnelbroker.net/tunnelInfo.php"
$webClient = New-Object System.Net.WebClient
$credCache = New-Object System.Net.CredentialCache
$creds = New-Object System.Net.NetworkCredential($Username, $pw)
$credCache.Add($url, "Basic", $creds)
$webClient.Credentials = $credCache
$webpage = $webClient.DownloadString($url)
# Now we have the XML page downloaded parse it using Powershell's XML parser
$tunnelinfo = [xml]$webpage
# Check to see how many tunnels we have
$tcount = $tunnelinfo.tunnels.ChildNodes.Count
if ($tcount -eq 1) #Only one tunnel so return it
{
return $tunnelinfo.tunnels.tunnel
}
else
{
$count = 0
do
{
$tunnel = $tunnelinfo.tunnels.tunnel[$count]
Write-Host($count + 1) ' ' $tunnel.id
$count = $count +1
}
while ($count -lt $tcount)
do
{
$num = Read-Host "Enter Tunnel number to use"
}
The second is simply used to Elevate the script is is called from. this means that you don't have to explicitly start in an elevated powershell session for the final script to work.
# Elevate.ps1
Function Elevate
{
$myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
$myWindowsPrincipal=New-Object System.Security.Principal.WindowsPrincipal($myWindowsID)
$adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator
if (-not $myWindowsPrincipal.IsInRole($adminRole))
{
$newProcess = New-Object System.Diagnostics.ProcessStartInfo "Powershell"
$newProcess.Arguments = $Script:MyInvocation.MyCommand.Definition
$newProcess.Verb = "runas"
[System.Diagnostics.Process]::Start($newProcess)
exit
}
}
The final Script takes the other two and sets up the tunnel
<#
Pwershell Script to automate setting up a HE.net IPv6 Tunnel
Copyright (C) 2014 Timothy Dutton
#>
cd $PSScriptRoot
# Script needs administrator priviledges to run the Netsh commands correctly
# So check to see if we are already running as such
. .\Elevate.ps1
. .\GetTunnelInfo.ps1
Elevate
# Have already created a function GetTunnelInfo which prompts for a username and password
# And then connects to Tunnelbroker.net and gets the first tunnel found using their API
$ErrorActionPreference = "Stop"
$tunnel = Get-TunnelInfo
# Strip out the info we need to create the tunnel. While not necessary it makes the
# netsh commands further down easier to read
$serverv4=$tunnel.serverv4
$clientv6=$tunnel.clientv6
$serverv6=$tunnel.serverv6
$routed64=$tunnel.routed64
# First Locate Which device is the Ethernet Adapter
$wiredAdapter = Get-NetAdapter | Where-Object {$_.PhysicalMediaType -eq '802.3'}
# Now Get the IPv4 address of the wired adapter
$ipAddress=Get-NetIPAddress -AddressFamily IPv4 -InterfaceIndex $wiredAdapter.ifIndex
$ipAddress=$ipAddress[0]
$clientv4=$ipAddress.IPAddress
# We also get the interface name and add quotes to the string so that if there are spaces
# The whole name is used in the netsh commands
$interface=$wiredAdapter.Name
$interface='"'+$interface+'"'
# Finally do a simple replace to get the first IP address of the Routed /64
$firstAdress = $routed64.Replace("/64","1")
# Before setting up the Tunnel Display the Values
Write-Host "Client IPv4 Address is $($clientv4)"
Write-Host "Server IPv4 Address is $($serverv4)"
Write-Host "Client IPv6 Address is $($clientv6)"
Write-Host "Server IPv6 Address is $($serverv6)"
Write-Host "Routed /64 Prefix is $($routed64)"
Write-Host "Network adapter used $($interface)"
# Now we wait for user to press enter
Read-Host "Press Enter to set up tunnel or CTRL-C to abort"
# Now set up the basic tunnel
netsh int ipv6 add v6v4tunnel IP6Tunnel $clientv4 $serverv4
netsh int ipv6 add address IP6Tunnel $clientv6
netsh int ipv6 add route ::/0 IP6Tunnel $serverv6 publish=yes
# And enable forwarding on this and the LAN interface which will advertise the
# IPv6 Prefix
netsh int ipv6 set interface IP6Tunnel forwarding=enabled
netsh int ipv6 set interface $interface forwarding=enabled advertise=enabled
# Add the first address of the routed prefix to the LAN interface and publish the route
netsh int ipv6 add address $interface $firstAdress
# Sleep for 2 seconds else last command does not sleep successfully
sleep -s 2
netsh int ipv6 set route $routed64 $interface publish=yes
To use the scripts they need to be copied and pasted into the following filenames - all in the same directory.
GetTunnelInfo.ps1
Elevate.ps1
SetupTunnel.ps1
To allow execution of the scripts you need to go into Powershell and enter Set-ExecutionPolicy -Scope CurrentUser Unrestricted
GetTunnelInfo is a stand alone script - it does require you to enter your tunnelbroker.net username and password in order to fetch the tunnel details. If you have more than one tunnel it will enumerate them by tunnelid. If only one tunnel it will return that.
SetupTunnel calls Elevate and GetTunnelInfo for that reason if it is not in the same folder as the other two functions it will not work.
When called it will open up an elevated Powershell session (If not already in one). You will be prompted for your tunnelbroker username and password.
It will then display the parameters it will use to set up the tunnel. At this point Press enter to proceed or Ctrl-C to quit the program.

On a final note - If you already have a tunnel set up using IP6Tunnel this will need to be deleted prior to running the script bey entering an elevated command prompt
and typing
netsh int ipv6 del int ip6tunnel
netsh int ipv6 reset
This code was developed on PowerShell 4.1 in windows 8.1 However AFAIK it should work on Windows 7 and Vista machines.
The scripts have been zipped up here
http://shadowraven.webspace.virginmedia.com/powershell/pstunnel.zipAny feedback from users would be welcome
Ravenstar68