介绍 (Introduction)

Do you have processes or scripts that require you to provide a password? Against the desires of your security officer, do you have to save those passwords in plain text, in your scripts? PowerShell offers a way that you can store a password or prompt the user for the information. You can then utilize that information to build what is known as a PSCredential. The majority of commands for PowerShell that support remote connections to servers (WMI, CIM, Invoke-Command, etc.), offer the ability to pass in a credential. While some only need the password, some need the full object to authenticate a user. This object in PowerShell can be made a few different ways based on your needs. I will go over a few options that are commonly used, but first lets discuss what makes up a PSCredential.

是否有要求您提供密码的流程或脚本? 违反安全人员的要求,您是否必须将这些密码以纯文本格式保存在脚本中? PowerShell提供了一种存储密码或提示用户输入信息的方法。 然后,您可以利用该信息来构建所谓的PSCredential。 PowerShell的大多数命令都支持到服务器的远程连接(WMI,CIM,Invoke-Command等),提供了传递凭据的功能。 虽然有些只需要密码,但有些则需要完整的对象来认证用户。 可以根据需要以几种不同的方式将PowerShell中的此对象制成。 我将介绍一些常用的选项,但首先让我们讨论组成PSCredential的内容。

PSC凭证 (PSCredential)

The full type is “System.Management.Automation.PSCredential” object. Commands that utilize a “-Credential” parameter will generally require this type to be passed in. You have a few different ways to go about it based on your needs. Each method generally lines up to two different scenarios: interactive or automated. The PSCredential object requires two arguments:

完整类型为“ System.Management.Automation.PSCredential”对象。 使用“ -Credential”参数的命令通常需要传递此类型。根据您的需要,您可以通过几种不同的方式进行处理。 每种方法通常最多可列出两种不同的方案:交互式或自动化。 PSCredential对象需要两个参数:

  • UserName (System.String) 用户名(System.String)
  • Password (System.Security.SecureString) 密码(System.Security.SecureString)

The username is pretty obvious, but that password is not just a string value. You cannot just take a string and declare it as a SecureString. In order to even build a SecureString means you have to provide a password. Based on how you do this it can pose a security risk in most environments, because you either pass in (or store) your password in plain text. When you are working with passwords in PowerShell it is best to obfuscate your password to protect against those folks with wandering eyes. PowerShell offers a few different options to hide the password. I will go over these below and provide a few examples.

用户名很明显,但是该密码不仅仅是一个字符串值。 您不能只接受字符串并将其声明为SecureString。 为了构建SecureString,还必须提供密码。 根据您的操作方式,它可能会在大多数环境中带来安全风险,因为您要么以纯文本形式传递(或存储)密码。 当您在PowerShell中使用密码时,最好对密码进行混淆处理,以保护那些眼神游荡的人。 PowerShell提供了一些不同的选项来隐藏密码。 我将在下面详细介绍这些示例。

一个小警告 (A small caveat)

When you work with PSCredential objects you will find that there is a way to read that password back as plain text. This object contains properties on a particular method, that will return the password back as plain text. The method is: GetNetworkCredential(). This method has four properties: Domain, Password, SecurePassword, and UserName. This is there because there could be times you work with commands or third party executables that you need to pass in that password as plain text. You can pull the property to do that without having to necessarily show it in your script as plain text.

当使用PSCredential对象时,您会发现有一种方法可以将该密码以纯文本形式读回。 该对象包含特定方法的属性,该属性会将密码作为纯文本返回。 该方法是:GetNetworkCredential()。 此方法具有四个属性:域, 密码 ,SecurePassword和用户名。 这是因为您有时可能需要使用命令或第三方可执行文件来以纯文本形式输入该密码。 您可以拉动属性来执行此操作,而不必在脚本中将其显示为纯文本。

That is all to say you just need to understand that while the methods being shown do work for meeting certain security requirements, understand the risk of leaving variables like this in memory once your script completes. It is best to get into the habit of cleaning up at the end. Anytime you use the methods below they need to be locally scoped to the specific function using it. I would also recommend using “Remove-Variable” to ensure the variable you capture the password in is cleared from memory once you are done with it.

