Click here to Skip to main content
12,406,971 members (64,375 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

3.3K views
3 bookmarked
Posted

Download #MVA Content with PowerShell

, 15 Apr 2014 CPOL
Rate this:
Please Sign up or sign in to vote.
So I'm starting to go through some of the content on Microsoft Virtual Academy but I don't have time to do this when I'm by a good internet connection and at the same time don't have time when by the good internet connection to run though all the content I need to download it to watch in my spa

image_thumb2So I'm starting to go through some of the content on Microsoft Virtual Academy but I don't have time to do this when I'm by a good internet connection and at the same time don't have time when by the good internet connection to run though all the content I need to download it to watch in my spare time.

Enter PowerShell Smile

As with any scenario like this you turn to code, I use to create all these types of functionality in C# apps but have recently decided that it's too easy in C# and wanted to learn PowerShell better so now these are all PowerShell scripts.

The Code

2 files

Remove-InvalidFileNameChars.ps1

#source - http://gallery.technet.microsoft.com/scriptcenter/Remove-Invalid-Characters-39fa17b1
#changed slightly <span style="color: #0000ff">for</span>

Download-Content.ps1

cls

Write-Output <span style="color: #006080">""</span>
Write-Output <span style="color: #006080">""</span>
Write-Output <span style="color: #006080">""</span>
Write-Output <span style="color: #006080">""</span>
Write-Output <span style="color: #006080">""</span>
Write-Output <span style="color: #006080">""</span>
Write-Output <span style="color: #006080">""</span>
Write-Output <span style="color: #006080">""</span>
Write-Output <span style="color: #006080">""</span>
Write-Output <span style="color: #006080">""</span>
Write-Output <span style="color: #006080">"Starting"</span>

$certPages = $(<span style="color: #006080">"mcsd-application-lifecycle-management"</span>,<span style="color: #006080">"mcsd-windows-store-apps-certification"</span>,<span style="color: #006080">"mcsd-web-apps-certification"</span>)
$baseSaveLocation = <span style="color: #006080">"Z:\Learning\Microsoft Virtual Academy"</span>

$pathToRemoveInvalidFileNameCharsScript = <span style="color: #006080">"$baseSaveLocation\Remove-InvalidFileNameChars.ps1"</span>

#------------Don<span style="color: #008000">'t edit below here----------------#</span>

. <span style="color: #006080">"$pathToRemoveInvalidFileNameCharsScript"</span>    
foreach($certPage <span style="color: #0000ff">in</span> $certPages)
{
    $certUrl=<span style="color: #006080">"http://www.microsoft.com/learning/en-us/$certPage.aspx"</span>
    Write-Output <span style="color: #006080">"Downloading Page: $certUrl"</span>
    $pageHtml=invoke-webrequest -uri $certUrl
    $destination=<span style="color: #006080">"$baseSaveLocation\$(Remove-InvalidFileNameChars $certPage.Replace("</span> <span style="color: #006080">","</span>-<span style="color: #006080">"))"</span>

    <span style="color: #0000ff">if</span> (!(Test-Path $destination)) {
        <span style="color: #0000ff">New</span>-Item -ItemType directory -Path $destination
    }
    
    $filteredLinks = $pageHtml.Links | Where-<span style="color: #0000ff">Object</span> { $_.href.ToLower().StartsWith(<span style="color: #006080">"http://www.microsoftvirtualacademy.com/training-courses/"</span>) } 

    foreach($link <span style="color: #0000ff">in</span> $filteredLinks)
    {        
        Write-Output <span style="color: #006080">"Downloading Page: $($link.href)"</span>
        $trainingPageHtml=invoke-webrequest -uri $link.href        
        [<span style="color: #0000ff">string</span>]$trainingTitle = $trainingPageHtml.AllElements | Where-<span style="color: #0000ff">Object</span> { $_.tagName.ToLower().StartsWith(<span style="color: #006080">"title"</span>) } | <span style="color: #0000ff">Select</span>-<span style="color: #0000ff">Object</span> -ExpandProperty innerText {$_}
        $trainingTitle = $trainingTitle.Trim()
        $trainingDestination=<span style="color: #006080">"$destination\$($link.innerText)-$(Remove-InvalidFileNameChars $trainingTitle.Replace("</span> <span style="color: #006080">","</span>-<span style="color: #006080">"))"</span>

        <span style="color: #0000ff">if</span> (!(Test-Path $trainingDestination)) {
            <span style="color: #0000ff">New</span>-Item -ItemType directory -Path $trainingDestination
        }

        $idEducationTypePattern = [regex]<span style="color: #006080">"parent='(?<idEducationType>[^']*)'"</span>
        [int]$idEducationType = $idEducationTypePattern.Match($trainingPageHtml.Content).Groups[<span style="color: #006080">"idEducationType"</span>].Value
        $jsonPostDataPattern = [regex]<span style="color: #008000">'showNextPanelEducationTypes((?<idEducationTypeSelected>[^"]*),(?<idEducationLevelSelected>[^"]*),(?<isApproved>[^"]*),(?<numControl>[^"]*),this)'</span>
        foreach($jsonPostData <span style="color: #0000ff">in</span> $jsonPostDataPattern.Matches($trainingPageHtml.Content))
        {

            [int]$idEducationTypeSelected = $jsonPostData.Groups[<span style="color: #006080">"idEducationTypeSelected"</span>].Value.TrimStart(<span style="color: #006080">"("</span>)
            [int]$idEducationLevelSelected = $jsonPostData.Groups[<span style="color: #006080">"idEducationLevelSelected"</span>].Value
            [int]$numControl = $jsonPostData.Groups[<span style="color: #006080">"numControl"</span>].Value
            $isApproved = $jsonPostData.Groups[<span style="color: #006080">"isApproved"</span>].Value
            $jsonPostUri = <span style="color: #006080">"http://www.microsoftvirtualacademy.com/Studies/EducationDetails.aspx/ShowNextPanelEducationTypes"</span>
            $jsonPostBody = @{
                    idEducationTypeSelected = <span style="color: #006080">"$idEducationTypeSelected"</span>;
                    idEducationLevelSelected = $idEducationLevelSelected;
                    isSubscribe = $<span style="color: #0000ff">true</span>;
                    selectedIsEnabled = <span style="color: #006080">"true"</span>;
                    numControl = $numControl;
                    idEducationType = <span style="color: #006080">"$idEducationType"</span>;
                    isApproved = <span style="color: #006080">"$isApproved"</span>;
                    culture=<span style="color: #006080">"en-US"</span>
                 }| ConvertTo-Json 

            $jsonInvokeResult = Invoke-RestMethod -Method Post -Uri $jsonPostUri -ContentType <span style="color: #006080">"application/json"</span> -Body $jsonPostBody 
        
            $ctIDPattern = [regex]<span style="color: #008000">'openEmbeddedVideo((?<Id>.+));'</span>
            foreach($ctID <span style="color: #0000ff">in</span> $ctIDPattern.Matches($jsonInvokeResult.d.HtmlResponseMaterials))
            {
                $Id = $ctID.Groups[<span style="color: #006080">"Id"</span>].Value.TrimStart(<span style="color: #006080">"("</span>).Split(<span style="color: #008000">',')[0]</span>
                $uriForTrainingVideo = <span style="color: #006080">"http://www.microsoftvirtualacademy.com/Content/ViewContent.aspx?et=$idEducationType&m=$idEducationTypeSelected&ct=$Id"</span>            
                Write-Output <span style="color: #006080">"Downloading Page: $uriForTrainingVideo"</span>

                $trainingVideoPageHtml=invoke-webrequest -uri $uriForTrainingVideo
        
                [<span style="color: #0000ff">string</span>]$trainingVideoTitle = $trainingVideoPageHtml.AllElements | Where-<span style="color: #0000ff">Object</span> { $_.tagName.ToLower().StartsWith(<span style="color: #006080">"title"</span>) } | <span style="color: #0000ff">Select</span>-<span style="color: #0000ff">Object</span> -ExpandProperty innerText {$_} 
                $trainingVideoTitle = $trainingVideoTitle.Trim()
                [<span style="color: #0000ff">string</span>]$videoMp4Link = $trainingVideoPageHtml.Links | Where-<span style="color: #0000ff">Object</span> {$_.href.EndsWith(<span style="color: #006080">".mp4"</span>) -<span style="color: #0000ff">and</span> $_.outerText -eq <span style="color: #006080">"MP4"</span>} | <span style="color: #0000ff">Select</span>-<span style="color: #0000ff">Object</span> -ExpandProperty href {$_} 
                $urlFileName = $($videoMp4Link.split(<span style="color: #006080">"/"</span>)[-1])
                $videoMp4LocalFullName = <span style="color: #006080">"$($trainingDestination +"</span>\<span style="color: #006080">" + $(Remove-InvalidFileNameChars $trainingVideoTitle.Replace("</span> <span style="color: #006080">","</span>-<span style="color: #006080">"))).mp4"</span>

                <span style="color: #0000ff">if</span>(!(Test-Path ($videoMp4LocalFullName))) 
                {
                    Write-Output <span style="color: #006080">"Downloading Video: $trainingVideoTitle to $videoMp4LocalFullName"</span>
                    Start-BitsTransfer <span style="color: #006080">"$videoMp4Link"</span> $videoMp4LocalFullName
                }
            }
        }
    }
}

Write-Output <span style="color: #006080">"Done"</span>

Configuration

$baseSaveLocation - Set this to the location you want to save the videos to

$certPages - This is an array of certification page names that you want to download content from, i.e.: for MCSD: Application Lifecycle Management which has a url http://www.microsoft.com/learning/en-us/mcsd-application-lifecycle-management.aspx, the page name would be mcsd-application-lifecycle-management. Note that you will exclude the extension.

$pathToRemoveInvalidFileNameCharsScript - This can stay the same unless you have placed the first script in a difference location to the base location.

Next Steps

The next steps for this script will be to try get it to download the PowerPoint slides for each video, currently you need to be logged in to download slides so this might not be ready for a while Smile

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Gordon W Beeming
Software Developer Derivco
South Africa South Africa
Gordon Beeming is a Software Developer at Derivco in the sunny city of Durban, South Africa. He spends most his time hacking away at the keyboard in Visual Studio or with his family relaxing. He is a Visual Studio ALM Rangers, Visual Studio ALM MVP and Friend of Red Gate. His blog is at 31og.com and you can follow him on Twitter at twitter.com/gordonbeeming

https://binary-stuff.com

You may also be interested in...

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160730.1 | Last Updated 16 Apr 2014
Article Copyright 2014 by Gordon W Beeming
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid