Today my DotNet Pretty articles were featured on @coding4fun by Greg Duncan and one of the comments by Niner bc3tech (@bc3tech) requested that I share this solution on Chocolatey. I decided that this was a good idea and decided to share my experience Smile.

Creating a Chocolatey Account

Creating the Chocolatey account was as simple as filling a couple of common fields at https://chocolatey.org/account/Register.


In the registration mail you are given a link to Rules to be observed before publishing packages which mentions that you can host your packages with MyGet


Creating a MyGet Account

Heading over to MyGet I saw that they had a Free subscription


But they also have an offer for MVP's, ASPInsiders, Windows Azure Insiders and ALM Rangers Smile. Fitting into 2 of these categories now I decided to head over to https://www.myget.org/mvp and request a NFR license Open-mouthed smile. The extra features available on this subscription made it perfect for my community project (and ones to follow Smile). In no time I had my DotNet Pretty Package Feed up.

MyGet Build Services

The DotNet Pretty project is currently hosted out on GitHub and so I decided that I'll try out MyGet's build services which is now in preview. This was as simple as clicking on BUILD SERVICES from the menu and then on Add build sources and then from GitHub.


this poped open the Link build source dialog where I selected the DotNet Pretty project from the list and clicked Add.


From here I clicked Build and in no time the build completed


2014-10-27_18-54-50 and I had a package hosted in MyGet



Updating GitHub project to show MyGet build status

From the build services page I was able to click on copy markdown


which gave me the markdown that I could insert into the readme.md file which I did with my new favorite Markdown editor MarkdownPad 2


A quick commit added this status to the public project on GitHub


Pushing the packaged to Chocolatey

The next thing I needed to do was add a new package source to my MyGet package feed Chocolatey. I went over to the Package Sources menu and clicked on Add package source and the NuGet feed.


The next bit was very simple, I simple clicked on Presets and then Chocolatey


This then went ahead and filled in the Name and Source for me


All that was left to do was provide my Chocolatey which was my Username, Password and API Key. I also filled in some of the extra meta data for my source


Next I headed over to build services again and clicked on Push upstream


this presented a window like below


where I just clicked on Push


And received the message saying they on it Open-mouthed smile. Headed back over to Chocolatey and my package was in the list


Installing Chocolatey "Client"

On the machine I'm using I didn't have Chocolatey installed so opened up a PowerShell Command Window as Administrator (just for in case Smile) and ran the command

iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))

Installing my package

To test if my package was installer I ran the command below

choco install DotNetPretty -Pre 

which confirmed that my package now now been installed


At this point my Chocolatey package "installs" by dropping the package contents in the Chocolatey folder


In a later post I will share how to configure the installation logic for a Chocolatey script.

Update: The post can be found here (Configuring a Chocolatey Install).


I watch and download a lot of videos from Channel 9 and because I’m a developer and always looking for ways to speed up anything I do I searched for a PowerShell script. I eventually found one (can’t remember where) and immediately set it up to download This Week on Channel 9 and Ping Show. Over time I have added many other shows, events and series. The initial script I was found with some modifications was