就是说,您只需要了解所显示的方法确实可以满足某些安全性要求,但要了解脚本完成后将此类变量保留在内存中的风险。 最好养成最后清理的习惯。 每当您使用下面的方法时,都需要使用它们将它们局部限制在特定的功能范围内。 我还建议您使用“ Remove-Variable”,以确保一旦完成捕获操作,便会从内存中清除捕获密码的变量。

读主机 (Read-Host)

Interactive commands mean you are going to prompt the user to enter some bit of information, like a password. Read-Host is useful to prompt for the password at the command line, especially if you don’t need the username as well. In order to get the SecureString object you just need to use the “-AsSecureString” parameter. This will show the password with asterisks as the user types, and will return a SecureString object.

交互式命令意味着您将提示用户输入一些信息,例如密码。 Read-Host对于在命令行提示输入密码很有用,尤其是在您不需要用户名的情况下。 为了获得SecureString对象,您只需要使用“ -AsSecureString”参数即可。 这将在用户键入时显示带有星号的密码,并将返回SecureString对象。


$t = Read-Host -Prompt "Please enter your password" -AsSecureString$t.GetType()

获取凭证 (Get-Credential)

Using this command will give the user a pop-up window they are likely more familiar with, to enter their username and password. The advantage you have with this command is after the user clicks the “Ok” button it will return a PSCredential object. This can save you a few more lines of code compared to the “Read-Host” command, that would still require you build the PSCredential object. This command is a favorite for one-liner commands where you need to quickly build a PSCredential object for a given command in PowerShell.

使用此命令将为用户提供一个他们可能更熟悉的弹出窗口,以输入用户名和密码。 使用此命令的好处是用户单击“确定”按钮后,它将返回一个PSCredential对象。 与“ Read-Host”命令相比,这可以节省更多的代码行,但仍然需要您构建PSCredential对象。 此命令是单行命令的常用命令,您需要为PowerShell中的给定命令快速构建PSCredential对象。


