本文基于 PowerShell 3.0 发布
Windows是一个面向API的操作系统

Getting started with PowerShell

一个脚本的平均寿命始于提示符,终结于字符

Cmd + C# + .net = PowerShell

cmdlets construction : Verb + Noun

分号; 可以使多条命令并行输出

Help System in PowerShell

我们并不可能去牢记所有的命令,这不仅仅是存在的cmdlets太多的问题,除非真的可以记住它们(?。。。)
作为一名啃文档症重度患者,查看一件事物的帮助手册是一个很好的解决方案!
以下指令用以获取PowerShell cmdlets的官方文档.
 语法:

1
Get-Help [[-Name] <string>]  [<CommonParameters>]

The Parameter parameter displays only the descriptions of the specified parameters. If you specify only the asterisk (*) wildcard character, it displays the descriptions of all parameters. When Parameter specifies a parameter name such as GroupBy, information about that parameter is shown.

当使用星号(*)通配符时,若为其指定参数名,ps将列出所有与它相关的 cmdlets:

e.g.

1
2
3
4
5
Get-Help *service*
# 它将列出前后包含 service 的相关 cmdlets

Get-Help g*service*
# 将列出以 g 开头并包含 service 的相关 cmdlets

如果想列出某 cmdlet 的完整文档:

1
2
3
4
Get-Help [cmdlet] -Detailed
# Display more information for a cmdlet
Get-Help [cmdlet] -full
# full 的文档与 detailed 相似,更完整的内容对学习'管道'很有帮助

对于一个cmdlet,使用 -example 参数将显示所有官方给出相关实例。

为了防止工作流混乱,可以使用-showwindow 属性显示一个单独的帮助窗口来查看帮助文档。

关于帮助文档中的语法结构 , 这里有一个概念 位置参数 , 即在参数列表中已经固定位置,不需要再输入形参名来指定参数,直接输入传递参数即可,如以下代码示例:

1
2
3
4
5
get-service -name bits
# 这条指令可以简化为
get-service bits
&& 利用别名那就更短了
gsv bits

嘛,其实我还是更习惯在ms官网看这些文档,不过ps确实提供了一条捷径来获取这一帮助,更利于查找所需命令的文档,以下命令可以快速转到线上文档

1
2
3
4
 get-help cmdlet -online
# -online 参数将跳转到在线帮助文档

# 我永远喜欢巨硬.jpg

Usage of pipeline

Powershell 中的重要的概念 – 管道 , ….简单的说,一组命令中,输出的命令结果将作为下一个命令的参数执行,
e.g.

1
2
get-service | export-csv -path F:\services.csv
# 这组命令将 获取所有服务 并 将其导出到 F盘 services.csv文件中

将获取的数据导出到本地:

1
2
3
4
5
gal | ConvertTo-Html | Out-File f:\Alias.html
# 这组命令将导出所有的别名及其所有属性到 Alias.html 文件中

gal | ConvertTo-Html -Property resolvedCommandname,displayname| Out-File f:\Alias.html
# 这组命令将导出 存在resolvedCommandname,displayname属性的别名 到 F:\Alias.html 中
✏️ ———— 手动分割线 ——————
另外 ,.在使用管道进行命令组测试时,有时候我们并不清楚这条命令组将会带来的效应。 比如输入以下命令组
1
2
3
get-service | stop-service
# 你不会想执行这一命令组的。。!它将关闭所有的的服务.这可能会导致各种问题 , 但 powershell 可不会告诉你这条命令安不安全
(嗯。。 powershell 的 “自雷式”编程)

所以使用类似这样的命令组之前,可以使用 -whatif 来测试,看看命令组究竟会进行哪些操作。
还可以使用 -confirm , 不过此参数是告诉 某指令会怎么做(即指令目标target)你是否要这样做 , 注意ps不会为你做出任何选择


Pipeline flow control cmdlet “Where-Object “

Docs Microsoft Docs "Where-Object(Microsoft.PowerShell.Core)"

alias: ? ; where

?Where-Object的别名,它还有另一个别名where , 主要用于过滤列表项或输出结果

Objects for PowerShell

先来看一组命令:

1
ps | ? -Property handles -gt 900 | sort handles

这组命令通过列出所有进程 并给到后面的管道处理 -> 从属性handles中筛选出大于900的 -> 以handles进行排序

这里能够使用属性,因为我们从get-process (ps)中得到的并不只是文本,实际是获取了一组对象,对象拥有属性和方法(老相识了)

可以使用Get-Member(gm) 查看有哪些属性或方法是可用的

使用Select-Object(select)来选择查看哪些属性

1
2
gal | select Definition,Name
# 查看definition 和 name 属性 , 即查看cmdlets 和 alias

💡 Terminal Solutions

此标题内容下将记录一些使用终端程序时发现的解决方案。

于 Windows Terminal 中使用 系统环境变量

Refer ISSUE #7239 "Environment changes are only picked up upon full restart"
✏️ ———— 手动分割线 ——————

在添加完环境变量后使用Windows Terminal 时,使用cd(Set-Location)无法即时进入目录或打开程序,解决方案即将 Windows Terminal 重启即可,访问设置的环境变量目录:

1
Set-Location -Path $env:SystemRoot

此问题已在 #7239 添加issue-Bug标签,Merged issue 来自 #7243

若是VSCode 或是 VS 中的终端,与上同理

[New] 关于Windows Terminal 中的权限提升

Refer ISSUE #632 "Configuring Windows Terminal profile to always launch elevated"

[Obsoleted] 由于在一个未使用管理员模式的窗口中使用了一个拥有管理员权限的命令行…使应用程序存在安全漏洞,开发团队正在寻找一个安全的解决方案。

已经可以以管理员权限启动WT.

在体验Windows 11 期间 , 我发现Windows Terminal V2.0已经集成到 Windows 11 且成为默认终端.. Win + x 可见”Windows Terminal (Administrator)”

Docs Windows Terminal | Microsoft Docs "Windows Terminal Overview"

💡 几个小特性

  • 若一个新的终端标签以权限提升启动,则其他存在的标签将转换为同等权限启动.
  • 可以使用批处理文件来初始化终端的配置文件
  • Windows 终端预览版 v1.12.2922.0开始,可以使用 firstWindowPreference全局设置关闭终端会话时保存窗口窗格布局

使用 PowerShell 添加永久的环境变量

更改完毕后重启Windows Terminal 即可生效

基于.NET 5 Environment类中的 SetEnvironmentVariable方法

1
2
3
### Modify a system environment variable ###
[Environment]::SetEnvironmentVariable
("Path", $env:Path, [System.EnvironmentVariableTarget]::Machine)

SetEnvironmentVariable(String, String, EnvironmentVariableTarget) - 重载 -

创建、修改或删除当前进程中或者为当前用户或本地计算机保留的 Windows 操作系统注册表项中存储的环境变量。

1
public static void SetEnvironmentVariable (string variable, string? value, EnvironmentVariableTarget target);
variable String 环境变量名。
value String 要分配给variable的值
target EnvironmentVariableTarget 一个用于指定环境变量的位置的枚举值。
Docs Microsoft Docs "Environment.SetEnvironmentVariable 方法 (System)"

🎁 Instances IN Practices

Get process ID though port which was occupied

1
Get-NetTCPConnection -LocalPort 443 | ft LocalPort,OwningProcess
Docs Microsoft Docs "Get-NetTCPConnection(NetTCPIP)"

以上命令将获取占用443端口PID

通过pipeline传递给ft,将所选属性的结果以表格形式输出

ft => Format-Table