Use PowerShell to Check In for Flight


Summary: Guest blogger, Microsoft PFE, Bill Grauer, talks about using Windows PowerShell to check in for a flight.

Microsoft Scripting Guy, Ed Wilson, is here. Today we have a new guest blogger—Bill Grauer, a Microsoft PFE...

As a Windows PowerShell instructor, I try to drive home a simple point to my students, whether they are absolute beginners or more seasoned scripters. Becoming proficient in a language, whether it be Spanish or Windows PowerShell, requires practice. This means finding every opportunity you can to accomplish some task you're currently doing manually, and automating it.  These opportunities don't all have to be work related.

Every year my family takes a trip north to visit the grandparents and cousins. On our last trip, we ended up taking a Southwest flight that departed at 6:35 AM. For those who've never flown Southwest, you don't get a seat assigned when you book your ticket. Instead, Southwest allows you to board the aircraft in the order in which you checked in for the flight.

Check-in can be done online, and it opens 24 hours prior to your scheduled departure time. Generally, if you don’t check in shortly after it opens, you will end up sitting in a middle seat in the back of the plane. I don't want to be up that early for my flight and I definitely don't want to be up that early to check in. So, when you don't want to do something manually, you automate.

It turns out that using Windows PowerShell to check in for my Southwest flight was pretty straight-forward. The process involves navigating to the correct URL in Internet Explorer and populating some form fields. After the fields are populated, I needed to click the Check In button.

All the Microsoft Office products are scriptable via Windows PowerShell by leveraging the application's COM interface.  To instantiate an Internet Explorer object in Windows PowerShell, I will use the New-Object cmdlet with the -ComObject parameter. The name of the object I instantiate is InternetExplorer.Application, and I will save it in the $IE variable:

$IE = New-Object -ComObject InternetExplorer.Application

Note: All Office products follow the same COM naming convention of product.application.

$word = New-Object -ComObject Word.Application

$excel = New-Object -ComObject Excel.Application

$Outlk = New-Object -ComObject Outlook.Application 

I can interrogate this object and look at its type, along with its members, by using the Get-Member cmdlet:

Get-Member -InputObject $IE

In the output, you can see a Navigate method. Unfortunately, there is only partial information here as it relates to the variable this method takes. It can take up to five parameters, a string, and four variants. But what do these represent?

Image of command output

For more information, see the following MSDN article: InternetExplorer object.

From this article, I learn that the first parameter is the URL I want to navigate to, and it is the only one required.

$Url = http://www.southwest.com/flight/retrieveCheckinDoc.html?int=HOME-BOOKING-WIDGET-AIR-CHECKIN

$iE.Navigate($Url)

If you ran the current three lines of code, they should have executed successfully, but you probably don’t see anything yet. The $IE object has a property named Visible that is set to False by default. This is intentional on all the Office COM objects. The idea is that if you are automating, you may not want or need to see what’s happening.

Let’s set the Visible property to True to see our progress.

   Note  It is not required that the page be visible to check in. This will be important later when I discuss running the
   Windows Powershell script as a scheduled task.

$IE.Visible = $true

Now that I’ve successfully navigated to the check-in page, I need to populate the Confirmation Number, First Name, and Last Name form fields on the page.

These fields are simple HTML input elements of the web page being rendered for us. If you knew the element's name or ID, you could set their values to whatever you wanted.

Getting the input element name can appear tedious at first glance. I could right-click the page in Internet Explorer and choose View Source to see all the markup. I would then have to search though this markup for the input element I suspect is correct, based on its name.

Luckily, Internet Explorer provides a much better way of finding this information. If I click the settings gear icon in the upper-right corner of the page and choose F12 Developer Tools (or simply press the F12 function key), the Internet Explorers Developer Tools suite is loaded at the bottom of the page. From here, I can choose the Select Element tool (CTRL+B) and then hover my mouse over the element with the markup that I want to view. Notice how Internet Explorer puts boundary markers around the element, which makes it easy to see what I selected.

