Andrew Odri

AppleScript Editor icon and Network Preferences pane of System Preferences

After recently configuring a Mac OS X Server to provide VPN access, I was also asked to create an all inclusive script which would automatically configure the connection. If you have been trying to do the same, I have included some pitfalls I came across, and the complete code for a script that can do the job.

The first script I stumbled across on Google seemed like it would do the trick. The poster had attempted to configure the VPN using UI automation, which didn’t seem to be working. The proposed solution used the command line networksetup tool instead, which seems like a far more elegant solution. It stated that by calling “networksetup -createnetworkservice networkservicename hardwareport” along with a few other related commands, the VPN could easily be configured. However, in practice this just creates a standard network service which had to be bound to a physical interface, rather than a VPN service. After much research, it became clear that there was no available hardware port that would magically configure a VPN, and even if there was, there seems to be no way to access VPN specific settings.

From what I can gather, the UI automation route seems to be the easiest way to go. I couldn’t find any existing solutions using UI automation that would be acceptable to send to clients. So, below are instructions for creating, customizing, and compiling a script to take care of this. It references UI elements by id and number, and uses names as little as possible. This should make it easy to internationalize if the need arises. I hope this helps someone else out there!

  1. Open Finder, navigate to Applications, then Utilities, and open AppleScript Editor.
  2. Select the code at the end of this article, and press ⌘ (Command) + C. This copies the code into the clipboard.
  3. Return to AppleScript Editor, and press ⌘ (Command) + V. This pastes the code from the clipboard into the editor.
  4. The first line of code defines the server name that will be defined on the local computer. Replace Server Name with the name of the network service that you would like to appear on the client computer.
  5. The second line of code defines the server address. Replace 127.0.0.1 with the URL or IP address of the VPN server.
  6. The third line defines the shared secret for the VPN. Replace s3cr3t with the shared secret of you VPN.
  7. Go to line 32, and remove the two dashes before “click pop up button 2″
    • For an L2TP over IPSec connection: Go to line 33 and remove the two dashes before ‘click menu item “L2TP over IPSEC” of menu 1 of pop up button 2′
    • For a PPTP connection: Go to line 34 and remove the two dashes before ‘click menu item “PPTP” of menu 1 of pop up button 2′
    • For a Cisco IPSec connection: Go to line 35 and remove the two dashes before ‘click menu item “Cisco IPSec” of menu 1 of pop up button 2′ [See Sergio's comment below for information on configuring Cisco IPSec VPNs]
  8. Go to Script menu, and select the Run menu item

The script will now execute, and prompt you for your VPN username and password. If you want to create a completely automated script, you can easily add two more variables at the beginning of the script and make the appropriate changes throughout.

To compile the script for deployment, simply go to the File menu, select the Save As… menu item, and you should now have a script that is ready to send to your users :)


set vpnname to "Server Name"
set vpnserver to "127.0.0.1"
set vpnsecret to "s3cr3t"

tell application "System Events"
	if not (UI elements enabled) then
		tell application "System Preferences"
			activate
			set current pane to pane id "com.apple.preference.universalaccess"
			display dialog "This script requires access for assistive devices be enabled." & return & return & "To continue, click the OK button and enter an administrative password in the security dialog." with icon note
		end tell
		set UI elements enabled to true
		if UI elements enabled is false then return "User Cancelled"
		delay 1
	end if
	tell application "System Preferences"
		activate
		set current pane to pane id "com.apple.preference.network"
		display dialog "This script will now create the Stracor VPN connection." & return & return & "Please wait as the operation is in progress, and do not click anything. This should not take longer than 30 seconds. You will be notified when the process is complete." with icon caution
		set vpnusername to display dialog "Please enter your username:" default answer "" with icon note
		set vpnpassword to display dialog "Please enter your password:" default answer "" with icon note with hidden answer
	end tell
	tell application "System Events"
		tell process "System Preferences"
			tell window 1
				click button 5
				delay 1
			end tell
			tell sheet 1 of window 1
				click pop up button 1
				click menu item "VPN" of menu 1 of pop up button 1
				--click pop up button 2
				--click menu item "L2TP over IPSEC" of menu 1 of pop up button 2
				--click menu item "PPTP" of menu 1 of pop up button 2
				--click menu item "Cisco IPSec" of menu 1 of pop up button 2
				set focused of text field 1 to true
				keystroke "a" using command down
				keystroke vpnname
				click button 1
				delay 1
			end tell
			tell group 1 of window 1
				click checkbox 1
				set focused of text field 1 to true
				keystroke vpnserver
				keystroke tab
				keystroke text returned of vpnusername
				click button 2
				delay 1
			end tell
			tell sheet 1 of window 1
				set focused of text field 3 to true
				keystroke text returned of vpnpassword
				keystroke tab
				keystroke vpnsecret
				click button 2
				delay 1
			end tell
			tell window 1
				click button 1
				delay 1
			end tell
			tell sheet 1 of window 1
				click button 1
			end tell
		end tell
	end tell
	tell application "System Preferences"
		quit saving yes
	end tell
	display alert "The VPN has been configured. Click on the \"Connect\" button to access the network." & return & return & "The connection status and various options are available through the menu bar at the top of the screen." as informational
