Creating VPNs
March 29th, 2018 by Charlie Russel and tagged Add-VPNConnection, PowerShell, VPN
First, an apology. I usually try to be conscientious about adding new nuggets of PowerShell fun on a regular basis, but this winter, LIFE has intruded, and it simply hasn’t happened. I won’t promise it won’t happen again, but I will try to do better.
Today’s post looks at a problem we’ve been dealing with at work — how to pre-configure new laptops with the VPN access they’ll need for users to get logged in, even when they’re not ever in an office to set themselves up. There are lots of different workarounds and solutions, but what we came up with was a PowerShell script that would create one or more VPNs programmatically. We take advantage of the Invoke-WebRequest cmdlet I discussed earlier to pull down an updated set of parameters for the available VPNs, allowing us to separate the code from the data, useful for providing some protection against changes — we only have to update one file.
The command to create a new VPN connection is: Add-VPNConnection, and it comes with a plethora of parameters, most of which you’ll never need. But as always, good to have them when you need them. For our purposes, we needed to specify the VPN type (-TunnelType), the authentication method, and an initial pre-shared key for L2TP. We also wanted the ability to use the same script for individual user profile VPNs, and to control whether the VPN used a split tunnel. (Normally, we configure for split tunneling.) The basic command is:
Add-VpnConnection -Name <ConnectionName> ` -ServerAddress <IP Address of VPN Server> ` -TunnelType L2TP ` -L2tpPsk <somereallylongandoddstring> ` -AuthenticationMethod MSChapv2 ` -AllUserConnection ` -SplitTunneling ` -PassThru
So, we know we’re going to need a name for the connection, and IP address, and the L2TP PSK for each connection. The easy way is to stuff that into a CSV file and store it up in the cloud where all the IT staff can get at it from whatever location we’re in. So we need to read the contents of a file, probably stored in the cloud, and, using a foreach statement, iterate the Add-VPNConnection command once for each line of the CSV file to create VPNs to all of the VPNs listed in the CSV file. Pretty simple, really. The annoying part is that we have to repeat ourselves doing this to handle the values of the AllUserConnection and SplitTunneling switches in the Add-VPNConnection command. If they were Booleans, it would be a bit less messy.
<# .Synopsis Creates one or more VPNs. Uses a CSV file stored in OneDrive for Business .Description New-myVPN reads a list of VPNs and their parameters from a CSV file stored in OneDrive for Business, and creates one or more VPNs based on that list. The created VPNs can be configured as AllUser VPNs, or only for the current user (the default). The VPNs are created as Split-Tunnel VPNs unless the NoSplitVPN parameter is specified. .Example New-myVPN Reads the default VPN.csv file and creates vpns using the details in that file to create VPNs as split-Tunnel VPNs available to all users. .Example New-myVPN -NoSplitVPN -AllUserConnection $False Reads the default VPN.csv file and creates new VPNs using the details in that file. The VPNs are created in the current user's profile, and are not created as split VPNs .Parameter Path Path to CSV file. The CSV file is in the format: Name,ServerAddress,L2tpPsk. The default path is to a file called VPN.csv, stored in a folder called Private, in the current user's OneDrive for Business. .Parameter AllUserConnection Boolean -- default is $True. When True, VPNs are created as an AllUserConnection and are available to all users on the computer. When False, VPNs are created in the current user's profile and are only available to the user after logon. .Parameter NoSplitTunnel Switch -- VPNs are created as SplitTunnel VPNs unless this switch is enabled. A SplitTunnel VPN sends all regular traffic to the main network interface, but sends traffic to hosts connected via the VPN to the VPN. When this switch is set, all traffic outside of the local subnet is sent over the VPN connection. .Inputs [string] [Boolean] [Switch] .Notes Author: Charlie Russel Copyright: 2018 by Charlie Russel : Permission to use is granted but attribution is appreciated Initial: 13 March, 2018 (cpr) ModHist: : #> [CmdletBinding()] Param( [Parameter(Mandatory=$False,Position=0)] [string] $Path = (Get-ItemProperty 'HKCU:\Software\Microsoft\OneDrive\Accounts\Business1').UserFolder + "\private\vpn.csv", [Parameter(Mandatory=$true)] [Boolean] $AllUserConnection, [Parameter(Mandatory=$False)] [Switch] $NoSplitTunnel ) if ($Path -match "http") { # We're connecting to the web to get the parameters Write-Verbose "Found a match against $Matches[0], so using WebRequest" $vpnParams = ConvertFrom-CSV (Invoke-WebRequest -Uri $Path ).ToString() } else { # We're going against a local path Write-Verbose "Reading from a local file $path" $vpnParams = ConvertFrom-CSV (Get-Content $Path) } $vpncount = $vpnParams.count if (($AllUserConnection) -AND (! $NoSplitTunnel)) { Write-Verbose "Creating $vpn.count AllUser VPNs using parameters in $path and split-tunneling" ForEach ($param in $vpnParams) { Add-VpnConnection -Name $param.Name ` -ServerAddress $param.ServerAddress ` -TunnelType L2TP ` -L2tpPsk $param.L2tpPsk ` -AuthenticationMethod MSChapv2 ` -EncryptionLevel Optional ` -AllUserConnection ` -SplitTunneling ` -Force ` -PassThru } } elseif (($AllUserConnection) -AND ($NoSplitTunnel)) { Write-Verbose "Creating $vpncount AllUser VPNs using parameters in $path and no split-tunneling" ForEach ($param in $vpnParams) { Add-VpnConnection -Name $param.Name ` -ServerAddress $param.ServerAddress ` -TunnelType L2TP ` -L2tpPsk $param.L2tpPsk ` -AuthenticationMethod MSChapv2 ` -EncryptionLevel Optional ` -AllUserConnection ` -Force ` -PassThru } } elseif ($NoSplitTunnel) { Write-Verbose "Creating $vpncount current user VPNs using parameters in $path and no split-tunneling" ForEach ($param in $vpnParams) { Add-VpnConnection -Name $param.Name ` -ServerAddress $param.ServerAddress ` -TunnelType L2TP ` -L2tpPsk $param.L2tpPsk ` -AuthenticationMethod MSChapv2 ` -EncryptionLevel Optional ` -Force ` -PassThru } } else { Write-Verbose "Creating $vpncount current user VPNs using parameters in $path and split-tunneling" ForEach ($param in $vpnParams) { Add-VpnConnection -Name $param.Name ` -ServerAddress $param.ServerAddress ` -TunnelType L2TP ` -L2tpPsk $param.L2tpPsk ` -AuthenticationMethod MSChapv2 ` -EncryptionLevel Optional ` -SplitTunneling ` -Force ` -PassThru } }
Posted in Annoyances, IT Admin, Network Administration, Networking, PowerShell | Comments Off on Creating VPNs