PowerShell之东扯西谈

接触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访问目标网页,并通过正则表达式获取值。

View Code
[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

多台服务器重启(关机类似)的例子

View Code
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::

...


以后出现新的需要关注的知识点就往这里面加了:)

原文地址:https://www.cnblogs.com/lightluomeng/p/2888733.html