Prepare Azure P2S domain deployment
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
#Requires -Version 5.1
|
||||
#Requires -RunAsAdministrator
|
||||
[CmdletBinding(SupportsShouldProcess)]
|
||||
param(
|
||||
[Parameter(Mandatory)][string]$VpnProfilePackagePath,
|
||||
[Parameter(Mandatory)][string]$ClientCertificatePfxPath,
|
||||
[securestring]$ClientCertificatePfxPassword,
|
||||
[Parameter(Mandatory)][string]$ClientRootCertificatePath,
|
||||
[string]$ConnectionName = 'SGU Azure P2S',
|
||||
[string[]]$AzureNetworkPrefixes = @('10.77.0.0/16'),
|
||||
[ipaddress]$DomainControllerIPv4Address = '10.77.0.4',
|
||||
[string]$DomainName = 'lci.lasalle.mx',
|
||||
[switch]$Connect
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
foreach ($path in @($VpnProfilePackagePath,$ClientCertificatePfxPath,$ClientRootCertificatePath)) {
|
||||
if (-not (Test-Path -LiteralPath $path -PathType Leaf)) {
|
||||
throw "Required P2S file not found: $path"
|
||||
}
|
||||
}
|
||||
if (-not $ClientCertificatePfxPassword) {
|
||||
$ClientCertificatePfxPassword = Read-Host 'Password protecting the P2S client PFX' -AsSecureString
|
||||
}
|
||||
|
||||
$temporaryRoot = Join-Path $env:ProgramData ("SGU\AzureP2S\Import-" + [Guid]::NewGuid().ToString('N'))
|
||||
try {
|
||||
Expand-Archive -LiteralPath $VpnProfilePackagePath -DestinationPath $temporaryRoot -Force
|
||||
$vpnSettingsPath = Get-ChildItem -LiteralPath $temporaryRoot -Recurse -Filter VpnSettings.xml -File |
|
||||
Select-Object -First 1 -ExpandProperty FullName
|
||||
if (-not $vpnSettingsPath) {
|
||||
throw 'The Azure package does not contain Generic\VpnSettings.xml. Generate it with IKEv2 enabled.'
|
||||
}
|
||||
[xml]$vpnSettings = Get-Content -LiteralPath $vpnSettingsPath -Raw
|
||||
$vpnServerNode = $vpnSettings.SelectSingleNode('//*[local-name()="VpnServer"]')
|
||||
if (-not $vpnServerNode -or [string]::IsNullOrWhiteSpace($vpnServerNode.InnerText)) {
|
||||
throw 'VpnSettings.xml does not contain the Azure VPN gateway FQDN.'
|
||||
}
|
||||
$vpnServer = $vpnServerNode.InnerText.Trim()
|
||||
|
||||
$serverRootPath = Get-ChildItem -LiteralPath (Split-Path $vpnSettingsPath -Parent) `
|
||||
-Filter VpnServerRoot.cer -File | Select-Object -First 1 -ExpandProperty FullName
|
||||
if ($serverRootPath) {
|
||||
Import-Certificate -FilePath $serverRootPath -CertStoreLocation Cert:\LocalMachine\Root | Out-Null
|
||||
}
|
||||
$clientRoot = Import-Certificate -FilePath $ClientRootCertificatePath `
|
||||
-CertStoreLocation Cert:\LocalMachine\Root | Select-Object -First 1
|
||||
$clientCertificates = @(Import-PfxCertificate -FilePath $ClientCertificatePfxPath `
|
||||
-Password $ClientCertificatePfxPassword -CertStoreLocation Cert:\LocalMachine\My)
|
||||
$clientCertificate = $clientCertificates |
|
||||
Where-Object {
|
||||
$_.HasPrivateKey -and
|
||||
$_.NotAfter -gt (Get-Date) -and
|
||||
@($_.EnhancedKeyUsageList | ForEach-Object ObjectId) -contains '1.3.6.1.5.5.7.3.2'
|
||||
} |
|
||||
Sort-Object NotAfter -Descending |
|
||||
Select-Object -First 1
|
||||
if (-not $clientCertificate) {
|
||||
throw 'The imported PFX does not contain a valid Client Authentication certificate with a private key.'
|
||||
}
|
||||
|
||||
if ($PSCmdlet.ShouldProcess($ConnectionName, 'Install an all-user IKEv2 Azure P2S connection using a machine certificate')) {
|
||||
$existingConnection = Get-VpnConnection -Name $ConnectionName -AllUserConnection `
|
||||
-ErrorAction SilentlyContinue
|
||||
if ($existingConnection) {
|
||||
Remove-VpnConnection -Name $ConnectionName -AllUserConnection -Force
|
||||
}
|
||||
Add-VpnConnection `
|
||||
-Name $ConnectionName `
|
||||
-ServerAddress $vpnServer `
|
||||
-TunnelType Ikev2 `
|
||||
-AuthenticationMethod MachineCertificate `
|
||||
-MachineCertificateIssuerFilter $clientRoot `
|
||||
-MachineCertificateEKUFilter '1.3.6.1.5.5.7.3.2' `
|
||||
-EncryptionLevel Required `
|
||||
-SplitTunneling `
|
||||
-AllUserConnection `
|
||||
-DnsSuffix $DomainName `
|
||||
-Force | Out-Null
|
||||
foreach ($prefix in $AzureNetworkPrefixes) {
|
||||
Add-VpnConnectionRoute -ConnectionName $ConnectionName `
|
||||
-DestinationPrefix $prefix -AllUserConnection -PassThru | Out-Null
|
||||
}
|
||||
|
||||
$nrptDisplayName = "SGU Azure P2S DNS - $DomainName"
|
||||
Get-DnsClientNrptRule -ErrorAction SilentlyContinue |
|
||||
Where-Object DisplayName -eq $nrptDisplayName |
|
||||
Remove-DnsClientNrptRule -Force
|
||||
Add-DnsClientNrptRule `
|
||||
-Namespace ".$DomainName" `
|
||||
-NameServers $DomainControllerIPv4Address.IPAddressToString `
|
||||
-DisplayName $nrptDisplayName `
|
||||
-Comment 'Managed by SGU Azure P2S bootstrap; routes only the AD namespace to the domain controller.' | Out-Null
|
||||
}
|
||||
|
||||
if ($Connect) {
|
||||
& "$env:SystemRoot\System32\rasdial.exe" $ConnectionName
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Windows could not connect $ConnectionName. Verify UDP 500/4500 (IKEv2) or use the Azure-generated SSTP profile when the local network blocks IKEv2."
|
||||
}
|
||||
}
|
||||
|
||||
$connection = Get-VpnConnection -Name $ConnectionName -AllUserConnection
|
||||
[pscustomobject]@{
|
||||
ConnectionName = $connection.Name
|
||||
ServerAddress = $connection.ServerAddress
|
||||
TunnelType = $connection.TunnelType
|
||||
AllUserConnection = $true
|
||||
AuthenticationMethod = $connection.AuthenticationMethod
|
||||
ConnectionStatus = $connection.ConnectionStatus
|
||||
ClientCertificateThumbprint = $clientCertificate.Thumbprint
|
||||
DomainControllerIPv4Address = $DomainControllerIPv4Address.IPAddressToString
|
||||
DomainDnsNamespace = ".$DomainName"
|
||||
AzureNetworkPrefixes = $AzureNetworkPrefixes
|
||||
AvailableBeforeLogon = $true
|
||||
}
|
||||
}
|
||||
finally {
|
||||
$ClientCertificatePfxPassword = $null
|
||||
if (Test-Path -LiteralPath $temporaryRoot) {
|
||||
Remove-Item -LiteralPath $temporaryRoot -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user