您的位置:首页 > 运维架构 > Shell

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.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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