接触PowerShell已经有一段时间了,由于个人比较花心的缘故,喜欢这里捣鼓一下,那里捣鼓一下,所以没有系统学习过。这篇基本上是跟进贴,用来记录我学习PowerShell的点滴,:)。这里假定各位朋友知道PowerShell是啥。
类型
想必很多朋友在编写脚本的时候,都被类型错误困扰过。这里就列举几种情况。首先,编写一个输出参数类型的方法吧。
PS D:\Users\OLC> Function printType{ >> $args[0].GetType().Name} >>
#关于">>",输入左括号的时候会自动缩进,输完又括号的时候会自动结束。更多情况见下文。现在我们来看几个调用。
这是值作为参数的情况,对于xx.xx.xx.xxx这样的string一般可以放心的传入,而不需要带上引号。比较有趣的是1;2;3和1,2,3。由于;在PowerShell中也负责断句,而PowerShell和函数式编程语言一样不舍弃返回值,所以有了如上结果。至于1,2,3,是一个数组。另外,如果不作为参数,单独输入1.2.3或者nihaoya都回返回错误。大家可以试试(1 .. 100)的类型。
>>
这个单独列出,因为困扰我很久。如果使用{,那么这个会有PowerShell环境自动处理,如果要手动输入的话。需要使用shift+enter,前后各一次。
管道
学过一段时间的F#,管道这个概念和F#中的“流式操作符 |> 很像”。作为通俗一点的理解,就是...“将左侧作为参数提交给右侧的方法”。多说无益,看例子。
由于强大的.NET,使得集合支持很多“模块化操作”,比如分组,排序,选取(Select 指定 Skip 和 First可分页),迭代(没错,是ForEach),过滤(熟悉的Where)。现在来看ForEach的有意思的地方。
按照通常的变成思维,返回结果应该是一个“数组的数组”,但是结果是PowerShell将结果展开了,返回值类型仅仅是“字符串数组”。
输出
如果要将变量嵌在一个字符串中输出,有如下几种方式。
两种方式,同时,我们还无意间发现了'和""的区别。现在来看看"和'的转义。
非常明显,只需要在字符串中输入两个''或者两个""就代表'或者"本身。还有的就是几个控制集合输出的指令,都可以配合管道运算符。
#fl:fulllist,显示完整列表
#ft:formattable,格式化列表
加载程序集
如果是.NET自带的类库呢,可以使用以下方式。
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
如果是自己编写的类库,就调用另一个方法。
#相对路径 [void][System.Reflection.Assembly]::LoadFrom("OLC.dll") #绝对路径 [void][System.Reflection.Assembly]::LoadFile("C:\Users\OLC\Desktop\OLC.dll")
调用.NET程序集
#规则是:实例方法通过点引用调用,静态方法通过::调用,[]用来包含名称空间,看几个例子。
PowerShell的ISE可以智能感知,为调用.NET程序集提供了很大的便利。现在来看一个比较完整的例子,使用WebRequest访问目标网页,并通过正则表达式获取值。
[void][System.Reflection.Assembly]::LoadFrom("OLC.dll"); Function getContent{ $req = [System.Net.WebRequest]::Create($args[0]) try{ $resp = $req.GetResponse() $stream = $resp.GetResponseStream() $reader = New-Object System.IO.StreamReader -ArgumentList $stream $html = $reader.ReadToEnd() $html } catch{ "" } } Function getMatch{ $url = $args[0] $ptm = $args[1] $html = getContent $url $result = [System.Text.RegularExpressions.regex]::Matches($html,$ptm) $result | foreach{ if($_.Value -eq $null){""} else{ $_.Value.ToString() }} }
调用示例:
SecureString
只要涉及权限验证,就会碰到这种类型的参数。一般情况下,可以通过Get-Credential,直接获取带用户名和密码的凭据,如图。
如果要获取SecureString的话,需要使用以下方式。
启用脚本
Set-ExecutionPolicy Unrestricted
快速配置远程管理
Enable-PSRemoting
查询磁盘信息
PS D:\Users\OLC\Desktop> Get-WmiObject win32_logicaldisk -Filter "drivetype=3"
远程管理
很多指令本身就支持远程调用,只需要在调用的时候指定ComputerName和一个凭据,比如刚才那个查询磁盘的指令。
另外,指定Credential的时候可以只提供一个用户名,运行环境在执行的时候要求你提供密码(当然这个时候用户名可以更改),不过...在循环中使用就不明智了。支持远程调用的指令有。
· Get-WmiObject · Invoke-WmiMethod · Limit-EventLog · Set-Service · Set-WmiInstance · Show-EventLog · Stop-Computer · Clear-EventLog · Get-Counter
· New-EventLog · Register-WmiEvent · Remove-EventLog · Remove-WmiObject · Restart-Computer · Get-EventLog · Get-HotFix · Get-Process · Get-Service
· Get-WinEvent
这里推荐一本书:A layman's guide to PowerShell 2.0 remoting
多台服务器重启(关机类似)的例子
PS C:\Users\OLC> Restart-Computer 192.168.11.41 -Credential $cre -Force PS C:\Users\OLC> $cmps = "31","41","42","21","61","62" | foreach {"192.168.11.$_ "} PS C:\Users\OLC> $cmps 192.168.11.31 192.168.11.41 192.168.11.42 192.168.11.21 192.168.11.61 192.168.11.62 PS C:\Users\OLC> $cmps | foreach {Restart-computer $_ -Credential $cre -Force }
管理注册表(引用这里)
获取PowerShell中广义的逻辑驱动器
Get-PSDriver
获取注册表的根节点
PS D:\Users\OLC> Get-ChildItem Microsoft.PowerShell.Core\Registry::
...
以后出现新的需要关注的知识点就往这里面加了:)