Transfer files from iCab Mobile to your PC with Powershell

I’m a big fan of iCab Mobile that I use everyday on my iPad as a Safari replacement. Among other awesome features, this browser has the best HTML5 video downloading I’ve seen.

Unfortunately, the device’s 16 GB fills up quickly and I have to transfer the files some place else quite often.

While I could use something like DownThemAll for Firefox to download the files to my PC, I’d much rather be able to automate the process with a script. This looked like a great opportunity to sharpen my Powershell skills.

Downloads all the files from a iCab Mobile server
Connects to a iDevice with iCab Mobile running a Import/Export server and downloads all the files to the specified destination
If the file already exists, it will be skipped.
Files are not deleted on the device once downloaded

.\Get-ICabMobileFiles.ps1 C:\Users\simon\Desktop\icab
The ip address and port of the iCab Mobile server. Default port is 8080
.PARAMETER destination
The local destination folder on your computer, without trailing slash. Will use current folder if none is specified

param (
[Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$true)]
[string] $url='',
[Parameter(Position=1, Mandatory=$false, ValueFromPipeline=$false)]
[string] $destination=(Get-Location -PSProvider FileSystem).ProviderPath

Import-Module BitsTransfer
$web = New-Object System.Net.WebClient
if (-not ($url -contains ':')) {
$url = '{0}:8080' -f $url
$html = $web.DownloadString('http://{0}/Download.html' -f $url)
$regex = [regex] '(?i)&lt;a href=''([^'']*)''&gt;([^&lt;]*)'
$matchdetails = $regex.Match($html)

while ($matchdetails.Success) {
$source = 'http://{0}/{1}' -f $url, $matchdetails.Groups[1].Value
$dest = '{0}\{1}' -f $destination, $matchdetails.Groups[2].Value
Write-Host ('Downloading {0}... ' -f $matchdetails.Groups[1].Value) -NoNewline
if (-not(Test-Path $dest)) {
Start-BitsTransfer -Source $source -Destination $dest -Prio Foreground
Write-Host 'Done'
} else {
Write-Host 'Already downloaded'
$matchdetails = $matchdetails.NextMatch()

I’m aware that this probably isn’t the best way to do it (I’m looking at you, regex!) but I’m fairly new to Powershell so if you have any comments, please share :-)