’’’powershell $t = Get-Credential -Message “Please enter your password” ```

After clicking OK we can see that a PSCredential object is returned.

单击“确定”后,我们可以看到返回了PSCredential对象。

If you wanted to use this in a one-liner like with “Get-WmiObject” you can simply do this:

如果您想像“ Get-WmiObject”那样在单层代码中使用它,则只需执行以下操作:


Get-WmiObject win32_service -ComputerName Server1 -Credential (Get-Credential)

SecureString转换 (SecureString Conversion)

Ok, now that we covered the interactive scenario, we can get to the fun one. There are two specific commands that are involved when you need to provide a password to your script and want to do it in an automated fashion. The commands do not build the PSCredential object, but help specifically in handling the password in a secure manner:

好的,既然我们已经介绍了交互式场景,那么我们就可以开始有趣了。 当您需要为脚本提供密码并希望以自动化方式进行操作时,涉及两个特定命令。 这些命令不会生成PSCredential对象,但是会特别有助于以安全的方式处理密码:

  • ConvertTo-SecureString ConvertTo-SecureString
  • ConvertFrom-SecureString ConvertFrom-SecureString

To build this process out you cannot talk about one command with out the other. Even reading the documentation you can see these commands are used in with each other. The first command, ConvertTo, takes a plain text string as input or an encrypted string (via methods shown previously). The output of the command is a SecureString object:

要建立此过程,您不能一概而论。 即使阅读文档,您也可以看到这些命令相互配合使用。 第一个命令ConvertTo使用纯文本字符串作为输入或加密的字符串(通过前面显示的方法)。 该命令的输出是一个SecureString对象:


$pwd = ConvertTo-SecureString "MySuperSecretPassword" -AsPlainText -Force
$pwd.GetType()

Now, when you pipe the output to ConvertFrom, it changes it to an encrypted standard string. This is where a bit of automation can be used. If you output the contents to a text file, it can then be read back and used in the creation of a PSCredential object.

现在,将输出传递给ConvertFrom时,它将其更改为加密的标准字符串。 这是可以使用一些自动化的地方。 如果将内容输出到文本文件,则可以将其读回并用于创建PSCredential对象。


# build the file with the encrypted password
ConvertTo-SecureString "MySuperSecretPassword" -AsPlainText -Force | ConvertFrom-SecureString | Out-File "C:\SomeSecureLocation\pwd.txt"# read it back in to get the SecureString
$t = Get-Content "C:\SomeSecureLocation\pwd.txt" | ConvertTo-SecureString

While this process would work for a single server, it does not if you need to use this password across multiple servers. Why is that you ask? There is a parameter for both commands, “-Key”, that is not required, but as stated in the help documentation:

尽管此过程适用于单个服务器,但如果您需要在多个服务器上使用此密码,则无效。 你为什么要问? 这两个命令都有一个参数“ -Key”,它不是必需的,但如帮助文档中所述:

Specifies the encryption key to use when converting a secure string into an encrypted standard string. Valid key lengths are 16, 24, and 32 bytes.

指定将安全字符串转换为加密标准字符串时要使用的加密密钥。 有效密钥长度为16、24和32个字节。

If you do not provide a value (Byte[]) for this parameter the command will utilize the DPAPI (Windows Data Protection API) to do the encryption. If you are not familiar with this API it is basically the operating system-level data protection (encryption) on each server. So if you let DPAPI do the encryption, then it goes to reason that only that single machine can decrypt it. If you try to convert the contents of that file on another server you will get an error about an invalid key.

如果没有为此参数提供值(Byte []),则该命令将利用DPAPI(Windows数据保护API)进行加密。 如果您不熟悉此API,则基本上是每台服务器上的操作系统级数据保护(加密)。 因此,如果让DPAPI进行加密,则会导致仅该一台计算机可以对其进行解密的原因。 如果尝试在另一个服务器上转换该文件的内容,则会收到有关无效密钥的错误消息。

So to make this automated and mobile, to use on any server in your environment, we need to utilize the “-Key” parameter. We just need to generate a “Byte[]” key and pass that into the command. You can generate a key with random bytes, and then use that each time you need to read that password into your script.

因此,要使此自动化和移动性能够在您环境中的任何服务器上使用,我们需要利用“ -Key”参数。 我们只需要生成一个“ Byte []”键并将其传递给命令即可。 您可以生成具有随机字节的密钥,然后在每次需要将该密码读入脚本时使用该密钥。

辅助功能 (Helper Functions)

I often forget the full syntax with commands that I do not have to use often. I don’t remember things I can look up most of the time. However, other ways I use to remember things with PowerShell, is to build functions that remember for me. So I built out three commands to share with you for the above process. I hope you find these useful for those one-time processes like building a secure password file a script being deployed in your environment. The functions contain help information but I will provide a full example that shows how they can be used below.

我经常忘记不需要使用的完整语法。 我不记得我大部分时间都可以查询的内容。 但是,我用PowerShell记住事情的其他方法是建立对我来说有用的函数。 因此,我为以上过程构建了三个命令与您共享。 我希望您发现这些对一次性过程有用,例如构建安全密码文件,在环境中部署脚本。 这些功能包含帮助信息,但是我将在下面提供一个完整的示例,说明如何使用它们。

You can download the script here.

您可以在此处下载脚本。


# (1) Create our key file
New-KeyFile -KeyFile .\MyKey.key -KeySize 16
# (2) Create our password file
New-PasswordFile -PwdFile .\MyPwd.txt -Key (Get-Content .\MyKey.key)
# (3) Pull in the password to use
$pwd = Get-SecurePassword -PwdFile .\MyPwd.txt -KeyFile .\MyKey.key# build the PSCredential object
$mycred = New-Object System.Management.Automation.PSCredential("MyUserName",$pwd)# show the password was captured
$mycred.GetNetworkCredential().Password

摘要 (Summary)

I hope the above shows that there are methods to help in keeping passwords a bit more secure than plain text. You may have processes or scripts that could already utilize the above code (e.g. creating Active Directory accounts, etc., and hope this helps.

我希望以上内容表明,有一些方法可以使密码比纯文本安全一些。 您可能已经使用上面的代码(例如,创建Active Directory帐户等)的进程或脚本,希望对您有所帮助。

翻译自: https://www.sqlshack.com/how-to-secure-your-passwords-with-powershell/

如何使用PowerShell保护密码相关推荐

  1. 用Apache的HTACCESS保护密码

    用Apache的HTACCESS保护密码 在staging模式中,如果想让网站上的指定目录对某些人开放,可以对站点使用密码保护方法--使用htpasswd文件来实现. 密码文件用于存储有效的需要访问网 ...

  2. 两种方法清除Excel保护密码

    一.利用VBA脚本直接清除 打Excel,打开脚本编辑器(Alt+F11)或者如图,右键sheet名称 输入代码并运行,即可清除密码保护: Sub DeletePW()ActiveSheet.Prot ...

  3. 用VBA去除Excel工作表保护密码

    今天帮同事解决个EXCEL问题,现记在这,以作备忘 现象: 想要修改保护单元 格的内容,在使用"工具"菜单"保护"子菜单的"撤消工作表保护" ...

  4. 撤销EXCLE工作表保护密码

    撤销工作表密码保护 有时工作簿太长时间没用,可能会忘掉工作表的保护密码以致无法编辑,本代码能快速有效解决此问题 有时工作簿太长时间没用,可能会忘掉工作表的保护密码以致无法编辑,本代码能快速有效解决此问 ...

  5. EXCEL工作表保护密码破解 宏撤销保护图文教程

    今天得到一个任务,是破解一个excel工作表的保护密码.我觉的网上的教程都挺好的,主要一点是注意excel中没有工具这一栏,需要自己去寻找出相关项. 用到的教程如下: 添加相关工具项 点击excel最 ...

  6. linux mysql 保护_linux – 在Puppet中,我如何保护密码变量(在这种情况下是MySQL密码)?...

    我正在使用Puppet为 MySQL配置参数化类: class mysql::server( $password ) { package { 'mysql-server': ensure => ...

  7. Excel 撤消工作表保护密码

    Excel表格密码保护的解除方法 表格受密码保护时,我们修改数据Excel弹出"您试图更改的单元格或图表受保护,因而是只读的.若要修改受保护单元格或图表,请先使用'撤消工作表保护'命令(在' ...

  8. 工作表、工作簿保护密码关闭

    此密码主要用于防止数据表的表格.格式.内容.公式等被修改删除.当工作表的单元格被保护时,试图编辑或删除那些单元格时你会收到提示 "试图更改的单元格或图表在受保护的工作表中" 告诉你 ...

  9. EI目录下载地址及保护密码

    EI目录下载地址及保护密码 EI目录下载地址:http://www.elsevier.com/solutions/engineering-village/content EI工作薄保护密码:AAAAA ...

最新文章

  1. 如何零基础开始自学Python编程
  2. [OS复习]进程管理4
  3. Security:CSRF
  4. Visual Studio 的码云扩展 V1.0.85 发布
  5. vue的getaction_vuex的actions属性
  6. web-4. 装饰页面的图像
  7. poj -- 1042 Gone Fishing(枚举+贪心)
  8. GB28181协议介绍
  9. 基于神经网络的分类设计——模式识别实验
  10. 自然语言处理中的伪数据 by哈工大教授车万翔
  11. 表格排版及其表格嵌套
  12. last reboot
  13. ic 主动均衡_分享几种锂电池均衡电路的工作原理
  14. 听说你有10年的工作经验?还是你把1个经验反复用了10年?(文末赠书)
  15. 【此间乐,不思蜀】 大一不想咸鱼的暑假7.17
  16. 尚硅谷李立超老师讲解web前端---笔记(持续更新)
  17. 算法小讲堂之B树和B+树(浅谈)|考研笔记
  18. c语言学生信息结构体录入文件,C语言—学生信息管理系统
  19. Day28 49. 丑数
  20. HTML5期末大作业:个人介绍/个人主页/网页设计——个人博客 (11页) HTML+CSS+JavaScript

热门文章

  1. 74LS139改3―8线译码器_3、5号线沿线楼盘6800起!另:为无缝衔接地铁 新增调整公交线路一览!...
  2. 填坑黑苹果(VMware装MacOS) - 修改 Unlocker 补丁源码版
  3. vue global filters
  4. 示例 - 10行代码在C#中获取页面元素布局信息
  5. 差速移动机器人之位姿整定
  6. 如何修改SQL Server 2008数据库服务器名称
  7. js/jquery判断浏览器的方法小结
  8. Boost.ASIO简要分析-4 多线程
  9. 关于Yaffs2在u-boot中的支持
  10. vue和react的diff算法对比