PowerShell 本身是基于 .Net 开发出来的,所以在 .Net 中的基本数据类型,在 PowerShell 中也可以使用,只是在 PowerShell 中用 [] 来标识具体的数据类型。比如 [int]、[bool]、[string] 等
PowerShell 中使用 -is
来判断某个变量是否是指定的数据类型
# 定义一个名为 a 的整型变量
$a = 10
# 可以在定义变量时指定数据类型
[double]$b = 1.0
# 结果为 True
$a -is [int]
# 结果为 False
$a -is [double]
# 下面语句会输出变量 b 的类型为 Double 类型
Write-Host "b'Type is $($b.GetType())"
# 输出
# b'Type is double
PowerShell 的默认数据类型转换会以第一个变量的类型为目标类型,后面所有运算的变量类型都会被转换为第一个类型
$a = 1
$b = "2"
$a + $b
# 此时返回的结果为 3,因为当前运算第一个变量 a ,其类型为 int,后面的所有变量都会转换为 int 类型
$b + $a
# 此时返回的结果为 21, 因为当前运算第一个变量 b ,其类型为 string,后面的所有变量都会转换为 string 类型
$a = 1
$b = "2"
# 方法一
[int]$b + $a
# 方法二
($b -as [int]) + $a
要定义一个集合,我们需要使用 @(对象1,对象2,对象3...)
的格式
例子:
# 定义一个名为 a 的集合
$a = @('a', 'b', 'c') # 等同于 $a = 'a','b','c'
# 如果需要定义空集合,就必须写为
$b = @()
$a = @()
$a += 'a'
$a += 'b'
Write-Host $a
# 输出:
# a b
移除元素需要使用Where查询(简写为?)找出要保留的元素,然后将保留的元素集合重新赋值给变量
$a = @('a', 'b', 'c')
# 移除c
# -ne 表示不等于
# ? {$_ -ne 'c'} 表示不等于 'c' 的放入集合 a 中
$a = $a | ? {$_ -ne 'c'}
Write-Host $a
# 输出:
# a b
要定义一个字典,我们需要使用 @{key1=value1;key2=value2;...}
的格式
例子:
# 定义一个名为 a 的字典
$a = @{'a'=10; 'b'=23; 'c'=15} # 等同于 $a = @{a=10; b=23; c=15}
# 如果需要定义空字典,就必须写为
$b = @{}
$a = @{}
$a.Add("a", "aaa")
注意
字典的 key 是不允许重复的,如果已经存在相同的值,添加时就会报错
可以再添加前先判断key是否存在,代码如下
if (-not $a.ContainsKey("a"))
{
$a.Add("a", "aaa")
}
$a = @{"a"="aaa"; "b"="bbb"}
$a.Remove("a")
$a = @{"a"="aaa"; "b"="bbb"}
$a["a"]
#上面的方法与下面的方法相同
$a.a
$a.GetEnumerator() | Sort-Object Name
注意:
直接对字典惊醒排序是无效的,需要先调用 GetEnumerator() 方法
可以通过 New-Object
创建一个对象。
下面我们会创建一个 Human 对象,他有姓名、性别、年龄三个属性,以及一个 SayHello 的方法
$human = New-Object object
可以使用 Add-Memeber
来增加属性,不过其 -MemberType
需要设置成 NoteProperty
Add-Member -InputObject $human -Name Name -Value "xiaoming" -MemberType NoteProperty
Add-Member -InputObject $human -Name Sex -Value "Man" -MemberType NoteProperty
Add-Member -InputObject $human -Name Age -Value 18 -MemberType NoteProperty
# 等同于
# $human | Add-Member NoteProperty Name "xiaoming"
可以使用 Add-Memeber
来增加方法,不过其 -MemberType
需要设置成 ScriptMethod
Add-Member -InputObject $human -Name SayHello -Value {"Hello!"} -MemberType ScriptMethod
# 等同于
# $human | Add-Member ScriptMethod SayHello {"Hello!"}
# 调用对象属性
$human.Name
$human.Sex
$human.Age
# 调用对象方法
$human.SayHello()
# 下面方法也能成功执行,但是它不会执行 SayHello 函数,而是返回方法的基本信息
$human.SayHello
运算符 | 含义 |
---|---|
+ | 加法操作 |
- | 减法操作 |
* | 乘法操作 |
/ | 除法操作 |
% | 取余操作 |
运算符 | 含义 |
---|---|
-[i|c]eq | 等于 |
-[i|c]ne | 不等于 |
-[i|c]gt | 大于 |
-[i|c]ge | 大于等于 |
-[i|c]lt | 小于 |
-[i|c]le | 小于等于 |
其中方括号中的前缀是可选的,i 表示大小写不敏感,c 表示大小写敏感, 默认为 i
"a" -eq "A"
# 输出
# True
"a" -ceq "A"
# 输出
# False
如果表达式左边是集合,那么 PowerShell 会将左边数组中的元素逐个与右边元素进行比较,最终返回符合条件的元素集合
12, 3, 21, 14, 9 -gt 10
# 与下面使用 where 语句等同
# 12, 3, 21, 14, 9 | ? {$_ -gt 10}
# 输出
12
21
14
运算符 | 含义 |
---|---|
-contains | 包含 |
-notcontains | 不包含 |
12, 3, 21, 14, 9 -contains 3
# 输出
# True
12, 3, 21, 14, 9 -contains 4
# 输出
# False
12, 3, 21, 14, 9 -notcontains 4
# 输出
# True
运算符 | 含义 |
---|---|
-like | 匹配 |
-notlike | 不匹配 |
-match | 匹配 |
-notmatch | 不匹配 |
-like 和 -notlike 使用字符+通配符 *
进行匹配
-match 和 -notmatch 使用正则表达式
进行匹配
"Hello world" -like "llo"
# 输出
# False
"Hello world" -like "*llo"
# 输出
# False
"Hello world" -like "*llo*"
# 输出
# True
"Hello world" -notlike "*llo"
# 输出
# True
"Hello world" -notlike "*llo*"
# 输出
# False
"Hello world" -match "^[a-zA-Z]+\sworld$"
# 输出
# True
"Hello world" -match "^[a-zA-Z]+world$"
# 输出
# False
"Hello world" -notmatch "^[a-zA-Z]+\sworld$"
# 输出
# False
运算符 | 含义 |
---|---|
-is | 是 |
-isnot | 不是 |
1 -is [int]
# 输出
# True
1 -isnot [int]
# 输出
# False
运算符 | 含义 |
---|---|
-not | 非,也可以使用! |
-and | 与 |
-or | 或 |
-xor | 异或 |
-not $True
# 输出
# False
!$True
# 输出
# False
$True -and $False
# 输出
# False
$True -and $True
# 输出
# True
$True -or $True
# 输出
# True
$True -or $False
# 输出
# True
$False -or $False
# 输出
# False
$False -xor $False
# 输出
# False
$True -xor $False
# 输出
# True
集合/字典/... | Where-Object/? {判断语句}
1,2,3,4,5 | ? {$_ -lt 3}
# 输出
# 1
# 2
# 下面例子用来获取已经停止的服务
Get-Service | Where-Object {$_.Status -eq "Stopped"}
# 等同于下面
Get-Service | Where-Object Status -eq "Stopped"
Get-Service | where Status -eq "Stopped"
Get-Service | ? Status -eq "Stopped"
if ()
{}
[elseif ()
{}]
[else
{}]
if ($a -gt 2) {
Write-Host "The value $a is greater than 2."
}
elseif ($a -eq 2) {
Write-Host "The value $a is equal to 2."
}
else {
Write-Host ("The value $a is less than 2 or" +
" was not created or initialized.")
}
PowerShell 7.0 引入了三元运算符
? <if-true> : <if-false>
$message = (3 -ge 1) ? "3" : "1"
注意
如果报错,可以通过 $psversiontable 查看 powershell 版本
Switch (<test-expression>)
{
{}
{}
}
switch (3)
{
1 {"It is one."}
2 {"It is two."}
3 {"It is three."}
4 {"It is four."}
}
# 输出
# It is three.
switch (4, 2)
{
1 {"It is one." }
2 {"It is two." }
3 {"It is three." }
4 {"It is four." }
3 {"Three again."}
}
# 输出
# It is four.
# It is two.
switch (4, 2)
{
1 {"It is one."; Break}
2 {"It is two." ; Break }
3 {"It is three." ; Break }
4 {"It is four." ; Break }
3 {"Three again."}
}
# 输出
# It is four.
For (;;) {}
For($i = 1; $i -lt 5;$i++) {Write-Host $i }
# 输出
# 1
# 2
# 3
# 4
集合/字典/... | ForEach-Object -Process {执行语句}
# 等同于
集合/字典/... | ForEach-Object {执行语句}
集合/字典/... | Foreach {执行语句}
30000, 56798, 12432 | ForEach-Object -Process {$_/1024}
# 输出
# 29.296875
# 55.466796875
# 12.140625
do {} while ()
while () {}
$i = 1
do {$i += 1;Write-Host $i } while ($i -lt 5)
# 输出
# 2
# 3
# 4
# 5
$i = 1
while ($i -lt 5){
$i += 1
Write-Host $i
}
# 输出
# 2
# 3
# 4
# 5
注意
如果想要跳过当次循环,可以使用
continue
,如果想要终结当前循环,可以使用break
Function 函数名(参数) {
语句
}
其中函数可以通过 $args
来确认接收的参数
# 定义函数
function SayHello {
if ($args.Count -eq 0){"No argument"}
else{
$args | foreach{$_}
}
}
# 调用函数
SayHello
# 输出
# No argument
SayHello xiaoming
# 输出
# xiaoming
# 定义函数
function SayHello($name) {
return "Hello " + $name
}
# 调用函数
SayHello -name xiaoming
# 输出
# Hello xiaoming
# 定义参数带默认值的函数
function SayHello($name="xiaowang") {
return "Hello " + $name
}
# 调用函数
SayHello -name xiaoming
# 输出
# Hello xiaoming
SayHello
# 输出
# Hello xiaowang
PowerShell(命令行) | 描述 |
---|---|
Get-ChildItem | 获取一个或多个指定位置中的项和子项。 |
Get-Clipboard | 获取剪贴板的内容。 |
Get-ComputerInfo | 获取系统和操作系统属性的合并对象。 |
Get-Content | 获取位于指定位置的项的内容。 |
Get-Item | 获取位于指定位置的项。 |
Get-ItemProperty | 获取指定项的属性。 |
Get-Location | 获取有关当前工作位置或某个位置堆栈的信息。 |
Get-Process | 获取在本地计算机上运行的进程。 |
Get-Service | 获取计算机上的服务。 |
Get-TimeZone | 获取当前时区或可用时区的列表。 |
Get-Command | 列出可用的命令。 |
Get-Help | 在控制台上打印命令的文档。 |
Set-Clipboard | 设置剪贴板的内容。 |
Set-Content | 写入新内容或替换文件中的现有内容。 |
Set-Item | 将项的值更改为命令中指定的值。 |
Set-ItemProperty | 创建或更改某一项的属性值。 |
Set-Location | 将当前工作位置设置为指定的位置。 |
Set-Service | 启动、停止和挂起服务并更改服务的属性。 |
Set-TimeZone | 将系统时区设置为指定的时区。 |
Clear-Host | 清除屏幕。 |
Copy-Item | 将文件和文件夹复制到另一个位置。 |
Move-Item | 将文件和文件夹移动到新位置。 |
Remove-Item | 删除文件或文件夹。 |
Rename-Item | 重命名单个文件,文件夹,硬链接或符号链接。 |
Write-Output | 获取一个或多个指定位置中的项和子项。 |
Stop-Process | 获取一个或多个指定位置中的项和子项。 |
Invoke-WebRequest | 获取网上的网页内容。 |
可以直接通过编辑器创建一个后缀为 ps1 的文件,然后就可以开始编写脚本了
可以通过控制台将要执行的脚本语句重定向给一个脚本文件
'Hello PowerShell' > MyScript.ps1
# 稍微较长的脚本可以使用下面的方法
@'
Hello
PowerShell
'@ > MyScript.ps1
脚本能否执行取决于 PowerShell 的执行策略(只有管理员才能修改执行策略),PowerShell 一般都会禁止脚本执行。
要查看 PowerShell 的执行策略,可以通过 Get-ExecutionPolicy 命令查看
策略 | 描述 |
---|---|
Unrestricted | 未签名的脚本可以运行 |
Restricted/Default | 不允许任何脚本执行 |
RemoteSigned | 本地脚本无限制,但是对来自网络的脚本必须经过签名 |
AllSigned | 要求所有脚本和配置文件都由受信任的发布者签名,包括在本地计算机上编写的脚本 |
Bypass | 不阻止任何操作,并且没有任何警告或提示 |
要更改 PowerShell 的执行策略,可以通过 Set-ExecutionPolicy 命令查看
# 管理员权限运行下
Set-ExecutionPolicy Bypass
如果修改为正确的执行策略后,直接输入脚本名称即可运行
# 运行脚本
.\MyScript.ps1 "Hello"
此时就可以通过 $args 来获取到传入的参数 Hello
param($Name,$Age)
"Name=$Name"
"Age=$Age"
.\MyScript.ps1 -Name xiaoming -Age 18
# 等同于
.\MyScript.ps1 -Age 18 -Name xiaoming
.\MyScript.ps1 xiaoming 18
# 输出
# Name=xiaoming
# Age=18
也可以给参数绑定类型等其他信息
param(
[string]$Name=$(throw "Parameter missing: -Name Name"),
[int]$Age=$(throw "Parameter missing: -Age x as number")
)
"Name=$Name"
"Age=$Age"
.\MyScript.ps1 xiaoming 18
# 输出
# Name=xiaoming
# Age=18
# 下面会报错
.\MyScript.ps1 xiaoming
# 输出
# Parameter missing: -Age x as number
# 下面会报错,因为类型做了限制了
.\MyScript.ps1 18 xiaoming
如果想了解更多 PowerShell 的知识,可以参考 PowerShell命令与脚本(1)——PowerShell的认识,这个博主我觉得写的比我还好。
更多详细知识,请参考微软官网-什么是 PowerShell?