Cisco AnyConnect: Powershell für Autologin
Inhaltsverzeichnis
1. Vorwort Inhalt
Seit geraumer Zeit schon geht mir der Cisco-Client () auf die Nerven mit seiner gewollten Unfähigkeit, das Benutzerkennwort zu speichern. Nein, ich will wirklich nichts über IT-Sicherheit wissen; der im BIOS eingebaute Keylogger hat mein Paßwort sowieso schon an alle Stellen, die interessiert sind, verteilt. Leider läßt sich der Client nicht per Kommandozeile mit Parametern versehen; es muß ein bißchen tiefer in die Trickkiste gegriffen werden.
2. Originale Vorlage Inhalt
Nach einiger Suche stieß ich in diesem Forum auf einen Vorschlag zur Verwendung der in Windows eingebauten PowerShell. Der originale Code wie folgt:
#Source www.cze.cz #This script is tested with "Cisco AnyConnect Secure Mobility Client version 3.0.5080" #Please change following variables #IP address or host name of cisco vpn [string]$CiscoVPNHost = "192.168.0.50" [string]$Login = "LOGIN" [string]$Password = "PASSWORD" #Please check if file exists on following paths [string]$vpncliAbsolutePath = 'C:\Program Files (x86)\Cisco\Cisco AnyConnect Secure Mobility Client\vpncli.exe' [string]$vpnuiAbsolutePath = 'C:\Program Files (x86)\Cisco\Cisco AnyConnect Secure Mobility Client\vpnui.exe' #**************************************************************************** #**** Please do not modify code below unless you know what you are doing **** #**************************************************************************** Add-Type -AssemblyName System.Windows.Forms -ErrorAction Stop #Set foreground window function #This function is called in VPNConnect Add-Type @' using System; using System.Runtime.InteropServices; public class Win { [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetForegroundWindow(IntPtr hWnd); } '@ -ErrorAction Stop #quickly start VPN #This function is called later in the code Function VPNConnect() { Start-Process -FilePath $vpncliAbsolutePath -ArgumentList "connect $CiscoVPNHost" $counter = 0; $h = 0; while($counter++ -lt 1000 -and $h -eq 0) { sleep -m 10 $h = (Get-Process vpncli).MainWindowHandle } #if it takes more than 10 seconds then display message if($h -eq 0){echo "Could not start VPNUI it takes too long."} else{[void] [Win]::SetForegroundWindow($h)} } #Terminate all vpnui processes. Get-Process | ForEach-Object {if($_.ProcessName.ToLower() -eq "vpnui") {$Id = $_.Id; Stop-Process $Id; echo "Process vpnui with id: $Id was stopped"}} #Terminate all vpncli processes. Get-Process | ForEach-Object {if($_.ProcessName.ToLower() -eq "vpncli") {$Id = $_.Id; Stop-Process $Id; echo "Process vpncli with id: $Id was stopped"}} #Disconnect from VPN echo "Trying to terminate remaining vpn connections" start-Process -FilePath $vpncliAbsolutePath -ArgumentList 'disconnect' -wait #Connect to VPN echo "Connecting to VPN address '$CiscoVPNHost' as user '$Login'." VPNConnect #Write login and password [System.Windows.Forms.SendKeys]::SendWait("$Login{Enter}") [System.Windows.Forms.SendKeys]::SendWait("$Password{Enter}") #Start vpnui start-Process -FilePath $vpnuiAbsolutePath #Wait for keydown echo "Press any key to continue ..." try{$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")}catch{}
Leider hatte er nicht auf Anhieb funktioniert, da inzwischen die Profilauswahl ebenfalls in der Kommandozeile verfügbar ist. Auch hätte ich gerne, daß das Fenster eines Batch Files nach erfolgreichem Verbinden geschlossen wird und nicht auf einen Tastendruck gewartet wird.
3. Verbesserte Lösung Inhalt
Daher ist das Script wie folgt angepaßt; es funktioniert einwandfrei.
#Source www.cze.cz #This script is tested with "Cisco AnyConnect Secure Mobility Client version 3.0.10057" [string]$CiscoVPNHost = "$CISCO-HOST" [string]$Login = "$LOGIN" [string]$Password = "$PASSWORD" [string]$vpncliAbsolutePath = 'C:\Program Files (x86)\Cisco\Cisco AnyConnect Secure Mobility Client\vpncli.exe' [string]$vpnuiAbsolutePath = 'C:\Program Files (x86)\Cisco\Cisco AnyConnect Secure Mobility Client\vpnui.exe' Add-Type -AssemblyName System.Windows.Forms -ErrorAction Stop Add-Type @' using System; using System.Runtime.InteropServices; public class Win { [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetForegroundWindow(IntPtr hWnd); } '@ -ErrorAction Stop Function VPNConnect() { Start-Process -FilePath $vpncliAbsolutePath -ArgumentList "connect $CiscoVPNHost" $counter = 0; $h = 0; while($counter++ -lt 1000 -and $h -eq 0) { sleep -m 10 $h = (Get-Process vpncli).MainWindowHandle } if($h -eq 0){echo "Could not start VPNUI it takes too long."} else{[void] [Win]::SetForegroundWindow($h)} } Get-Process | ForEach-Object {if($_.ProcessName.ToLower() -eq "vpnui") {$Id = $_.Id; Stop-Process $Id; echo "Process vpnui with id: $Id was stopped"}} Get-Process | ForEach-Object {if($_.ProcessName.ToLower() -eq "vpncli") {$Id = $_.Id; Stop-Process $Id; echo "Process vpncli with id: $Id was stopped"}} echo "Trying to terminate remaining vpn connections" start-Process -FilePath $vpncliAbsolutePath -ArgumentList 'disconnect' -wait echo "Connecting to VPN address '$CiscoVPNHost' as user '$Login'." VPNConnect [System.Windows.Forms.SendKeys]::SendWait("{Enter}") start-sleep 2 [System.Windows.Forms.SendKeys]::SendWait("$Login{Enter}") start-sleep 2 [System.Windows.Forms.SendKeys]::SendWait("$Password{Enter}") start-sleep 5 start-Process -FilePath $vpnuiAbsolutePath
4. Anmerkungen Inhalt
Zwei Dinge gilt es zu beachten; beide auch hier erwähnt. Auf jungfräulichen Windows-Installationen ist das Ausführen eigener PowerShell-Scripts nicht gestattet. Außerdem muß, wenn der erste Punkt behoben wurde, das Script mit vollem oder wenigstens relativen Pfad durch „./“ aufgerufen werden.
Happy Connecting…
8 Kommentare zu “Cisco AnyConnect: Powershell für Autologin”
Hi, i have test you script and it is working very nice. thanks to you, but 2 things are still disturbing,(1) first i am getting a popup message like „Connect not available. Another AnyConnect application is running or the functionality is not requested by this application.“ (2)at the same time powershell shows the successful connection and then it needs to get the cisco acceptance? certificate? by entering „Y“
in the end the connection gets ok/
could you pl help in this regard?
Rizwan
Rizwan.qadeer@gmail.com
Hi,
sorry, the first error has never occurred on my installations and I don’t know how to solve it. On my computers it makes no difference if the previous instance is still running, since the script attempts to close the instance (see line 34).
As for the second issue, I don’t know either, it looks like you need to find the appropriate window (maybe by its title or its process image name) and send a „Y“ to it. I have no idea how to do that with powerscript, sorry.
Hey, i have an issue.. we have a Password with some @ and / signgs.. thats generating errors.
Can you help me?
Ok.. the problem is not the @.. the problem is a ( in the password
Hi, without source code it’s difficult to give an exact solution. If you compare the password string to a saved one and use the match() function, be aware that it uses regular expressions: http://www.vistax64.com/powershell/199639-comparing-string-contains-parenthesis.html
In this case, you need to escape the parenthesis character by preceeding an escape character (most likely the backslash „\“). Hope that helps.
This is about your script… just try it with a $Password like 1245(@ABC
Well, same thing basically. See documentation for
::Send()
-Method here.It states that some characters, such as parenthesis, have special meaning and must be escaped if used as characters. Escaping takes place by enclosing the appropriate character in (curly) braces „{}“. So, your password string „1245(@ABC“ should become „1245{(}@ABC“, if I’m not mistaken.
Unfortunately, I cannot test this, since our company threw all Cisco equipment overboard after NSA stuff.
Thank you! that {(} worked 🙂
Einen Kommentar hinterlassen