EnhancedVPNAO.psm1

#Region '.\Public\Export-VPNConnectionsToXML.ps1' -1

function Export-VPNConnectionsToXML {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [string]$ExportFolder
    )

    try {
        # Get the list of current VPN connections
        $vpnConnections = Get-VpnConnection -AllUserConnection

        # Check if there are no VPN connections
        if ($vpnConnections.Count -eq 0) {
            Write-EnhancedLog -Message "NO VPN connections found." -Level "WARNING"
            return
        }

        # Generate a timestamp for the export
        $timestamp = Get-Date -Format "yyyyMMddHHmmss"
        $baseOutputPath = Join-Path -Path $ExportFolder -ChildPath "VPNExport_$timestamp"

        # Setup parameters for Export-Data using splatting
        $splatExportParams = @{
            Data             = $vpnConnections
            BaseOutputPath   = $baseOutputPath
            IncludeCSV       = $true
            IncludeJSON      = $true
            IncludeXML       = $true
            IncludePlainText = $true
            # IncludeExcel = $true
            IncludeYAML      = $true
        }

        # Call the Export-Data function with splatted parameters
        Export-Data @splatExportParams
        Write-EnhancedLog -Message "Data export completed successfully." -Level "INFO"
    }
    catch {
        Handle-Error -ErrorRecord $_
        Write-EnhancedLog -Message "Failed to export VPN connections." -Level "ERROR"
    }
}
#EndRegion '.\Public\Export-VPNConnectionsToXML.ps1' 43
#Region '.\Public\Import-VPNConnection.ps1' -1

function Import-VPNConnection {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [string]$XmlFilePath
    )

    try {
        Write-EnhancedLog -Message "Script starting..." -Level "INFO"

        # Load the XML file
        [xml]$vpnConfig = Get-Content -Path $XmlFilePath

        # Extract VPN connection details from the XML
        $connectionName = $vpnConfig.Objs.Obj.Props.S | Where-Object { $_.N -eq "Name" } | Select-Object -ExpandProperty '#text'
        $serverAddress = $vpnConfig.Objs.Obj.Props.S | Where-Object { $_.N -eq "ServerAddress" } | Select-Object -ExpandProperty '#text'
        $tunnelType = $vpnConfig.Objs.Obj.Props.S | Where-Object { $_.N -eq "TunnelType" } | Select-Object -ExpandProperty '#text'
        $encryptionLevel = $vpnConfig.Objs.Obj.Props.S | Where-Object { $_.N -eq "EncryptionLevel" } | Select-Object -ExpandProperty '#text'
        $splitTunneling = $vpnConfig.Objs.Obj.Props.B | Where-Object { $_.N -eq "SplitTunneling" } | Select-Object -ExpandProperty '#text'
        $rememberCredential = $vpnConfig.Objs.Obj.Props.B | Where-Object { $_.N -eq "RememberCredential" } | Select-Object -ExpandProperty '#text'
        $useWinlogonCredential = $vpnConfig.Objs.Obj.Props.B | Where-Object { $_.N -eq "UseWinlogonCredential" } | Select-Object -ExpandProperty '#text'
        $idleDisconnectSeconds = $vpnConfig.Objs.Obj.Props.U32 | Where-Object { $_.N -eq "IdleDisconnectSeconds" } | Select-Object -ExpandProperty '#text'
        # $authenticationMethod = $vpnConfig.Objs.Obj.Props.Obj.LST.S | Select-Object -ExpandProperty '#text'
        $authenticationMethod = $vpnConfig.Objs.Obj.Props.Obj | Where-Object { $_.N -eq "AuthenticationMethod" } | Select-Object -ExpandProperty LST | Select-Object -ExpandProperty S
        $l2tpPsk = $vpnConfig.Objs.Obj.Props.S | Where-Object { $_.N -eq "L2tpIPsecAuth" } | Select-Object -ExpandProperty '#text'
        # $napState = $vpnConfig.Objs.Obj.Props.S | Where-Object { $_.N -eq "NapState" } | Select-Object -ExpandProperty '#text'

        # Convert boolean values from text to actual boolean type
        $splitTunneling = [System.Convert]::ToBoolean($splitTunneling)
        $rememberCredential = [System.Convert]::ToBoolean($rememberCredential)
        $useWinlogonCredential = [System.Convert]::ToBoolean($useWinlogonCredential)

        # Validate extracted details
        if ([string]::IsNullOrWhiteSpace($connectionName) -or [string]::IsNullOrWhiteSpace($serverAddress)) {
            Write-EnhancedLog -Message "Connection name or server address could not be found in the XML file." -Level "ERROR"
            return
        }

        # Validate if VPN connection already exists
        if (Test-VPNConnection -ConnectionName $connectionName) {
            Write-EnhancedLog -Message "VPN connection '$connectionName' already exists. Removing it before re-importing." -Level "WARNING"
            Remove-VpnConnection -Name $connectionName -Force -AllUserConnection -ErrorAction SilentlyContinue

            # Verify the VPN connection is removed
            if (Test-VPNConnection -ConnectionName $connectionName) {
                Write-EnhancedLog -Message "Failed to remove existing VPN connection '$connectionName'." -Level "ERROR"
                return
            }

            Start-Sleep -Seconds 5 # Wait to ensure the connection is fully removed
        }

        # Splatting parameters for Add-VpnConnection
        $splatVpnParams = @{
            Name                  = $connectionName
            ServerAddress         = $serverAddress
            TunnelType            = $tunnelType
            EncryptionLevel       = $encryptionLevel
            SplitTunneling        = $splitTunneling
            RememberCredential    = $rememberCredential
            UseWinlogonCredential = $useWinlogonCredential
            IdleDisconnectSeconds = $idleDisconnectSeconds
            AuthenticationMethod  = $authenticationMethod
            L2tpPsk               = $l2tpPsk
            AllUserConnection     = $true
            Force                 = $true
        }

        # Remove L2tpPsk parameter if TunnelType is not L2tp
        if ($tunnelType -ne 'L2tp') {
            $splatVpnParams.Remove('L2tpPsk')
        }

        # Create the VPN connection
        Add-VpnConnection @splatVpnParams
        Write-EnhancedLog -Message "VPN connection '$connectionName' imported. Verifying the import..." -Level "INFO"

        # Introduce a brief pause to ensure the connection is fully created
        Start-Sleep -Seconds 5

        # Verify the VPN connection was created successfully
        if (Test-VPNConnection -ConnectionName $connectionName) {
            Write-EnhancedLog -Message "VPN connection '$connectionName' was successfully imported." -Level "INFO"
        } else {
            Write-EnhancedLog -Message "VPN connection '$connectionName' failed to import." -Level "ERROR"
        }
    }
    catch {
        Handle-Error -ErrorRecord $_
        Write-EnhancedLog -Message "An error occurred while importing VPN connection." -Level "ERROR"
        throw $_
    }
}
#EndRegion '.\Public\Import-VPNConnection.ps1' 94
#Region '.\Public\New-And-ValidateVPNConnection.ps1' -1

