PowerShell 技能连载 - 补零
您是否曾需要将数字转换为以零开头的字符串,例如生成服务器名?只需要使用 PowerShell 的 -f
操作符:
1 | $id = 12 |
以下是输出结果:
1 | server0012 |
-f
操作符左边是文本模板,右边是数值。在文本模板中,用 {x}
作为右侧数值的占位符。占位符的下标从 0 开始。
要在左侧补零,使用 d
(digit 的缩写)加上您需要的数字位数即可。
您是否曾需要将数字转换为以零开头的字符串,例如生成服务器名?只需要使用 PowerShell 的 -f
操作符:
1 | $id = 12 |
以下是输出结果:
1 | server0012 |
-f
操作符左边是文本模板,右边是数值。在文本模板中,用 {x}
作为右侧数值的占位符。占位符的下标从 0 开始。
要在左侧补零,使用 d
(digit 的缩写)加上您需要的数字位数即可。
PowerShell 代码中所有的错误信息都包含在错误记录对象中。请看以下的函数,它可以从这样的错误记录中解析所有相关的错误信息:
1 | function Get-ErrorInfo |
这个函数使得错误处理代码更短更容易理解。如果您需要立即处理一个错误,请使用 try/catch
概念,并且确保使用 -ErrorAction
通知 cmdlet 当发生错误时立即停止:
1 | try |
如果您希望代码完成,并且在过后检查发生了哪些错误,请使用 -ErrorAction SilentlyContinue
以及 -ErrorVariable
。同时,Get-ErrorInfo
函数有很大帮助:
1 | $result = Get-ChildItem -Path C:\Windows -Filter *.ps1 -Recurse -ErrorAction SilentlyContinue -ErrorVariable myErrors |
Get-CimInstance
是一个用来获取 WMI 信息的有用的 cmdlet,因为它使用标准的 .NET DateTime 对象,而不是奇怪的 WMI datetime 格式。然而,Get-CimInstance
使用 WinRM 来进行远程访问,而传统的 Get-WmiObject
使用 DCOM 来进行远程访问。
非常古老的系统可能还没有配置为使用 WinRM 远程处理,并且可能仍然需要 DCOM。以下是演示如何使用 Get-CimInstance
和 DOM 来查询非常古老的机器的示例代码:
1 | # change computer name to a valid remote system that you |
WMI 可以告诉您系统是什么时候启动的,还可以利用这个信息计算启动以来经历的时间:
1 | $bootTime = Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object -ExpandProperty LastBootupTime |
请注意当使用 -ComputerName
访问远程系统时,Get-CimInstance
默认使用 WinRM 远程处理。旧的系统可能没有启用 WinRM 远程处理,而仍然使用 DCOM 技术。
以下是一个短小但是十分有用的函数,能够从其它 cmdlet 接收数据并发送到 Excel:
1 | function Out-Excel |
只需要将任何数据通过管道输出至 Out-Excel
。例如:
1 | PS C:\> Get-Process | Out-Excel |
Get-EventLog
可以访问传统的 Windows 事件日志写入的内容。可以在一个名为 ReplacementStrings
的属性中找到最有价值的信息。以下是一个使该信息可视化并且可以利用它来生成报告的方法。
在这个例子中,将获取 Windows Update 客户端写入的 ID 为 44 的事件,并且这段代码输出替换的字符串。它们将精确地告知我们何时下载了哪些更新:
1 | Get-EventLog -LogName System -InstanceId 44 -Source Microsoft-Windows-WindowsUpdateClient | |
始终确保查询一个唯一的事件 ID:对于每个事件 ID,ReplacementStrings 中的信息是唯一的,您一定不希望将不同的事件 ID 类型中的信息混在一起。
有些时候,您会被奇怪的数据格式难住,例如在 log 文件中,它无法自动转换为 DateTime
对象。以下是一个快速的解析此类日期时间信息的方法:
1 | $weirdDate = '03 12 --- 1988' |
如您所见,ParseExact()
用标准的 .NET 日期和时间字符,如您所愿处理自定义日期和时间格式。以下是大小写敏感的:
yy,yyyy: Year
M, MM, MMM, MMMM: Month
d,dd,ddd,dddd: Day
H, HH: Hour (24hr clock)
h,hh: Hour (12hr clock)
m,mm: Minute
s,ss: Second
在前一个技能中我们解释了如何使用 ActiveDirectory
模块和它的 cmdlet 来查找组织中的所有域控制器,或执行任何其它 LDAP 查询。
以下使用纯 .NET 方法实现相同目的。它不需要任何其它 PowerShell 模块,而且不需要事先安装 RSAT 工具。它需要您的电脑是 Active Directory 中的一个成员。
1 | $ldapFilter = "(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))" |
这行代码返回搜索结果对象。如果您确实想查看真实的 AD 对象,请试一试:
1 | $searcher.FindAll() | ForEach-Object { $_.GetDirectoryEntry() } |
如果您安装了免费的 Microsoft RSAT tools,那么您就拥有了 ActiveDirectory 模块。以下是一个查找组织中所有域控制器的简单方法:
1 | #requires -Module ActiveDirectory |
基本上,您可以运行任意的 LDAP 过滤器查询。只需要选择合适的 cmdlet,例如 Get-ADComputer
、Get-ADUser
或最通用的 Get-ADObject
。
微软正在提供关于不同主题,无限量的免费电子书。电子书可以通过 PowerShell 来下载。
https://blogs.msdn.microsoft.com/mssmallbiz/2017/07/11/largest-free-microsoft-ebook-giveaway-im-giving-away-millions-of-free-microsoft-ebooks-again-including-windows-10-office-365-office-2016-power-bi-azure-windows-8-1-office-2013-sharepo/
以下是下载这些电子书的 PowerShell 代码:
当您运行这个脚本之前,请确保创建了 c:\book
目录。这是电子书的下载目录。不过,这个脚本还不够智能,如果该目录不存在的话需要手动创建这个目录。