当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 欢迎使用实用 PowerShell

作者:精品下载站 日期:2024-12-14 04:12:55 浏览:13 分类:玩电脑

欢迎使用实用 PowerShell


帮助您改进 PowerShell 脚本的系列

许多实用 365 文章和来自其他网站的帖子都包含 PowerShell 代码片段以及解释如何解决特定问题的信息。为了简洁和提高可读性,许多元素通常从代码中省略,例如连接性和可能的错误处理。这些代码片段不是完整的脚本;管理员必须获取代码并对其进行自定义,以满足他们在交互式脚本或 Azure 自动化 Runbook 中的需求。

管理员和顾问经常询问 Practical 365 如何通过将已发布的代码片段合并和增强到他们的工作中来提高 PowerShell 熟练程度。事实上,管理员常常被期望成为比他们想象的更多的开发人员。通常,他们知道如何应用俏皮话并可以阅读脚本,但在自己创作一些东西时可能会遇到困难。通常,会提出支持他们需求的相关问题,例如如何通过更优雅地处理错误而不是简单地说“我们遇到了问题”来使基本代码片段更具弹性。有时,问题更加面向任务,例如如何合并日志记录。

虽然 GitHub Copilot 在更改脚本时可能会有所帮助,但它仍然需要人工验证 Copilot 生成的代码。为此,人类需要具备某些技能。这是每月 PowerShell 脚本系列的第一部分,旨在帮助兼职 PowerShell 开发人员。我们希望读者具备一些 PowerShell 知识,并能够轻松加载和使用 Microsoft 365 PowerShell 模块。我们从一些基本的讨论点开始,例如功能和流程控制。最后,我们将讨论如何将片段合并到独立的脚本中。

目标是通过实际例子帮助目标受众提高技能。实用是关键词。我对代码布局或哪种风格更好的理论或美学讨论不感兴趣。我把这个争论留给 PowerShell 社区,他们经常可以就为什么方法 X 更好进行半宗教性的讨论。我希望代码和示例易于阅读和理解。此外,PowerShell 不关心的布局和样式首选项通常由社区或组织决定。通常使用 PascalCase(PowerShell 的典型)和 Kernighan & Ritchie 缩进样式。我不能保证其他 Practical365 作者会遵循我的指导。

最后,在发布代码时,最好扩展别名,包括 ForEach-Object (%) 和Where-Object (?) 的简写。拼写 cmdlet 可提高可读性。当使用命令行或起草一些代码时,这不是一个问题,但如果您希望人们阅读和理解您的代码,那么这一点就至关重要。

单行话与脚本

我可能会想到关于定义台词和脚本之间区别的问题。单行是一组连续的命令,它们捆绑在一起以形成使用管道的操作流。管理员通常使用单行命令来执行频率较低或临时的任务,其中命令是从 OneNote 或包含针对环境定制的特定命令的文本文件复制的。

然而,PowerShell 一行代码可能由多个“物理行”组成,而一些两行或三行的较小“脚本”通常更像是扩展的一行代码,具有更高的可读性。对于嵌套命令尤其如此,如以下示例所示:

Get-Mailbox | ForEach-Object { $_.EmailAddresses | ForEach-Object { Write-host $_ } }

相对

$Mailboxes= Get-ExoMailbox
ForEach( $Mailbox in $Mailboxes) {
 ForEach( $Email in $Mailbox.EmailAddresses) {
 Write-host $Email
 }
}

在评论开始之前:是的,最后一个示例可以用多种方式编写,是的,可以使用 Select-Object -ExpandProperty,是的,这效率和性能较低,但这不是这里的重点。关键是这两个命令执行相同的任务,但根据定义,只有第一个命令是单行命令。理论上,使用管道可能会带来性能优势,因为它可以并行处理通过管道发送的对象。我说理论上是因为,例如,排序对象需要收集所有输入才能发挥其魔力。