$rss=invoke-webrequest -uri $url
$destination="Z:\Media\Videos\ch9\This Week on ch9\"
Checking $($_.url.split("/")[-1]), we will skip it if it already exists in $($destination)"
  if(!(test-path ($destination + $_.url.split("
Downloading: " + $_.url
    start-bitstransfer $_.url $destination

Because of the amount of shows growing that I was interested in I added another piece to this. On the root level of all my Channel 9 videos I added a PowerShell file that would run all the other PowerShell files that looked like

cd Z:\Media\Videos\ch9

$psScripts = Get-ChildItem -Recurse -Filter "*.ps1" | ForEach-Object -Process { if($_.Name -ne "Download All.ps1"){ Write-Text "$($_.Name)"; . $_.FullName; } }

Write-Output "Done"

This was working great as I wouldn’t need to go and run multiple files in order to update all my videos. Recently because of all the new stuff that was released because of the announcements  at #VS2013Launch I had to add about 5 new feeds to my collection. This took quite a while as I needed to create a new folder for the show, then get a copy of the first PowerShell script above and then alter the feed url and location to save the videos to. This lead to yet another script, the way I saw it I could either write a script that automates the create of the folder and script or I could do the longer but right thing and start “fresh”. The script I now run takes in an array of the url of the show, series, event or any other type of channel that has an RSS feed, basically everything after http://channel9.msdn.com/. The new and improved script looks like


Write-Output "Starting"

$feedTypeNameList = $("Events/Build/2014",
$baseSaveLocation = "N:\s\ch9`$"

$mediaFormat = "high"
$mediaType = "mp4"
$fileExtension = "mp4"

$pathToRemoveInvalidFileNameCharsScript = "$baseSaveLocation\Remove-InvalidFileNameChars.ps1"

#------------Don't edit below here----------------#

. "$pathToRemoveInvalidFileNameCharsScript"
foreach($feedTypeName in $feedTypeNameList)
$channelType = $feedTypeName.Split("/")[0]
$feedUrl="http://channel9.msdn.com/$($feedTypeName.Trim("/"))/RSS/$($mediaType + $mediaFormat)"
Write-Output @"

Downloading Feed: $feedUrl

$rss=invoke-webrequest -uri $feedUrl

if (!(Test-Path $destination)) {
New-Item -ItemType directory -Path $destination

$videos = @()
[Array]$array = @($_.SelectSingleNode("enclosure").url,$_.SelectSingleNode("title").InnerText)
$videos += , $array
foreach($video in $videos){
$url = $video[0]
$title = $video[1]
if (![string]::IsNullOrEmpty("$url"))
$fileName = $($url.split("/")[-1])
$mp4fileName = $($fileName.Replace("." + $fileExtension,"") + "-" + (Remove-InvalidFileNameChars $title.Replace(" ","-")) + ".$fileExtension")
if ($mp4fileName.Contains("_"))
$pptxFileName = $mp4fileName.Remove($mp4fileName.LastIndexOf("_")) + ".pptx"
$pptxFileNameSaveAs = $mp4fileName.Remove($mp4fileName.LastIndexOf("_")) + "-" + (Remove-InvalidFileNameChars $title.Replace(" ","-")) + ".pptx"
$pptxFileName = $mp4fileName.Remove($mp4fileName.LastIndexOf(".")) + ".pptx"
$pptxFileNameSaveAs = $mp4fileName.Remove($mp4fileName.LastIndexOf(".")) + "-" + (Remove-InvalidFileNameChars $title.Replace(" ","-")) + ".pptx"

if (![string]::IsNullOrEmpty("$mp4fileName"))
"Checking $mp4fileName, we will skip it if it already exists in $($destination)"
#if we have the file from the previous script rename it or delete it
if(Test-Path ($destination + $fileName))
if(!(Test-Path ($destination + $mp4fileName)))
"Renaming: " + $fileName
Rename-Item $($destination + $fileName) $($destination + $mp4fileName)
"Deleting: " + $fileName
Remove-Item $($destination + $fileName)
#download media if it doesn'
t exists
if(!(Test-Path ($destination + $mp4fileName)))
$dest = $($destination + $mp4fileName)
"Downloading: '$url' to '$dest'"
Start-BitsTransfer $url $dest
#download pptx if it doesn't exists
if ($channelType -eq "Events") #only attempt to get pptx file for events
if (![string]::IsNullOrEmpty("$pptxFileName"))
"Checking $pptxFileName, we will skip it if it already exists in $($destination)"
$dest = $($destination + $pptxFileNameSaveAs)
if(!(Test-Path ($dest)))
$urlToDownload = $url.Remove($url.LastIndexOf("/")) + "/" + $pptxFileName
"Downloading: '
$urlToDownload' to '$dest'"
Start-BitsTransfer $urlToDownload $dest -ErrorAction SilentlyContinue

Write-Output "

This script caters for renaming of media files from the old just file name format to including the title in the file name. In order to add this extra script that I used for trimming funny characters from the file names. 

#source - http://gallery.technet.microsoft.com/scriptcenter/Remove-Invalid-Characters-39fa17b1

Function Remove-InvalidFileNameChars {
    This is a PowerShell function to remove invalid characters from strings to be used as file names.

    The function takes a string parameter called Name and returns a string that has been stripped of invalid file name characters, i.e. *, :, \, /.  The Name parameter will also receive input from the pipeline.

    Specifies the file name to strip of invalid characters.

    Parameter Name accepts System.String objects from the pipeline.

    System.String.  Outpus a string object

    Remove-InvalidFileNameChars -Name "<This/name\is*an:illegal?filename>"
    PS C:\>Thisnameisanillegalfilename

    It would be easiest to copy the function from the script file and place it in your profile.  However, you may also dot-source the script to load the function into PowerShell:
    i.e. PS C:\>. .\Remove-InvalidFileNameChars.ps1



    return [RegEx]::Replace($Name, "[{0}]" -f ([RegEx]::Escape([String][System.IO.Path]::GetInvalidFileNameChars())), '')

Hope this helps others that download Channel 9 videos to watch offline as well Smile.