参考链接:PowerShell官方文档
PowerShell 是微软 Windows 系统自带的升级版原生开发语言,参考 Linux 的 shell 进行的重做,提供比 cmd 更加完善的功能。
可以通过Get-Help
来获取基本的帮助。
注释
PowerShell 使用#
来引导单行注释。每一行从注释符号开始到行末不会被执行。多行注释用<# …… #>
来标识。
hello world
> Write-Output helloworld
helloworld
续行符
在交互式界面中,一般而言,换行意味着执行已经输入的代码,不过在续行符处换行不会直接执行代码,而是另起一行继续输入。续航符包括管道符|
、逗号,
、左括号(
、[
、{
、左引号'
、"
、等于号=
等。
PowerShell 常见数据类型有
PowerShell 使用$
来定义和引用一个变量。PowerShell 的变量是动态类型的,也可以用方括号[]
来限定变量的数据类型。
[int]$a = 1.1 # a = 1
数值
整型int
和浮点型double
是 PowerShell 的基本类型,PowerShell 也提供对象类型的整型和浮点型。
# 定义和赋值
$a = 1 # a会自动识别为整型
$b = $a + 0.1 # b = 1.1 整型和浮点型计算,结果为浮点型
# 用括号来将基本数据类型包装为对象
(1).CompareTo(2) # -1
1.CompareTo(2) # 报错
布尔型
布尔型bool
变量只有真和假两个取值,需要用$true
和$false
来引用。其他类型变量转换为布尔型时,0和空值会转换为假,其他转换为真。
日期型
日期型datetime
用于记录时间信息,可以进行日期和时间的操作,并转化为格式化字符串。
$a = Get-Date
$a.ToString("yyyy-MM-dd HH:mm:ss")
字符串
PowerShell 的字符串string
实际上是一种对象。
# 定义和赋值
> $a = "asd"
# 引用
> $b = $a + 1 # b = "asd1" 整型和字符串进行运算,结果为字符串
PowerShell 也提供基本的字符串处理函数,如 split()、trim()、contains()等。
集合
PowerShell 支持定义集合操作,集合是动态类型的,允许存放不同类型的变量。
# 集合有三种定义方式
> $a = 1,2,3
> $a = ("a","b")
> $a = @(1,2,3)
# 集合支持嵌套
> $b = $a, 1, "a"
# 集合的大小是固定的,要往集合中添加元素,要用+=
> $a.Add(1) # 报错
> $a += 2 # 此时会生成一个新的集合替代原有的集合
集合是有序的,可以用[]
方括号来引用集合的某一项。
集合本身是对象类型的。使用Get-Member
查看集合的类型,将打印集合中所有项的数据类型介绍。
PowerShell 支持 .Net 框架中更高级的集合类型
$a = New-Object System.Collections.ArrayList
$a.Add(1)
字典
PowerShell 提供键值对字典(System.Collections.Hashtable)类型,键会被默认解释为字符串类型。
> $d = @{1=2;3=4}
> $d
Name Value
---- -----
1 2
3 4
字典项可以通过点号(引用运算符)或者方括号进行赋值和引用,点号引用时不需要双引号,方括号引用时需要双引号。严格来说,方括号引用的泛用性更好,因为存在部分情况无法使用点号引用。
# 以下两种方式等价
$ass.qerqererqw = "qqww222"
$ass["qerqererqw"] = "qqww222"
$ass["1q"] = 1 # ass.1q 的引用方法会报错
算数运算符
PowerShell 支持对数字(整型、浮点型)进行常见的算数运算操作,包括+
、-
、*
、/
、%
(整数取余)等。
字符串、数组支持+
(连接)、*
(重复)运算。
不同数据类型之间进行运算,会将运算符右边的值转换为左边的数据类型后再进行计算。
赋值运算符
最基础的赋值运算符是=
,PowerShell 同时提供+=
、-=
、*=
、/=
、%=
等复合赋值运算符。
此外,PowerShell 支持自增++
、自减--
运算符。
比较运算符
PowerShell 包含许多比较运算符,用于逻辑运算或查找符合一定要求的值,常用于条件语句和where
语句匹配筛选场景。如同其他编程语言一样,比较运算的结果是布尔值。比较运算符清单如下:
运算符 | 含义 | 运算符 | 含义 |
---|---|---|---|
-eq | 等于 | -ne | 不等于 |
-gt | 大于 | -ge | 大于或等于 |
-lt | 小于 | -le | 小于或等于 |
-Like | 使用 * 通配符进行匹配 | -NotLike | 不使用 * 通配符进行匹配 |
-Match | 匹配指定的正则表达式 | -NotMatch | 不匹配指定的正则表达式 |
-Contains | 确定集合中是否包含指定的值 | -NotContains | 确定集合是否不包含特定值 |
-In | 确定指定的值是否在集合中 | -NotIn | 确定指定的值是否不在集合中 |
-Replace | 替换指定的值 |
以上比较均不区分大小写,如需要区分大小写,则应在运算符前加c
,如将-eq
改为-ceq
。
> "a" -eq "A" # True
> "a" -ceq "A" # False
> 1 -ge 2 # False
> 1 -in (1,2,3) # True
逻辑运算符
布尔型变量可以使用与-and
、或-or
、非-not
、亦或-xor
等基本的逻辑运算。
> (2 -gt 3) -and (1 -eq 1) # False
> $true -or (2 -gt 3) # True
> -not $false # True
> $true -xor $false # True
类型运算符
方括号[]
可以在变量、参数声明时限定其类型,或在引用一个变量时强制转换其类型。也通过-as
来进行强制类型转换,如果类型无法进行转换,会报错。
[int]$a = 1
[int]$a = "1"
[int]$a = [int]"1"
$a = "1111" -as [int]
[int]$a = "a" # 会报错
可以通过-is
、isnot
来判断某个变量是否是某个类型,结果为布尔型变量。
if ($a -is [int]) {echo 1}
其他运算符
引用运算符.
:可以用来引用对象的属性、方法,集合或字典的某一项。
范围操作符..
:可以简便地记录一定范围内的数字序列
$a = 1..5 # $a = (1, 2, 3, 4, 5)
数字简记符号KB
、MB
、GB
、TB
:可以简便记录2的整10次方数字,1KB=1024=2^10,1MB=10241024=2^20,1GB=10241024*1024=2^30
Powershell 一般情况下是从上往下顺序执行所有语句,同时也提供条件语句和循环语句。
条件语句
if-else
语句:当括号中的运算结果为真时,执行if语句,为假时执行else语句
if (1 -is [int]) {echo "int"}
else {echo "Not int"}
switch
语句:当括号中的运算结果等于下列某个选项时,执行该选项对应的语句块。如果没有命中任一选项,执行default语句块。
switch($a){
1 {echo 1}
2 {echo 2}
default {echo default}
}
循环语句
for
语句:括号中包含三个子语句,语句1用于初始化循环变量;语句2在每次循环开始前执行,为真则展开循环,为假则跳出循环;语句3在每次循环结束后执行。
for ($i = 0;$i -lt 10;$i++) {echo $i}
foreach
语句:枚举一个集合中的所有元素,并在循环体中引用它们。
foreach($i in 1..9) {echo $i}
while
语句:当括号中的语句为真时,执行循环体。
while($a -gt 0) {
echo $a;
$a--
}
do-while
语句:先执行一遍循环体,再判断当括号中的语句,为真时,继续执行循环体。
do {
echo $a;
$a--
} while($a -gt 0);
可以用以下语法定义和调用函数
# 无参数函数
function func{
echo "func"
}
# 有参数函数
function add($a, $b) {
return $a + $b
}
# 可以指定函数的参数类型
function add([int]$a, [int]$b) {
return $a + $b
}
函数的完整定义方式,可以设置参数是否必要和参数的顺序(通过Mandatory标记)、参数的验证方式(长度、范围等),常见的验证内容有:
function func {
param (
[parameter(Mandatory = $true, Position = 0)]
[ValidateRange(1,5)] [string]$a,
[parameter(Mandatory = $true, Position = 1)]
[validateset("a","b")] $b
)
return $a + $b
}
# 调用函数
add 1 2
add -a 1 -b 2
Powershell 提供交互式及文件输入渠道。
交互式输入
Read-Host
指令允许终端从键盘读入用户输入,并将输入解释为字符串。-AsSecureString
参数可以将输入内容以*
形式展示,且以 SecureString 格式存储。
> $username = Read-Host "请输入用户名:"
> $password = Read-Host "请输入密码:" -AsSecureString
# AsSecureString参数可以将输入内容以`*`形式展示并加密存储,不过只能用来传输给.Net进程
弹窗输入登录凭证
Get-Credential
指令会弹出一个对话框,接受用户名口令输入,并存储为 PSCredential 对象。
文件读取
Get-Content
指令接受一个文件路径,并将内容以字符串形式读入。读入的字符串可以通过方括号来选择行数。
> cat .\2.txt -First 10 # 前10行内容
> cat .\2.txt -Tail 10 # 尾部10行内容
> (cat .\2.txt)[3,6] # 第3行和第6行内容
> (cat .\2.txt)[3..6] # 第3行至第6行内容
Get-Content
可以自动识别 XML 格式文件(文档第一行需要有 XML 声明)。
Select-String
指令在Get-Content
基础上,提供字符串模式匹配功能,可以直接从文件中读取所需的字符串。
Import-CSV
指令会将识别 csv 表格,并将第一行解释为属性名称,第二行起每一行解释为一个对象。可以自定义分隔符,默认是英文逗号。
Import-Clixml
指令可以读取 Clixml 文件,一般用来读取Export-Clixml
输出的文件。
常见的数据输出指令如下:
Set-Content
覆盖写入。Add-Content
追加写入。Out-File
将数据写入文件。与Set-Content
、Add-Content
功能相近。Export-CSV
可以将对象输出为 CSV 文件。Export-Clixml
可以将对象输出为 Clixml 文件。ConvertTo-Html
可以将对象转换为 HTML 表格形式。Out-GridView
可以将对象呈现在窗口化的表格中,并提供内置筛选器。PowerShell cmdlet 命令是 PowerShell提供的轻量化调用模块,基本上以动作名开头,用-
引导形参(使用Linux的形式,与cmd的/
不同)。
可以用Get-Command
来获取所有支持的命令清单,或特定命令的信息。也可以通过COMMAND名称 -?
的方式获取单条命令的帮助信息。
,
分隔,*
为通配符。PowerShell 在交互式命令行中提供自动补全功能,使用 Tab 键可以自动补全命令名称、参数名称、参数值和文件路径等。
PowerShell 单行是一个连续管道,通过管道符|
可以连接多个 cmdlet,将前一个命令的输出作为后一个命令的输入参数。
一个重要的问题是,哪些命令可以在管道右侧接受管道输出,且输出会作为哪一个参数被接受。此处可以通过help COMMAND-NAME -Full
命令来获取相应信息。help COMMAND-NAME -Parameter *
也有相似的效果。
> help write -full
# 以下内容是输出
名称
Write-Output
语法
Write-Output [-InputObject] <psobject[]> [<CommonParameters>]
参数
-InputObject <psobject[]>
是否必需? True
位置? 0
是否接受管道输入? True (ByValue, FromRemainingArguments)
参数集名称 (所有)
别名 无
动态? false
-NoEnumerate
是否必需? False
位置? 已命名
是否接受管道输入? False
参数集名称 (所有)
别名 无
动态? false
代码示例中可以看到,“参数”部分“是否接受管道输入?”项标识了某个参数是否可以接受管道输入,以及接受管道输入的方式。其中:
此外,也可以用括号方式进行 cmdlet 的嵌套,括号内的命令会优先执行,并作为括号外的命令的参数。
标准命令较长,不易输入,为了简化命令,兼容旧版 cmd 命令,并提供 Linux 风格命令扩展,PowerShell提供了别名机制,可以在命令行中输入Get-Alias
查看。常用的别名有:
别名 | 标准命令 | 别名 | 标准命令 |
---|---|---|---|
% | ForEach-Object | ?/where | Where-Object |
cat/gc/type | Get-Content | cd/sl | Set-Location |
clear/cls | Clear-Host | curl | Invoke-WebRequest |
compare/diff | Compare-Object | dir/ls | Get-ChildItem |
echo/write | Write-Output | man/help | Get-Help |
md | mkdir | del/rm/rmdir | Remove-Item |
move/mv/mi | Move-Item | copy/cp/cpi | Copy-Item |
ps | Get-Process | sort | Sort-Object |
ft | Format-Table | fl | Format-List |
可以用Set-Alias
设置别名,一般建议在配置文件中设置别名。
PowerShell 一个巨大的变化在于,绝大多数 cmdlet 的返回值是一个.NET Framework 对象,而不是单纯的字符串。这样有利于对结果进行筛选、计算、排序等进一步处理。
事实上,字符串在 PowerShell 中也是以对象形式存在的。
对象拥有属性(Property)和方法(Method)两类成员。获取特定属性或者调用特定方法的方式与一般面向对象的编程语言一致,通过.
和()
来实现。
# 结束名字为“cmd”的进程
> (Get-Process| Where name -like "cmd").Kill()
# 获取字符串长度
> "123456".length
6
属性(Property)又可以细分为以下几类:
可以用New-Object
命令创建新的对象。
> $no = New-Object psobject
> $no | Get-Member
TypeName:System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
也可以用以下语法快速创建对象
# 普通对象
$obj = [pscustomobject]@{
Name = 'Doris'
Age = '20'
}
# 日期对象
$date = [Datetime]"1970-1-1" # 1970年1月1日 0:00:00
$date = "1970-1-1" -as [Datetime] # 1970年1月1日 0:00:00
$date = [Datetime]"1970-1-1 19:21:5" # 1970年1月1日 19:21:05
可以用Add-Member
命令给对象增加成员。如果 PowerShell 预定义的属性中没有我们需要的值,需要通过计算得到,或者需要给某个属性改名、更改数据类型以适配管道需要,我们可以自定义一个属性。详见下方示例代码。
查看
可以将对象传输给Get-Member
命令来查看其类型、具有的属性和方法。对象的属性有很多,默认打印在输出流中的属性不一定全。可以将返回值传输给Select-Object
命令并指定-Property
等参数来查看该类对象的其他属性。如果返回值中包含多个对象,可以用Where-Object
进行筛选
Get-Service |
Where-Object CanPauseAndContinue -eq $true |
Select-Object -Property *
在展示时增加属性
如果 PowerShell 预定义的属性中没有我们需要展示的值,需要通过计算得到,或者需要给某个属性改名以适配管道需要,我们可以自定义一个属性。
基本语法是@{name="自定义属性的名称"; expression={自定义属性的计算方法}}
,其中,自定义属性的名称是一个字符串,计算方法是一个表达式或者值,表达式中可以用$_
来枚举引用对象自身。详见下方示例代码。
格式化展示
标准输出流会将对象以格式化形式展示,其中
Format-Table
来手动将输出格式改为表格。Select-Object
使用列表方式展示数据,会将对象属性按行输出,多个对象通过空行分隔。也可以用Format-List
来手动将输出格式改为列表。Format-Wide
会将所有数据项名称平铺排列。Format-Custom
是自定义显示格式,比较复杂,很少用到。详见下方示例代码。
示例代码
> $no = Get-Service -Name w32time
> $no | Add-Member -MemberType NoteProperty -Name noteP -Value 1234 # 此处会将1234的值理解为int
> $no | Add-Member -MemberType AliasProperty -Name strNoteP -Value noteP -secondValue string # noteP的别名,但是字符串
> $no | Add-Member -MemberType ScriptProperty -Name scriptP -Value {$this.name} # 脚本中用$this引用自身
> $no | select name, noteP, @{name="noteP+1";expression={$_.noteP+1}},
strNoteP, @{name="strNoteP+1";expression={$_.strNoteP+1}}, scriptP |
Format-Table
Name noteP noteP+1 strNoteP strNoteP+1 scriptP
---- ----- ------- -------- ---------- -------
w32time 1234 1235 1234 12341 w32time
排序
将输出传输给Sort-Object
可以对其进行排序。默认是对名称进行顺序排列,可以通过-Property
参数选择排序的属性,通过-desc
来倒序排序。
> Get-ChildItem|sort -Property LastWriteTime -Desc
统计
Measure-Object
是 PowerShell 提供的一个统计工具,可以统计输出内容中某个属性的计数、总和、平均数、最大值、最小值等。-Character
可以让这个工具统计文档中的字符数量、行数等。
> Get-ChildItem|measure -Property Length -sum -max -min -Average
分组
Group-Object
可以将对象进行分组统计。
> Get-ChildItem|group -Property mode
PowerShell 脚本文件是以.ps1作为扩展名的文本文件,可以实现PowerShell命令的批量运行。
执行权限
如果出现不允许执行 PowerShell 脚本的情况,可以用管理员权限打开 PowerShell 命令行,并输入
set-ExecutionPolicy RemoteSigned
并在跳出来的选项中选“全是”即可。
如果要关闭运行权限,则输入
set-ExecutionPolicy Default
脚本参数
PowerShell 脚本文件可以带参数,参数存储在变量$args
中。$args
是一个字符串集合。
if ($args.count -eq 0) {
echo "No Argument"
} else {
foreach($a in $args) {
echo $a
}
}
配置文件
PowerShell 的配置文件路径存储在 $PROFILE
变量中,是一个 PowerShell 脚本文件。
评论区