第二个例子在可读性方面更好,但它也使用变量来存储对象。将数据放入变量可以启用其他选项,例如对对象执行其他操作(例如设置值)的能力。但随后代码已经开始看起来更加脚本化,而不是单行代码。

在我看来,一切都取决于代码的预期用途。此外,由于您可以在 PowerShell 中使用分号分隔 cmdlet,因此您可以举办自己的 PowerShell 模糊代码竞赛,例如国际模糊 C 代码竞赛。虽然这种技术可能很值得炫耀,但该代码是否可读且可维护?没那么多。

朋友不要让朋友使用反引号

之前我提到过一行可以由多行组成,这就是反引号可能发挥作用的地方。 PowerShell 的一行语句可能会变得很长。为了提高可读性,您可能需要将同一行或 cmdlet 中的语句打断,并将它们放在多行中。此外,反引号可用于添加手动换行符以提高可读性,而不是在参数破折号后立即插入自动换行符,如下例所示:

Set-Mailbox -Identity [email protected] – MessageCopyForSentAsEnabled $True

反引号 (`) 是行继续符,允许您使用多行编写命令。然而,社区的共识是反引号对于可读性来说很糟糕。根据具体情况,使用哈希表进行展开等技术可能更合适,如下例所示:

反引号

Set-CalendarProcessing -Identity Ohio.Conference `
-AllRequestInPolicy $True -AllBookinPolicy $False `
-BookInPolicy 'Conference Organizers'

泼溅

$CPSettings= @{
 Identity= 'Ohio.Conference'
 AllRequestInPolicy= $True
 AllBookinPolicy= $False
 BookInPolicy= 'Conference Organizers'
}
Set-CalendarProcessing @CPSetting

快速浏览一下第二个示例就可以看出为什么它比单行版本更美观且更易于维护。当您向命令添加更多参数时,这一点变得更加明显。

一个小小的好处是,splatting 无需在处理时检查参数是开关还是(布尔)值。例如,在以下示例中, IncludeActiveMailbox 是一个开关:

Get-Mailbox -RecipientTypeDetails UserMailbox –IncludeInactiveMailbox

IncludeInactiveMailbox 的存在与否决定了 Get-Mailbox 应获取的内容;不需要以通常的方式传递值。因此,这是行不通的:

Get-Mailbox -RecipientTypeDetails UserMailbox -IncludeInactiveMailbox $True

对于参数有一个技巧:使用冒号赋值。这也适用于交换机。通过指定 -Confirm:$False 关闭 cmdlet 的确认提示时,您可能已经使用了此选项:

Get-Mailbox -RecipientTypeDetails UserMailbox -IncludeInactiveMailbox:$True

在splatting中,你不必担心开关:

$filter= @{
 RecipientTypeDetails='UserMailbox'
 IncludeInactiveMailbox=$True
}
Get-Mailbox @filter

如果您不需要更改命令,反引号就可以,但是一旦您需要更改一两个参数,splatting 就会使代码更易于维护。不使用反引号还可以防止误读,因为表明一行是前一行的延续的唯一指示符是在末尾,这很容易被错过。请注意,如果您将展开示例粘贴到 PowerShell 命令窗口中,您会注意到它将在下一行等待更多输入。这是因为哈希表({)的开场赞誉。命令输入将在您发送结束致谢后完成。同样的原则也适用于其他括号和引号。 PowerShell 会检测您何时输入不完整的内容,例如缺少结束引号。除非操作员使用 ctrl-break 取消输入,否则它将显示继续提示并等待其他输入,直到输入完成。

总结我们的开始

我希望本系列能够帮助人们通过使用和理解命令来更多地了解 PowerShell,以便您可以创建自己的带有附加功能的脚本。请随时与我联系并在评论中告诉我您在使用 PowerShell 时遇到的困难。如果没有,请等待下一篇文章,我将在其中讨论函数和参数化。

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