end tell
January
12
2011
by Alice

Awesome!! Great work :)

January
13
2011

nice tutorial you have there..I’ll see if I can try it on my machine…thanks mate

January
24
2011
by shaun miller

I’ve been playing with your script and using it for a Cisco VPN connection but the server address keeps getting populated into the account name field any help you can provide would be great

February
2
2011
by Andrew Odri (@andrewodri)

Hi Shaun, I had a similar issue when I was setting this up, it seemed like the default text field was constantly changing. Try putting in some delays before these calls:

set focused of text field 1 to true

It may be that the interface doesn’t have time to initialize the default text field. Let me know how that goes :)

February
10
2011
by Mark

Hi Andrew,

Thanks for this script – just what I was looking for.

I get the following when I run it:

error “system events got an error: can’t get sheet 1 of window 1 of process \”system preferences\”. invalid index.” number -1719 from sheet 1 of window 1 of process “system preferences”

Mac OS X 10.6.6

What am I missing?

Mark Patterson

February
10
2011
by Andrew Odri (@andrewodri)

Hey Mark,

I seems like the script is trying to open the sheet before it even exists. Try inserting the code below just prior to the line “tell sheet 1 of window 1″ on line 29:

tell window 1
	repeat until exists sheet 1
		delay 0.2
	end repeat
end tell

Let me know if this works for you, I will update the post with the modification :)

Thanks! Andrew

February
25
2011
by shaun miller

Andrew,

That worked great for me!!!

I have another question for you. Is there a way to modify to script so that the network pref pane stays open after the VPN connection is loaded?

February
26
2011
by Andrew Odri (@andrewodri)

Yeah, that should be really easy actually, just delete the following chunk of code:

tell application "system preferences"
	quit saving yes
end tell

That should do the trick :) The lines previous to this that say “click button 1″ also manage applying the settings, so playing around with those might give you the results you are after.

April
13
2011
by John

Hi Andrew,

I’ve followed your instructions to the letter, and I’m still getting the exact same error that Mark reported back in Feb. I’m 10.6.6 as well, and I’ve made the modification you suggest, but I’m still getting the same error.

Please help me understand where I’m going wrong.

Here’s the exact error:

error “System Events got an error: Can’t get pop up button 2 of sheet 1 of window 1 of process \”System Preferences\”. Invalid index.” number -1719 from pop up button 2 of sheet 1 of window 1 of process “System Preferences”

Any help would be most appreciated!

Thanks,

John

April
13
2011
by John

I forgot to mention that I’m trying to create a Cisco IPSec connection. Here’s the code from my script:

tell application “System Events”
tell process “System Preferences”
tell window 1
click button 5
delay 1
end tell
tell window 1
repeat until exists sheet 1
delay 0.2
end repeat
end tell
tell sheet 1 of window 1
click pop up button 1
click menu item “VPN” of menu 1 of pop up button 1
click pop up button 2
–click menu item “L2TP over IPSEC” of menu 1 of pop up button 2
–click menu item “PPTP” of menu 1 of pop up button 2
click menu item “Cisco IPSec” of menu 1 of pop up button 2
set focused of text field 1 to true
keystroke “a” using command down
keystroke vpnname
click button 1
delay 1
end tell

