Just as last year, I wrote a PowerShell script using which you can download the PowerPoint decks, and, videos from Microsoft Build’s conference, instead of streaming it (or manually download it one by one). You can choose if you want the decks, or the videos, or both. For the videos you can choose the desired resolution (Low, Medium, High) – of course the higher the resolution, the more space is needed. The script also downloads the description and if there is a session image (if there is one).
A few points to note:
- The slides only once downloaded is ~10GB and with videos (high-resolution), the size goes up to 90.5 GB. So make sure you have enough space.
- By default the download location is “C:\build-2018\”; you can change this to whatever you want, but make sure there is a trailing backslash. Think of this as the ‘base’ folder.
- For each session a sub-folder with the session name will be created in the ‘base’ folder setup in the previous step.
- If a file already exists, it will be skipped.
- As each file is downloaded, it save it in the root folder and once the download is complete, only then moves it in the relevant subfolder.
- If a download fails for some reason to retry it, delete the ‘left over’ file(s) in the base folder and then run the script again. The script itself will ‘eat’ the exception and move on to the next file.
- The video quality parameter is 1 for Low, 2 for Medium, and 3 for High (default).
And if you read through, the script is quite self-explanatory.
# Comments that you should read, before you kick this off. Yes, seriously. :)
# 1. Setup the folder where to download using the parameters outlined below
# 2. Loop through and get the slides first
# 3. Finally, loop through and get the videos last
param (
[string]$path = "C:\build-2018\",
[switch]$sessionvideo = $true,
[int][ValidateRange(1,3)]$videoquality = 3,
[switch]$sessiondeck = $true
)
[Environment]::CurrentDirectory=(Get-Location -PSProvider FileSystem).ProviderPath
$rss = (new-object net.webclient)
#Filenames might get long, so keep this short!
#$downloadlocation = "D:\build-2018"
if (-not (Test-Path $path)) {
Write-Host "Folder $fpath dosen't exist. Creating it..."
New-Item $path -type directory
}
set-location $path
if($sessiondeck) {
# Grab the Slides RSS feed - Build 2018
$slides = ($rss.downloadstring("http://s.ch9.ms/events/build/2018/rss/slides"))
# ********** download the decks **********
try {
foreach($item in $slides.rss.channel.item) {
$code = $item.comments.split("/") | select -last 1
# Get the url for the pptx file
$urlpptx = New-Object System.Uri($item.enclosure.url)
# make the filename readable
$filepptx = $code + " - " + $item.title.Replace(":", "-").Replace("?", "").Replace("/", "-").Replace("<", "").Replace("|", "").Replace('"',"").Replace("*","").Replace("’","'").Replace("â€","").Replace("'NEW SESSION'","").Replace("™","").Replace("œ","")
$filepptx = $filepptx.substring(0, [System.Math]::Min(120, $filepptx.Length))
$filepptx = $filepptx.trim()
$filejpg = $filepptx
$filepptx = $filepptx + ".pptx"
$filejpg = $filejpg + "_960.png"
$folder = $item.title.Replace(":", "-").Replace("?", "").Replace("/", "-").Replace("<", "").Replace("|", "").Replace('"',"").Replace("*","").Replace("’","'").Replace("â€","").Replace("'NEW SESSION'","").Replace("™","").Replace("œ","")
$folder = $folder.substring(0, [System.Math]::Min(100, $folder.Length))
$folder = $folder.trim()
if (-not (Test-Path $folder)) {
Write-Host "Folder $folder doesnt exist. Creating it..."
New-Item $folder -type directory
}
# Make sure the PowerPoint file doesn't already exist
if (!(test-path "$path\$folder\$filepptx")) {
# Echo out the file that's being downloaded
$filepptx
$wc = (New-Object System.Net.WebClient)
# Download the pptx file
Invoke-WebRequest $urlpptx -OutFile $path\$filepptx
# download the jpg but don't want to break if this doesn't exist; hence the nested try blocks
try {
if($item.thumbnail -ne $null) {
$urljpg = New-Object System.Uri($item.thumbnail.url)
if (!(test-path "$path\$filejpg")) {
$wc.DownloadFile($urljpg, "$path\$folder\$filejpg")
}
}
}
catch {
Write-Host "Image (jpeg) $filejpg doesn't exist ... eating the exception and moving on ..."
}
mv $filepptx $folder
#mv $filejpg $folder
} #endif
else {
Write-Host "PPTX: $filepptx exist; skipping download."
}
#try and get the sessions details
try {
$descriptionFileName = "$($path)\$($folder)\$($Code.trim()).txt"
if (!(test-path "$descriptionFileName")) {
$OutFile = New-Item -type file $descriptionFileName -Force
$Content = "Title: " + $item.title.ToString().trim() + "`r`n" + "`r`n" + "Presenter: " + $item.creator + "`r`n" + "`r`n" + "Summary: " + $item.summary.ToString().trim() + "`r`n" + "`r`n" + "Link: " + $item.comments.ToString().trim()
#some categories are missing; so need to eat the exception
#this is a hack and not very elegant
try {
if($item.category -ne $null) {
$Content = $Content + "`r`n" + "`r`n" + "Category: " + $item.category.ToString().trim().Replace("+"," ")
}
}
catch {
#do nothing; eat the exception
}
add-content $OutFile $Content
}
}
catch {
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
Write-host "\t" $ErrorMessage + "\n" + $FailedItem
}
} #end-loop foreach
Write-host "*************** Downloading all the decks complete ***************"
}
catch
{
Write-host "Oops, could not find any slides."
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
Write-host "\t" $ErrorMessage + "\n" + $FailedItem
}
} #download session-deck
# ********** download the videos **********
# if you don't want the video but only the slides just comment all the code below in the foreach loop
try {
# check for video download
if($sessionvideo) {
switch ($videoquality) {
1 {$video = ($rss.downloadstring("http://s.ch9.ms/events/build/2018/rss/mp3")); break}
2 {$video = ($rss.downloadstring("http://s.ch9.ms/events/build/2018/rss/mp4")); break}
default {$video = ($rss.downloadstring("http://s.ch9.ms/events/build/2018/rss/mp4high")); break}
}
foreach($item in $video.rss.channel.item) {
# Grab the URL for the MP4 file
$url = New-Object System.Uri($item.enclosure.url)
# Create the local file name for the video download
$file = $item.title.Replace(":", "-").Replace("?", "").Replace("/", "-").Replace("<", "").Replace("|", "").Replace('"',"").Replace("*","").Replace("’","'").Replace("â€","").Replace("'NEW SESSION'","").Replace("™","").Replace("œ","")
$file = $file.substring(0, [System.Math]::Min(120, $file.Length))
$file = $file.trim()
$file = $file + ".mp4"
$folder = $item.title.Replace(":", "-").Replace("?", "").Replace("/", "-").Replace("<", "").Replace("|", "").Replace('"',"").Replace("*","").Replace("’","'").Replace("â€","").Replace("'NEW SESSION'","").Replace("™","").Replace("œ","")
$folder = $folder.substring(0, [System.Math]::Min(100, $folder.Length))
$folder = $folder.trim()
if (-not (Test-Path $folder)) {
Write-Host "Folder $folder doesn't exist. Creating it..."
New-Item $folder -type directory
}
# Make sure the video file doesn't already exist
if (!(test-path "$folder\$file"))
{
# Echo out the file that's being downloaded
$file
# Download the video file
try{
if (!(test-path "$path\$file"))
{
Invoke-WebRequest $url -OutFile $path\$file
#move it from the current working folder to the target
mv $file $folder
}
else {
Write-Host "Video: $file - anoter process possibly working on this; skipping download."
}
}
catch {
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
Write-host "\t" $ErrorMessage + "\n" + $FailedItem
}
}
else {
Write-Host "Video: $file exist; skipping download."
}
} #end-loop foreach
} #end - video check
}
catch
{
Write-host "Oops, could not find any videos or some other error happened."
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
Write-host "\t" $ErrorMessage + "\n" + $FailedItem
} # ********** End - download the videos section **********
Write-host "*************** All Done! Woot! ***************"
Like this:
Like Loading...