Public/Install-NetExtender.ps1

function Install-NetExtender {
    [CmdletBinding(SupportsShouldProcess)]
        param (
        [string]$Installer,
        [ValidateScript({
            if($_ -notmatch ':\d+$' -or ($_ -match ':(\d+)$' -and ([int]$matches[1] -lt 1 -or [int]$matches[1] -gt 65535))) {
                throw "Server must include a colon followed by a valid port number."
            } else {
                $true
            }
        })]
        [string[]]$Server,
        [ValidateScript({
            if($_.Count -gt 1 -and $_.Count -ne $Server.Count) {
                throw "The number of values for Domain must be one or, if greater than one, it must be the exact same amount as Server."
            } else {
                $true
            }
        })]
        [string[]]$Domain,
        [ValidateScript({
            if($_ -eq $true -and ($Server.Count -gt 1 -or $Domain.Count -gt 1)) {
                throw "Editable cannot be used when multiple strings are specified for either Server or Domain."
            } else {
                $true
            }
        })]
        [bool]$Editable = $true,
        [bool]$AllUsers = $true,
        [switch]$PreLogin,
        [switch]$ResetProfiles
        )

        #Requires -Modules Carbon, Carbon.Windows.Installer

        # . $PSScriptRoot\Get-NetExtenderProfile.ps1
        # . $PSScriptRoot\Remove-NetExtenderProfile.ps1

        if($null -eq $Installer -or $Installer -eq "") {
            Write-Verbose "Fetching latest installer..."
            $Installer = Get-NetExtender
        }


        # Check for an existing installation of NetExtender
        $NEInstalled = Get-CInstalledProgram *NetExtender* | Select-Object -First 1
        $NEMsi = Get-CMsi $Installer

        # Test the installer is for NetExtender
        if($NEMsi.ProductName -ne "SonicWall NetExtender") {
        Write-Error "The installer is not for NetExtender."
        exit 1
        }

        # Initialize variable for NetExtender installer arguments
        $NEArgs = @("/i $Installer /qb /norestart")

        # Compare the installed version with the latest version
        $InstalledVersion = [System.Version]$NEInstalled.DisplayVersion
        $ThisVersion = [System.Version]$NEMsi.ProductVersion

        if($null -ne $NEInstalled) {
            if($InstalledVersion -ge $ThisVersion) {
                if(-Not $ResetProfiles) {
                    Write-Output "NetExtender is already installed and is the same or newer version."
                    Write-Output "Use -ResetProfiles if you wished to remove existing profiles and add new ones."
                    timeout -t 5
                    exit 0
                } else {
                    $SkipInstall = $true
                    Write-Output "NetExtender is already installed and is the same or newer version."
                    Write-Output "ResetProfiles is set..."
                }
            } else {
                Write-Verbose "NetExtender is installed but an older version. Proceeding..."
            }
        } else {
            Write-Verbose "NetExtender is not installed. Proceeding..."
        }

        if(-Not $SkipInstall) {

            if($Editable -eq $true) {
                $NEArgs += "EDITABLE=TRUE"
            } 

            if ($Editable -eq $false) {
                if($Server.Count -gt 1) {
                    Write-Error "Multiple server profiles cannot be added when the profile is not editable."
                    exit 1
                }

                $NEArgs += "EDITABLE=FALSE"
            }

            if($AllUsers) {
                $NEArgs += "ALLUSERS=2"
            }

            if($PreLogin) {
                $NEArgs += "netlogon=true"
            }

            if($PSCmdlet.ShouldProcess("NetExtender", "Install")) {
                # Install NetExtender
                Start-Process -FilePath "c:\windows\system32\msiexec.exe" -ArgumentList ($NEArgs -Join " ") -Wait -Verb RunAs

                # Check for successful installation
                $NEInstallCheck = Get-CInstalledProgram *NetExtender* | Select-Object -First 1

                if($NEInstallCheck.DisplayName -eq $NEMsi.ProductName -and $NEInstallCheck.DisplayVersion -eq $NEMsi.ProductVersion) {
                    Write-Output "NetExtender installed successfully."

                } else {
                    Write-Error "NetExtender installation failed."
                    exit 1
                }

            }
        } else {
            Write-Output "Skipping installation..."
        }

        # Make sure NEGui is not running before changing profiles
        Get-Process "NEGui" -ErrorAction SilentlyContinue | Stop-Process -Force

        $NEProfiles = Get-NetExtenderProfile

        if($ResetProfiles) {
            Write-Output "Removing all profiles..."

            Remove-NetExtenderProfile

            $NEProfiles = Get-NetExtenderProfile
        }

        if($Server) {
            $counter = 0
            foreach($entry in $Server) {
                $entryDomain = $Domain[$counter]

                if($counter -gt 0 -and $null -eq $entryDomain) {
                    # If the domain is not specified, use the domain of the initial server
                    $entryDomain = $Domain[0]
                }

                # Check if the profile already exists
                if($NEProfiles.Server -Contains $entry -and $NEProfiles.Domain -Contains $entryDomain) {
                    Write-Output "Profile for $entry and $entryDomain already exists."
                    $counter++
                    continue
                }

                if($PSCmdlet.ShouldProcess("NetExtender", "Add profile for $entry and $entryDomain")) {
                    Write-Output "Adding profile for $entry and $entryDomain..."
                    Start-Process -FilePath "C:\Program Files (x86)\SonicWall\SSL-VPN\NetExtender\NECLI.exe" -ArgumentList "addprofile -s $entry -d $entryDomain" -Wait -Verb RunAs
                }

                $counter++
            }
        }

}

Export-ModuleMember -Function Install-NetExtender -Alias Update-NetExtender