KiZAN has been using Windows 10 IoT Core running on a Raspberry Pi 2 for several months inside of a traveling IoT lab kit. With the kits we’re able to bring a unique hands-on development workshop direct to businesses. Right now, our lab contains 25 Raspberry Pi 2 units flashed with Windows 10 IoT Core. After flashing the units, we also spend time pre-configuring WiFi adapters, network settings, and pre-installing lab exercises. Setting up 25 units is time consuming: it can take an entire day for a single person to deploy all of the lab exercises through Visual Studio to all of the devices. After the second time doing this, we set out to find a better way. In this post, I’ll take you through our journey of learning how to deploy Windows 10 IoT Core UWP apps with PowerShell. A special thanks to David Buckingham and Mike Branstein for helping me put this together!
Deploying to Windows 10 IoT Core is a Manual Process
When you deploy Universal Windows Platform (UWP) apps to Windows 10 IoT Core devices, it is a rather manual process: compile your app in Visual Studio, locate your device in the “Remote Machine” drop down, then press the green run arrow:
Once you start this deployment process, sit back and wait. Then, wait some more. Each deploy can take up to 5 minutes. When you’re working with a single Pi, it’s not a big deal, but when you have a lab of 25 Pi’s, it becomes unmanageable rather quickly.
Our search started with a blog post by John Dandison. John discusses various approaches taken that wouldn’t work with automating deployment of UWP apps to Windows 10 IoT Core. Throughout our searches, I ended up attempting all of these eventually, to have the exact problems that John had.
Here are several ways you may be able to deploy UWP apps to Windows 10 IoT Core, John described in his blog:
- Web-Based Deployment: this seems very straightforward because you choose an app package file (.appx), choose a certificate, choose any dependencies you might have, and click Deploy. This process is not as easy as it sounds. I had issues with creating and finding the certificate file needed along with the AppX file. I eventually solved this problem by renewing the certificate on the .pfx file from the Visual Studio file and used the Developer Command Prompt for Visual Studio 2015. More on this later.
- WinAppDeployCmd: WinAppDeployCmd uses a PowerShell script to install UWP apps. An example of a script would be WinAppDeployCmd install -file “Documents\MyApp.appx” -ip 192.0.2.1 -pin ABC123. This approach works with windows phone applications, but not UWP apps deployed to Windows 10 IoT because it requires a pin number to make the connection between the two. This is not possible on the Raspberry Pi 2 device that we are using. More on WinAppDeployCmd can be found here.
- Custom PowerShell: John finally arrived at using a custom PowerShell script that interfaces with the Windows 10 IoT Core REST API to upload and deploy UWP apps.
Windows 10 IoT Core REST API
Although it may seem like you’re limited when accessing Windows 10 IoT Core, there is an extensive REST API that you can leverage to interface with pretty much every aspect of the OS. If you can configure something via the admin portal, you can configure it with the REST API. The greatest problem with the API is a lack of documentation. Well, let’s be clear: there is no documentation. Pick your favorite packet sniffer (mine is WireShark) and strap in – it’ll be a wild ride.
Problems with John’s PowerShell Script
John’s Multi-Deployment PowerShell script worked for him, but we did not see the same results. It took us a while to figure out why: John’s blog post was written in October of 2015, since then Microsoft has released two new versions of the Windows 10 IoT Core. The most recent stable release is from November of 2015, and we were running the Windows 10 IoT Core Insider Preview that was released in March of 2016.
Many things changed between John’s build (a.k.a. version 4), the November build (version 5), and our Insider’s build of Windows 10 IoT Core (version 15!). Among the changes were the routes used by the REST API and the REST Documentation.
Discovering the Windows 10 IoT Core REST API Documentation
Once we figured out that the versions have different REST API routes, I found a great blog by David Jones that shows tables of path changes from version 4 to version 5. David’s blog also talks about being able to view the REST Documentation with http://<ip-address>:8080/restdocumentation.htm. Whammy! David’s post should solve all of our problems. Not quite.
The admin portal of Windows 10 IoT Core is hosted form the Raspberry Pi, and we have access to the entire file system. This means the source files are there somewhere. We started our journey by using PowerShell to remotely access Windows 10 IoT Core to search for the admin portal source files. After a little hunting, we found C:/Windows/WebManagement/www/default. Jackpot! This is the directory containing RestDocumentation.htm. Unfortunately, by looking at the file, we confirmed it was actually blank, with very few HTML tags or script tags. Third strike and you’re out…
But, we started looking closer at the script tags and found the page wasn’t designed to have a lot of HTML – it was being dynamically generated, and it relied upon a file named RestDocumentation.json, located in the js directory of the web root. We finally got our break.
This file gave us all of the REST API Documentation needed to use the new paths for version 5 and 14.
We’re still working on our final PowerShell script to remotely deploy Universal Windows Platform (UWP) Apps to Windows 10 IoT Core, so stay tuned. In part 2 of this series, we’ll share the completed script.
Curious if you ever posted how to create an update routine for an appx package on Windows 10 IoT Core? Or maybe you have the script available?
Hi Ed. I do have a script for this. I haven’t been able to get it up on the site yet, but here’s a link to the Gist: https://gist.github.com/mikebranstein/578b60fb2f237804b68fae56512f6a45.
Uploading is a little tricky, and needs a whole post on the process. Essentially, you get the list of installed packages, uninstall the app if it already exists, install (via uploading) the appx dependencies (these need to be uploaded first), then install the appx package. The whole process feels fragile, because you can’t just upload the dependencies. You need to upload each dependency, then wait for the device to install the dependency before moving on.
The attached script should do all of this. Let me know if you run into issues.
inspired by your post, I wrote a C# wrapper for the REST API and embedded it into a small console application.
The mechanism works pritty similar to what Mike Branstein has written above.