PowerShell 技能连载 - 探索文件夹结构(第 1 部分)
这是一个快速示例,说明了如何发现文件夹结构。本示例采用任何根文件夹路径,并递归遍历其子文件夹。
对于每个子文件夹,将返回一个新的自定义对象,其中包含文件和子文件夹计数以及相对的子文件夹路径:
1 | # specify the folder that you want to discover |
这是一个快速示例,说明了如何发现文件夹结构。本示例采用任何根文件夹路径,并递归遍历其子文件夹。
对于每个子文件夹,将返回一个新的自定义对象,其中包含文件和子文件夹计数以及相对的子文件夹路径:
1 | # specify the folder that you want to discover |
在 Windows上,默认情况下,许多 cmdlet 使用BOM (Byte Order Mask) 编码对文本文件进行编码。 BOM 会在文本文件的开头写入一些额外的字节,以标记用于写入文件的编码。
不幸的是,BOM 编码在 Windows 世界之外并未得到很好的采用。如今,当您在 Windows 系统上保存文本文件并将其上传到 GitHub 时,BOM 编码可能会损坏文件或使其完全不可读。
以下是一段可用于确保以与 Linux 兼容的方式,在不使用 BOM 的情况下保存文本文件:
1 | $outpath = "$env:temp\nobom.txt" |
如果您需要访问使用自签名测试证书或已过期或不可信的证书的 HTTPS 网站,PowerShell 将拒绝连接。在大多数情况下,这是正确的选择,但有时您知道目标服务器是安全的。
这是一段通过重写证书策略来信任所有 HTTPS 证书的 PowerShell 代码。新的证书策略始终返回 $true
并完全信任任何证书:
1 | class TrustAll : System.Net.ICertificatePolicy |
现在仍然有许多旧文件格式(.doc 而不是 .docx)的 Microsoft Office 文档。
这是一个简单的 PowerShell 函数,它将旧的 .doc Word 文档转换为 .docx 格式并保存。如果未锁定旧的 Word 文档,则此过程是完全不可见的,并且可以在无人值守的情况下运行:
1 | function Convert-Doc2Docx |
使用文本文件时,务必始终使用相同的文本编码进行读取和写入,否则特殊字符可能会损坏,或者文本文件可能变得不可读,这一点很重要。
在 PowerShell 7 中,除非您指定其他编码,否则所有 cmdlet 以及重定向操作符都将使用默认的 UTF8 文本编码。那挺好的。
在W indows PowerShell 中,不同的 cmdlet 使用不同的默认编码。所以,要为所有 cmdlet 和重定向操作符建立通用的默认默认编码,您应该为带有参数 -Encoding
的任何命令设置默认参数值。
将以下行放入您的配置文件脚本中:
1 | $PSDefaultParameterValues.Add('*:Encoding', 'UTF8') |
此外,在 Windows PowerShell 中,无论 cmdlet 是否具有参数 -Encoding
,都指定一个唯一的值。当前推荐的编码为UTF8。
如果在编辑 PowerShell 脚本时 VSCode 不会启动 PowerShell 引擎,而状态栏中的黄色消息“正在启动 PowerShell”不会消失,则可能的解决方法是使用全新独立的可移植 PowerShell 7 安装作为 VSCode 中的默认 PowerShell 引擎。
首先,运行以下这行代码以创建 Install-PowerShell
cmdlet :
1 | Invoke-RestMethod -Uri https://aka.ms/install-powershell.ps1 | New-Item -Path function: -Name Install-PowerShell | Out-Null |
接下来,在本地文件夹中安装 PowerShell 7 的新副本,例如:
1 | Install-PowerShell -Destination c:\portablePowerShell |
安装完成后,请确保可以手动启动新的 PowerShell 实例:
1 | c:\portablePowerShell\pwsh |
现在,继续告诉 VSCode,您要在编辑 PowerShell 脚本时使用此新的 PowerShell 实例运行:在 VSCode 中,选择“文件/首选项/设置”,单击设置左栏中的“扩展”,然后单击子菜单中的“PowerShell 配置”。
接下来,搜索设置“PowerShell 默认版本”,然后输入任何名称,即“portable PowerShell 7”。在上面的“PowerShell Additional Exe Paths”部分中,单击链接“Edit in settings.json”。这将以 JSON 格式打开原始设置文件。
其中,新设置部分已经插入,需要像这样完成:
1 | "powershell.powerShellAdditionalExePaths": [ |
注意:所有标记和关键字均区分大小写,并且在路径中,反斜杠需要由另一个反斜杠转义。在 “exePath” 中,在下载的可移植 PowerShell 文件夹中指定 pwsh.exe
文件的路径。确保路径不仅指向文件夹,而且指向 pwsh.exe
。
在 “versionName” 中,使用之前在 “PowerShell Default Version” 中指定的相同标签名称。
保存 JSON 文件后,重新启动 VSCode。该编辑器现在使用您的 portable PowerShell 7,并且在许多情况下,这解决了 PowerShell 启动卡住的问题。
如果您想手动将其他 PowerShell 版本添加到 VSCode,则上面的方法也很有用。当您单击 VSCode 状态栏中的绿色 PowerShell 版本时,任何手动添加的 PowerShell 将出现在选择对话框中(除非已被使用,在这种情况下,该菜单将显示 PowerShell 类型和版本,而不是您的标签名称)。
有时,VSCode 在尝试启动 PowerShell 引擎时停止,或者报告诸如 “Language Server Startup failed” 之类的错误。
如果您遇到后一种异常,则可能与企业中的安全设置有关。要解决此问题,请在 PowerShell 控制台中运行以下行(这是一长行代码):
1 | Import-Module $HOME\.vscode\extensions\ms-vscode.powershell*\modules\PowerShellEditorServices\PowerShellEditorServices.psd1 |
如果您没有得到提示,那么这不是造成问题的原因。如果确实收到提示要求确认导入此模块的提示,则只需允许运行“来自不受信任的发布者的软件”。该确认仅需要一次,因此下次 VSCode 尝试使用此模块启动 PowerShell 引擎时,很可能会解决您的问题。
Get-Command
可以帮助您查找给定任务的 PowerShell 命令,但是此 cmdlet 只能搜索命令名称和参数中的关键字。
可以从 PowerShell Gallery 中安装更复杂的搜索命令:
1 | Install-Module -Name PSCommandDiscovery -Scope CurrentUser -Verbose |
Find-PowerShellCommand
使用关键字并返回与此关键字相关的所有命令。它在命令名称,命令参数以及返回的对象属性中搜索关键字。如果找到的命令类型是已编译的应用程序,则该命令还将返回命令的类型(GUI 或基于控制台的命令)。
1 | PS> Find-PowerShellCommand -Keyword user -CommandType Function,Cmdlet,Application |
“MatchType
“ 属性报告匹配的种类。可以根据命令名称,参数名称或返回对象的任何属性名称中的关键字匹配找到命令。
有关其他示例,源代码和所有参数的说明,请参见 https://github.com/TobiasPSP/PsCommandDiscovery。
使用 Install-Module
,您可以轻松地从 PowerShell Gallery (www.powershellgallery.com) 下载和安装其他 PowerShell 模块。但是,在 Windows 系统上,此命令可能会中断。许多 Windows 系统仍随附 1.x 版本,并且 PowerShell Gallery 已切换到 Internet 协议 TLS 1.2,较早的 Windows 版本不会自动支持该协议。
要解决 Install-Module 的问题,您应确保 PowerShell 可以使用 TLS 1.2 来访问 PowerShell Gallery:
1 | [System.Net.ServicePointManager]::SecurityProtocol = |
接下来,您应该像这样手动重新安装 PowerShellGet 和 Packagemanagement 模块的当前版本(不需要管理员权限):
1 | Install-Module -Name PowerShellGet -Scope CurrentUser -Force -AllowClobber |
这应该能为大多数用户解决问题。
如果根本无法使用 Install-Module
,则可以手动将 PowerShellGet 和 Packagemanagement 的模块文件夹从更新的 Windows 版本复制到另一个版本。运行以下行以查找可以在何处找到最新版本的 PowerShellGet:
1 | Get-Module -Name powershellget -ListAvailable | Sort-Object -Property Version -Descending | Select-Object -First 1 |
最新版本是 2.2.5,并且您不应使用低于 2.x 的版本。如果您的 PowerShell 报告系统上同时存在版本 1.x 和 2.x,则一切正常。PowerShell始终会自动选择最新版本。
Out-GridView
是最常用的 cmdlet 之一,它会打开一个通用选择对话框。不幸的是,PowerShell 只能在 Windows 操作系统上显示图形元素,例如窗口。在 Linux 和 macOS 上,图形 cmdlet(例如 Out-GridView
)不可用。
您可能想尝试使用新的基于文本的 Out-ConsoleGridView
。此 cmdlet 仅适用于PowerShell 7(在Windows PowerShell中不起作用)。像这样安装它:
1 | Install-Module -Name Microsoft.PowerShell.ConsoleGuiTools -Scope CurrentUser |
安装完成后,在许多情况下,您现在可以轻松地将 Out-GridView
替换为 Out-ConsoleGridView
,并享受类似于旧版 Norton Commander 的基于文本的选择对话框。这是旧版 Windows PowerShell 脚本,无法在 Linux 上使用:
1 | Get-Process | |
只需将 Out-GridView
替换为 Out-ConsoleGridView
,便一切就绪。