{"id":2693,"date":"2013-10-21T00:01:00","date_gmt":"2013-10-21T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2013\/10\/21\/invokerestmethod-for-the-rest-of-us\/"},"modified":"2013-10-21T00:01:00","modified_gmt":"2013-10-21T00:01:00","slug":"invokerestmethod-for-the-rest-of-us","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/invokerestmethod-for-the-rest-of-us\/","title":{"rendered":"InvokeRestMethod for the Rest of Us"},"content":{"rendered":"<p><strong>Summary<\/strong>:&nbsp;Learn how to use Windows PowerShell to search web pages.\nScripting Guy, Ed Wilson here. Today&rsquo;s post is written by Doug Finke, a Windows PowerShell MVP, and June Blender, senior programming writer on the Windows Azure Active Directory team.\nTake it away, June&hellip;\nI was bending my brain around the cool new <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/hh974478.aspx\" target=\"_blank\">Windows Azure Graph REST APIs<\/a> &nbsp;and <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windowsazure\/dd179355.aspx\" target=\"_blank\">Windows Azure Storage Services REST APIs<\/a>, when I noticed that Doug Finke, author of <a href=\"http:\/\/shop.oreilly.com\/product\/0636920024491.do\" target=\"_blank\">Windows PowerShell for Developers<\/a> was posting about calling Representational State Transfer (REST) APIs in Windows PowerShell.\nTo give you a bit of background, a REST API is an interface based on the HTTP protocol. You use one of four operations&mdash;<strong>Get<\/strong>, <strong>Post<\/strong>, <strong>Put<\/strong>, or <strong>Delete<\/strong>&mdash;with a string parameter in HTTP format. The strings look like URIs, but they don&#8217;t refer to a web page. Instead, they provide the data for one of the four operations.\nI didn&#8217;t know how to call REST APIs in Windows PowerShell, so I asked Doug for help. Before we started, I asked Doug how to determine which websites have web services with REST interfaces. It turns out that this isn&#8217;t a very straightforward task. You have to search online for the name of your favorite website or service and &#8220;REST API.&#8221; Doug found YouTube and StackOverflow, and he pointed me to the <a href=\"http:\/\/www.programmableweb.com\/apitag\/?page=1&amp;page=1&amp;q=shipping&amp;tagtype=api\" target=\"_blank\">ProgrammableWeb&nbsp; API search<\/a>.\nDoug suggested that we start with the <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=217034\" target=\"_blank\">Invoke-RestMethod<\/a> cmdlet, which was introduced in Windows PowerShell&nbsp;3.0, and YouTube, which has a well-documented REST API. I started here: <a href=\"https:\/\/developers.google.com\/youtube\/2.0\/developers_guide_protocol_api_query_parameters\" target=\"_blank\">YouTube API v2.0 &ndash; API Query Parameters<\/a>. This page lists the parameters that you can include in a <strong>Get<\/strong> or query operation.\nThe syntax of the query string is:<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">https:\/\/gdata.youtube.com\/feeds\/api\/videos?\n&hellip;followed by a parameter and parameter value in key=value format.\nFor example, the instructions recommend that you include the <strong>v<\/strong> (version) parameter with a value of <strong>2<\/strong> to use the latest version of the REST API:<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">https:\/\/gdata.youtube.com\/feeds\/api\/videos?v=2\nTo specify the query string (the text you are searching for), use a parameter of <strong>q <\/strong>(lower-case) and the search text. This query string searches for <strong>PowerShell<\/strong>:<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">https:\/\/gdata.youtube.com\/feeds\/api\/videos?q=PowerShell\nTo search for multiple words, concatenate the words with a plus sign (<strong>+<\/strong>).<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">https:\/\/gdata.youtube.com\/feeds\/api\/videos?q=Windows+PowerShell\nTo use multiple parameters, separate them with an ampersand (<strong>&amp;<\/strong>). The following query string specifies <strong>v 2<\/strong> and searches for <strong>PowerShell<\/strong>:<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">https:\/\/gdata.youtube.com\/feeds\/api\/videos?v=2&amp;q=Powershell\nNow, to run the query in Windows PowerShell, use the <strong>Invoke-RestMethod<\/strong> cmdlet. The following command searches YouTube videos with <strong>PowerShell<\/strong> in the title.<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:&gt; Invoke-RestMethod -Uri &nbsp;&#8220;https:\/\/gdata.youtube.com\/feeds\/api\/videos?v=2&amp;q=PowerShell&#8221;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">etag&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : W\/&#8221;D0UNQH47eCp7I2A9Wh5TFU4.&#8221;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">id&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : tag:youtube.com,2008:video:-Ya1dQ1Igkc<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">published&nbsp;&nbsp;&nbsp;&nbsp; : 2012-03-27T19:43:26.000Z<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">updated&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 2013-09-30T10:01:31.000Z<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">category&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : {category, category}<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">title&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : My Final 1-Day PowerShell v2 Workshop<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">content&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : content<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">link&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : {link, link, link, link&#8230;}<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">author&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : author<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">accessControl : {yt:accessControl, yt:accessControl, yt:accessControl, yt:accessControl&#8230;}<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">comments&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : comments<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">group&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : group<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">rating&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : {gd:rating, yt:rating}<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">statistics&nbsp;&nbsp;&nbsp; : statistics<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">etag&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : W\/&#8221;DU8DRn47eCp7I2A9WhFaGE0.&#8221;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">id&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;: tag:youtube.com,2008:video:XpHgSHQZNpU<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">published&nbsp;&nbsp;&nbsp;&nbsp; : 2011-09-21T15:38:13.000Z<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">updated&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 2013-09-21T23:57:57.000Z<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">category&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : {category, category}<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">title&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Hacking Windows Accounts with Powershell<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">content&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : content<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">link&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : {link, link, link, link&#8230;}<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">author&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : author<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">accessControl : {yt:accessControl, yt:accessControl, yt:accessControl, yt:accessControl&#8230;}<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">comments&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : comments<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">hd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">group&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : group<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">rating&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : {gd:rating, yt:rating}<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">statistics&nbsp;&nbsp;&nbsp; : statistics<\/p>\n<p style=\"padding-left: 30px\">&nbsp;. . .\nWow, it works!&nbsp; I&#8217;ll select the title, author, and the URL of the video:<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:ps-test&gt; Invoke-RestMethod -Uri &#8220;https:\/\/gdata.youtube.com\/feeds\/api\/videos?v=2&amp;q=PowerShell&#8221; | Select-Object Title, Author, Link<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">title&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;author&nbsp;&nbsp;&nbsp; link<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&nbsp;&nbsp;&nbsp; &#8212;-<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">My Final 1-Day PowerShell v2 Workshop&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; author&nbsp;&nbsp;&nbsp; {link, link, link, link&#8230;}<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">Hacking Windows Accounts with Powershell&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; author&nbsp;&nbsp;&nbsp; {link, link, link, link&#8230;}<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">What is PowerShell and how can it make IT &#8230;&nbsp;&nbsp;&nbsp; author&nbsp;&nbsp;&nbsp; {link, link, link, link&#8230;}<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">Basics of Powershell P1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; author&nbsp;&nbsp;&nbsp; {link, link, link, link&#8230;}<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&#8230;\nHmm. That doesn&#8217;t quite work. The author property is in author.name and the link is in content.src. You can use a calculated property or a PSCustomObject to fix this. Let&#8217;s use a <a href=\"http:\/\/powershell.org\/wp\/2013\/04\/24\/pscustomobject-save-puppies-and-avoid-dead-ends\/\" target=\"_blank\">PSCustomObject<\/a>.<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:&gt; Invoke-RestMethod -Uri &#8220;https:\/\/gdata.youtube.com\/feeds\/api\/videos?v=2&amp;q=PowerShell&#8221; | foreach {[PSCustomObject]@{Title=$_.Title; Author=$_.Author.name; Link=$_.content.src}} | Format-List<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">Title&nbsp; : My Final 1-Day PowerShell v2 Workshop<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">Author : Don Jones<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">Link&nbsp;&nbsp; : https:\/\/www.youtube.com\/v\/-Ya1dQ1Igkc?version=3&amp;f=videos&amp;app=youtube_gdata<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">Title&nbsp; : Hacking Windows Accounts with Powershell<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">Author : David Hoelzer<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">Link&nbsp;&nbsp; : https:\/\/www.youtube.com\/v\/XpHgSHQZNpU?version=3&amp;f=videos&amp;app=youtube_gdata<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&#8230;\nThat&#8217;s much better! There&#8217;s lots of other useful information, including the publication date and last updated date, comments, statistics, and ratings.\nBut before I turn you over to Doug to hear why this works, let me share one more tidbit. One of the parameters in the YouTube REST API is <strong>Max-Results<\/strong>. Its default value is 25, and its maximum value is 50.\nIt doesn&#8217;t seem to work in Windows PowerShell&nbsp;3.0. By default, it returns the first 13 hits. When we specified values of 5, 10, 30, and 50, we got only half of what we requested: 3, 5, 15, and 25.<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:&gt; (Invoke-RestMethod -Uri &#8220;https:\/\/gdata.youtube.com\/feeds\/api\/videos?v=2&amp;q=PowerShell&#8221;).count<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">13<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:&gt; 5,10,30,50 | % {<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $url=https:\/\/gdata.youtube.com\/feeds\/api\/videos?v=2&amp;q=Powershell&amp;max-results=$_;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; (Invoke-RestMethod $url).count<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">}<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">3<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">5<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">15<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">25\nBut when we tested it in Windows PowerShell&nbsp;4.0, it worked perfectly.<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:&gt; (Invoke-RestMethod -Uri &#8220;https:\/\/gdata.youtube.com\/feeds\/api\/videos?v=2&amp;q=PowerShell&#8221;).count<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">25<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:&gt; 5,10,30,50 | % {<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $url=https:\/\/gdata.youtube.com\/feeds\/api\/videos?v=2&amp;q=Powershell&amp;max-results=$_;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; (Invoke-RestMethod $url).count<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">}<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">5<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">10<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">30<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">50\nWe checked with Windows PowerShell developer, Lee Holmes; and indeed, in Windows PowerShell&nbsp;4.0, the team fixed a bug that returned only half of the results of <strong>Invoke-RestMethod<\/strong> calls.\nSo, let me turn you over to Doug so you can learn about why all of this works&hellip;\nThanks, June. That was a great write-up about how Windows PowerShell integrates with REST APIs.\nREST is the predominant Web API. It&rsquo;s a way to serve standard programmatic access to data over HTTP. So, as June shows, you can get to a wealth of YouTube data by using a Window PowerShell one-liner.\nThe cool part is that all REST APIs work this way. So, when you learn the fundamentals, you can identify REST sources and apply these techniques again and again.<\/p>\n<h2>Invoke-RestMethod<\/h2>\n<p><strong>Invoke-RestMethod<\/strong> is great because the Windows PowerShell team has written and tested a ton of script, and I can get super productive with two lines:<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:&gt;$url = &#8220;https:\/\/gdata.youtube.com\/feeds\/api\/videos?q=PowerShell&#8221;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:&gt; (Invoke-RestMethod $url).title.&#8217;#text&#8217;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">My Final 1-Day PowerShell v2 Workshop<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">Windows PowerShell 2.0 for Beginners Training &amp; Overview &#8211; EPC Group<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">Hacking Windows Accounts with Powershell<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">Introduction to Windows PowerShell Part 1<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">What is PowerShell and how can it make IT more efficient? Jason Helmick &#8211; Interface<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">Windows PowerShell Remoting: Definitely NOT Just for Servers<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">Basics of Powershell P1<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">O&#8217;Reilly Webcast: Getting Started with Windows PowerShell 3.0<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">Advanced Automation Using Windows PowerShell 3.0<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">TechEd 2013: Windows PowerShell Unplugged &#8211; Jeffrey Snover<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">My PowerShell Scripts &#8211; Systems Administration<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">[Powershell] Einfu&#776;hrung Teil 1<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">MCITP 70-640: PowerShell<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">German PowerShell Basis Video Tutorial Teil 1 von 21 Was ist PowerShell, Warum PowerShell<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">Bootable USB Drive Using Powershell and Windows 8<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&#1048;&#1085;&#1089;&#1090;&#1088;&#1091;&#1084;&#1077;&#1085;&#1090;&#1099; Windows PowerShell 2.0. &#1063;&#1072;&#1089;&#1090;&#1100; 1<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">Bruce Payette &#8211; PowerShell Workflows<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">Powershell. Curso Hispano.<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">Exploring PowerShell for Beginners Dec 9th<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PowerShell: Introduction and Scripting Tutorial<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">No Tools No Problem Building a PowerShell Botnet Christopher @obscuresec Campbell<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">Creating HTML Reports with PowerShell<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PowerShell Scripting Basics<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PowerShell for common Office 365 Operations<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">Windows Powershell &#8211; What are The Top 10 Cmdlets to Start Using Immediately\nTake note of how the &shy;title information is retrieved:<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;(Invoke-RestMethod $url).title.&#8217;#text&#8217;\nThe title data is stored in the <strong>#text<\/strong><em> <\/em>property, but if you don&rsquo;t enclose <strong>&#8220;#text&#8221;<\/strong> in quotation marks, Windows PowerShell interprets it as a comment because it begins with a <strong><em># <\/em><\/strong>sign, and you will receive an error message.\nBefore Windows PowerShell delivered <strong>Invoke-RestMethod<\/strong>, we could reach into the .NET Framework and use the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.net.webclient.aspx\" target=\"_blank\">System.Net.WebClient<\/a> class to grab this data ourselves:<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:&gt;$wc = New-Object System.Net.WebClient<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:&gt;$url = &#8220;https:\/\/gdata.youtube.com\/feeds\/api\/videos?q=PowerShell&#8221;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:&gt;$youtubedata = [xml]$wc.DownloadString($url)<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:&gt;$youtubedata.feed.entry.title.&#8217;#text&#8217;\n<strong>Invoke-RestMethod<\/strong> does a lot for us. It connects and downloads the data from the target URL, converts the returned string into XML, and extracts the <strong>feed.entry<\/strong> information so we can use less .NET notation to get at what we want faster. A <a href=\"http:\/\/en.wikipedia.org\/wiki\/Web_feed\" target=\"_blank\">feed<\/a> is a data format for providing frequently updated content. <strong>Invoke-RestMethod<\/strong> leverages this standard to make our lives easier.\nBut wait! There&rsquo;s more&hellip;<\/p>\n<h2>Earthquake data and JSON<\/h2>\n<p><strong>Invoke-RestMethod<\/strong> also automatically detects the type of data the URL returns. While REST is the predominate way to interact with data on the web, <a href=\"http:\/\/en.wikipedia.org\/wiki\/JSON\" target=\"_blank\">JavaScript Object Notation<\/a> (JSON), a text-based standard for data interchange, is often used too.\nGreat news! The designers of <strong>Invoke-RestMethod<\/strong> also made it easy to interact with JSON REST feeds. Here&#8217;s an <strong>Invoke-RestMethod<\/strong> command that gets earthquake data from Seismi.org. It returns JSON, but you don&#8217;t need to know that. Windows PowerShell returns custom objects (<a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=254914\" target=\"_blank\">PSCustomObject<\/a>) that you can use in your commands.<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:&gt;(Invoke-RestMethod -URI &#8220;http:\/\/www.seismi.org\/api\/eqs&#8221;).earthquakes | Select-Object -First 10 | Format-Table &ndash;AutoSize<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">src eqid&nbsp;&nbsp;&nbsp;&nbsp; timedate&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lat&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lon&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; magnitude depth&nbsp; region&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&#8212; &#8212;-&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212; &#8212;&#8211;&nbsp; &#8212;&#8212;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">us&nbsp; c000is61 2013-07-29 22:22:48 7.6413&nbsp;&nbsp; 93.6871&nbsp;&nbsp; 4.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 40.90&nbsp; Nicobar Islands, India region&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">us&nbsp; c000is4s 2013-07-29 21:52:12 -57.7816 -25.3260&nbsp; 5.2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 53.50&nbsp; South Sandwich Islands region&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">us&nbsp; c000is3k 2013-07-29 21:33:34 36.6696&nbsp; 71.0615&nbsp;&nbsp; 4.7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 234.10 Hindu Kush region, Afghanistan&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">us&nbsp; c000irvf 2013-07-29 18:27:41 -37.2993 177.2515&nbsp; 4.9&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 160.50 off the east coast of the North Island of New Zealand<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">us&nbsp; c000irpf 2013-07-29 14:53:32 24.5038&nbsp; 62.5255&nbsp;&nbsp; 4.5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 24.30&nbsp; off the coast of Pakistan&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">us&nbsp; c000irl3 2013-07-29 10:23:35 45.9104&nbsp; 143.0497&nbsp; 4.4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 337.70 Hokkaido, Japan region&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">us&nbsp; c000irjj 2013-07-29 08:21:31 -6.8134&nbsp; 130.2114&nbsp; 4.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 87.80&nbsp; Banda Sea&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">us&nbsp; c000irjf 2013-07-29 08:12:27 -16.9852 -177.0945 5.1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.00&nbsp; Fiji region&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">us&nbsp; c000irj9 2013-07-29 08:08:00 36.5108&nbsp; 70.5896&nbsp;&nbsp; 5.0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 193.10 Hindu Kush region, Afghanistan&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">us&nbsp; c000irhe 2013-07-29 05:49:35 -4.6368&nbsp; -104.9759 4.7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.00&nbsp; central East Pacific Rise &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\nYou can use the <strong>WebClient<\/strong> class to build a command like this on your own. Prior to Windows PowerShell&nbsp;3.0, you&rsquo;d need to use a third-party .NET JSON parser or build your own. Windows PowerShell&nbsp;3.0 introduced the <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=217031\" target=\"_blank\">ConvertFrom-Json<\/a> cmdlet:<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:&gt;$wc = New-Object System.Net.WebClient<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:&gt;$data = $wc.DownloadString(&#8220;http:\/\/www.seismi.org\/api\/eqs&#8221;) | ConvertFrom-Json<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:&gt;$data.earthquakes | select -First 10 | Format-Table -AutoSize\nThe results are much noisier than the out-of-the-box experience of <strong>Invoke-RestMethod<\/strong>. Plus, <strong>Invoke-RestMethod <\/strong>automatically detects whether XML or JSON is being returned, and it does the right thing&mdash;it returns Windows PowerShell objects for you to easily work on.<\/p>\n<h2>Invoke-RestMethod under the covers<\/h2>\n<p><strong>Invoke-RestMethod<\/strong> is one of the Windows PowerShell&nbsp;3.0 core cmdlets. It is written in C# and delivered in the Microsoft.PowerShell.Commands.Utility.dll. To examine it, I used a free tool from JetBrains, called <a href=\"http:\/\/www.jetbrains.com\/decompiler\/\">DotPeek<\/a>. This tool can look into the compiled DLL and decompile it to source code so you can browse it.\nAfter reading the <strong>Invoke-RestMethod<\/strong> code, I asked the Windows PowerShell team to confirm my assumptions. Lee Holmes, author of the great book, <a href=\"http:\/\/shop.oreilly.com\/product\/0636920024132.do\" target=\"_blank\">Windows PowerShell Cookbook, 3<sup>rd<\/sup> Edition<\/a>, replied, &ldquo;If it looks like an RSS or ATOM feed, we process and return the elements in the feed. If the response says it returns some form of JSON (there are many), we will first try to convert it to JSON. If that fails, we will convert it to XML. If that fails, we return it as text.&rdquo;\nHere is a simplified Windows PowerShell version I came up with that I sent along with the question:&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">$url = &#8220;http:\/\/www.seismi.org\/api\/eqs&#8221;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">$request = [System.Net.WebRequest]::Create($url)<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">$request.Method=&#8221;Get&#8221;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">$response = $request.GetResponse()<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">$requestStream = $response.GetResponseStream()<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">$readStream = New-Object System.IO.StreamReader $requestStream<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">$data=$readStream.ReadToEnd()<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">if($response.ContentType -match &#8220;application\/xml&#8221;) {<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $results = [xml]$data<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">} elseif($response.ContentType -match &#8220;application\/json&#8221;) {<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $results = $data | ConvertFrom-Json<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">} else {<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; try {<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $results = [xml]$data<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; } catch {<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $results = $data | ConvertFrom-Json<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; }<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">}<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">$results&nbsp;\nThese 23 lines of code give the same results for the earthquake data as the one-line that used <strong>Invoke-RestMethod<\/strong>. Thank you, Windows PowerShell team!\nThat&rsquo;s a very simple overview of how YouTube and Seismi.org serve this information. The better news is that this is a web standard and many sources of data are available to you this way. Even better, Windows PowerShell makes working with this information a breeze.\n~Doug\nThanks, June and Doug.\nI invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"http:\/\/blogs.technet.commailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.\n<strong>Ed Wilson<\/strong>, Microsoft Scripting Guy<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary:&nbsp;Learn how to use Windows PowerShell to search web pages. Scripting Guy, Ed Wilson here. Today&rsquo;s post is written by Doug Finke, a Windows PowerShell MVP, and June Blender, senior programming writer on the Windows Azure Active Directory team. Take it away, June&hellip; I was bending my brain around the cool new Windows Azure Graph [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[78,56,370,3,4,45],"class_list":["post-2693","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-doug-finke","tag-guest-blogger","tag-june-blender","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary:&nbsp;Learn how to use Windows PowerShell to search web pages. Scripting Guy, Ed Wilson here. Today&rsquo;s post is written by Doug Finke, a Windows PowerShell MVP, and June Blender, senior programming writer on the Windows Azure Active Directory team. Take it away, June&hellip; I was bending my brain around the cool new Windows Azure Graph [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/2693","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=2693"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/2693\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=2693"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=2693"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=2693"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}