Windows 10下基于Openconnect的VPN会话启动脚本问题求助
解决Windows PowerShell中Openconnect --passwd-on-stdin传参失败的问题
以下是几种经过验证的可行方案,针对PowerShell与Openconnect交互时的stdin输入问题:
方案1:使用临时文件重定向输入
PowerShell的管道有时会和原生exe的stdin处理存在兼容性问题,用临时文件传递输入更可靠:
# 替换为你的VPN配置信息 $vpnServer = "vpn.yourcompany.com" $username = "your_username" $password = "YourSecurePassword" $totpSecret = "YourBase32TOTPSecret" # 生成实时TOTP(需先安装Otp.NET模块:Install-Module -Name Otp.NET -Scope CurrentUser) Import-Module Otp.NET $totpGenerator = [OtpNet.Totp]::new([OtpNet.Base32Encoding]::Decode($totpSecret)) $currentTotp = $totpGenerator.ComputeTotp() # 准备输入内容:部分VPN要求密码和TOTP分两行,部分要求拼接为一行,根据实际情况调整 $inputContent = "$password`n$currentTotp" # $inputContent = "$password$currentTotp" # 若需拼接为一行则用这个 # 写入ASCII编码的临时文件(避免编码问题) $tempFile = Join-Path $env:TEMP "vpn_creds.txt" $inputContent | Out-File -FilePath $tempFile -Encoding ASCII # 启动Openconnect并重定向stdin Start-Process -FilePath "openconnect.exe" -ArgumentList "-u $username --passwd-on-stdin $vpnServer" -RedirectStandardInput $tempFile -NoNewWindow -Wait # 清理临时文件 Remove-Item $tempFile -Force
方案2:通过cmd /c中转管道输入
利用cmd的管道机制更适配原生exe的stdin读取,避免PowerShell的编码差异:
# 替换为你的VPN配置信息 $vpnServer = "vpn.yourcompany.com" $username = "your_username" $password = "YourSecurePassword" $totpSecret = "YourBase32TOTPSecret" # 生成TOTP Import-Module Otp.NET $currentTotp = [OtpNet.Totp]::new([OtpNet.Base32Encoding]::Decode($totpSecret)).ComputeTotp() # 拼接输入(分两行或一行根据VPN要求调整) echo "$password`n$currentTotp" | cmd /c "openconnect.exe -u $username --passwd-on-stdin $vpnServer"
方案3:直接通过.NET Process类控制stdin
手动处理字节流输入,完全规避PowerShell管道的编码问题:
# 替换为你的VPN配置信息 $vpnServer = "vpn.yourcompany.com" $username = "your_username" $password = "YourSecurePassword" $totpSecret = "YourBase32TOTPSecret" # 生成TOTP Import-Module Otp.NET $currentTotp = [OtpNet.Totp]::new([OtpNet.Base32Encoding]::Decode($totpSecret)).ComputeTotp() # 配置进程 $process = New-Object System.Diagnostics.Process $process.StartInfo.FileName = "openconnect.exe" $process.StartInfo.Arguments = "-u $username --passwd-on-stdin $vpnServer" $process.StartInfo.UseShellExecute = $false $process.StartInfo.RedirectStandardInput = $true $process.StartInfo.NoWindow = $true # 启动进程并写入输入 $process.Start() $inputBytes = [System.Text.Encoding]::ASCII.GetBytes("$password`n$currentTotp") $process.StandardInput.BaseStream.Write($inputBytes, 0, $inputBytes.Length) $process.StandardInput.Close() # 等待进程结束 $process.WaitForExit()
关键注意事项
- TOTP实时生成:不要使用固定的TOTP值,必须在每次连接时生成当前有效的验证码,否则会验证失败。
- 编码问题:Openconnect默认期望ASCII编码的输入,PowerShell默认是UTF-16,所以必须确保输入是ASCII编码(如方案1的
-Encoding ASCII,方案3的ASCII字节流)。 - VPN输入格式:不同VPN的验证流程不同,有的要求先输密码再输TOTP(分两行),有的要求密码和TOTP拼接为一行,需要根据实际情况调整
$inputContent的格式。 - Openconnect版本:确保使用最新版的Openconnect,旧版本可能存在
--passwd-on-stdin参数的bug。
内容的提问来源于stack exchange,提问作者Daniel Zuluaga
相关产品推荐
相关产品推荐