April
19
2011
by Andrew Odri (@andrewodri)

Perhaps try putting this in just before the line that says “click menu item “vpn” of menu 1 of pop up button 1″:

repeat until exists pop up button 2
delay 0.2
end repeat

This will make the script wait until the button that it is looking for exists before attempting to click it.

Hope that helps :)

April
21
2011
by Sergio (@Chalcahuite)

Andrew, John,

I also was trying to configure a Cisco IPSec VPN connection and these are the tweaks I made to get it to work. (10.6.6/10.6.7) I had to add the variable “vpngroup” to add the group name we use in our configuration. Hope this helps.

tell sheet 1 of window 1
click pop up button 1
click menu item “vpn” of menu 1 of pop up button 1
delay 1
repeat until exists pop up button 2
delay 0.2
end repeat
click pop up button 2
delay 0.5
–click menu item “l2tp over ipsec” of menu 1 of pop up button 2
–click menu item “pptp” of menu 1 of pop up button 2
click menu item “cisco ipsec” of menu 1 of pop up button 2
delay 1
set focused of text field 1 to true
keystroke “a” using command down
keystroke vpnname
click button 1
delay 1
end tell
delay 1
tell group 1 of window 1
set focused of text field 3 to true
keystroke vpnserver
keystroke tab
keystroke text returned of vpnusername
keystroke tab
keystroke text returned of vpnpassword
click checkbox 1
click button 2
delay 1
end tell
tell sheet 1 of window 1
delay 0.2
set focused of text field 1 to true
keystroke vpngroup
keystroke tab
keystroke vpnsecret
click button 2
delay 1
end tell

April
21
2011
by Andrew Odri (@andrewodri)

Awesome, thanks for posting that up for everyone Sergio!

September
14
2011
by nick

hey andrew, thanks for this post! I was ready to fall back to simply distributing the exported configuration from sysprefs instead of scripting this, but your code got it working for me. I’m using this on Lion, though, and I did have to change one thing to get it working- on line 26 where you have ‘click button 5′ I had to change that to ‘click button “Add Service”‘. That was it though, everything else worked with sergio’s modification for cisco VPN’s.
One question, though, since I know literally nothing about applescript . . . I’d like to have the VPN status shown in the menubar- how do I tell applescript to click that button before exiting?

September
14
2011
by nick

hmm, it seems that the ‘show VPN’ setting is a system-wide toggle. if it’s already been enabled for any other existing VPN connections, having the script click the checkbox disables it. Is there a way to read the status of the element and only click it if it isn’t already?

September
20
2011
by Mecca

Great script. Anyone get this working for OS X Lion.

September
20
2011
by Jeremy Koerber (@bluntobjekt)

Thanks, that was really helpful for getting a basic PPTP VPN setup going on my clients.
Now what I’m looking to do is to add one last action to the end of the script, and I’m having some trouble. I want to go into the Advanced… properties sheet of the newly created VPN, and then check off the ‘Send all traffic over VPN connection’ checkbox. Then click OK, close the preferences window, and end there with the dialog that confirms the script is complete.
I’m just having a hard time selecting the VPN object in the left pane before the script presses the Advanced… button.
Any help would be greatly appreciated. I’m trying to use the Accessibility Inspector to figure it out, but no dice yet.
Thanks much!

October
12
2011
by Venkateshwaran

Hi Admin,

Is it possible to connect to PPTP programatically not through Apple Script? Any pointers would be of great help.

Thanks
Venkat

October
14
2011
by Sojourner (@seesolve)

Open Configure a VPN in Mac OS X script in AppleScript Editor.

October
18
2011
by nick

last problem i’m running into is setting the proxy ports. i’ve got the script doing everything successfully except that. We need to set the proxies up for HTTP, HTTPS, and FTP. I can get the urls in there just fine, but the proxy port value seems to have the same UI name for each proxy type- if I have the script attempt to fill in the port value, the only type that has it after the script runs is the last one I have the script modify, the others revert to blank.

December
6
2011
by Will

LOVE THIS

I took Nick’s tweak for Lion and got really close.

