PowerShell 技能连载 - 计算第几周(第 1 部分)
计算第几周不是一件很容易的事,并且根据文化不同而不同。以下是一个计算任何日期是第几周的方法:
1 | # calculate day of week |
只需确保您按照当地文化调整了日历的周规则和一周的第一天。
前面的示例使用当前的文化日历。如果您想控制文化,请尝试使用这种方法:
1 | $Date = [DateTime]'2022-12-31' |
在这里,您可以使用 $CultureName 来定义要使用的日历的文化名称。
PowerShell 技能连载 - 计算第几周(第 1 部分)
计算第几周不是一件很容易的事,并且根据文化不同而不同。以下是一个计算任何日期是第几周的方法:
1 | # calculate day of week |
只需确保您按照当地文化调整了日历的周规则和一周的第一天。
前面的示例使用当前的文化日历。如果您想控制文化,请尝试使用这种方法:
1 | $Date = [DateTime]'2022-12-31' |
在这里,您可以使用 $CultureName 来定义要使用的日历的文化名称。
PowerShell 技能连载 - 通过 PowerShell 创建日历电子表格
是否需要计划为您的俱乐部,社区或爱好进行重复的会议吗?当然,有很多在线工具可以帮助您,但如果您想在 Microsoft Excel 中创建日历列表,PowerShell 可以是一个优秀的帮手。
让我们假设您每周三都有一次重复的会议,会议在下午十二点开始,除了每个月的最后一周。
您可以这样使用 PowerShell,而不是将这些日期和时间手动添加到 Excel 表:
1 | # generate calendar for weekly incidents |
此脚本使用了许多有用的技术:
PowerShell 技能连载 - 打开关闭 Windows 的对话框
以下是打开关闭 Windows 对话框的一行代码:
1 | (New-Object -ComObject Shell.Application).ShutdownWindows() |
使用此行代码,它变成了名为 “bye” 的新命令:
1 | function bye { (New-Object -ComObject Shell.Application).ShutdownWindows() } |
如果将此行放在 $profile 中的自动配置文件 (start) 脚本中(可能需要先创建该文件),则完成脚本时,您现在可以简单地输入 “bye” 以关闭您的 Windows 会话。
powershellgallery.com 是找到新的免费 PowerShell 扩展模块的好地方,可以为您的 PowerShell 添加新的 cmdlet。
但是,在 Web 界面中查看所有模块详细信息可能会有点麻烦。这就是为什么通过 RESTful WebService 检索模块信息可能会有所帮助。
这是一个脚本,它传入 PowerShell Gallery 中托管的(任何)模块的名称。然后,它检索所有详细信息(例如版本历史记录、下载计数、更新日期和发行说明),并以一种使信息易于访问的方式准备它们。特别是,将检索到的基于 XML 的信息转换为简单对象:
1 | # replace module name with any module name hosted |
PowerShell 技能连载 - 识别主 PowerShell 模块位置
PowerShell 只是一个脚本引擎。 其所有 cmdlet 来自外部模块,环境变量 $env:PSModulePath 返回 PowerShell 自动扫描模块的文件夹:
1 | PS> $env:PSModulePath -split ';' |
同样,Get-Module 查找位于其中一个文件夹中的所有模块和 cmdlet:
1 | Get-Module -ListAvailable |
当您以专家的身份使用 PowerShell 时,确保所有所需的模块(以及其 cmdlet)都可以使用,将越来越重要。因此,第一步是选择一个好的位置来存储新模块,下一步是良好地部署和更新这些模块。
本地存储模块的最佳位置是代表 “AllUsers” 范围的文件夹。在 Windows 系统上,此文件夹位于 Program Files 中,您需要管理员权限来更改它。
在大型企业中部署和更新模块的最佳方法是使用现有的软件部署基础架构和部署模块及其更新,以及之前识别的 “AllUsers” 文件夹。
该文件夹的路径可能会根据您使用的 PowerShell 版本而异。以下是一个脚本,用于计算所有用户的模块位置的路径:
1 | # determine the primary module location for your PowerShell version |
在 Windows 上,PowerShell 7 和 Windows PowerShell 可以共享一个文件夹,因此如果您不想专门为 PowerShell 7 部署模块,则可以进一步简化脚本:
1 | # determine the primary module location for your PowerShell version |
PowerShell 经常基于 API,您不需要深入正则表达式和文本模式。相反,.NET Framework 中可以使用多种专业的测试方法。困难的是找到并知道它们,而不是运行它们和进行测试。
例如,要测试 URL 是否正确,请尝试:
1 | $url = 'powershell.one' |
结果将是 false ,因为 “powershell.one” 不是一个绝对的 URL。在前面添加 “https://“,结果会变为 true。
PowerShell 技能连载 - 是否在 Windows PowerShell 中运行(第 2 部分)
在上一个技能中,我们介绍了一个向后兼容的单行代码,能够判断您的脚本是否运行在传统的 Windows PowerShell 环境中,还是运行在新的 PowerShell 7 便携版 shell 中。
如果您使用的是跨平台的 PowerShell 7,那么有一个名为 [Management.Automation.platform] 的新类型,能返回更多的平台信息。Windows PowerShell 尚未包含此类型,因此您可以使用此类型来确定您是否当前正在 Windows PowerShell 上运行。如果没有,则该类型提供了额外的平台信息:
1 | # testing whether type exists |
在 Windows PowerShell 上,脚本只会产生警告。 在 PowerShell 7 上,它返回一个哈希表,其中包含所有相关平台信息:
Name Value
---- -----
IsStaSupported True
IsLinux False
IsCoreCLR True
IsWindows True
IsNanoServer False
IsMacOS False
IsWindowsDesktop True
IsIoT False
PowerShell 技能连载 - 是否在 Windows PowerShell 中运行(第 1 部分)
现在的 PowerShell 可以在各种平台上运行,并且在上一个技能中,我们解释了如何查看脚本运行的操作系统。
如果操作系统是 Windows,您仍然不能知道您的脚本是由内置 Windows PowerShell 还是新的便携式 PowerShell 7 运行。
以下是一种安全和向后兼容的方式,可以了解您的脚本是否在 Windows PowerShell 上运行:
1 | $RunOnWPS = !($PSVersionTable.ContainsKey('PSEdition') -and |
现在的 PowerShell 已是跨平台的,因此即使能在 Windows 服务器上正常使用 Windows PowerShell,您的脚本也有可能在不同的操作系统上停止运行。
如果您的脚本想要知道它正在运行的平台,以向后兼容的方式运行,请尝试这些代码:
1 | $RunOnWindows = (-not (Get-Variable -Name IsWindows -ErrorAction Ignore)) -or $IsWindows |
在 Windows 系统上,结果如下所示:
Name Value
---- -----
RunOnLinux False
RunOnMacOS False
RunOnWindows True
您现在可以安全地检查先决条件,并确保您的脚本代码仅在适当的情况下运行。
在前一个技能中,我们解释了如何转义整个字符串序列。如果您只需要转义单个字符,请使用 HexEscape() 如:
1 | PS> [Uri]::HexEscape('a') |
此方法实际上是检索 ASCII 代码并将其转换为十六进制。
实际上,还可以进行相反的操作,您可以将转义的字符转换回正常字符。例如,”a” 的 ASCII 代码为 65,它的十六进制表达是 41。因此,”A” 的转义表示为 “%41”,这行代码将得到 “A”:
1 | PS C:\> [Uri]::HexUnescape('%41',[ref]0) |
(第二个参数表示要转换转义的字符在字符串中的位置)。
有了这个,您现在可以生成一个范围内的字母:首先,生成所需字母的 ASCII 代码,并以十六进制形式手动转换它们。-f 运算符可以执行此转换:
1 | PS> $decimal = 65 |
以下是来自 A 到 Z 的转义字母:
1 | 65..90 | ForEach-Object { '%{0:X}' -f $_ } |
反转义它们的方法:
1 | 65..90 | ForEach-Object { [Uri]::HexUnescape( ('%{0:X}' -f $_), [ref]0) } |
不过,不要爱上这个过度的技巧。类型转换可以让您更轻松实现:
1 | [char[]](65..90) |