new-blogentry -topic "Powershell and More"

My observations about Powershell, Windows, System Center and life.

Recent comments

Tags

Don't show

    Disclaimer

    Any opinions expressed herein are completely accidental. But if one happens to slip in, it represents my own personal opinion and NO one elses. I'm also not concerned with changing anyone elses opinion, so any rants about anything presented on this site are likely to be 100% ignored.

    © Copyright 2010

    Managing Podcasts with Powershell (Part 2)

    In my last part of this topic, I touched on using IE7's built in RSS Platform to setup a few podcasts to be automatically downloaded.

    I wanted to use Windows Media Player to sync the Podcasts with my MP3 player. My particular player (Sansa Fuze 8gb) requires the Genre tag to be set to 'Podcast' in order to show up in the approrpriate place in the UI.

    To start with, I create a NTFS symbolic link for each podcasts folder. Explaining Vista's implementation of symbolic links is beyond the scope of this article. See http://en.wikipedia.org/wiki/NTFS_symbolic_link if you want to begin a research project on them.

    All you really need to know is that by using symbolic links, I can access a folder using

    c:\users\gaurhoth\podcasts\{feed name}
    instead of
    C:\Users\gaurhoth\AppData\Local\Microsoft\Windows\Temporary Internet Files\Enclosure\{E4E0D525-2BAC-4618-BA87-3A6310945820}

    This does require Vista. Since we are using a LINK to the original folder that the RSS Platform manages, we can let the RSS Platform handle removing old enclosures instead of having to write extra code.

    The next big task that I let powershell handle for me is removing the Read Only attribute so that I can remove any Alternate Data Streams (another topic covered in many articles on the internet - search for 'Alternate Data Streams in NTFS'). This is equivalent to clicking 'UNBLOCK' in the Properties of certain files downloaded using IE.

    I also update the MP3 Genre Tag to say 'Podcast' using taglib-sharp which you can find at http://www.taglib-sharp.com/Download/.

    Setting up Windows Media Player is pretty straight-forward. Create an 'Auto-Playlist' to sync with your device like this: wmppod1

    Next, setup your library to pick up audio files from your podcasts folder (the symbolic link created using Powershell): wmplib1

     

    You can download the script here: podcastsync.ps1 and it's pasted below:

    # Require taglib-sharp. See http://www.taglib-sharp.com/Download/.
    # You'll find the compiled .NET 2.0 DLLs in taglib-sharp-x.x.x.x-windows.zip
    # Change path appropriately
    [void][Reflection.Assembly]::LoadFile("c:\Users\gaurhoth\ps\poshpodsync\taglib-sharp.dll")

    # Root of folder to store the symbolic links
    $podcasthome = "$home\podcasts"

    # Root of the Feed Folder where you are storing podcasts feeds
    $feedhome = 'Podcasts'

    if (-not [system.IO.Directory]::Exists("$podcasthome")) {
        Throw "$podcasthome does not exists."
    }

    # enumerate the feeds under under your $feedhome
    $feeds = (New-Object -ComObject Microsoft.FeedsManager).RootFolder.getsubfolder($feedhome)
    foreach ($feed in $feeds.feeds) {
        if (-not (Test-Path "$podcasthome\$($feed.Name)")) {
            #create NTFS Symbolic Links to path were IE7 stores the enclosures for each feed
            cmd /c "mklink /J `"$podcasthome\$($feed.name)`" `"$($feed.localenclosurepath)`""
        }

        get-childitem "$podcasthome\$($feed.name)" -Recurse -Include *.mp3,*.wma | % {
            Write-Host "$_"
            # Test for ReadOnly flag and remove if present
            if ($_.attributes -band [system.IO.FileAttributes]::ReadOnly) {
                $_.attributes = $_.attributes -bxor [system.IO.FileAttributes]::ReadOnly
            }

            # Simulates clicking 'UNBLOCK' on properties of a file downloaded
            # using Internet Explorer. Look up Alternate Data Streams in NTFS if your
            # curious.
            cmd /c "echo on > `"$($_):Zone.Identifier`""

            # Using taglib-sharp to make sure each podcast is tagged as a podcast.
            # My mp3 player uses the tag to create a separate list of files separate
            # from my music list.
            $media = [TagLib.File]::Create($_.fullname)
            $dirty = $FALSE
            if (-not $media.Tag.Artists) {
                $media.Tag.Artists = $feed.Name
                $dirty = $TRUE
            }
            if (-not $media.Tag.Album) {
                $media.Tag.Artists = $feed.name
                $dirty = $TRUE
            }
            if ($media.Tag.Genres -notmatch "Podcast") {
                $media.Tag.Genres = "Podcast"
                $dirty = $TRUE
            }
            if ($dirty) { $media.Save() }

            #replace Read-Only or IE RSS Platform doesn't clean up old enclosures.
            if (-not ($_.attributes -band [system.IO.FileAttributes]::ReadOnly)) {
                $_.attributes = $_.attributes -bxor [system.IO.FileAttributes]::ReadOnly
            }
        }
    }

     

    That's all for now.

    Gaurhoth


    Posted by gaurhoth on Sunday, April 13, 2008 11:25 AM
    E-mail | Permalink | Comments (124) | Post RSSRSS comment feed

    Managing Podcasts with Powershell (Part 1)

    I've never before embraced the idea of listening to podcasts on a regular basis. With the recent purchase of an MP3 Player, it's garnered more of my interest. Unfortunately, I haven't stumbled on an automated approach to manage getting the downloaded podcasts synced to my player. I'm a creature of great laziness and would quickly lose interest in podcasts unless I find a way dump new episodes to my player with as little effort as possible.

    I could probably find a client somewhere (iTunes? WinAmp?)... but what fun would that be?

    I decided to play with the built in RSS Platform that's included as a part of Internet Explorer 7 (as such, IE 7 must be installed on your system). The RSS Platform includes a COM object which we can utilize from Powershell with ease. You could also use the FEED provider from PSCX if you chose.

    Once you subscribe to the feed using IE7, view the Feed Properties and make sure you have the 'Automatically download attached files' option checked and set a reasonable limit for 'Keep the most recent items only'. I set my limit at 3 items. Keep in mind that if you totally automate this as I have, every podcast will be synchronized to your MP3 device which may have limited space.

    feed01

    Give the system some time to download your enclosures in the background.

    Now, we run into the downside of using IE7's RSS Platform. It stores the enclosures in an obscure folder under the Temporary Internet Files. Let's take a peek at the object that will let us dive into the RSS Platform and find these mysterious enclosure folders.

    $feeds = (New-Object -ComObject Microsoft.FeedsManager).RootFolder
    $feedpodcast = $feeds.GetSubfolder('Podcasts')

    I store all of my Podcasts in a folder off the root of the FEED listing called 'Podcasts'. The second line is getting the object that represents that level of feed listings.

    We can get a list of all feeds in this folder using this:

    66> $feedpodcast.feeds
    Type     Name                                             ItemCount UnreadItemCount
    ----     ----                                             --------- ---------------
    feed     Adventures of Superman Podcast                          47               0
    feed     Batman Adventures                                       25               0
    feed     British Science Fiction Podcast                          3               0
    feed     Hanselminutes                                            3               0
    feed     Mind Of Root                                             3               0
    feed     PowerScripting Podcast                                   3               0
    feed     PowerShell Basics                                        3               0
    feed     Science Fiction Theater Podcast                         58               0
    feed     Scifi Friday                                             3               0
    feed     X Minus One Podcast                                     46               0
    feed     .NET Rocks!                                              3               0
    67> 

    Now, let's find the enclosure path:

    84> $($feedpodcast.feeds)[5]  | fl Name,Url,LocalEnclosurePath,DownloadEnclosuresAut
    omatically
    
    
    Name                            : PowerScripting Podcast
    Url                             : http://feeds.feedburner.com/Powerscripting
    LocalEnclosurePath              : C:\Users\gaurhoth\AppData\Local\Microsoft\Window
                                      s\Temporary Internet Files\Enclosure\{1BA818DF-D3
                                      C1-447D-A57F-8097CD250521}
    DownloadEnclosuresAutomatically : True
    
    
    
    85> 

    Now we know where to find the downloaded podcast files. Whew. Armed with this, we'll be able to write a script that will tie in all of these Enclosure Paths into a single parent folder so that Windows Media Player can monitor and sync to my player. I'll save that for the next part.

    Gaurhoth


    Posted by gaurhoth on Saturday, March 29, 2008 7:47 PM
    E-mail | Permalink | Comments (20) | Post RSSRSS comment feed