Only fly in my ointment was that I have Tab set to go between all controls so to make it insert my shared secrete I had to remove the “keystroke tab” line and replace it with “set focused of text field 2 to true”. And it worked!

W

December
8
2011
by Andrew Odri (@andrewodri)

@Nick and @Will: Great to hear the tweak is working in Lion! I will update the post with the information as soon as I have a chance…

December
14
2011
by Rocky

@andrew @jeremy, any luck with a script that will check on “send all traffic over VPN connection”?
I’ve got it as far as to open up the “Advanced” tab but get stuck there

Thanks,
R

December
15
2011
by Rocky

spoke too soon, i got it. here is what i entered to get it working in case anyone wants it:

under your new VPN configuration tab, this will click advanced and check on the box “send all traffic over VPN connections”, click ok to bring you back to the network window.
—–
tell window 1
click button 9
delay 1
end tell
tell tab group 1 of sheet 1 of window 1
click check box 3
delay 1
end tell
tell sheet 1 of window 1
click button 1
end tell

January
17
2012

Quite interested in using this script, but at the moment can’t be used, because it is too big a security risk.

I have just tested the script and changed focus to TextEdit at the right time and as expected, the shared secret was typed into TextEdit.

Is there a way of checking the currently active application before doing the keystrokes. Even better, check that focus remains in Network preferences between the keystroke of every letter?

January
24
2012
by ghjm

Daniel – even if you could avoid letting the user switch to TextEdit, they could still just open the script in AppleScript Editor, just like we’re doing. If you don’t want to put the shared secret in the script, then just code another popup and ask the user for it at install time.

August
30
2012
by Matt

Hi

I’ve just found this and got it working on 10.7.4 (I’ve yet to test it on other versions of Lion)

To do this I had to do the following in order:

The button click is button 10
The text field for the server address is 3
The Authentication settings are entered in groupname then tab then secret order (because we use Cisco we have a groupname and shared secret)

Hope this help someone – because it’s far easier than entering the info each time :)

Matt

January
30
2013
by maclilly

Hey Matt,

I’m trying to get this working on 10.8. If you have the entire script for 10.7 that you could share, maybe I could have a go at it.

May
10
2013
by Paris

Has anyone got this working on 10.8?

I got the same error as Mark:
error “system events got an error: can’t get sheet 1 of window 1 of process \”system preferences\”. invalid index.” number -1719 from sheet 1 of window 1 of process “system preferences”

When I introduced the suggested loop.
tell window 1
repeat until exists sheet 1
delay 0.2
end repeat
end tell

The script just loops. So window 1 doesn’t get created. Sorry, I’m new to Applescript so I can’t troubleshoot beyond basic script flow. In this instance what is window 1?

May
13
2013
by Paris

So I got past the first hurdle. The error was the button call in line 27. It had to be changed from 5 to 10. (thanks matt).
Now I need to get figure out how to get the script to select “VPN” from the “interface” drop down. I tried changing “PPTP” to VPN in line 38, but that didn’t do it….oh well, more reading. J! Unless someone steps in :-)

May
24
2013
by robert (@rmullins0609)

AppleScript Error

System Events got an error: Can’t get pop button 1 of sheet 1 of window1 of process “System Perferences”. invalid index.

this the error when I run your script as is

any help?

thanks

robert

July
10
2013
by angela

Hello Andrew,
i tried this for pptp connection and its giving me: System Events got an error: Can’t get pop up button 1 of sheet 1 of window 1 of process “System Preferences”. Invalid index.

September
3
2013
by Rich

anyone have this working for 10.8 or higher… that can post there version.

Be a great help.. thanks.

January
4
2014
by Kevin Jin

This somehow dose nto work for me nd I get this error

2014-01-05 08:06:59.748 Phantomore VPN[2223:303] *** -[XYZAppDelegate Buttonhandlerinstallvpn:]: System Events got an error: Can’t set UI elements enabled of application to true. (error -10006)

Thank you!

May
28
2014
by gordon

hi can someone help me im a newbie and cant do this right, any help by email woukld be nice

June
26
2014
by marc

This doesn’t work in mavericks (10.9.3)

Error stating “System Events got an error: Can’t set UI elements enabled of application to true”

Leave a Response

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>