{"id":1521,"date":"2014-09-29T16:37:00","date_gmt":"2014-09-29T16:37:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/powershell\/2014\/09\/29\/simple-http-api-for-executing-powershell-scripts\/"},"modified":"2019-02-18T13:05:14","modified_gmt":"2019-02-18T20:05:14","slug":"simple-http-api-for-executing-powershell-scripts","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/powershell\/simple-http-api-for-executing-powershell-scripts\/","title":{"rendered":"Simple HTTP api for Executing PowerShell Scripts"},"content":{"rendered":"<p>[Based on the feedback, I&#8217;ve renamed this to HTTP]<\/p>\n<p>There may be scenarios where you don&rsquo;t need the full interactive experience of PowerShell remoting over <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dd357801.aspx\">PSRP<\/a>&nbsp; (PowerShell Remoting Protocol), or have the need to execute some PowerShell scripts from a non-Windows system.&nbsp; You could directly code against WS-Man as I&rsquo;ve <a href=\"http:\/\/blogs.msdn.com\/b\/wmi\/archive\/2011\/01\/25\/using-ws-man-to-invoke-a-powershell-cmdlet.aspx\">blogged<\/a> about a long time ago, however, it&rsquo;s quite complicated requiring knowledge of SOAP and WS-Man.&nbsp; In cases where you want to simply invoke a PowerShell script remotely, a REST api is a good choice since all modern programming languages make it simple to perform a HTTP GET operation.<\/p>\n<p>I wrote a simple HTTP Listener in PowerShell script that uses the .Net HttpListener class.&nbsp; You simply start an instance of the listener (requires an elevated prompt to listen on the network) and now you can execute an arbitrary PowerShell command-line and get back the results in a variety of formats.<\/p>\n<p>Once you have the module installed (just copy the HttpListener folder to your Documents\\WindowsPowerShell\\Modules folder) and imported, you can start an instance by using the Start-HTTPListener commandlet:<\/p>\n<p>&nbsp;<a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/30\/2018\/10\/6761.image_1D357D67.png\"><img decoding=\"async\" title=\"image\" src=\"https:\/\/devblogs.microsoft.com\/00\/00\/00\/63\/74\/metablogapi\/4617.image_thumb_2B07C362.png\" alt=\"image\" width=\"693\" height=\"156\" border=\"0\" \/><\/a><\/p>\n<p>By default, I have it set to listen on port 8888 and using Integrated Windows Authentication, but this is all configurable as parameters to the commandlet.&nbsp; Here, I have another PowerShell window open and I execute &ldquo;get-process powershell&rdquo;:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/30\/2018\/10\/3122.image_5CFF63EC.png\"><img decoding=\"async\" title=\"image\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/30\/2018\/10\/6758.image_thumb_7FC32C5A.png\" alt=\"image\" width=\"698\" height=\"313\" border=\"0\" \/><\/a><\/p>\n<p>Note that I used the &ndash;UseDefaultCredentials to ensure I authenticate with my current security context otherwise you&rsquo;ll get back Access Denied since anonymous access is not supported.<\/p>\n<p>By default, I return the output as JSON.&nbsp; Because the resulting JSON object is large, it&rsquo;s truncated.&nbsp; The body of the HTTP response is in the Content property, but it&rsquo;s a byte array.&nbsp; I use the Utf8 .Net class to decode it and show a portion of the JSON:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/30\/2018\/10\/7652.image_2691429B.png\"><img decoding=\"async\" title=\"image\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/30\/2018\/10\/1300.image_thumb_5888E325.png\" alt=\"image\" width=\"699\" height=\"458\" border=\"0\" \/><\/a><\/p>\n<p>I can utilize the ConvertFrom-Json to make it more presentable within PowerShell:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/00\/00\/00\/63\/74\/metablogapi\/2860.image_2D444C1E.png\"><img decoding=\"async\" title=\"image\" src=\"https:\/\/devblogs.microsoft.com\/00\/00\/00\/63\/74\/metablogapi\/7268.image_thumb_7837BCED.png\" alt=\"image\" width=\"700\" height=\"459\" border=\"0\" \/><\/a><\/p>\n<p>Of course, if you&rsquo;re using a different scripting client such as Python, Perl, or Ruby, then you would use script libraries in those languages to use the JSON version.<\/p>\n<p>If you&rsquo;re just playing around, you can use the Text formatting to make things more easily readable and resembles what you would get executing the same command line directly in PowerShell:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/30\/2018\/10\/6663.image_060A02E9.png\"><img decoding=\"async\" title=\"image\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/30\/2018\/10\/2061.image_thumb_7AE0789E.png\" alt=\"image\" width=\"701\" height=\"460\" border=\"0\" \/><\/a><\/p>\n<p>Other formatting options are available and if you call the HTTP endpoint without any parameters, you&rsquo;ll get the basic usage information back:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/30\/2018\/10\/2475.image_45D3E96E.png\"><img decoding=\"async\" title=\"image\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/30\/2018\/10\/8322.image_thumb_3AAA5F24.png\" alt=\"image\" width=\"703\" height=\"246\" border=\"0\" \/><\/a><\/p>\n<p>The code is available on <a href=\"http:\/\/gallery.technet.microsoft.com\/Simple-REST-api-for-b04489f1\">TechNet<\/a> where I also explain a bit more on how the code actually works.<\/p>\n<p>Steve Lee <br \/>Principal Test Lead PowerShell <br \/>Windows Server<\/p>\n","protected":false},"excerpt":{"rendered":"<p>[Based on the feedback, I&#8217;ve renamed this to HTTP] There may be scenarios where you don&rsquo;t need the full interactive experience of PowerShell remoting over PSRP&nbsp; (PowerShell Remoting Protocol), or have the need to execute some PowerShell scripts from a non-Windows system.&nbsp; You could directly code against WS-Man as I&rsquo;ve blogged about a long time [&hellip;]<\/p>\n","protected":false},"author":600,"featured_media":13641,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1521","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-powershell"],"acf":[],"blog_post_summary":"<p>[Based on the feedback, I&#8217;ve renamed this to HTTP] There may be scenarios where you don&rsquo;t need the full interactive experience of PowerShell remoting over PSRP&nbsp; (PowerShell Remoting Protocol), or have the need to execute some PowerShell scripts from a non-Windows system.&nbsp; You could directly code against WS-Man as I&rsquo;ve blogged about a long time [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/1521","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/users\/600"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/comments?post=1521"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/1521\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media\/13641"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media?parent=1521"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/categories?post=1521"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/tags?post=1521"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}