• 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::
    

    ...


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

  • 相关阅读:
    关于分析web.xml的一篇博客,写的很详细
    (转)Java编译后产生class文件的命名规则
    Standard 1.1.x VM与Standard VM的区别
    throws和throw的用法例子以及检测和非检查异常
    终端IO(上)
    [APUE]进程关系(下)
    [APUE]进程关系(上)
    [APUE]进程控制(下)
    [APUE]进程控制(中)
    深究标准IO的缓存
  • 原文地址:https://www.cnblogs.com/lightluomeng/p/2888733.html
Copyright © 2020-2023  润新知