Get Early Voting Locations, Drop Off Ballot Sites, and Election Polling Places with PowerShell

Get Early Voting Locations, Drop Off Ballot Sites, and Election Polling Places with PowerShell

The 2020 Election is happening on November 3rd, and many people have been lining up to vote early due to COVID-19. Now using PowerShell, you can get your registered polling places based on your address, all early voting locations around you, and drop off ballot locations. All of the information is retrieved using Google’s Civic Information API.


Early Voting Locations

To get early voting locations you can use Get-EarlyVotingPlaces or Get-EarlyPollingPlaces. It will return as many results as the API gets and show you the starting date of the location, Name, Polling hours for each day, address, city, state, and zip code.

Ballot Drop Off Locations

If you got a Mail-in ballot, you can look up drop off locations by using, Get-BallotDropOffLocations or Get-DropOffBallotLocations. Note: Not all states publish this data. You will get a max of 10 results back and it will show you the start and end dates you could drop off your ballot, name of the location, hours, and full address.

Election Day Polling Places

If you plan on voting on election day, you can view locations where the voter is eligible to vote on election day (based on the provided address) by using Get-PollingPlaces or Get-VotingLocations. If your state allows you to be eligible in more than one location, it will return a max of 10 results.

Install the Module

The module is published on the PowerShell Gallery and can be installed by running Install-Module -Name PSElection

All of the files are also publicly available on GitHub.

Hows it Work

Google’s Civic Information API requires an API key to access it. In order to not publicize the key, the PowerShell functions call an Azure Function that interfaces with the API and returns the response back. The Azure Function keeps the API Access Key as an Application setting which allows it to be encrypted at rest and transmitted over an encrypted channel. This also allows it to become an environment variable. The PowerShell function passes the parameter values in the Uniform Resource Identifier (URI) of the internet resource to which the web request is sent.

$Data = Invoke-RestMethod -uri "$($State)&HouseNumber=$($HouseNumber)&Street=$($Street)&City=$($City)"

The returned data is then parsed and ‘cleaned’ within the local PowerShell function

$Data.pollingLocations | Select-Object -First 10 | ForEach-Object {
    $_ | Select-Object @{ Name = 'Name'; Expression = { ($_ | Select-Object -ExpandProperty address).locationname } }, @{ Name = 'Address'; Expression = { ($_ | Select-Object -ExpandProperty address).line1 } }, @{ Name = 'City'; Expression = { ($_ | Select-Object -ExpandProperty address).city } }, @{ Name = 'State'; Expression = { ($_ | Select-Object -ExpandProperty address).state } }, @{ Name = 'Zip'; Expression = { ($_ | Select-Object -ExpandProperty address).zip } }

The Azure Function code is hosted on the same GitHub project and the code can be seen below. It takes the incoming request values for our Parameters and sends them to the Google Civic Information API and then sends the response back using Push-OutBinding

using namespace System.Net

# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)

$HouseNumber = $Request.Query.HouseNumber
$Street = $Request.Query.Street
$City= $Request.Query.City
$State = $Request.Query.State

$Address = "$HouseNumber $Street $City $State"
$AddressFormat = $Address.Replace(" ","%20")
$APIKey = $ENV:apikey
$resource = "$APIKey&address=$AddressFormat"

$body = Invoke-RestMethod -Method Get -Uri $resource 

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = [HttpStatusCode]::OK
    Body = $body




No matter who you are voting for, it is incredibly important for you to get out there and vote. I hope this PowerShell module makes that easier for you and others.


Leave a Reply

Your email address will not be published. Required fields are marked *