How to use PowerShell for a IPSec VPN IKEv2 connection? - powershell

To test an IPSec connection, I've used a client implementation StrongSwan with Ubuntu 16 without UI.
Is it possible to use only PowerShell to create and test the VPN connection?
Available assets:
public VPN endpoint i.e. IP
user name
password
PSK (private shared key)

This script is for cert-auth but you can modify:
# Set these to the correct values
$server_address = "vpn.example.com"
$connection_name = "VPN Connection"
$certificate_path = "certificate.p12"
$ca_cert_path = "strongswanCert.pem"
$password = ConvertTo-SecureString -String "P12 passphrase" -AsPlainText -Force
# Import machine cert
Import-PfxCertificate -FilePath $certificate_path -CertStoreLocation Cert:\LocalMachine\My\ -Password $password
# Import CA root
Import-Certificate -FilePath $ca_cert_path -CertStoreLocation Cert:\LocalMachine\Root\
# Add VPN connection IKEv2 with machine cert
Add-VpnConnection -Name $connection_name -ServerAddress $server_address -TunnelType Ikev2 -EncryptionLevel Required -AuthenticationMethod MachineCertificate -AllUserConnection
# Add IPv6 default route (::/0 does not work)
Add-VpnConnectionRoute -ConnectionName $connection_name -DestinationPrefix ::/1
Add-VpnConnectionRoute -ConnectionName $connection_name -DestinationPrefix 8000::/1

Related

set username and password VPN powershell

I have a powershell script where I can add an VPN to the local computer. It prompts for the users credentials and after that it creates the VPN connection and adds the credentials. When I try this on my own computer it works perfectly fine but when I try this on another computer it gives an error saying Set-VpnConnectionUsernamePassword isn't a command.
Does anyone know what causes this or how to fix this.
$creds = $host.ui.PromptForCredential("Need credentials", "Voer de inloggegevens in van de VPN gebruiker", "", "")
$name = "name of vpn"
$username = $creds.username
$plainpassword = $creds.password
Add-VpnConnection -Name $name -ServerAddress $name -RememberCredential -TunnelType Pptp
Set-VpnConnectionUsernamePassword -connectionname $name -username $username -password $plainpassword
The error message indicates that on the other computer, the module VPNCredentialsHelper is not installed.
Beside that, with your code
$plainpassword = $creds.password
the variable $plainpassword will receive the password as System.Security.SecureString, but the code wants a plain-text string (hence the variable name).
You should change that to
$plainpassword = $creds.GetNetworkCredential().Password

Import certificate to the Group Policy store with PowerShell

