我们通过一个实际任务,讲述如何在 Powershell 创建自定义命令。

现在回看,在没有 LLM 的时代,写脚本之流的低级劳动实在痛苦。

功能

生成如下目录结构,添加目录至 VSCode 工作区,并打开生成的 Markdown 文件。

1
2
3
$Disk:.
└─$name$name.md
└─imgpasted

希望命令提供如下可选参数

1
2
3
-name     : .md 文件/目录名称
-savepath : 保存路径(相对路径)

编写脚本

新建 .ps1 文件,输入如下内容

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
# 指定命令行参数,并提供默认值
#
# name : 默认为时间戳
# savepath : 默认为统一存放 markdown 的文件夹

param(
[Parameter()]
[String]$name = "$(Get-Date -Format 'yyyy-mm-dd-hh-mm-ss')",
[String]$savepath = "$([Environment]::GetFolderPath("Desktop"))\mdfiles\"
)

$exist = $False

# 获取 $savepath 下所有内容的名称并沿管道传送
# 遍历检查是否重名,打印错误信息并将 $exist 设为真
# 注意大括号不能分行写

Get-ChildItem -Path $savepath -Name | Foreach-Object -Process {
if ([String]$_ -eq $name)
{
Write-Host "[$(Get-Date)]makemd: Error: $savepath$name already existed.`n" -ForegroundColor red
$exist = $True
}
}

# 未发现重命名则创建文件、文件夹
# code -a <dir> : 将文件夹添加至 VSCode 工作区
# code <file> : 打开文件至编辑区
# 打印提示信息

if ($exist -eq $False)
{
mkdir "$savepath$name", "$savepath$name\imgpasted"
new-item "$savepath$name\$name.md" -type file
code -a "$savepath$name"
code "$savepath$name\$name.md"
Write-Host "[$(Get-Date)]makemd: $savepath$name created successfully.`n" -ForegroundColor green
}

保存后打开终端,可以脚本方式运行。

创建 PowerShell 命令

假定命令名为:Makemd,为保持 PowerShell 命令风格,首字母大写。

查看 PowerShell 命令的搜索路径

1
echo "$env:PSModulePath"

将脚本放在位于 Program Files 的 Powershell Modules 路径下,笔者这里为 C:\Program Files\WindowsPowerShell\Modules,并修改 .ps1 文件,对脚本进行包装

1
2
3
4
function Makemd
{
# 这里放脚本内容
}

在上一步的路径(Modules)下新建文件夹 Makemd,在其内放置修改后的脚本,并重命名为 Makemd.psm1。

命名注意事项

  • 目录/文件对应关系:包含新模块的文件夹内至少含一个同名文件,如这里的 Makemd/Makemd.psm1
  • 文件/函数对应关系:函数可与文件不同名,一个 .psm1 文件可包含多个函数

我们可以执行没有包装为 function 的原始脚本试一下。查询模块

1
2
# Get-Command 会执行 Import-Module Makemd,查询 + 导入
Get-Command -Module Makemd # 文件夹

这里可以成功打印提示信息,可知,脚本按默认参数执行了一次。然而如果以 Makemd 命令的方式调用,则提示命令无法找到

1
Makemd: 无法将“Makemd”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。

因此,必须将脚本包装为函数。执行 Remove-Module Makemd,然后重新导入模块,打印如下信息

1
2
3
CommandType Name         Version Source
----------- ---- ------- ------
Function Get-OldFiles 0.0 Makemd

可以看到,函数成功导入。这时就可以在终端里使用命令了。

每次更新 .psm1 文件后,都需要移除模块并重新导入。

正常情况下,使用该命令的时候是无需导入该模块的,相比脚本也不需要写路径,十分方便。

附 | PowerShell 常用命令

System.ConsoleColor

1
Black, DarkBlue, DarkGreen, DarkCyan, DarkRed, DarkMagenta, DarkYellow, Gray, DarkGray, Blue, Green, Cyan, Red, Magenta, Yellow, White

编辑配置文件

1
notepad $PROFILE

References

  1. VSCode命令行常用快捷操作
  2. PowerShell获取时间格式
  3. 在 Windows PowerShell 中获取命令行参数
  4. PowerShell脚本输出颜色文字
  5. Powershell如何查询目录所有文件和文件夹的名称
  6. 在 PowerShell 中比较两个字符串对象的内容
  7. 自定义供日常使用的PowerShell脚本模块
  8. 用windows Powershell 创建新文件夹或文件
  9. 如何在Windows PowerShell中获取当前的用户名
  10. 获取Windows某路径的环境变量
  11. PowerShell列出某个文件夹内的所有文件和文件夹