prod@blog:~$

Tracking NetMotion Secure Access Events with PowerShell

I recently needed to troubleshoot authentication issues with our NetMotion Secure Access infrastructure, and found myself repeatedly digging through log files across multiple servers. NetMotion Secure Access stores all its events in log files within the running directory, making it possible to search for specific parameters - but doing this manually across six servers was becoming time-consuming.

Understanding NetMotion Authentication Methods

NetMotion Secure Access supports two primary authentication methods:

Device Authentication: When using device certificates or device-based authentication, the VPN authenticates based on the device itself. The user doesn't need to provide credentials - the device certificate handles the authentication automatically. In this scenario, tracking issues requires searching for the device name.

User Authentication: When users authenticate with certificates, username/password, or SAML requests, the authentication is tied to the user account rather than the device. Users can connect from any device, but they must authenticate with their credentials. This method allows tracking user-specific events including administrative actions like policy changes and console access.

Script 1: User-Based Event Search

This first script searches for events based on username. It's particularly useful when you're using user authentication and need to track:

  • Failed authentication attempts
  • Policy changes made by administrators
  • Console access elevation
  • User connection patterns across different devices
# User-based NetMotion event search and CSV export
param (
    [Parameter(Mandatory = $true)]
    [string]$Username,
    [Parameter(Mandatory = $false)]
    [int]$DaysBack = 1
)

# Map each server to its log path
$ServerPaths = @{
    "VPNACCESS01" = "c`$\Program Files\NetMotion Server\logs"
    "VPNACCESS02" = "c`$\Program Files\NetMotion Server\logs"
    "VPNACCESS03" = "c`$\Program Files\NetMotion Server\logs"
    "VPNSECURE01" = "c`$\Program Files\Secure Access Server\logs"
    "VPNSECURE02" = "c`$\Program Files\Secure Access Server\logs"
    "VPNSECURE03" = "c`$\Program Files\Secure Access Server\logs"
}

The script uses a hashtable to map server names to their log paths. I've found that NetMotion can install to slightly different paths depending on the product version - older "NetMotion Server" installations versus newer "Secure Access Server" installations.

$CutoffDate = (Get-Date).AddDays(-$DaysBack)
$Results = @()

foreach ($Server in $ServerPaths.Keys) {
    $LogPath = "\\$Server\$($ServerPaths[$Server])"
    
    if (-not (Test-Path $LogPath)) {
        Write-Warning "[$Server] Log path not accessible: $LogPath"
        continue
    }

The -DaysBack parameter is crucial for historical investigations. By default, it searches only today's logs, but you can extend this based on your log retention. For example, -DaysBack 7 will search the past week's logs.

    Get-ChildItem -Path $LogPath -Filter "Mobility_events*" -File -ErrorAction SilentlyContinue |
        Where-Object { $_.LastWriteTime -ge $CutoffDate } |
        ForEach-Object {
            $File = $_
            Write-Verbose "[$Server] Processing $($File.Name)"
            
            try {
                Get-Content -Path $File.FullName -ReadCount 1 -ErrorAction Stop |
                    Where-Object { $_ -match [regex]::Escape($Username) } |
                    ForEach-Object {
                        $Results += [PSCustomObject]@{
                            Server    = $Server
                            FileName  = $File.Name
                            FileDate  = $File.LastWriteTime
                            EventLine = $_
                        }
                    }
            }
            catch {
                Write-Warning "[$Server] Failed to read $($File.Name): $($_.Exception.Message)"
            }
        }
}

# Output the exact event lines to screen
$Results | Sort-Object Server, FileDate | ForEach-Object { Write-Output $_.EventLine }

# Export to CSV
$CsvFile = "MobilityEvents_$Username.csv"
$Results | Export-Csv $CsvFile -NoTypeInformation
Write-Host "Results exported to $CsvFile"

I use [regex]::Escape() to handle usernames that might contain special characters. The script captures the full event line, preserving all the detail NetMotion logs provide.

Script 2: Device-Based Event Search