I am building ARM-templates to set up test-environments in Azure. I am using DSC to set up the different machines. One thing I want to automate is to import a certificate to the group-policies. You can do it like this manually on the domain-controller (Active-Directory server):
Group Policy Management -> Forest: mydomain.net -> Domains -> mydomain.net -> Group Policy Objects -> Default Domain Policy
Right click -> Edit
Default Domain Policy -> Computer Configuration -> Policies -> Windows Settings -> Security Settings -> Public Key Policies -> Trusted Root Certification Authorities
Right click -> Import
I have laborated with Import-PfxCertificate, CertUtil.exe and .NET C# to accomplish it but haven’t succeeded. What I have tested you can see below, I have put some comments about my thoughts.
Can anyone help me? How should I do this?
First we create a certificate and export it and finally we delete it (we keep the exported one):
$certificateStoreLocation = "CERT:\LocalMachine\My";
$password = ConvertTo-SecureString -String "P#ssword12" -Force -AsPlainText;
$certificate = New-SelfSignedCertificate -CertStoreLocation $certificateStoreLocation -DnsName "Test-Certificate";
$certificateLocation = "$($certificateStoreLocation)\$($certificate.Thumbprint)";
$result = Export-PfxCertificate -Cert $certificateLocation -FilePath "C:\Data\Certificates\Test-Certificate.pfx" -Password $password;
Get-ChildItem $certificateLocation | Remove-Item;
List the certificate stores
foreach($item in Get-ChildItem "CERT:\")
{
Write-Host " - CERT:\$($item.Location)\";
foreach($store in $item.StoreNames.GetEnumerator())
{
Write-Host " - CERT:\$($item.Location)\$($store.Name)";
}
}
PowerShell – Import-PfxCertificate
$certificateStoreLocation = "CERT:\LocalMachine\Root";
$password = ConvertTo-SecureString -String "P#ssword12" -Force -AsPlainText;
Import-PfxCertificate -CertStoreLocation $certificateStoreLocation -FilePath "C:\Data\Certificates\Test-Certificate.pfx" -Password $password;
Get-ChildItem $certificateStoreLocation;
# Now you can find the certificate in the MMC Certificate Snapin:
# [Console Root\Certificates (Local Computer)\Trusted Root Certification Authorities\Certificates]
# Now you can find the certificate in the registry.
# Get-ChildItem "REGISTRY::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SystemCertificates\Root\Certificates\";
# I want to put the certificate here:
# Get-ChildItem "REGISTRY::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\SystemCertificates\Root\Certificates\";
PowerShell – CertUtil
CertUtil -p "P#ssword12" -ImportPfx "Root" "C:\Data\Certificates\Test-Certificate.pfx";
Get-ChildItem "CERT:\LocalMachine\Root";
CertUtil -p "P#ssword12" -ImportPfx -GroupPolicy "Root" "C:\Data\Certificates\Test-Certificate.pfx"; # No error but the same result as CertUtil -p "P#ssword12" -ImportPfx "Root" "C:\Data\Certificates\Test-Certificate.pfx".
.NET C#
using(var certificate = new X509Certificate2(#"C:\Data\Certificates\Test-Certificate.pfx", "P#ssword12"))
{
// We only have StoreLocation.CurrentUser and StoreLocation.LocalMachine.
// Can I use System.Management.Automation.Security.NativeMethods+CertStoreFlags.CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
// somehow to create/open a store by calling new X509Store(IntPtr storeHandle).
using (var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine))
{
store.Open(OpenFlags.ReadWrite);
store.Add(certificate);
}
}
My imaginary solution
Thought this was a possible solution:
Import the certificate to “CERT:\LocalMachine\Root”
Move the registry-key “HKLM:\SOFTWARE\Microsoft\SystemCertificates\Root\Certificates\THUMBPRINT” to “HKLM:\Software\Policies\Microsoft\SystemCertificates\Root\Certificates\THUMBPRINT”
Restart the machine
The registry-keys get correct but the localmachine-root-certificate is still in the certificate-mmc-snapin and no root-certificate is found in the Group Policy Management console.
$certificateRegistryKeyPathPrefix = "HKLM:\SOFTWARE\Microsoft\SystemCertificates\Root\Certificates\";
$certificateStoreLocation = "CERT:\LocalMachine\Root";
$password = ConvertTo-SecureString -String "P#ssword12" -Force -AsPlainText;
$pfxCertificatePath = "C:\Data\Certificates\Test-Certificate.pfx";
$policyCertificateRegistryKeyPathPrefix = "HKLM:\Software\Policies\Microsoft\SystemCertificates\Root\Certificates\";
# Get the thumbprint from the pfx-file so we can check if it's already in the registry.
$certificate = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2;
$certificate.Import($pfxCertificatePath, $password, "DefaultKeySet");
$policyCertificateRegistryKeyPath = "$($policyCertificateRegistryKeyPathPrefix)$($certificate.Thumbprint)";
$policyCertificateRegistryKey = Get-Item -ErrorAction SilentlyContinue -Path $policyCertificateRegistryKeyPath;
if(!$policyCertificateRegistryKey)
{
$certificateRegistryKeyPath = "$($certificateRegistryKeyPathPrefix)$($certificate.Thumbprint)";
$certificateRegistryKey = Get-Item -ErrorAction SilentlyContinue -Path $certificateRegistryKeyPath;
if(!$certificateRegistryKey)
{
$certificate = Import-PfxCertificate -CertStoreLocation $certificateStoreLocation -FilePath $pfxCertificatePath -Password $password;
$certificateRegistryKey = Get-Item -Path $certificateRegistryKeyPath;
}
Move-Item -Destination $policyCertificateRegistryKeyPath -Path $certificateRegistryKeyPath;
# And then we need to reboot the machine.
}
Instead of trying to directly modify the registry under the 'Policies' path, create or modify an 'Registry.pol' file to populate it.
You could use the 'PolicyFileEditor' module from the PowerShell Gallery to do this, but the easiest way is to use the native GroupPolicy module to create and set a Registry.pol file as part of a domain GPO, which will also push out the certificate to member servers.
On a domain controller, import/create a cert so it has a blob value stored in the registry, create a GPO, then run something like the following to configure the GPO (named "DistributeRootCerts" here):
$certsGpoName = 'DistributeRootCerts'
$certThumbprint = '3A8E60952E2CDB7A31713258468A8F0C7FB3C6F6'
$certRegistryKeyPath = 'HKLM:\SOFTWARE\Microsoft\SystemCertificates\MY\Certificates\{0}' -f $certThumbprint
$certBlob = Get-ItemProperty -Path $certRegistryKeyPath -Name 'Blob' | Select -Expand 'Blob'
$certPoliciesRegistryKey = 'HKLM\SOFTWARE\Policies\Microsoft\SystemCertificates\Root\Certificates\{0}' -f $certThumbprint
$null = Set-GPRegistryValue -Name $certsGpoName -Key $certPoliciesRegistryKey -ValueName 'Blob' -Type Binary -Value $certBlob
Then you just need to link the GPO into production with 'New-GPLink'.

Scripting VPN Credentials

I can easily create a VPN connection through the PowerShell command Add-VpnConnection, however it doesn't seem able to specify any credentials (there is no option to specify username/password). As a workaround I tried to use -RememberCredential option in Add-VpnConnection and to pass the credentials by forcing a connection through rasdial command, yet even though the connection succeeds Windows doesn't save the credentials :(
Add-VpnConnection -Name xxxxx ...
rasdial xxxxx user password
rasdial xxxxx /disconnect
Is it possible some way ?
Maybe it is too late, but I had same task and here is solution:
$vpnName = "YourVpnName"
$vpnServerAddress = "YourVpnServerAddress"
$vpnUserName = "YourVpnUserName"
$vpnPassword = "YourVpnPassword"
$vpn = Get-VpnConnection -Name $vpnName
if($vpn -eq $null) {
Add-VpnConnection -Name $vpnName -ServerAddress $vpnServerAddress -TunnelType Pptp -EncryptionLevel Required -PassThru
echo "vpn created"
}
if($vpn.ConnectionStatus -eq "Disconnected"){
$cmd = $env:WINDIR + "\System32\rasdial.exe"
$expression = "$cmd ""$vpnName"" $vpnUserName $vpnPassword"
Invoke-Expression -Command $expression
}

Specify App Pool and Authentication when creating a Virtual Directory via Powershell

I have a powershell function I use to create virtual directories:
New-Item $commitpath -PhysicalPath $virtualdirPath -Type VirtualDirectory
But I need to be able to specify a DIFFERENT Authentication and a DIFFERENT App Pool than the parent website uses. Something like this:
New-Item $commitpath -PhysicalPath $virtualdirPath -Authentication "Anonymous" - AppPool "MyOtherAppPool" -Type VirtualDirectory
How do I do this via script?
Thanks,
Eric West
I recommend the webadministration module to configure the IIS.
Here is an example to create a new application pool named MyNewPool running as Administrator (identitytype 3 = SpecificUser):
Import-Module WebAdministration
$applicationPoolName = 'MyNewPool'
$UserName = 'Administrator'
$Password = '12345'
$applicatonPoolUri = "IIS:\AppPools\$applicationPoolName"
if (-not(Test-Path $applicatonPoolUri)) # check whether the application pool exists
{
$applicationPool = ni $applicatonPoolUri
$applicationPool.processModel.username = $UserName
$applicationPool.processModel.password = $Password
$applicationPool.processModel.identityType = 3
$applicationPool | si
}
After you created the application pool, you can create the website and assign the pool using the New-Website cmdlet:
New-Website -name 'MyNewWebSite' `
-port 80
-ip '*' `
-PhysicalPath $virtualdirPath `
-ApplicationPool $applicationPoolName

Install certificate with PowerShell on remote server

I want to install a certificate (X.509) created with makecert.exe on a remote server. I am not able to use psexec or something like that but have to use PowerShell.
Server operating system: Windows Server 2008 R2
PowerShell version: 4
Question: How to install a certificate with PowerShell on a remote server.
Scenario: ServerA has the SSL cert, ServerB would like the SSL cert imported
define two variables (ServerB only):
$afMachineName = "SomeMachineNameOrIp"
$certSaveLocation = "c:\temp\Cert.CER"
enable trust on both machines (ServerA & ServerB):
Function enableRemotePS() {
Enable-PSRemoting -Force
Set-Item wsman:\localhost\client\trustedhosts $afMachineName -Force
Restart-Service WinRM
}
Save the certificate (ServerB only):
Function saveCert([string]$machineName,[string]$certSaveLocation) {
Invoke-Command -ComputerName $machineName -ArgumentList $certSaveLocation -ScriptBlock {
param($certSaveLocation)
$cert = dir Cert:\LocalMachine\Root | where {$_.Subject -eq "CN=YOURCERTNAME" };
$certBytes = $cert.Export("cert");
[system.IO.file]::WriteAllBytes($certSaveLocation, $certBytes);
}
Copy-Item -Path \\$machineName\c$\temp\CertAF.CER -Destination $certSaveLocation
}
Import the certificate (ServerB only)
Function importCert([string]$certSaveLocation) {
$CertToImport = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $certSaveLocation
$CertStoreScope = "LocalMachine"
$CertStoreName = "Root"
$CertStore = New-Object System.Security.Cryptography.X509Certificates.X509Store $CertStoreName, $CertStoreScope
# Import The Targeted Certificate Into The Specified Cert Store Name Of The Specified Cert Store Scope
$CertStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
$CertStore.Add($CertToImport)
$CertStore.Close()
}
To import a PFX file you can use Import-PfxCertificate, for example
Import-PfxCertificate -FilePath YOUR_PFX_FILE.pfx -Password (ConvertTo-SecureString -String "THE_PFX_PASSWORD" -AsPlainText -Force)
To do this on a remote computer, you can use Invoke-Command -ComputerName (and use an UNC path for the PFX file).