David Fowler tweeted the link for viewing NuGet download stats. You can use the URL in the browser and you’ll see the XML. This PowerShell code demonstrates a few cool reusable ideas. Working with XML downloaded from a URL OData feed all in PowerShell.
Leveraging PowerShell’s .NET Framework integration (Net.WebClient) you download the XML string from the OData endpoint, convert it an XML Document using the [xml] accelerator and iterate the collection extracting the Id, converting the download count to an int and finally selecting the top 15 ( pipes to PowerShell’s Select cmdlet using the –First parameter).
Get Top 15 NuGet Downloads
You can add the Get-NuGetStats function to your NuGet PM Console Profile (type $profile at the prompt) so it will be available the next time you load Visual Studio. For now, paste the code (see below) into the PM Console (or any other PowerShell Host) and run the function.
The Code
Function Get-NuGetStats { $url = 'http://packages.nuget.org/GalleryServer/FeedService.svc/Packages?$orderby=VersionDownloadCount desc&$select=Id,VersionDownloadCount' $wc = New-Object net.webclient $( ForEach($entry in ([xml] ($wc.DownloadString($url))).feed.entry ) { $entry.properties | Select Id, @{ Name="DownloadCount" Expression={[int]($_.VersionDownloadCount.'#text') } } } ) | Select -First 15 | Format-Table -AutoSize }
Paste the Code into the NuGet Package Manager Console
Works in any PowerShell Host, PowerShell Console, ISE (Integrated Scripting Environment) or NuGet PM Console.
Note, these steps can be used to pull and transform any OData feed. The differences being the OData endpoint and the field names being retrieved.
Check out the NuGet OData URL. It specifies both the $orderby and $select system query options. This makes the work of sorting the data the responsibility of the server as well as reduces the amount of data returned. $Select limits how many fields are sent back to the client.
Modifications
You can easily parameterize Get-NuGetStats so it defaults to returning the Top 15 or lets the user specify how many they would like.





{ 1 trackback }
{ 4 comments… read them below or add one }
Hi Doug,
What does ‘#text’ in the expression line do?
Expression={[int]($_.VersionDownloadCount.’#text’)
If removed – an empty string displays.
Thanks,
Steve
Thanks for the question Steve.
Here is what the NuGet XML looks like for VersionDownloadCount (without the xmlns).
Here is PowerShell code that reads that XML into an XMLDocument and prints it out. PowerShell transforms the node content and sets it to the property name #text.
prints out the 271.
Hope this helps.
Doug
Your code snippets cleared things up immediately.
When I removed the “type” attribute, ‘.text’ returned nothing and VersionDownloadCount returned 271 as expected.
My theory is that if no attributes are present, ps responds to the element name, otherwise #text must be specified to differentiate from the attributes.
Another thing I noticed is that you disregarded namespaces. I wish the .net Xlinq classes had the the ability to do the same.
Namespaces, yes the magic of PowerShell. Reduces the ceremony needed to get at what you want.