function New-And-ValidateVPNConnection {
    param (
        [Parameter(Mandatory = $true)]
        [string]$VPNConnectionName,
        [Parameter(Mandatory = $true)]
        [string]$VPNServerAddress
    )

    try {
        # Create the VPN connection
        New-VPNConnection -ConnectionName $VPNConnectionName -ServerAddress $VPNServerAddress -TunnelType 'Pptp'

        # Validate VPN connection
        if (Test-VPNConnection -ConnectionName $VPNConnectionName) {
            Write-EnhancedLog -Message "VPN connection '$VPNConnectionName' is ready for use." -Level "INFO" -ForegroundColor ([ConsoleColor]::Green)
        }
        else {
            Write-EnhancedLog -Message "VPN connection '$VPNConnectionName' validation failed." -Level "ERROR" -ForegroundColor ([ConsoleColor]::Red)
        }
    }
    catch {
        Write-EnhancedLog -Message "An error occurred: $_" -Level "ERROR" -ForegroundColor ([ConsoleColor]::Red)
    }
}

# # Example usage
# $vpnConnectionName = "MyVPNConnection"
# $vpnServerAddress = "vpn.example.com"
# New-And-ValidateVPNConnection -VPNConnectionName $vpnConnectionName -VPNServerAddress $vpnServerAddress
#EndRegion '.\Public\New-And-ValidateVPNConnection.ps1' 30
#Region '.\Public\New-VPNConnection.ps1' -1

function New-VPNConnection {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [string]$ConnectionName,

        [Parameter(Mandatory = $true)]
        [string]$ServerAddress,

        [Parameter(Mandatory = $true)]
        # [string]$TunnelType = "Pptp" # Default to Pptp, can be changed to Ikev2, L2tp, etc.
        [string]$TunnelType
    )

    try {
        # Validate if VPN connection already exists
        if (Test-VPNConnection -ConnectionName $ConnectionName) {
            Write-EnhancedLog -Message "VPN connection '$ConnectionName' already exists." -Level "INFO"
            return
        }

        # Create the VPN connection
        Add-VpnConnection -Name $ConnectionName -ServerAddress $ServerAddress -TunnelType $TunnelType -AuthenticationMethod MSChapv2 -EncryptionLevel Optional -Force

        # Validate if VPN connection was created successfully
        if (Test-VPNConnection -ConnectionName $ConnectionName) {
            Write-EnhancedLog -Message "VPN connection '$ConnectionName' created successfully." -Level "INFO"
        } else {
            Write-EnhancedLog -Message "Failed to create VPN connection '$ConnectionName'." -Level "ERROR"
            throw "Failed to create VPN connection '$ConnectionName'."
        }
    }
    catch {
        Write-EnhancedLog -Message "An error occurred while creating VPN connection '$ConnectionName': $_" -Level "ERROR"
        throw $_
    }
}
#EndRegion '.\Public\New-VPNConnection.ps1' 38
#Region '.\Public\Test-VPNConnection.ps1' -1

function Test-VPNConnection {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [string]$ConnectionName
    )

    try {
        # Check if the VPN connection exists
        $vpnConnection = Get-VpnConnection -Name $ConnectionName -AllUserConnection -ErrorAction SilentlyContinue
        if ($null -ne $vpnConnection) {
            Write-EnhancedLog -Message "VPN connection '$ConnectionName' exists." -Level "INFO"
            return $true
        } else {
            Write-EnhancedLog -Message "VPN connection '$ConnectionName' does not exist." -Level "INFO"
            return $false
        }
    }
    catch {
        Handle-Error -ErrorRecord $_
        Write-EnhancedLog -Message "An error occurred while checking VPN connection '$ConnectionName'." -Level "ERROR"
        throw $_
    }
}



# Test-VPNConnection -ConnectionName "ICTC VPN"
#EndRegion '.\Public\Test-VPNConnection.ps1' 29