使用Powershell实现自动登录域账号

问题背景

由于愈来愈烦于单位里处理办公事务的电脑开机访问站点时弹出的域账号登陆对话框,因而就寻思着想个办法解决一下。单位为了处理这个问题已经为每人提供了叫USB Key的东西,插入U盘接口后,再访问须要身份认证信息的网站时就能够自动获取这些信息而不用手工输入了。但不幸的是个人这个工具自打发下来后就以没有好用过,幸亏还能够像之前同样用域账号登陆,只是每次第一次打开须要身份认证的网站都要手动录入。html

无心间知道了微软很早之前就在Windows系统中集成了一个命令行工具Powershell,上网找了些参考资料一看,虽然使用者大都是系统管理员、数据库管理员,但看到它能操做.NET对象,能用在自动化部署和测试上,对开发者也是好处多多,功能甚是强大。因而就萌生了用它处理域认证的问题的想法。web

解决思路

单位里决大多数B/S应用都在.NET环境下开发部署运行的,而且这些应用都使用了统一的第三方集中式身份认证接口。这个API使用了Form认证和Windows集成身份认证两种方式,关于这两种认证方式的介绍请参考这篇文章:http://www.cnblogs.com/fish-li/archive/2012/04/15/2450571.htmlhttp://www.cnblogs.com/fish-li/archive/2012/05/07/2486840.htmlshell

按照这个思路,首先要知道这个身份认证API的认证机制。由于按照通常操做,若是是第一次登陆网站,客户端上可能找不到身份认证信息,因而若是选择的是Windows集成身份认证方式,它会弹出一个输入认证信息的Windows对话框。等用户录入提交后,就发送给身份认证服务器进行验证。若是验证成果,它会以某种方式(Cookies)把这些信息存储在客户端。这样在下次访问或访问其它使用相同身份验证API的应用时,就能够直接使用而不用重复登陆了。另外若是在Internet上访问域中的服务器,解决方案请参考这篇文章:http://www.pstips.net/access-web-app-that-authenticated-with-adfs.html数据库

因而解决登陆问题时,只要发给身份验证API一个请求,并在请求头中加上它须要的认证信息,再解析响应中的认证并把身份信息存储在客户端。理论上用Powershell调用.NET对象完成这些工做是可行的,但问题是这个过程应该怎么实现,要说清楚整个过程貌似能够写个连载了。编程

因而就有了第二个方法:访问一个须要认证的站点,弹出Windows域认证对话框后,自动用Powershell填写用户名/密码,再自动点击确认,模拟用户操做来完成这个任务。服务器

用Powershell自动实现填写Windows对话框和确认动做

有了以上想法就能够写Powershell脚本实现了。基本的流程就是启动一个IE窗口,导航到一个须要认证的站点,在它弹出的对话框中自动填写用户名和密码,再点击肯定就OK了。app

启动IE并导航到某站点是很容易的,就是调用一个COM对象。代码以下:工具

$IEHost = New-Object -ComObject "InternetExplorer.Application"
$IEHost.Navigate(yourUrl)
$IEHost.Visible = $true

这样就会弹出一个干净的IE窗口并导航到指定网址。测试

但涉及到自动化操做就有些麻烦了。要自已写方法吗,想一想涉及到进程、WinForm编程之类的,好像也是能够写个连载的。按照少写代码的原则,仍是找个现成的库吧。翻阅如今的Powershell资料,不多有涉及到这种模拟WinForm应用操做的,但偶然间发现了一个(可能也是惟一一个)关于这方面的库--WASP。这是一个好久没更新的库了,托管在CodePlex上。官方没有文档(其实它只有几个方法)但有一些讨论内容能够参考。网站

有了这个库就好多了。因为是第三方库,用以前要导入它。

Import-Module Your_Path\WASP.dll

接下来我把模拟登陆操做的命令先写出来(注意,这实际上是一个模拟点击弹出框的命令,但原理是同样的),很短只有一句话,再详细说明一下。

Select-Window -Class "Alternate Modal Top Most" | Select-ChildWindow | Select-Control | Send-Click -ControlButton

Select-Window表明选择窗口,即IE窗,若是你看Select-Window命令的可选项,其实除了Class,还有Title和ProcessName可用。但Title重复率高,而且有时Title是根据文档内容变化的,Process Name也不具备惟一性,我的感受仍是Class辨识度高。这里值得注意的问题是如何选择正确的类名。有一个小技巧,就是先单独使用Select-Window命令,这样它会列出全部桌面上的应用对应的类名,选择须要的便可。

以后的“|”符号表明管道操做。Select-ChildWindow表示选择这个弹出框,不直接用Select-Control是由于这个模态对话框属于窗口而不是IE的控件。

选好弹出框后就能够操做里面的控件了。Select-Control就表示选择了窗口中全部控件。由于整个窗口只有一个按钮可点击,因此就不用指定操做哪一个控件了。固然有兴趣的同窗也能够了解一下这个命令的参数,它也有几个参数可选来指定某些或某一个控件。

接下来Send-Click表示点击了弹出框中的控件,ControlButton表示点击了确认按钮。

这是模拟弹出框,要是有文本录入那种输入框怎么办呢?就须要这义到文本框控件,并使用Send-Keys命令就能够了,具体就是再后面加上命令:

Send-Keys -Keys "userName"

而后再Send-Click。这样就实现了一个完整的登录操做。在同一个会话中再打开其余须要认证的站点就不须要再登录了。

总结

上面其实是一个迂回的方案。伟光正的作法就是解决思路的第一个思路。这里重点在于“自动”二字,这是完全的自动--连文本录入和点鼠标的动做省去了,我的认为在一些情景下仍是有用的--好比这个每次开机或清除了认证信息就提示登录的烦人的域认证对话框。

相关文章
相关标签/搜索