Tag Archives: Regular Expressions

Apartment Hunting with PowerShell

Note: Expect a part two on this post.

I know a guy, and that guy is looking for an apartment. It turns out that apartments are going really fast and inventory is low — maybe you knew this, but it was news to me. Just about as soon as they become available, they are gone. I suggested that I might be able to lend a hand… maybe, who knows. This is not because I know someone in apartments, but rather that if there is a way to use PowerShell here, then there is a good chance I can help. He got lucky and I learned something new.

I started by going to the apartment website where he was interested and found a page that listed each apartment model and whether or not they had any availability. It was a floor plan page. I was not expecting much honestly, but I used the built-in Web Developer Tools in my browser and viewed the page source, and found some exciting news (for me and PowerShell, at least). It was enough good news that I am able to write about this whole experience.

While empty here, this data structure caught my eye. The output I had hoped to gather, was in JSON format; that was huge! Best I can tell, it is generated by a JavaScript file, which then embeds the JSON in the HTML that makes up the webpage. That is not overly important, however, but look at this structure; it is magnificent.

floorplans: [
  {...
  },
  {...
  },
  {...
  },
  {...
  },
  {...
  },
  {...
  }
],
propertyID: 60484,

Inside the floor plans JSON array ([]) are six objects, each in their own set of curly braces. Inside each of those, was a plethora of information regarding each floor plan. These properties included things like Model, Sq.Ft., Beds, Baths, etc. Let’s start by taking a look at the Watch-Apartment PowerShell function I wrote. Just a note, but in order to make this work for yourself, you will need to edit the path in the $ContentPath variable.

function Watch-Apartment {
    $Uri = 'https://theplaceatcreekside.securecafe.com/onlineleasing/the-place-at-creekside/floorplans'
    $WebRequestContent = (Invoke-WebRequest -Uri $Uri).Content
    $ContentPath = 'C:\users\tommymaynard\Documents\tommymaynard.com\Apartment Hunting\WebpageContents.txt'
    Set-Content -Path $ContentPath -Value $WebRequestContent

    $File = Get-Content -Path $ContentPath
    $Pattern = "floorplans:(.*?)propertyID:"
    $ParsedPage = [regex]::Match($File,$Pattern).Groups[1].Value
    $ParsedPage = $ParsedPage.Trim(); $ParsedPage = $ParsedPage.TrimEnd(',')

    $JsonDocument = ConvertFrom-Json -InputObject $ParsedPage
    $JsonDocument |
        Select-Object -Property @{Name='Available';Expression={if ($_.isFullyOccupied -eq 0) {"Yes ($($_.availableCount))"} else {'No'}}},
        @{Name='Model';Expression={$_.name}},
        @{Name='Sq.Ft.';Expression={$_.sqft}},
        @{Name='Beds';Expression={$_.beds}},
        @{Name='Baths';Expression={$_.baths}} |
    Format-Table -AutoSize
}
Watch-Apartment

We will discuss the above function using its line numbers:

Line 1: Declares/creates the Watch-Apartment function.
Line 2: Stores the site’s URI inside the $Uri variable.
Line 3: Invokes an Invoke-WebRequest command using the URI and stores the Contents (as in the Contents property) inside the $WebRequestContent variable.
Line 4: Creates the ContentPath variable to hold a path to a text file that will be created in the next line/command.
Line 5: Takes the content from the webpage and writes it to a text file.

Writing to a file was not a requirement, however, it was my first choice for whatever reason and so I went with it, and then stayed with it.

Line 7: Read in the contents from the file and store them in the $File variable.
Line 8: Create a Regex pattern to allow us to collect all the content between the word “floorplans:” and “propertyID:”.
Line 9: Parse out the data we want and store it in the $ParsedPage variable.
Line 10: Trim off the white space from the beginning and end of the JSON string, and then trim off the trailing comma at the end of the JSON string.

Line 12: Assign the $JsonDocument variable the value assigned to the $ParsedPage variable after it has been converted from JSON by CovertFrom-Json.
Lines 13 – 19: Use Select-Object to select and modify our desired properties.

In the final command, we determine which floor plan is available, how many apartments there are, which model it is, how many square feet that model has, and how many bedrooms and bathrooms it has. Each line/property includes a calculated property and often, just to modify the case of the text.

I edited the friend’s PowerShell profile script and added this function. Not only is the function added to the PowerShell session by the profile script, but it also invokes the function, too. Open PowerShell, and just about instantly know whether anything is available or not.

These were the results the first time it ran back on my machine.

It was a good thing that the Available property included both the isFullyOccupied (“Yes” versus “No”) and the availableCount (# of apartments) information. Take a look at the next image to see why.

In the above image, it still says, “Yes,” but the count is zero. Apparently, my decision to include both values was the right choice, as this information is not all updated at the same time.

Later that same day, it cleared up.

Now, he waits, as my work is done.

Note: As stated at the top of this post, expect a part two. There is more than one apartment complex now.

A Quick, Learn Windows PowerShell in a Month of Lunches, Review

I’ve been using, and continuing to learn, Windows PowerShell for a while now. While I’ve used various resources to promote my learning and understanding, I had never sat down and actually read a PowerShell book, front to back. Well, now I have.

While I knew upwards of 95% of the content, I went ahead and read Learn Windows PowerShell in a Month of Lunches by Don Jones and Jeffery Hicks. I have followed both authors in the past and was certain this would be a good title to start with—it was. In fact, being familiar with these two authors was why I was able to recommend this title, even long before I read the book myself. A bit backwards perhaps, but undeniable true. It’s a wonderfully, comprehensive guide to getting started with Windows PowerShell. As stated by Bennett Scharf, on the back cover, this in fact will be an extremely useful reference. With a generous and complete index, I will be able to easily pull up the concepts I read about in this book, whenever necessary.

Besides being able to say I’ve read the title (and with a good conscience, get it signed by the authors at theĀ PowerShell Summit North America 2015 in April), I wanted to make sure that my method of learning PowerShell was in fact complete. I’ve learned PowerShell by reading help files, blogs, and articles posted to Twitter, as well as, trying things in the shell (this is key), and helping people on PowerShell forums. Even so, I wanted to be sure I hadn’t missed some of the fundamentals. I know many of the ‘hows,’ but was worried I may have missed a ‘why’ along the way. Like, why does it (PowerShell) do it this way?

My first, favorite part was the discussion on pipeline parameter binding. Parts of that topic never just came to me, and it is a concept that requires a complete understanding. The fantastic explanations in the book (chapter 9) have helped ensure I won’t have any questions about this concept again. After all my non-book learning, I never once read anywhere that you can only have one ByValue per cmdlet, even though it makes perfect sense as to why.

The second part that I greatly appreciated was the Regex (Regular Expressions) review. For whatever reason, I have the hardest time cementing these in my mind, and often find myself in need of a quick review. Knowing this book will spend all, or most, of it’s life after this weekend sitting with me at the office, will allow me to get a quick refresh when that’s required. It can be a scary concept for many, and this book laid it out in a quick and calm approach. I wish I read this the first time I was introduced to Regex. No kidding, but I folded down the top corner of this page—something I just don’t do to my books.

In the end, I will continue to recommend this book to people starting out with PowerShell. It explains PowerShell from the start, up to your first parameterized script. I had already purchased the toolmaking followup, Learn PowerShell Toolmaking in a Month of Lunches, even before I started this one, and plan to start reading it tomorrow. I left my copy in my office and so, sadly, I couldn’t start sooner.