Here's how to use it:
//Get a VPN connector ready
VPNConnector vpn = new VPNConnector("VPN_NAME", "USER_NAME", "USER_PASSWORD");
//Connect
Tuple<bool, IList<string>> response = vpn.Connect();
if (response.Item1)
{
    //Successfully connected
    Console.WriteLine("Connected!");
}
else
{
    //Failed to connect
    Console.WriteLine("Failed to connect :(");
    foreach (string s in response.Item2)
    {
        Console.WriteLine(s);
    }
}
//Disconnect
vpn.Disconnect();
You can optionally check if the connection is already open by using vpn.IsOpen.
The code:
/// <summary>
/// Gives access to Windows VPN connections
/// </summary>
public class VPNConnector
{
	#region Properties
	#region VPNName
	/// <summary>
	/// The name of the VPN connection
	/// </summary>
	public string VPNName { get; set; }
	#endregion
	#region Username
	/// <summary>
	/// The username to use for the connection
	/// </summary>
	public string Username { get; set; }
	#endregion
	#region Password
	/// <summary>
	/// The password to use for the connection
	/// </summary>
	public string Password { get; set; }
	#endregion
	#region IsOpen
	/// <summary>
	/// Whether the connection is currently open or not
	/// </summary>
	public bool IsOpen
	{
		get
		{
			if (String.IsNullOrWhiteSpace(this.VPNName))
				throw new ArgumentException("No VPN name (VPNName) has been set");
			
			Process p = this.getNewProcess;
			p.Start();
			bool bOpen = false;
			while (!p.StandardOutput.EndOfStream)
			{
				string sOutput = p.StandardOutput.ReadLine();
				if (sOutput.ToLower() != "no connections")
				{
					if (sOutput == this.VPNName)
					{
						bOpen = true;
						break;
					}
				}
				else
					break;
			}
			p.WaitForExit();
			return bOpen;
		}
	}
	#endregion
	#region parametersAreASet
	/// <summary>
	/// Determines if all the necessary parameters are set to make a VPN connection
	/// </summary>
	private bool parametersAreASet { get { return (!String.IsNullOrWhiteSpace(this.VPNName) && !String.IsNullOrWhiteSpace(this.Username) && !String.IsNullOrWhiteSpace(this.Password)); } }
	#endregion
	#region getNewProcess
	/// <summary>
	/// Get a new process ready to start a rasdial call
	/// </summary>
	private Process getNewProcess
	{
		get
		{
			return new Process
			{
				StartInfo = new ProcessStartInfo
				{
					FileName = "rasdial.exe",
					UseShellExecute = false,
					RedirectStandardOutput = true,
					CreateNoWindow = true
				}
			};
		}
	} 
	#endregion
	#endregion
	#region Cosntructor
	public VPNConnector() { }
	public VPNConnector(string name, string username, string password)
	{
		this.VPNName = name;
		this.Username = username;
		this.Password = password;
		if (!this.parametersAreASet)
			throw new ArgumentException("All arguments must have a value");
	}
	#endregion
	#region Public Methods
	#region Instance
	#region Connect
	/// <summary>
	/// Make a connection to the VPN. Item1 of Tuple indicates success or failure. Item2 of Tuple is the output of the dial call
	/// </summary>
	public Tuple<bool, IList<string>> Connect()
	{
		if (!this.IsOpen)
		{
			if (!this.parametersAreASet)
				throw new ArgumentException("All arguments must have a value");
			Process p = this.getNewProcess;
			p.StartInfo.Arguments = $"\"{this.VPNName}\" \"{this.Username}\" \"{ this.Password}\"";
			p.Start();
			bool bSuccess = false;
			IList<string> outputs = new List<string>();
			while (!p.StandardOutput.EndOfStream)
			{
				string sOutput = p.StandardOutput.ReadLine();
				outputs.Add(sOutput);
				if (sOutput.ToLower().StartsWith("success"))
					bSuccess = true;
			}
			p.WaitForExit();
			return new Tuple<bool, IList<string>>(bSuccess, outputs);
		}
		else
			return new Tuple<bool, IList<string>>(false, new List<string>() { "Connection already open" } );
	}
	#endregion
	#region Disconnect
	/// <summary>
	/// Disconnect from the VPN. Item1 of Tuple indicates success or failure. Item2 of Tuple is the output of the dial call
	/// </summary>
	public Tuple<bool, IList<string>> Disconnect()
	{
		if (this.IsOpen)
		{
			Process p = this.getNewProcess;
			p.StartInfo.Arguments = $"\"{this.VPNName}\" /d";
			p.Start();
			bool bSuccess = false;
			IList<string> outputs = new List<string>();
			while (!p.StandardOutput.EndOfStream)
			{
				string sOutput = p.StandardOutput.ReadLine();
				outputs.Add(sOutput);
				if (sOutput.ToLower().Contains("success"))
					bSuccess = true;
			}
			p.WaitForExit();
			return new Tuple<bool, IList<string>>(bSuccess, outputs);
		}
		else
			return new Tuple<bool, IList<string>>(false, new List<string>() { "Connection already closed" });
	}
	#endregion
	#endregion
	#endregion
}