Image of form

Now that I can see the element name and ID (confirmationNumber), I can interact with these elements via Windows Powershell.

The markup is stored in a property named Document in the $IE object:

$Element = $IE.Document.getElementById("ConfirmationNumber")

This property has the GetElementByID or GetElementsByName methods that I can use (note that it's ElementS in the second method):

Image of command output

As you can see, GetElementByID returns an object, which I will save in $Element. This returned object has a Value property, which I set to the value I want reflected in the form field:

$Element.value = "123456"

Now all I need to do is repeat the previous steps, get the elementID for the First Name and Last Name fields, and set them:

$Element = $IE.Document.getElementById("firstName")

$Element.value = "Bill"

$Element = $IE.Document.getElementById("LastName")

$Element.value = "Grauer"

After these six lines of code run, my form looks like this:

Image of form

I still have to click the Check In button, which is just more of the same. I use the Select Element tool to hover over the button and get its ID.

When I have the return object back from GetElementByID, I use its Click() method to invoke it:

$Element = $IE.Document.getElementById("submitButton")

$Element.click()

If all works as planned, you should receive an error message on the Southwest page that indicates it was unable to retrieve the reservation. That’s probably OK—unless you put in a valid confirmation number.

Image of error message

That’s all there is to automating this process. The few lines of Windows PowerShell I shared here are not enough to accomplish a fully automated check-in. For that, I would have to embellish this a bit. I need to add some code to handle errors, validate that I'm on the page expected, and set up a way to have this code run at 6:35 AM while I snooze. For the full solution, see SouthWest Airlines Automated Check-In in the TechNet Gallery.

~Bill

Thanks, Bill, for sharing your time and knowledge.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy 

Comments (5)

  1. willigmsft says:

    @Luke – I see this from time to time and it usually ends up being a timing issue where the page is still loading but the script is ready to move on. Make sure you have the $IE.Visible property set to $false (setting it true slows stuff down). If it already
    is, you may have to put in a check to hold up the script until the element is found. While($element -eq $null){start-sleep -milliseconds 250} as an example.

    HTH
    ~Bill

  2. Guido Diepen says:

    Using this trick of automating IE a lot at the moment. However, recently ran into two major issues with it:
    1. Depending on some security / protection settings the COM object gets disconnected after the $IE.navigate call.
    2. Appears I cannot access the content of iframes via $IE.document

    For problem (1), I have found a workaround to use the Shell.Application COM object to find the IE window with the same URL. Not sure if there is a cleaner/better solution for this?

    For problem (2), I have not found any solution other than doing the automation by positioning the mouse at a given (X,Y) coordinate, sending click messages, and sending keys. Big disadvantage of this approach is that you cannot use your screen anymore, as it
    will mess up the positioning and it can send the keys to a different application 🙂
    Same question here, is there a smarter/cleaner/better solution for this?

    Guido

  3. Hello, I am experiencing a rather confusing error while attempting to script this task. When I run the commands one right after the other within Powershell everything works successfully. However, when I attempt to create a script with the commands I received
    the following error message: You cannot call a method on a null-valued expression (for the line $Element = $ie.Document.getElementById("confirmationNumber")). Does anyone know why I might be experiencing the problem with executing the commands in a script?
    Thanks!

  4. Eric Courville says:

    In all practicality we likely would not automate the IE browser in an active sessions. This functionality would be better handled with a tool like Selenium. I would personally use Invoke-WebRequest to automate the form submission and session handling and
    bypass the need for interacting with IE all together.

    Great post though this is certainly worth while to learn how to interact with teh COM objects in general.

  5. Guido Diepen says:

    @Luke: this might be the problem I encountered also with regards to my point 1. If the COM object is going to a page in another security zone, the underlying IE process is killed and restarted. This will invalidate your COM object. If you are starting
    with elevated rights, this problem does not occur (this might explain the situation that manually it works for you, but not when started from script).

    Still looking for a good solution (other than my look at all IE windows and check the location)

Skip to main content