Want to quickly restart your Mac in your Windows Bootcamp partition, without having to hold down option/alt as the computer starts?
Click this link, which will open an AppleScript in your default editor, and replace “YourBootcampPartition” in the first line with your Windows partition’s actual name (making sure that is exactly the same, as it’s case sensitive). Then save it as a .scpt file in your user scripts folder, which you can access through the system-wide script menu (which is turned on in AppleScript Editor’s preferences).
Then, to restart, just pick it from that script menu.
Using Leopard (10.5) or earlier? You’ll have to change the first line as “diskutil info” doesn’t work with volume names. Try this:
set deviceID to (do shell script "diskutil list ¬
| grep YourBootcampPartition | awk '{print $8}'")
That should return something like “disk0s4”. If it doesn’t change “print $8” to a different number, probably 7. (I recommend you try this in the Terminal until you’ve got it right, then adjust the AppleScript. The number refers to the column of the information.)
Don’t want to have to type your password in every time? Add “password “YourPassword” ” after “ -nextonly” ” on the second line, then save your script as run-only. I do not recommend this. Your password will not be encrypted. It is only slightly less insecure than keeping your password in a text file. Please, do not do this.
I’ve got it saved to my ~/Library/Scripts folder, and have Launchbar set to index that folder so I can just type “Restart in Windows” into the prompt, hit enter, type my password and then I’m set.
You could also use FastScripts, a really nice replacement for the system script menu that you can use to give the script a keyboard shortcut.
I don’t recommend that you save it as an application, which would let you add it to your dock. I did that once and got stuck in a restart loop, thanks to Lion’s ability to re-open applications that were running when you restarted. You can disable that feature in Mountain Lion, but I still strongly advise that you keep it as a plain old script file.
set deviceID to (do shell script "diskutil info ¬
YourBootcampPartition | grep Identifier | awk '{print $3}'")
do shell script "bless -device /dev/" & deviceID & ¬
" -legacy -setBoot -nextonly" with administrator privileges
tell application "Finder" to restart
I talk about the origins in my first post about the script. Basically, holding down option on my keyboard was unreliable because the computer had booted up too fast for the Bluetooth connection. I’d been using Bootchamp, a menubar utility, for a while but you couldn’t trigger a restart from Launchbar and had to mount the partition first.
The first version relied on the disk identifier never changing. You can’t rely on a partition having the same identifier after a restart, so the script would silently fail.
The next version relied on the disk identifier being in a certain character position, which (aside from being a dirty hack) was also unreliable if you had more than 10 disks connected.
The most recent (and probably final) version uses grep and awk on the command line to fetch the disk identifier after pulling up the information for the partition. (In Leopard it has to get the identifier from the list of every partition, as “diskutil info [PartitionName]” only works in Snow Leopard and later. As such it’s a little less reliable and needs a bit more tweaking by users.)
For such a simple script (three whole lines!) this has taken more work than I originally anticipated. But it’s also taught me a fair bit about the command line and how to retrieve information from it.
So, yeah. I think it’s done now. If you have any questions or comments please message me on Twitter or add a comment to the script’s gist.

AppleScript gets a lot of stick for being a rubbish language. And it is. But before last night there wasn’t anything that really threw me and made me think “wow, that’s incredibly, impressively, mind-meltingly dumb”. (Admittedly, I’m not a programmer.)
But it happened. Here’s the example code:
set myRecords to {Abc:"1", Def:"2", Ghi:"3"}
set myVar to "Abc"
get myVar of myRecords
Try that and you’ll get a big fat error message. Why? Because there’s no property in myRecords that’s literally called myVar.
“But it’s a variable,” I hear you sob quietly into Script Debugger. I know, I know. You were after the value of property “Abc”. Unfortunately AppleScript doesn’t let you access records in this way. If you want to access that property you need to refer to its “real” name directly in the code.
Even to me this is ridiculous. I’ve learnt a little JavaScript with Codecademy recently and you can do this very easily:
var theRecords = {
Abc: 1,
Def: 2,
Ghi: 3
};
var theVar = "Abc";
console.log(theRecords[theVar]);
This becomes important when you want to do something else and then refer back to the record.
What I wanted to do is store a simple name for a more complex string, and then later pass the simple name to the record and have it return the longer, hard-to-remember string. But there was no way I could hard-code the property name without defeating the entire purpose of the script I was writing. I just wanted to pass a variable containing the simple name string.
But no. Not in AppleScript.
Well, not quite. The language does not support doing this, true. But the language does let you contain a script within a script — which allows us to get past the “no variables to records” rubbish.
Thanks go to the heroic jobu on the MacScripter forums, who posted this code in 2006. (Despite being so long ago, this technique doesn’t seem to have gotten much attention, as looking at many, many forum posts about this issue has shown.)
Let’s have a look:
set myRecords to {Abc:"1", Def:"2", Ghi:"3"}
set myVar to "Abc"
return (searchRecord(myVar, myRecords))
to searchRecord(theKey, theRecord)
run script "on run{theKey,theRecord}
return (" & theKey & " of theRecord )
end" with parameters {theKey, theRecord}
end searchRecord
The important thing to note is that when the variable (in this case, myVar) is passed to the run script code, the variable’s contents are passed. That’s what you’d expect it to do, but what that means is that the variable is essentially hard-coded into this new script — you’re not recreating myVar, you’re just passing along myVar’s contents.
Boom. A regular “get value of property x of the record.” And that data is then returned from the internal script to the parent, containing script. You can then call this as you would a subroutine handler, whenever you need to get a value for an unknown-at-compile-time property.
Essentially, the shopkeeper won’t sell to you in person, but if you step outside and ring him then you’re set.
Yeah. It’s a hack. Thankfully a short, understandable one, but a hack nonetheless. It’s crazy and this should be built into the language. Here’s JavaScript’s way again, for reference:
objectName[myVariable];
Why is this missing? God knows.
I’m pretty sympathetic towards AppleScript. It’s the first language I’ve ever done any kind of programming in, and it’s been — and continues to be — useful at home and essential at work. I do like it, and there’s things you can’t do without it — for better and for worse.
I plan to learn Python at some point so I may end up leaning towards “for worse” quite heavily in the future, but at the moment I’m happy using AppleScript to accomplish the (mostly work-related) things I need to do, even with all of its oddities.
(My “favourite” weird things are:
There’s a bunch more, like slash-separated paths being treated differently from colon-separated paths — often requiring a line of code to convert them, because in many cases you can only get one type. But whatever. I’m a little worried that “proper” programming languages won’t be masochistic enough.)

Learning AppleScript can really pay off.
It isn’t always the easiest language to work with, as anyone who’s ever used it will tell you. Commands that look like they should work sometimes don’t, you occasionally have to use bizarre methods to refer to that thing right there. It’s not a picnic.
But I’ve been using it for a little while and am pretty comfortable with it. I’ve ended up using it more and more for everyday tasks, or one-off situations that would usually require a lot of donkey work.
Let me share one that’s just happened.
I was browsing the New Yorker’s print shop and — I thought — was opening up the individual pages for covers I liked and wanted to go back to after I’d finished browsing.
It turns out that I was just opening up the preview images in tabs. Whoops. And their URLs don’t contain a unique code that’s shared with their purchase pages. Ah. And there are 10 of them. Erm.
The one similarity they do have is that the filename is kinda sorta repeated on the purchase page, but it’s hyphen-separated so (I thought, wrongly) you can’t just copy and paste it into a search field.
So I cooked up this little script in about a minute:
tell application "Safari"
set theURL to (get the URL of the front document)
end tell
set printsOffset to (get the offset of "/prints/" in theURL)
set jpgOffset to (get the offset of ".jpg" in theURL)
set hyphenString to characters (printsOffset + 8) ¬
through (jpgOffset - 1) of theURL as text
set AppleScript's text item delimiters to "-"
set theWords to (get the text items of hyphenString)
set AppleScript's text item delimiters to " "
set searchString to theWords as string
set AppleScript's text item delimiters to "" -- return to default
tell application "Safari"
tell the front document
search the web for searchString
end tell
end tell
Then I saved it, gave it a shortcut in FastScripts, opened up the first tab in Safari, hit the shortcut, tabbed to select the first URL in the search results, then hit enter to load it. Rinse, repeat.
As I was writing this I tried just pasting the filename into Google and — shocker — that works. Which makes me look a little dumb.
And the script isn’t even that sophisticated; I could have used a repeat command to loop through each tab, for example.
However my wider point about getting your teeth into automation still stands. I’ve written loads of little scripts like this over the past few months and, combined, they’ve saved me bags of time and plenty of frustration.
Hell, the InDesign script I wrote to set a text frame’s name (≥CS5) to its script label (≤CS4) alone saved me half an hour.
The problem of AppleScript being frustrating to learn — and continually frustrating with certain applications’ opaque AppleScript dictionaries and command parsing — does stand in the way of more people using it (which is why Automator exists, as limited as it is).
But if you’re tempted, even a little, give it a go. If you don’t have any programming experience I recommend AppleScript 1-2-3. (Don’t buy the Kindle edition. You want the paper copy.)
Also make sure to check out Script Debugger 5, which at $199 (about £170 including VAT) is a bit pricey if you’re just starting but makes things so much easier it’s a joke. It’s like switching from MSPaint to Photoshop. You’ll never go back to (Apple)Script Editor.
Speaking of AppleScript, this is what 450 lines of it look like.
(When you paste it into BBEdit, set the font size to 2pt and switch on syntax highlighting.)
UPDATE 06/10/2012: Please ignore this post and look at my most recent post about the script.
I came a across a more sophisticated method of getting your Bootcamp partition’s device ID for my restart in Windows AppleScript, so you may want to grab the new code (also below).
It no longer uses my hack to pull the device ID from a certain character position in the result of a shell command — which would break if you had more than 10 disks or partitions anyway — and instead just uses grep and awk to strip out the identifier. It should be pretty solid.
Click here to open the script in your script editor.
set deviceID to (do shell script "diskutil info [Your Bootcamp ¬
partition's name] | grep Identifier | awk '{print $3}'")
do shell script "bless -device /dev/" & deviceID & " -legacy -setBoot ¬
-nextonly" password "XXXXXXX" with administrator privileges
tell application "Finder" to restartUPDATE 06/10/2012: Please ignore this post and look at my most recent post about the script.
I’ve used a Mac — and Windows on a Mac — since 2007 but I’ve just, only just, figured out a way to quickly restart from OSX into Windows.
And it’s really easy to use it on your computer too, even if the words code or script make you freak out a bit. (If they don’t, skim the post for the meat but make sure to read the last few paragraphs.)
I use LaunchBar to run a script that mounts my Bootcamp partition, sets it as the startup disk for the next time only and then reboots into it. It means I don’t have hold down Option (⌥) while the computer boots up, which I’ve found very unreliable now that I use a bluetooth keyboard. (It might actually just be the SSD booting quicker than the keyboard can switch on. That’s a nice problem to have.)
As it’s just a bit of AppleScript you can also run it from FastScripts or the system-wide script menu.
Click here to open the script in your script editor.
set deviceID to (do shell script "diskutil info [Your Bootcamp ¬
partition's name] | grep Identifier | awk '{print $3}'")
do shell script "bless -device /dev/" & deviceID & " -legacy -setBoot ¬
-nextonly" password "XXXXXXX" with administrator privileges
tell application "Finder" to restart
Update 07/09/2012: I’ve changed the script to get the device ID in a more sophisticated way, so it’s far less likely to break even if you have more than 10 disks.
Update 21/07/2012: OSX doesn’t guarantee that your Windows partition will get the same device ID every time the computer boots, which means my previous method (which was dependent on the device ID not changing) can and will break if you have more than one HDD.
I’ve changed the script to use the partition’s name and then pull the correct device ID from the result of diskutil info [Partition Name]. If you have more than 10 disks you may run into problems.
First of all, open up AppleScript Editor (called Script Editor before Lion) from the Utilities subfolder of your Applications folder and copy the code above into a new window.
Then open Disk Utility from the Utilities folder, select your Bootcamp partition, click the Info button and change [Partition Name] in the script to its exact name. It should look something like this:
set terminalRAW to do shell script "diskutil info BOOTCAMP"
If the partition’s name is more than a single word, put it in quotes with backslashes in front, like this: \"Windows HDD\".
Now change myPassword to your user account’s password and save the script, making sure to check the box next to Run Only at the bottom of the save sheet.
(Saving a run-only script makes sure no-one will be able to open it and grab your password. If you’d rather not put it in there to begin with just delete password "myPassword" and the system will prompt you for it every time you run the script.)
Generally the best place to put your finished script is in ~/Library/Scripts. This means it’ll appear in the system-wide script menu, which you can enable from AppleScript Editor’s preferences, as well as FastScripts. (By default the user library is hidden in Lion so just copy that path, switch to the Finder, click Go in the menu bar and choose Go to Folder and paste it in).
To use it in LaunchBar you’ll want to go into its indexing preferences (⌘⌥I), select Actions, then Options, and check the box next to ~/Library/Scripts. I use “Restart in Windows” to keep things simple.
I tried this and it didn’t work out well. Even though it should quit immediately after the final command (restart) is passed, Lion’s resume-after-restart feature (where it reopens running applications) can put the computer into a loop where booting back into OSX from Windows causes the computer to boot into Windows.
(If you accidentally get into this position perform a safe boot by holding shift from the Mac chime until you see the Apple logo. Then log in, delete the application and empty the trash.)
Thankfully the only advantage to having it as an application, that I can see, is that you can put it in the dock. (And you don’t want to be one of those people.)