PowerShell 技能连载 - 解析 Windows 产品密钥(第 2 部分)
在上一个技能中,我们解释了如何向 WMI 请求 Windows 的部分产品密钥。如果您丢失了原始产品密钥,可以通过以下方法恢复完整密钥:
1 | function Get-WindowsProductKey{ |
PowerShell 技能连载 - 解析 Windows 产品密钥(第 2 部分)
在上一个技能中,我们解释了如何向 WMI 请求 Windows 的部分产品密钥。如果您丢失了原始产品密钥,可以通过以下方法恢复完整密钥:
1 | function Get-WindowsProductKey{ |
PowerShell 技能连载 - 解析 Windows 产品密钥(第 1 部分)
有很多脚本示例,甚至还有密钥恢复工具,它们都承诺会返回完整的产品密钥,但是在许多情况下,返回的密钥不是 Windows 产品密钥。
当您使用密钥恢复工具时,通常会丢失产品密钥,因此没有简单的方法来检查密钥恢复脚本或工具返回的承诺密钥是否正确。
幸运的是,WMI 至少可以返回“部分”产品密钥。这样,您可以验证恢复的密钥是否是有效的。
SoftwareLicensingProduct WMI 类返回有关大多数 Microsoft 产品的许可状态的详细信息。下面的此行获取所有以 “Windows” 开头且许可证状态为非 0 的 Microsoft 产品的所有许可信息:
1 | PS> Get-CimInstance -ClassName SoftwareLicensingProduct -Filter 'Name LIKE "Windows%" AND LicenseStatus>0' |
不幸的是,此调用需要很长时间才能完成。为了加快速度,请告诉 WMI 您要做什么,以便该调用不会计算您不需要的大量信息。下面的调用仅从所需实例中读取 PartialProductKey 属性,并且速度更快:
1 | PS> Get-CimInstance -Query 'Select PartialProductKey From SoftwareLicensingProduct Where Name LIKE "Windows%" AND LicenseStatus>0' | Select-Object -ExpandProperty PartialProductKey |
通过读取适当的注册表值,PowerShell 可以轻松检索重要的操作系统详细信息,例如内部版本号和版本:
1 | # read operating system info |
不过,其中一些值使用加密格式。例如,InstallTime 注册表项只是一个非常大的整数。
1 | PS> $key = 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion' |
事实证明,这些是时间 tick 值,通过使用 [DateTime]类型及其 FromFileTime() 静态方法,您可以轻松地将时间 tick 值转换为有意义的安装日期:
1 | PS> $key = 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion' |
您可以在遇到时间 tick 值时使用 FromFileTime()。例如,Active Directory 也以这种格式存储日期。
当您运行 Get-Credential 或提示您输入用户名和密码时,Windows PowerShell (powershell.exe) 始终会打开一个单独的凭据对话框。而新的 PowerShell 7 (pwsh.exe) 则在控制台内提示:
1 | PS> Get-Credential |
如果您更喜欢控制台提示而不是打开单独的对话框,则可以切换 Windows PowerShell 的默认行为。您需要管理员特权才能更改注册表设置:
1 | $key = "HKLM:\SOFTWARE\Microsoft\PowerShell\1\ShellIds" |
若要恢复默认行为,请将值更改为 $false,或通过 Remove-ItemProperty 删除注册表值。
PowerShell 技能连载 - 在 PowerShell Gallery 搜索新模块
官方的 PowerShell Gallery 是一个公共仓库,其中包含数千个免费的 PowerShell 模块。无需重新设计轮子,而是完全可以浏览 gallery 以查找可重用的代码,这些代码可按原样使用或用作自己项目的起点。让我们看一下如何从 PowerShell 库中发现和下载 PowerShell 代码。
您可以在 https://powershellgallery.com 上使用其图形前端来搜索代码,但是 Find-Module cmdlet 是一种更好,更强大的方法。如果您正在寻找通过 PowerShell 管理 Office 365 的方法,可以通过下面这行代码获取包含 “Office” 关键字的所有模块:
1 | Name CompanyName PublishedDate Description |
该列表包括发布者和模块描述,并按从新到旧的顺序对模块进行排序。PublishedDate 列指示模块是否是最近刚添加到 gallery中,这样您可以立即查看它是否维护良好并且值得一看。
如果您发现某个特定模块有趣,请获取其所有元数据:
1 | PS> Find-Module -Name Office365PowershellUtils -Repository PSGallery | Select-Object -Property * |
如果您只对源代码感兴趣,请使用 Save-Module 并将模块下载到您选择的文件夹中:
1 | # path to source code |
如果您想按原样实际使用该模块,请改用 Install-Module:
1 | PS> Install-Module -Name Office365PowershellUtils -Scope CurrentUser -Repository PSGallery |
PowerShell 技能连载 - 管理 SharePoint Online
如果您使用 SharePoint Online,并希望通过 PowerShell 对其进行管理,请从 PowerShell Gallery 中下载并安装 Microsoft.Online.SharePoint.PowerShell 模块:
1 | # search for the module in PowerShell Gallery (optional) |
现在,您可以使用大量新的 PowerShell cmdlet 来管理 SharePoint Online:
1 | PS> Get-Command -Module Microsoft.Online.SharePoint.PowerShell | Format-Wide -Column 3 |
第一步总是从 Connect-SPOService 开始,连接到SharePoint Online:
1 | Get-Help -Name Connect-SPOService -ShowWindow |
接下来,使用查找动词为 Get 的 cmdlet这将安全地提供大量信息,但不会更改任何设置,也不会损坏任何东西:
1 | PS> Get-Command -Verb Get -Module Microsoft.Online.SharePoint.PowerShell | Format-Wide -Column 3 |
当您适应了以后,可以接着查看更改和管理 SharePoint 的其余 cmdlet:
1 | PS> Get-Command -Module Microsoft.Online.SharePoint.PowerShell | Group-Object Verb -NoElement | Sort-Object Count -Desc |
PowerShell 技能连载 - 检测泄露的密码(第 2 部分)
当您想向 PowerShell 函数提交敏感信息时,通常使用 SecureString 类型。这种类型可确保用户通过一个带遮罩的对话框输入数据,这样能保护输入内容免受不会被旁人看到。
由于 SecureString 始终可以由创建 SecureString 的人解密为纯文本,因此您可以利用带的输入框,但仍可以使用输入的纯文本:
1 | function Test-Password |
当您运行代码然后运行 Test-Password 时,系统会提示您带有遮罩的输入。在函数内部,会将提交的 SecureString 解密为纯文本。
但是,这种方法有一个明显的缺点:如果希望通过参数传入信息,则现在必须提交 SecureString。您不能再传入纯文本:
1 | # fails: |
不过,使用自定义属性,您可以为任何参数添加自动功能,以将纯文本自动转换为 SecureString:
1 | # create a transform attribute that transforms plain text to a SecureString |
现在,用户可以在不使用参数的情况下运行 Test-Password,并获得带掩码对话框的提示。用户还可以直接传入纯文本:
1 | # use built-in masked input |
如果您想了解转换属性的工作原理,请查看以下详细信息:https://powershell.one/powershell-internals/attributes/transformation
PowerShell 技能连载 - 检测泄露的密码(第 1 部分)
密码复杂时也不一定是安全的。相反,您需要确保密码没有受到破坏,并且不在默认的攻击者词典中。如果自动攻击经常检查该密码,那么即使是最复杂的密码也不安全。
要确定密码是否被泄露,请使用以下功能:
1 | function Test-Password |
使用起来非常简单:只需将密码传给 Test-Password 函数即可。它返回已知泄露的数量,并且返回大于 0 泄露的任何密码都被认为是不安全的,必须进行更改。
1 | PS> $password = Read-Host -AsSecureString |
密码必须作为 SecureString 提交。您可以不带密码运行 Test-Password,在这种情况下,系统会提示您。或者您需要以 SecureString 形式读取密码。
在该示例中,复杂密码 “P@$$w0rd” 在 4880 次攻击中被泄露,使用起来非常不安全。
Windows 注册表存储已安装的所有软件的名称和详细信息。PowerShell 可以读取该信息,并为您提供完整的软件清单:
1 | # read all child keys (*) from all four locations and do not emit |
如果您想添加更多信息(例如,软件是 32 位还是 64 位),或者要将代码转换为可重用的新 PowerShell 命令,请在此处阅读更多内容:https://powershell.one/code/5.html。
PowerShell 技能连载 - 使 PowerShell 模块保持最新
务必经常检查您的 PowerShell 模块是否为最新。如果您使用的是旧的和过时的模块,则可能会遇到问题,就像平时使用旧的和过时的软件一样。
例如,PowerShellGet 模块提供了诸如 Install-Module 之类的 cmdlet,可让您轻松下载和安装其他 PowerShell 模块,并通过新的命令和功能扩展 PowerShell。
为了了解这一点,下面是一个示例,该示例下载并安装 QRCodeGenerator 模块,该模块会生成各种 QR 代码,例如用于 Twitter 个人资料:
1 | # install new PowerShell module from PowerShell Gallery |
使用智能手机相机扫描创建的 QR 码时,您可以访问 QR 码中编码的 Twitter 个人资料。同样,其他 QR 码类型也可以提供前往某个地点的路线或向您的地址簿添加联系人:
1 | PS> Get-Command -Module QRCodeGenerator -CommandType function |
如果您在新添加的模块上遇到问题,则可能是因为 PowerShellGet 模块已过时。如果您仍在使用古老的 PowerShellGet 版本 1.0.0.1,则可能会遇到讨厌的错误。
当模块仅使用 manifest 文件中的 major 和 minor 版本号时,Install-Module 会将它们安装到具有 3 位数字版本号的子文件夹中。这使已安装的模块不可用。
因此,保持模块最新很重要。PowerShellGet 的最新版本已修复此错误。让我们看一下如何检查和更新模块。
首先,找出您当前使用的模块版本,例如 PowerShellGet:
1 | PS> Get-Module -Name PowerShellGet -ListAvailable |
在此示例中,安装了两个不同版本的 PowerShellGet模块:初始发行版本1.0.0.1和更新版本2.2.1。要找出您使用的版本,请尝试以下操作:
1 | PS> Import-Module -Name PowerShellGet |
接下来,检查是否有可用的较新版本(这要求该模块通过官方 PowerShell 库提供,但并非对所有模块都适用。如果此处未提供您的模块,则需要检查最初提供该模块的实体):
1 | PS> Find-Module -Name PowerShellGet |
如果有较新的版本,请先尝试更新模块:
1 | PS> Update-Module -Name PowerShellGet |
Update-Module 要求该模块最初是通过 Install-Module 安装的。如果是这样,PowerShell 会知道原始源码库并自动更新该模块。
如果 Update-Module 失败,请尝试使用 -Force 参数重新安装该模块。如果仍然失败,请添加 -SkipPublisherCheck 参数:
1 | PS> Install-Module -Name PowerShellGet -Scope CurrentUser -Force -SkipPublisherCheck |
要验证成功,请确保已加载最新版本:
1 | PS> Import-Module -Name PowerShellGet -Force -PassThru |