PowerShell是Microsoft的任务自动化和配置管理框架,由命令行shell和相关的脚本语言组成。本文是PowerShell的入门教程。
什么是PowerShell
PowerShell是Microsoft的任务自动化和配置管理框架,由命令行shell和相关的脚本语言组成,可以用来管理windows或者执行脚本程序。Windows操作系统内带PowerShell,同时Linux系统也可以下载安装PowerShell,所以它也算是跨平台的框架了。
PowerShell能做什么
在PowerShell中直接管理Windows系统只是最基础的一个功能。PowerShell是个Shell,它内部定义好了一堆命令与操作系统,特别是与文件系统交互,能够启动应用程序,甚至操纵应用程序;可以编写Shell脚本,将几个命令组合起来放到文件里执行,实现文件级的重用;PowerShell是基于.Net,所以他能够能够充分利用.Net类型和COM对象,来简单地与各种系统交互,完成各种复杂的、自动化的操作。
一个PowerShell例子
这里有一个用PowerShell计算占用内存前十的应用并显示一个饼状图的脚本。这个脚本来自网络(https://www.zhihu.com/question/21787232/answer/63774856)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| # create new excel instance $objExcel = New-Object -comobject Excel.Application $objExcel.Visible = $True $objWorkbook = $objExcel.Workbooks.Add() $objWorksheet = $objWorkbook.Worksheets.Item(1)
# write information to the excel file $i = 0 $first10 = (ps | sort ws -Descending | select -first 10) $first10 | foreach -Process {$i++; $objWorksheet.Cells.Item($i,1) = $_.name; $objWorksheet.Cells.Item($i,2) = $_.ws} $otherMem = (ps | measure ws -s).Sum - ($first10 | measure ws -s).Sum $objWorksheet.Cells.Item(11,1) = "Others"; $objWorksheet.Cells.Item(11,2) = $otherMem
# draw the pie chart $objCharts = $objWorksheet.ChartObjects() $objChart = $objCharts.Add(0, 0, 500, 300) $objChart.Chart.SetSourceData($objWorksheet.range("A1:B11"), 2) $objChart.Chart.ChartType = 70 $objChart.Chart.ApplyDataLabels(5)
|
在你的windows系统上打开start菜单,找到WindowsPowershel并打开它,将上面这段代码拷贝到命令行窗口中按回车键。
变量
PowerShell中使用 $ 作为变量的起始字符。变量名称是不区分大小写并且不需要显示指定变量类型——PowerShell会自动判断赋值的数据类型。
比如我们用下面这个语句创建一个变量as并且赋值一个字符串:
变量名不区分大小写也是通过$引用
GetType方法可以返回变量的类型。
从新赋值一个整数后,变量类型变成了整数。
大部分时候我们不需要在定义变量的时候指定类型,但是总是会有期望使用强类型变量来限定赋值的情况,这个时候我们可以这样定义变量:
1 2 3
| [int]$i = 123; $i = '456' # 自动转换为整数456 $i = 'abc' # 无法转换为数字,直接报错
|
数据类型
基本数据类型
包括
1 2 3 4 5 6 7 8 9
| char, sbyte(-128 到127), byte (0到255), int16,int32 (int),int64 (long), string, bool, double , Single(float), decimal
|
要注意的是PowerShell中是用 [] 来标识数据类型。
定义一个32位长度的整数:
1 2
| $i = [int32]123 $i.GetType()
|
定义一个64位的长整数:
1 2
| $i = [long]123 $i.GetType()
|
定义一个boolean值是不能直接使用true或者false,所以你得像下面这样定义一个bool变量:
1 2 3 4 5
| $b = [bool]'true' $b1 = 'false' -as [bool] $b2 = [bool]1 $b3 = $true $b4 = $false
|
类型之间可以进行转换,PowerShell中使用-as关键字来转换类型:
1 2
| $i = '1234' -as [int] $i.GetType()
|
也可以使用其他语言惯用的强制转换格式:
数组
Powershell中的基本集合类型就是数组Array。比如我们可以直接初始化一个数组,里面可以存放各种类型的数据:
1 2
| $ar = 'a','b','c',1,12.4 $ar.GetType()
|
如果要指定数组的类型,需要使用New-Object的方式去创建数组:
1 2 3 4
| $ar = New-Objectint [] 2 $ar[1] = '10' #自动转型为整数 $ar[0] = 100 $ar[0] = 'www' #这个会报类型转换错误
|
数组上使用+=运算符可以在末尾添加上新的元素(数组长度也会增加)。
哈希表(Hashtable、Dictionary)
Hashtable用来存放Key-value结构的数据:
1 2 3 4
| $hash = @{'a'=1; 'b'=2; 'c'=3} $hash.Add('d',5) $hash.GetType() $hash
|
运算符
数学运算
PowerShell支持常用的+-运算,比如
1 2 3 4 5
| $i=1; $i++ ##先用再加 ++$i ##先加再用 $i-- ##先用再减 --$i ##先减再用
|
数值比较
需要注意的是数值的比较运算符不能用常规的>、=、<。要使用大于(-gt),大于等于(-ge),小于(-lt),小于等于(-le),等于(-eq),不等于(-ne)。
1 2 3 4 5 6
| 1 -gt 0 10 -lt 100 11 -ge 10 11 -ne 10 11 -eq 11 11 -le 11
|
创建对象
PowerShell 中可以使用New-Object的模式创建对象,例如前文提到的创建指定类型和长度的数组。PowerShell中也可以直接创建C#类型的对象,有两种创建模式:
1 2 3 4 5 6 7 8 9 10 11
| # 用new的方式创建对象 # 读取一个文件的内容(5.0之前不可用) $o = [System.IO.FileStream]::new('F:\luo.jks','Open','Read') $o $o.Close()
# 用New-Object的方式创建对象 # 读取一个文件的内容 $o = New-Object System.IO.FileStream('F:\luo.jks','Open','Read') $o $o.Close()
|
基本控制逻辑:顺序,选择,循环
既然是一种语言,那么必定会包含基本的编程控制逻辑
顺序代码:定义一个变量,然后使用它
1 2 3
| $i = 0; $i += 1; echo $i;
|
选择代码,也就是判断执行的代码逻辑:
1 2 3 4 5 6 7 8
| #生成一个1到6之间的随机数 $i = Get-Random -inputobject (1..6) if($i -gt 5){ $i-=5; }else{ $i+=5; } echo $i;
|
循环代码,重复执行一段代码:
1 2 3 4 5 6
| #生成一个10到20之间的随机数 $i = Get-Random -inputobject (10..20) while($i -gt 5){ echo $i; $i--; }
|
管道
脚本语言中管道(Pipeline)是很重要的一个概念,就算不会用也是需要了解一下。管道的作用是传输数据:将前一个命令的输出数据作为下一个命令的输入数据。PowerShell中的管道用 | 这个符号表示。例如我们用下面这个例子输出当前系统中运行的cmd processes:
1 2 3 4 5 6
| # Where-Object要求输入一个列表, # 大括号中的表达式对列表的中的每个元素进行判断, # 进而过滤掉不符合要求的元素 # ‘$_’ 指的列表中的元素
Get-Process | Where-Object {$_.Name -eq'cmd'}
|
用正则表达式查找当前目录下的文件:
1 2 3 4
| # ‘dir’ 列出指定(默认当前文件夹)文件夹下包含的文件和文件夹 # ‘-match’ 用来进行正则表达式匹配
dir | Where-Object {$_.Name -match'.*android.*'}
|
指定显示Processes的信息(不显示全部属性)
1 2 3
| # ‘Select-Object’ 用来选择指定的数组对象的属性并且输出
Get-Process | Select-Object Name,Id
|
PowerShell 脚本
PowerShell的脚本文件就是包含一些列PowerShell命令的文本文件,可以在PowerShell中逐行执行。现在回到本文最开始的那个显示一个饼状图的脚本例子,让我们结合已经介绍过的基本概念来具体看看这个脚本的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| # 通过New-Object的方法创建一个新的Excel对象 $objExcel = New-Object -comobject Excel.Application # 设置访问权限为True $objExcel.Visible = $True # 在Excel中增加一个新工作表(默认打开的excel是空的) $objWorkbook = $objExcel.Workbooks.Add() # 创建一个sheet (Excel中的单表格概念) $objWorksheet = $objWorkbook.Worksheets.Item(1) # 下面通过管道将process的命令传给Excel
$i = 0 # 通过管道在命令间传输数据 # ‘ps’ 命令获取进程的列表 # ‘sort’ 命令根据内存占用大小对进程进行降序排序 # ‘select’ 命令选择前10个进程 $first10 = (ps | sort ws -Descending | select -first 10) # 通过‘foreach’将数据逐个写入到表格中 $first10 | foreach -Process { $i++; $objWorksheet.Cells.Item($i,1) = $_.name; $objWorksheet.Cells.Item($i,2) = $_.ws } $objWorksheet.Cells.Item($i,2) = $_.ws} # 将其他进程占用的内存汇总为一个数据 $otherMem = (ps | measure ws -s).Sum - ($first10 | measure ws -s).Sum # 将其他进程占用的内存写入表格 $objWorksheet.Cells.Item(11,1)="Others"; $objWorksheet.Cells.Item(11,2)=$otherMem
# 下面开始绘制Excel表格 # 首先获取一个表格图表绘制对象 $objCharts = $objWorksheet.ChartObjects() # 新建一个新的的图表 $objChart = $objCharts.Add(0, 0, 500, 300) # 给这图表指定源数据 $objChart.Chart.SetSourceData($objWorksheet.range("A1:B11"), 2) # 指定图表的类型 $objChart.Chart.ChartType = 70 # 显示 $objChart.Chart.ApplyDataLabels(5)
|
将这个脚本保存到一个文本文件中,并且命名为Top10MemChart.ps1。这样这个脚本就可以在安装有PowerShell的电脑上执行了:
如果抛出脚本不能执行的错误(配置上禁止执行脚本),那么可以执行下面这个命令修改配置:
1 2
| # 当前登陆用户可以执行脚本 Set-ExecutionPolicy-ExecutionPolicyRemoteSigned-ScopeCurrentUser
|