The second script is nearly identical but searches for device names instead. This is essential when troubleshooting device authentication issues where the connection fails before user authentication even occurs.

# Device-based NetMotion event search and CSV export
param (
    [Parameter(Mandatory = $true)]
    [string]$DeviceName,
    [Parameter(Mandatory = $false)]
    [int]$DaysBack = 1
)

# Map each server to its log path
$ServerPaths = @{
    "VPNACCESS01" = "c`$\Program Files\NetMotion Server\logs"
    "VPNACCESS02" = "c`$\Program Files\NetMotion Server\logs"
    "VPNACCESS03" = "c`$\Program Files\NetMotion Server\logs"
    "VPNSECURE01" = "c`$\Program Files\Secure Access Server\logs"
    "VPNSECURE02" = "c`$\Program Files\Secure Access Server\logs"
    "VPNSECURE03" = "c`$\Program Files\Secure Access Server\logs"
}

$CutoffDate = (Get-Date).AddDays(-$DaysBack)
$Results = @()

foreach ($Server in $ServerPaths.Keys) {
    $LogPath = "\\$Server\$($ServerPaths[$Server])"
    
    if (-not (Test-Path $LogPath)) {
        Write-Warning "[$Server] Log path not accessible: $LogPath"
        continue
    }
    
    Get-ChildItem -Path $LogPath -Filter "Mobility_events*" -File -ErrorAction SilentlyContinue |
        Where-Object { $_.LastWriteTime -ge $CutoffDate } |
        ForEach-Object {
            $File = $_
            Write-Verbose "[$Server] Processing $($File.Name)"
            
            try {
                Get-Content -Path $File.FullName -ReadCount 1 -ErrorAction Stop |
                    Where-Object { $_ -match [regex]::Escape($DeviceName) } |
                    ForEach-Object {
                        $Results += [PSCustomObject]@{
                            Server    = $Server
                            FileName  = $File.Name
                            FileDate  = $File.LastWriteTime
                            EventLine = $_
                        }
                    }
            }
            catch {
                Write-Warning "[$Server] Failed to read $($File.Name): $($_.Exception.Message)"
            }
        }
}

# Output the exact event lines to screen
$Results | Sort-Object Server, FileDate | ForEach-Object { Write-Output $_.EventLine }

# Export to CSV
$CsvFile = "MobilityEvents_$DeviceName.csv"
$Results | Export-Csv $CsvFile -NoTypeInformation
Write-Host "Results exported to $CsvFile"

Usage Examples

Tracking Administrative Changes

When I needed to audit who made policy changes last week:

.\Search-UserEvents.ps1 -Username "admin.jsmith" -DaysBack 7

This revealed all console access events and policy modifications made by that administrator account.

Troubleshooting Device Authentication Failures

A user reported their laptop "LAPTOP-BEAR-042" couldn't connect:

.\Search-DeviceEvents.ps1 -DeviceName "LAPTOP-BEAR-042" -DaysBack 3

The output showed certificate validation failures, pointing to an expired device certificate.

Investigating User Connection Issues

To see all authentication attempts for a user having intermittent issues:

.\Search-UserEvents.ps1 -Username "jdoe@bear.local" -DaysBack 2

This revealed the user was attempting connections from multiple devices, with failures only occurring from their home laptop.

Important Considerations

Log Retention

The effectiveness of these scripts depends on your log retention settings. NetMotion typically rotates logs based on size or age, so historical data might be limited.

Performance

Searching through large log files can take time. I've used -ReadCount 1 to process files line by line, which is memory-efficient but may be slower for very large files.

Access Rights

You'll need administrative access to the NetMotion servers and the ability to access the administrative shares (C$). The scripts will warn you if a server is inaccessible rather than failing completely.

CSV Output

Both scripts create CSV files that include the server name, file name, timestamp, and the complete event line. This format makes it easy to import into Excel for further analysis or to share findings with other team members.

Conclusion

These scripts have saved me considerable time when troubleshooting authentication issues, investigating security events, and performing compliance audits. The ability to quickly search across all NetMotion servers for specific events has proven invaluable for maintaining our remote access infrastructure.