Solving the Problem of Blocking Calendar Hours When Traveling
AI tools are supposed to improve our lives by reducing drudgery and enabling us to do things quickly that otherwise are boring or difficult. I decided to put that to the test by trying to solve a vexing problem.
I am U.S.-based and normally operate on Central Time. I often travel to Europe because that’s where my company headquarters and many of my customers are. The problem arises when I am in Europe, but my calendar still thinks I’m in the United States. The result is that my American co-workers, or customers, try to schedule meetings with me in the late evening or overnight in the European time zone where I currently am. Rather than continually declining meetings, I want to define a flexible set of working hours that follows my physical location. Unfortunately, Microsoft’s tools can’t do this yet. It is possible for me to change my working hours, but since those follow the local time zone, people can still book meetings outside of those hours, leaving me to clean up the mess.
To work around the problem, when I go out of town, I create a recurring meeting that covers the evening hours. That solves the problem, but it requires me to remember to book the event, and to consider my physical location and current time zone. The manual solution also doesn’t do anything to help my fellow American coworkers, who are often in the same situation. While flying back from a recent European business trip, I was both bored and online, which is always a dangerous combination. I decided to experiment with asking a large language model powered system to automate the process by writing a PowerShell script. After all, if AI coding tools are so great and if AI is supposed to solve useful problems, this is a terrific test case. Here’s what happened.
Attempt #1: Basic Prompting Goes Astray
My first attempt used the Claude AI tool from Anthropic. I like Claude because its reasoning strikes me as being better than Copilot or ChatGPT. I intentionally did not try using a tool integrated with Visual Studio Code, such as GitHub Copilot. I also intentionally did not sign into a Claude account because I wanted to simulate what would happen if a casual user with a good idea opened up an AI tool and just started prompting. My initial prompt specified the basics of what I wanted:
Write a PowerShell script that will create a series of recurring meetings on my calendar. The script should accept a start date, an end date, and the time zone for the meetings. The meetings should be created from 5:30pm local time until 11:59pm local time in the target time zone. They should be created only on weekdays.
In a few seconds, I had a script… but it used the Outlook application data object . This was an excellent reminder of two important facts. First, LLM-based tools produce output based on the input they’ve been trained on—in this case, decades of code using COM, Visual Basic, and so on. Second, and more importantly, you usually get exactly what you ask for. I didn’t think I needed to tell the LLM to use the Microsoft Graph, but obviously that was an oversight on my part. The generated code might have worked, but I couldn’t test it because I was on an airplane with my MacBook Pro, and that doesn’t support running any version of Outlook that has the Windows COM interface. On to the next attempt.
Attempt #2: Require the use of Microsoft Graph
This time, I added “using Microsoft Graph” to the first sentence of my prior prompt. This result was significantly better in a number of ways: it included code to connect and disconnect to Graph (using Connect-MgGraph), it included better code for figuring out what time zone I wanted, and it correctly used New-MgUserEvent to create the event. When I tried to run it, it prompted me for the start date, end date, time zone, and a meeting subject (which I hadn’t asked for), but it wasn’t obvious what time zone format to use. I guessed wrong, and the script failed (Figure 1).

Attempts #3, #4, and #5: Rapid Iteration and a Few Bugs
As a long-time amateur radio operator and private pilot, I am comfortable with the concept of time zones and the common abbreviations used for them. But it occurred to me that maybe some of my co-workers who might run this script were not necessarily time zone nerds. I decided to improve the prompt by giving the LLM some guidance on how it should handle time zones. The new prompt was a little more complicated; I’ve highlighted the changes:
Write a PowerShell script that will create a series of recurring meetings on my calendar using Microsoft Graph. The script should accept a start date, an end date, the time zone for the meetings, and a meeting title. The meeting title is optional. If it is not supplied, use “EuroBlock” as the meeting title. The script should recognize common abbreviations (such as BST, CEST, etc) for time zones in Europe. The meetings should be created from 5:30pm local time until 11:59pm local time in the target time zone. They should be created only on weekdays.
I ran the script and it… didn’t work. Each call to New-MgUserEvent produced an error (Figure 2):

