最近更新于 2024-05-08 15:20
环境
Windows 11 专业工作站版 22H2
PowerShell 7.3.3
注意
大小写区分
Windows 不区分大小写,但是在 Linux 下会区分,所以如果涉及到读写文件同时要求跨平台时就要注意这个问题,当然变量命名这些是 PS 内部的操作就不区分大小写
跨平台
PowerShell 不仅限于 Windows,在多个平台都有支持,比如 macOS、Linux(Ubuntu、Debian、树莓派系统…)等等,只是和 Windows 是同一家,所以 Windows 是预装的,有代替命令提示符(CMD)的趋势
安装 PowerShell 可参考:https://learn.microsoft.com/zh-cn/powershell/scripting/install/installing-powershell
脚本执行策略
Windows 下 PowerShell 可能默认状态是禁止运行脚本文件的
修改参考:https://blog.iyatt.com/?p=10735
### Shebang 行
在 Windows 下执行 .ps1 扩展名的文件会自动使用 PowerShell 作为解释器,但是如果在 Linux 系统下就需要写 Shebang 行来指定解释器,即在首行写上
```bash
#!/usr/bin/env pwsh
因为以 # 开头,在 Windows 下的时候就直接当做注释忽略了,在 Linux 下就会根据 Shebang 行内容去寻找对应的解释器执行,pwsh 就是 PowerShell 解释器(版本 7 及以上才是 pwsh,否则就是 powershell)
注释
单行
# 输出一句话
Write-Output 你好,世界!
多行
<# 这里是
被注释
的内容 #>
Write-Output 你好,世界!
清屏
在 CMD 中清屏是使用的 cls 命令,PS 也支持,另外 PS 中还可以使用 clear 命令或者按 Ctrl+L,这一点和 Linux 终端一样了。
不过实际上,PS 中不管 cls 还是 clear,它们其实都是给 Clear-Host 命令起的别名,所以也可以直接用这个命令
字符串
注意单引号和双引号
字符串格式化
(仅使用 -f 时可以使用单引号)
转义字符
(必须使用双引号)
转义字符与一般使用反斜杠 \ 不同,PS 使用反单引号 \` ,数字 1 键的左边
双引号字符串中显示引号
单引号字符串显示引号
对象方法
部分举例
字符串分割
结尾判断
包含判断
比较
查找
插入
替换
输入输出
-
Write-Output:如果有接触过批处理,一个对 echo 比较熟悉,而 echo 就是 Write-Output 的别名。用于将指定的 对象写入管道。 如果 Write-Output 是管道中的最后一个命令,则对象将显示在控制台中。
-
Write-Host:将自定义的输出写入主机。
-
Read-Host:从控制台读取一行输入。
管道和重定向
直接执行 Get-ChildItem,显示的是指定路径下的文件的多项信息,看列标
这里我要匹配 Name 列,并将内容写到一个文件中
Get-ChildItem D: | Format-Table Name > D:\fileNames.txt
“Get-ChildItem D:” 获取到 D: 路径下文件信息后通过管道传给 “Format-Table Name” 筛选出 Name 列内容,如果没有后面的指令,结果会直接在控制台显示,但是这里使用了一个重定向,将其定向到一个文件,那么它就会把本来要显示的内容保存到这个文件里
\> 代表的就是创建或者覆盖写入,而 >> 则是创建或追加写入
Write-Output 你好,附加一行 >> D:\fileNames.txt
两条命令执行以后,查看文件内容
数学运算
这个就没啥说的了,反正可以当计算器用
自增自减
自增
$a = 1
++$a
Write-Output $a
$a++
Write-Output $a
$a = 1
$b = $a++ # 返回自增前的值
Write-Output $a $b
$a = 1
$b = ++$a # 返回自增后的值
Write-Output $a $b
自减
$a = 5
--$a
Write-Output $a
$a--
Write-Output $a
Path 环境变量
在 PS 中执行的各种命令,说到底它们都是一个个程序。在执行命令的时候,PS 会去指定的路径查看是否存在这个程序文件,存在就执行,不存在时则报错:
而这个查看的路径就是 Path 变量中保存的路径
或许可能会想为啥要这个 Path 变量,为什么不让 PS 自己去挨着找。那么请先试试打开文件资源管理器,在 C 盘中搜索一个文件名,你看看会花多少时间。有时候还需要一些自定义的,不一定在 C 盘,那就是所有盘都得搜一遍。那么放在 PS 执行上,每敲一个命令都得等一会。那不如直接指定路径,而且系统的命令也集中在那几个路径,更高效率。
需要自定义 Path 变量的,有些是软件安装的时候,可以勾选自动添加,比如 Python
还有些,可能安装程序没有提供自动添加,又或者是绿色版无安装的软件,比如 FFmpeg,第三方提供的 Windows 编译版,就是几个可执行程序,程序文件位置随便你自己放,然后设置 Path 变量,写入你程序文件放置的绝对路径。
设置方法的话,打开控制面板->系统和安全->系统,点击左侧高级系统设置
点到高级-环境变量
上面是 xxx 的用户变量,就是当前登录的账号对应的变量,下面的系统变量就是对所有用户有效,如果设置了,你电脑上的其它用户账号也会生效(如果是多用户的话),一般系统的环境变量就设置在下面,用户自定义的设置上面的就行
要修改的话,双击 Path
上面说的是永久生效的修改方式,如果是临时修改的话,直接修改 $env:Path 变量,这个修改只对当前的 PS 窗口有效,换一个就没有用了。可以这样理解,当你打开一个 PS 窗口时,PS 会去 Path 设置文件中读取其中保存的变量值,并存到 $env:Path 中,另外打开一个 PS 窗口,它也是这样操作,相当于每个 PS 窗口有个自己的 $env:Path 。所以要永久有效,就得去设置修改,只是修改 $env:Path ,修改的也是自己的,关闭了这个 PS 窗口它也就消失了。
而 Path 变量设置的规则,路径要用绝对路径,即从盘符开始,每个路径以英文分号结束。假如我要临时新添加一个环境变量 D:\Program Files\ffmpeg\,可以执行一下
$env:Path = $env:Path + 'D:\Program Files\ffmpeg\;'
别名
前面说清屏的时候,我就说 cls 和 clear 都是 Clear-Host 的别名。这个可以使用 Get-Alias 命令查看
如果要设置别名的话(临时当前窗口有效),可以使用 Set-Alias
这里我为 clear 取别名为 aaa,而 clear 指向 Clear-Host,最终 aaa 就指向 Clear-Host
删除别名使用 del、rm 或 Remove-Item 都可以(前两个是最后一个的别名)
变量
自定义变量
自己根据需要创建变量,变量名前面需要添加美元符号 $。变量仅在当前控制台窗口运行中有效
查看当前控制台中使用的变量
ls Variable:
查看前面创建的变量
删除变量
自动化变量
自动化变量在 PS 打开时就会创建,比如
$? 是上一个程序执行的状态,如果有过 C/C++ 编程经历的可以这样理解,main 函数里结束时返回 0,$? 就是 True,如果返回非 0 值,$? 就是 False。可以用于判断上一个命令是否成功执行
$HOME 家目录
$PID 当前 PS 窗口的进程标识符
这里就列举几个例子,实际还有很多
环境变量
前面说到的 Path 变量就是环境变量的一种,查看环境变量
ls env:
只在当前窗口修改环境变量就操作 $env:XXXX=$env:XXXX + 'xxxxxxxxxx' 进行追加,或则对 $env:XXXX 赋值
要永久生效,可以去设置修改,或者使用
# 获取旧的用户 Path 环境变量
$oldPath = [System.Environment]::GetEnvironmentVariable('Path', 'User')
## 拼接新的 Path,后面字符串内容根据自己实际需要添加
$newPath = $oldPath + 'D:\abcd\1234\;'
## 设置新的用户 Path 变量
[System.Environment]::SetEnvironmentVariable('Path', $newPath, 'User')
执行后可以在设置可以看到已经添加了
然后再设置回原来的
[System.Environment]::SetEnvironmentVariable('Path', $oldPath, 'User')
修改 Path 环境变量建议按我上面的流程来,Path 中不止一个值,修改的话要在原来的尾巴追加,别直接修改了,到时候把其它的环境变量值清掉了就很糟心了。
即使是只有一个值的变量也建议先获取旧值,备份一下,避免有问题时恢复原样
命令行传参
如果通过命令行执行脚本文件,想要传入参数,那么在脚本内可以使用 $args 获取参数内容
# PowerShell
Write-Output ("参数个数:{0}" -f $args.Length)
Write-Output $args[0]
Write-Output $args[1]
Write-Output $args[2]
foreach ($arg in $args)
{
Write-Output $arg
}
条件
运算符
比较运算符
-
等于 -eq
-
不等于 -ne
-
大于 -gt
-
-ge 大于等于
-
-lt 小于
-
-le 小于等于
-
-like 通配符匹配,? 匹配单个字符, * 匹配任意个字符(不区分大小写,区分用 -clike。一般不区分加 i,区分加 c,下同)
反过来不匹配就是 -notlike,一般取反向的加 not,下同
-
-match 正则表达式(不区分大小写)
-
-is 属于类型
集合运算符
-
-contains 包含(不区分大小写)
-
-in(不区分大小写)
逻辑运算符
-
和 -and
-
或 -or
-
异或 -xor
-
逆 -not 或者英文感叹号 !
位运算符
- -band 二进制和
- -bor 二进制或
- -bxor 二进制异或
- -bnot 二进制非
- -shl 左移
- -shr 右移
if 条件判断
$a = 5
if ($a -eq 3)
{
Write-Output '等于 3'
}
elseif ($a -gt 3)
{
Write-Output '大于 3'
}
else
{
Write-Output '小于 3'
}
switch 条件判断
$abcdefghijklmn = 3
switch ($abcdefghijklmn)
{
{$_ -gt 3}
{
Write-Output '大于 3'
break
}
3
{
Write-Output '等于 3'
break
}
default
{
Write-Output '小于 3'
break
}
}
循环结构
foreach
foreach ($file in dir 'D:\Program Files')
{
Write-Output $file
}
while
$counter = 5
while ($counter -gt 0)
{
Write-Output $counter
--$counter
}
$counter = 0
while ($true)
{
++$counter
if ($counter % 2 -ne 0)
{
continue
}
Write-Output $counter
if ($counter -eq 16)
{
break
}
}
do-while
$counter = 5
do
{
Write-Output $counter
--$counter
}
while ($counter -gt 0)
for
$sum = 0
for ($i = 0; $i -lt 100; ++$i)
{
$sum += $i
}
Write-Output $sum
switch
$array = 1..10
switch ($array)
{
{$_ % 2 -eq 0}
{
Write-Host $_ 是偶数
}
default
{
Write-Host $_ 是奇数
}
}
数组
$a = 'a'..'k'
for ($i = 0; $i -lt $a.Count; ++$i)
{
Write-Output $a[$i]
}
$a = 'a'..'k'
foreach ($i in $a)
{
Write-Output $i
}
自定义函数
function add($num1, $num2)
{
return $num1 + $num2
}
$result = add 3 5
Write-Output $result
function createArray($num1, $num2, $num3, $num4)
{
return $num1,$num2,$num3,$num4
}
$result = createArray "b" 5 "abc" 87
Write-Output $result