在搜索指定的 AD 账户时,您可能曾经用过 Get-ADUser 命令,并且用 filter 参数来过滤结果。不过这样的过滤器可能会变得非常复杂。
这就是为什么针对最常见的 AD 搜索有一个快捷方式。只需要用 Search-ADAccount 命令即可:
1 | #requires -Modules ActiveDirectory |
Search-ADAccount 暴露一系列参数来搜索最常见的条件。
在搜索指定的 AD 账户时,您可能曾经用过 Get-ADUser 命令,并且用 filter 参数来过滤结果。不过这样的过滤器可能会变得非常复杂。
这就是为什么针对最常见的 AD 搜索有一个快捷方式。只需要用 Search-ADAccount 命令即可:
1 | #requires -Modules ActiveDirectory |
Search-ADAccount 暴露一系列参数来搜索最常见的条件。
PowerShell 技能连载 - 探索本地账户管理 cmdlet
PowerShell 5.1(随着 Windows 10 和 Server 2016 发布)现在原生支持管理本地账户。在前一个技能中您学习了如何使用 Get-LocalUser 命令。
要探索本地账户管理的其它 cmdlet,以下是如何识别暴露 Get-LocalUser 命令的模块的方法,然后列出该模块的其它 cmdlet:
1 | #requires -Modules Microsoft.PowerShell.LocalAccounts |
最终,列出所有新的管理 cmdlet:
1 | CommandType Name Version Source |
PowerShell 5.1 终于发布了管理本地用户账户的 cmdlet。要获取本地用户账户的列表,请使用 Get-LocalUser 并将结果通过管道传给 Select-Object 命令来查看所有属性:
1 | PS C:\> Get-LocalUser | Select-Object -Property * |
缺省情况下,Get-ADUser(由 ActiveDirectory 模块提供,该模块是免费的 Microsoft RSAT 工具的一部分)只获取一小部分缺省属性。要获取更多信息,请使用 -Properties 参数,并且指定您需要获取的属性。
要获取所有 AD 用户的列表,以及他们的备注和描述字段,请使用这段代码:
#requires -Modules ActiveDirectory
Get-ADUser -Filter * -Properties Description, Info
如果你不知道所有可用属性的名字,请使用“*”代替,来获取所有可用的属性。
PowerShell 技能连载 - 小心 Get-Credential 和 SecureString
有些时候,脚本以交互的方式询问凭据或密码。请时刻注意脚本的作者可以获取所有输入信息的明文。仅当您信任脚本和作者的时候才可以输入敏感信息。
请注意:这并不是一个 PowerShell 问题,这是所有软件的共同问题。
让我们看看一个脚本如何利用输入的密码。如果一个脚本需要完整的凭据,它可以检查凭据对象并解出密码明文:
1 | $credential = Get-Credential |
类似地,当提示您输入密码作为安全字符串时,脚本的作者也能获取到输入的明文:
1 | $password = Read-Host -AsSecureString -Prompt 'Enter Password' |
当 PowerShell 自动加密一个安全字符串时,它使用您的身份作为密钥。只有您可以解密该安全字符串。而如果您想用一个共享的密码来加密一段安全字符串,会怎么样呢?
以下是一个经典的做法,用密码来加密:
1 | # $secretKey MUST be of length 8 or 16 |
该密钥 ($secretKey) 必须是 8 或 16 个字符的文本。任何知道密钥的人都可以解密(这就是为何 secretKey 不应该是脚本的一部分,而下面的脚本下方加入了硬编码的密钥是为了演示解密的过程。最好以交互的方式输入密钥):
1 | # this is the key to your secret |
结果是一个安全字符串,您可以用它来构建一个完整的凭据:
1 | $credential = New-Object -TypeName PSCredential('yourcompany\youruser', $SecureString) |
您也可以再次检查密码明文:
PS C:\Users\tobwe> $credential.GetNetworkCredential().Password
myPassword
请注意安全字符串的所有者(创建它的人)总是可以取回明文形式的密码。这并不是一个安全问题。创建安全字符串的人在过去的时刻已经知道了密码。安全字符串保护第三方的敏感数据,并将它以其他用户无法接触到的形式保存到内存中。
密钥和对称加密算法的问题是您需要分发密钥,而密钥需要被保护,它既可以用来加密也可以用来解密。
在 PowerShell 5 中有一个简单得多的方法:Protect-CMSMessage 和 Unprotect-CMSMessage,它们使用数字证书和非对称加密。通过这种方法,加密安全信息的一方无需知道解密的密钥,反之亦然。加密的一方只需要制定谁(哪个证书)可用来解密保密信息。
在前一个脚本中我们演示了如何以加密的方式将一个凭据保存到磁盘上。一个类似的方法只将密码保存到加密的文件中。这段代码将创建一个加密的密码文件:
1 | # read in the password, and save it encrypted |
它只能由保存的人读取,而且必须在同一台机子上操作。第二个脚本可以用该密码登录其它系统而无需用户交互:
1 | # read in the secret and encrypted password from file |
凭据对象可以用在所有支持 -Credential 参数的 cmdlet 中。
1 | # use the credential with any cmdlet that exposes the –Credential parameter |
对于无人值守的脚本,以硬编码的方式将密码保存在脚本中是不安全且不推荐的。
有一种替代方法是,您可以一次性提示输入密码,然后创建一个凭据对象,然后在您的脚本中需要的地方使用它。这段代码提示输入一个密码,然后创建一个凭据对象:
1 | $password = Read-Host -AsSecureString -Prompt 'Enter Password' |
凭据对象可以用在任何接受 -Credential 参数的 cmdlet 中。
1 | # use the credential with any cmdlet that exposes the –Credential parameter |
对于无人值守运行的脚本,您可以从代码创建登录凭据。这需要将密码以明文的方式存在脚本中(这显然是不安全的,除非您用加密文件系统(EFS)加密您的脚本,或是用其它办法来保护内容):
1 | $password = 'topsecret!' | ConvertTo-SecureString -AsPlainText -Force |
假设您每天都要运行一个需要凭据的脚本。一个使用强壮凭据的安全方法是将它们保存到一个加密的文件中。这段代码提示输入凭据,然后将它们保存到您桌面上的 XML 文件中:
1 | $credential = Get-Credential -UserName train\user02 -Message 'Please provide credentials' |
密码是以您的身份加密的,所以只有您(并且只能在保存凭据的机器上)能存取该凭据。
以下是读取保存的凭据的代码:
1 | $credential = Import-Clixml -Path "$home\desktop\myCredentials.xml" |