Remember that the point of using AI is that it’s supposed to save time. Instead of trying to figure out the problem or how to fix it (although the error message makes obvious what the problem is), I told the AI to quit screwing around and write better code (Figure 3):

The revised code still uses Graph, but instead of calling New-MgUserEvent, it called Invoke-RestMethod to run a Graph request to the Events endpoint. That’s certainly an unusual approach. If a human showed me code like that, I’d probably just stare at them for a minute before asking them why they wrote it that way. I’d probably follow up by saying something like “instead of doing that, modify the script to use the user’s userPrincipalName retrieved from Get-MgUser, then pass it to New-MgUserEvent”… and that’s exactly the next instruction I gave to the LLM. I ran the revised script and it worked! The results were pretty much exactly what I had asked for (Figure 4):

The Outlook calendar time zone labels on the left of Figure 4 show that the meetings are created starting at 630pm Copenhagen time, which is 530pm GMT, and continuing until nearly midnight GMT. There’s no appointment on Saturday, since it’s not a weekday. This is pretty good considering that, up to this point, I’d only spent about 10 minutes telling Claude what to do.
Iteration #6: Fixing a Few Minor Details
The generated appointments were still not perfect. For one thing, the events generated Teams meetings, which didn’t make any sense. They also had an unnecessary calendar reminder set. Presumably, the generated code included those options because the training data ingested by the model included them too. After all, if you create calendar appointments for actual humans, as opposed to creating them as a defensive measure to avoid having meetings, you would probably want to set those options. I gave Claude one additional instruction: “Update the script so that the generated meetings do not include an online meeting and do not have a reminder set.” Claude updated the script in a few seconds and even helpfully produced a summary of the changes it made (Figure 5):

The final prompt ended up being much more comprehensive than the original:
Write a PowerShell script that will create a series of recurring meetings on my calendar using the New-MgUserEvent Microsoft Graph cmdlet. The script should accept a start date, an end date, the time zone for the meetings, and a meeting title. Use the user’s userPrincipalName retrieved from Get-MgUser, then pass it to New-MgUserEvent to create the events. The meeting title is optional. If it is not supplied, use “EuroBlock” as the meeting title. The script should recognize common abbreviations (such as BST, CEST, etc) for time zones in Europe. The meetings should be created from 5:30pm local time until 11:59pm local time in the target time zone. They should be created only on weekdays. The generated meetings should not include an online meeting and should not have a reminder set.
Of course, one key thing to remember when using generative AI systems is that the same prompt may produce different results when repeated! If you plug in the above prompt, your script may differ from the one I generated, even when using the same model. One thing I found is that it’s helpful to keep a log of the prompts you provide as you iterate; most systems can’t repeat the entire prompt back to you if you start with a complicated prompt and then give iterative instructions.
Problem Solved! Or… is There More?
The resulting script does exactly what I asked for: it creates weeknight appointments in the time zone I’m in so that people who bother to check free/busy status will see that I’m not available in the European nighttime. From that standpoint, this experiment is a huge success. (Of course, it doesn’t do any good with people who send meeting requests without checking availability. So it’s not perfect, but I don’t think there’s a useful technical solution for that.)
More importantly, the script still requires me to take manual action to run it. There are a lot of potential enhancements that I could apply. For one, it could be tied to an app so that my tenant admins can run the script to update my calendar using app-only mode. For another, I use a flight tracking tool called Flighty to automatically synchronize flights with my work calendar. Flighty uses the airplane emoji to mark flights; the script could find an arriving flight, figure out what city (and thus what time zone) I’m in, figure out when I’m leaving again, and then block evenings in between. These incremental improvements probably wouldn’t take more than another hour or so of playing with an AI assistant to get it done. But would that extra time spent now save me enough time later to be worthwhile?
There’s a famous cartoon that captures the dilemma: at what point would I be spending more time fooling with PowerShell to build a solution compared to the manual work required? Even though I travel a couple of times a month, the big jump in utility for me is getting the blocked appointments on the calendar at all. Adding more functionality would be fun, but ultimately probably wouldn’t make me any more productive. Of course, your own experience might vary.
With that said, this kind of incremental development can be a very powerful way to quickly converge on a good enough solution. The generated scripts have minimal error handling and no documentation, but for individual use, the final version was more than good enough to get the job done.