Ril*_*ley 6 windows vbscript powershell batch-file
@ECHO OFF
DFC.EXE get /isfrozen
IF Errorlevel 1 GOTO Frozen
IF Errorlevel 0 GOTO Thawed
:Frozen
Echo Errorlevel 1 Computer is Frozen, Thawing Now
DFC.EXE fakepassword123 /BOOTTHAWED
Echo
Goto END
:Thawed
Echo Errorlevel 0 Computer is Not Frozen
Echo
Goto END
:END
Exit
Run Code Online (Sandbox Code Playgroud)
我正在尝试运行一个非常简单的批处理文件,但如果有人要编辑密码,我不希望以纯文本形式存储密码。
现在 DFC.exe 密码行是存储密码的地方。
有没有办法将此密码隐藏在另一个文件中并从那里调用它?
您可以使用 PowerShell 将密码存储在磁盘上,这种方式(默认情况下)只能由创建密码的计算机上的当前执行用户检索。如果您无法在 PowerShell 中编写整个脚本,您至少可以通过powershell.exe
在脚本期间调用来完成此操作。
要创建凭证文件(这将提示您输入凭证,在这种情况下用户名无关紧要,但必须提供):
powershell.exe -c "Get-Credential | Export-CliXml cred.xml"
Run Code Online (Sandbox Code Playgroud)
Export-CliXml
是一个特殊的 cmdlet,它将 PowerShell 对象序列化到磁盘,并带有一些边缘警告(例如不要尝试使用 COM 对象执行此操作并期望它可以工作),通常可用于将对象读回另一个会话,因为我们下面做。并将其从您的脚本读入一个变量并在您的命令中使用它:
for /f %i in ('powershell.exe -c "( Import-CliXml cred.xml ).GetNetworkCredential().Password"') do set PASSWORD=%i
DFC.EXE %PASSWORD% /BOOTTHAWED
Run Code Online (Sandbox Code Playgroud)
我们需要获取网络凭据,以便我们可以获得可用密码作为该命令的一部分。如果您发现自己在其他命令中也需要用户名,您也可以以类似的方式获取:
for /f %i in ('powershell.exe -c "( Import-CliXml cred.xml ).UserName"') do set USERNAME=%i
Run Code Online (Sandbox Code Playgroud)
对于用户名,它没有加密,因此您无需返回网络凭据即可获得可用的用户名。
上面,Get-Credential
为了简单起见,我们利用创建初始凭证,但使用它构建凭证对象并不是绝对必要的。
如果您需要解密来自多台机器或用户的凭据,则稍微复杂一些。您将无法利用Get-Credential
并且必须自己构建凭证,并且仅将密码存储在文件中(您也可以存储用户名,但对于这种情况)。
要准备凭证,首先我们需要创建一个密钥文件。这比能够使用更复杂,Get-Credential
但您只需在第一次生成密钥文件或密码文件时执行这些步骤。最好从powershell.exe
以下位置执行此步骤:
$keyFile = "C:\path\to\keyfile.key"
# you can adjust this number for different levels of AES encryption
# 32 = 256 bits
# 24 = 192 bits
# 16 = 128 bits
$key = New-Object Byte[] 32
[Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($key)
# Save the key file to disk
$key | Out-File $keyFile
Run Code Online (Sandbox Code Playgroud)
现在我们有了密钥文件,我们可以使用它将您的密码存储到磁盘(请记住,这次我们只是将密码存储在文件中,而不是PSCredential
对象中)。再一次,这最好powershell.exe
与上一步一样:
# Save your password in a file so you don't have it plaintext in your history
$insecurePassFile = "C:\path\to\insecurePassFile.txt"
# This will be the encrypted password outfile
$securePassFile = "C:\path\to\securePassFile.txt"
# This can also be a UNC path if on a share
$keyFile = "C:\path\to\keyfile.key"
# Read the key in
$key = Get-Content $keyFile
# Read the plaintext password in and convert it to a secure string using our key
$password = Get-Content $insecurePassFile | Select-Object -First 1 | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString -key $key
# Write the encrypted password out to a file to be read in later using our key
$password | Out-File $securePassFile
Run Code Online (Sandbox Code Playgroud)
现在,您将加密的密码文件保存到$securePassFile
. 此时,您可以将密码文件和密钥复制到网络上的某个位置。
现在我们要回到批处理世界。要读入密码,您需要知道密码文件和密钥文件的位置,并有权访问这两个文件。我很抱歉,但这将是一个很长的 PowerShell 命令,可以放在一行中:
for /f %i in ('powershell.exe -c "$key = Get-Content \\server.domain.tld\share\path\to\keyfile.key; [System.Net.NetworkCredential]::new("", ( Get-Content \\server.domain.tld\share\path\to\password.txt | ConvertTo-SecureString -Key $key ) ).Password"') do set PASSWORD=%i
Run Code Online (Sandbox Code Playgroud)
那是一口,所以让我们分解一下:
for
循环是将变量设置为命令输出所需的“魔法”。最终将PASSWORD
变量设置为PowerShell 命令的输出。IMO 编写命令提示符的人是受虐狂 XD。$key
从密钥文件中读取。没有这个,我们就无法从密码文件中解密我们的密码。System.Net.NetworkCredential
对象来从中提取密码。第一个参数是用户名(这里我们不需要,空字符串有效),第二个参数是SecureString
密码:SecureString
使用我们的密钥文件中的密钥将其解密为正确的。NetworkCredential
对象中,我们可以读取Password
属性,这是我们可以返回的可用密码。for
循环的一部分,PASSWORD
设置为前一个 PowerShell 命令的输出,在本例中是我们构建的Password
属性NetworkCredential
。如果您提供了自己的密钥,请确保将您的密钥存放在安全的地方。只有应该有权访问它的用户和机器才能读取它。理想情况下,凭证和机密应该从机密保险库(例如 Hashicorp 保险库、Keepass 等)存储和检索,但文件 ACL 也可用于控制谁可以访问这些信息。
请注意,当帐户密码更改时,cred.xml
如果您依赖默认加密行为,则必须重新生成。
归档时间: |
|
查看次数: |
1389 次 |
最近记录: |