PowerShell技术文章翻译#2:Invoke-RestMethod -- 把cURL放到你的Shell里
2012-08-06 05:44
302 查看
PowerShell -- Invoke-RestMethod: ”内置“在Shell中的cURL
Eric - http://www.discoposse.com/
PowerShell 3.0里很棒的一个Cmdlet就是Invoke-RestMethod。有了这个命令,我们在PowerShell Script中就能直接使用HTTP方法来访问网络资源,这些HTTP方法包括Get, Head, Post, Put, Delete, Trace, Options, Merge, Patch. 过去如果你想在PowerShell里做同样的事,一般只能选择一个为Cmd写的命令行工具cURL(Linux里常用的是Wget), 你可以在你的batch脚本或者PowerShell脚本里使用cURL来获取你需要的HTTP资源。当然,cURL很胜任这项工作,不过既然PowerShell 3.0里内置了有同样功能的Invoke-RestMethod, 那么就让我们看看它用起来怎么样吧。
假设我们要从一个网站上获取些XML数据并保存到一个文件中,那么使用cURL的话就是下面这行命令:
这并不是件复杂的操作,cURL完全可以胜任,但是有个问题,curl是个第三方命令行工具,也就是说上面这行命令的可移植性不好,毕竟不是每台电脑上都装有cURL。Invoke-RestMethod不一样,PowerShell 3.0是内嵌在Windows 8/Windows Server 2012里的,只要有PowerShell 3.0,就有Invoke-RestMethod这个内置命令。使用Invoke-RestMethod的话,我们需要下面这行命令:
很简单吧,Invoke-RestMethod的参数名和使用语法都会让这行命令更容易被人理解 -- 使用HTTP Get方法来获取指定URI的news feed。Invoke-RestMethod使用的默认方法就是Get,所以我们这个例子里也可以干脆省略"-Method Get"。
现在我们来看看这个命令会返回什么东西:
Eric - http://www.discoposse.com/
PowerShell 3.0里很棒的一个Cmdlet就是Invoke-RestMethod。有了这个命令,我们在PowerShell Script中就能直接使用HTTP方法来访问网络资源,这些HTTP方法包括Get, Head, Post, Put, Delete, Trace, Options, Merge, Patch. 过去如果你想在PowerShell里做同样的事,一般只能选择一个为Cmd写的命令行工具cURL(Linux里常用的是Wget), 你可以在你的batch脚本或者PowerShell脚本里使用cURL来获取你需要的HTTP资源。当然,cURL很胜任这项工作,不过既然PowerShell 3.0里内置了有同样功能的Invoke-RestMethod, 那么就让我们看看它用起来怎么样吧。
假设我们要从一个网站上获取些XML数据并保存到一个文件中,那么使用cURL的话就是下面这行命令:
curl.exe www.discoposse.com/index.php/feed > C:\Temp\DiscoPosseFeed.xml
这并不是件复杂的操作,cURL完全可以胜任,但是有个问题,curl是个第三方命令行工具,也就是说上面这行命令的可移植性不好,毕竟不是每台电脑上都装有cURL。Invoke-RestMethod不一样,PowerShell 3.0是内嵌在Windows 8/Windows Server 2012里的,只要有PowerShell 3.0,就有Invoke-RestMethod这个内置命令。使用Invoke-RestMethod的话,我们需要下面这行命令:
Invoke-RestMethod -Uri www.discoposse.com/index.php/feed -Method Get
很简单吧,Invoke-RestMethod的参数名和使用语法都会让这行命令更容易被人理解 -- 使用HTTP Get方法来获取指定URI的news feed。Invoke-RestMethod使用的默认方法就是Get,所以我们这个例子里也可以干脆省略"-Method Get"。
现在我们来看看这个命令会返回什么东西:
PS C:\Users> Invoke-RestMethod -Uri www.discoposse.com/index.php/feed -Method Get title : Linked Mode separation? Veeam to the Rescue link : http://www.discoposse.com/index.php/2012/07/31/linked-mode-separation-veeam-to-the-rescue/ comments : {http://www.discoposse.com/index.php/2012/07/31/linked-mode-separation-veeam-to-the-rescue/#comments, 0} pubDate : Tue, 31 Jul 2012 15:20:01 +0000 creator : Eric category : {category, category, category, category...} guid : guid description : description commentRss : http://www.discoposse.com/index.php/2012/07/31/linked-mode-separation-veeam-to-the-rescue/feed/ title : BCP/DR Primer – Part 5 – Test the plan, don’t plan the test link : http://www.discoposse.com/index.php/2012/07/25/bcpdr-primer-part-5-test-the-plan-dont-plan-the-test/ comments : {http://www.discoposse.com/index.php/2012/07/25/bcpdr-primer-part-5-test-the-plan-dont-plan-the-test/#com ments, 0} pubDate : Wed, 25 Jul 2012 14:24:20 +0000 creator : Eric category : {category, category, category, category...} guid : guid description : description commentRss : http://www.discoposse.com/index.php/2012/07/25/bcpdr-primer-part-5-test-the-plan-dont-plan-the-test/feed/[/code]
看到这儿你可能会问,这是什么?返回的结果不应该是XML数据吗?是的,这个例子里HTTP Get方法返回的结果的确是XML数据,如果使用cURL的话,输出的结果会是一个很长的string,包含所有XML数据的内容。但记住,我们在使用PowerShell!! PowerShell和传统Shell最大的一个不同点就是,传统Shell是基于纯文本数据,而PowerShell是基于object的。Invoke-RestMethod得到Get方法的Response后,会尝试确定Response的类型。如果是XML类型,就会把Response的内容转换成System.Xml.XMLElement类型的对象;如果是Json类型,就会转换成PowerShell的CustomPSObject类型的对象。这样作为用户就能更直观的对返回结果进行处理,而不需要再自行解析文本了。在我们这个例子里,Response的类型是XML,所以XML数据被转换成了XMLElement对象。更清晰了不是吗?Tags和与其对应的content都一目了然,我们可以直接以property access的方式去获取我们感兴趣的内容。
下一步就是输出结果导入到一个xml文件里,我们可以使用pipeline也可以直接用重定向操作符:Invoke-RestMethod -Uri www.discoposse.com/index.php/feed -Method Get > C:\Temp\DiscoPosseFeed.xml # Or Invoke-RestMethod -Uri www.discoposse.com/index.php/feed -Method Get | Out-File -FilePath C:\Temp\DiscoPosseFeed.xml
让我们来看看xml文件里的内容:PS C:\Users> cat C:\Temp\DiscoPosseFeed.xml title : Linked Mode separation? Veeam to the Rescue link : http://www.discoposse.com/index.php/2012/07/31/linked-mode-separation-veeam-to-the-rescue/ comments : {http://www.discoposse.com/index.php/2012/07/31/linked-mode-separation-veeam-to-the-rescue/#comments, 0} pubDate : Tue, 31 Jul 2012 15:20:01 +0000 creator : Eric category : {category, category, category, category...} guid : guid description : description commentRss : http://www.discoposse.com/index.php/2012/07/31/linked-mode-separation-veeam-to-the-rescue/feed/ title : BCP/DR Primer – Part 5 – Test the plan, don’t plan the test link : http://www.discoposse.com/index.php/2012/07/25/bcpdr-primer-part-5-test-the-plan-dont-plan-the-test/ comments : {http://www.discoposse.com/index.php/2012/07/25/bcpdr-primer-part-5-test-the-plan-dont-plan-the-test/#com ments, 0} pubDate : Wed, 25 Jul 2012 14:24:20 +0000 creator : Eric category : {category, category, category, category...} guid : guid description : description commentRss : http://www.discoposse.com/index.php/2012/07/25/bcpdr-primer-part-5-test-the-plan-dont-plan-the-test/feed/[/code]
惨了,这只是一个纯文本文件,完全不是我们想要的Xml文档。问题出在哪儿呢?是这样的,Invoke-RestMethod输出的结果是XMLElement objects,于是上面那两行命令实际做的事情是把这些XMLElement objects按照在console上显示的格式,保存到文件中,结果当然不会是Xml文档。这其实是对Invoke-RestMethod灵活性的一个需求:当我要直接处理返回结果时,我需要你把response content转换成更直观的对象;当我要保存返回结果时,我需要你给我raw data而不是转换后的对象。Invoke-RestMethod当然考虑到了这个问题,它提供了”-OutFile“参数,用来直接将raw data保存到文件里,所以我们想要的操作可以用下面这行命令来实现:Invoke-RestMethod -Uri www.discoposse.com/index.php/feed -Method Get -OutFile C:\Temp\DiscoPosseFeed.xml
来,我们再看看这次的文件内容,正是我们想要的XML文档:PS C:\Users> cat C:\Temp\DiscoPosseFeed.xml <?xml version="1.0" encoding="UTF-8"?> <rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" > <channel> <title>DiscoPosse - Using the chicken to measure IT</title> ...
好了,这个小小的例子就结束了,在这个例子里我们使用Invoke-RestMethod命令运行了HTTP Get方法,获取了指定URI的内容,并把获取的数据输出到了一个文件里,很方便,只需要一行简单的命令。唯一的一个问题就是现在PowerShell 3.0环境还并非那么普及,但我们都知道,这只是个时间问题,很快我们就会发现,用Invoke-RestMethod的脚本有着让人满意的可移植性 :)
【译者注】Invoke-RestMethod/Invoke-WebRequest有很大很大的潜力,它让脚本程序与Web资源的交互更加的方便简单。这里还有两篇文章是有关基于Invoke-RestMethod的应用,第一个使用Invoke-RestMethod外加ShowUI(一个第三方的PowerShell Module,能让我们直接用PowerShell Script写WPF UI的应用程序)来显示今年TechEd的会议信息;另一个是使用Invoke-WebRequest获取多篇blogs输出到PDF文档:
Interacting with TechEd NA 2012 Schedule using PowerShell v3
How to Download an Entire WordPress Blog
相关文章推荐
- PowerShell技术文章翻译#1 -- Queueing Theory,献给繁忙的系统管理员
- PowerShell中使用curl(Invoke-WebRequest)的方法教程
- mojoportal学习——文章翻译之在mojoportal中使用微软Ajax技术
- Chromium技术文章翻译——Views Windowing
- How to pass multiple parameters in PowerShell invoke-restmethod
- 谈技术文章翻译的信雅达-上
- 一个定期翻译国外Android优质的技术、开源库、软件架构设计、测试等文章的开源项目
- 一个定期翻译国外Android优质的技术、开源库、软件架构设计、测试等文章的开源项目
- 谈技术文章翻译的信雅达-下
- 翻译一篇关于OpenGL实现Billboarding技术的文章
- 【翻译自mos文章】将expdp的dmp文件从asm磁盘组里边放到本地文件系统里边
- 【翻译自mos文章】将expdp的dmp文件从asm磁盘组里边放到本地文件系统里边
- 经典技术文章翻译(1):COM+集成:.NET Enterprise Services 如何帮你建立分布式应用(2)
- 经典技术文章翻译(2)Does WCF use or Supports IOCP?WCF是否支持或者使用了IOCP完成端口。
- 【免费】承接翻译各类英文技术文章
- 经典技术文章翻译(1):COM+集成:.NET Enterprise Services 如何帮你建立分布式应用(1)
- 经典技术文章翻译(2)Does WCF use or Supports IOCP?WCF是否支持或者使用了IOCP完成端口
- 一个定期翻译国外Android优质的技术、开源库、软件架构设计、测试等文章的开源项目
- 一个定期翻译国外Android优质的技术、开源库、软件架构设计、测试等文章的开源项目 http://www.devtf.cn
- python queue 的put的暂停当前线程 国内大部分技术文章翻译都翻译错的