我希望能够使用PowerShell登录VIServers,并在脚本第一次运行时请求凭据,然后将这些凭据保存在password.txt文件中,让VIServer只使用存储的password.txt文件如果用户再次运行脚本,则在用户计算机上本地。痛点在于,当用户想要多次运行脚本时,凭证提示会一次又一次地弹出。
我可以使用Stackoverflow上发布的另一个答案中的以下代码(链接:http://www.adminarsenal.com/admin-arsenal-blog/secure-password-with-powershell-encrypting-credentials-part-1)
它有效:
Read-Host "Enter Password" -AsSecureString | ConvertFrom-SecureString |
Out-File "G:\dev\Password.txt"
$pass = Get-Content "G:\dev\Password.txt" | ConvertTo-SecureString
$User = "MyUserName"
$File = "G:\dev\Password.txt"
$MyCredential = New-Object -TypeName System.Management.Automation.PSCredential
-ArgumentList $User, (Get-Content $File | ConvertTo-SecureString)
我从vmware博客(链接:http://blogs.vmware.com/PowerCLI/2011/11/have-you-seen-powerclis-credential-store-feature.html)
中找到了以下内容以下是来自vmware博客的代码(有一些解释):
要使用凭证存储,我会执行以下操作:
New-VICredentialStoreItem -Host 192.168.10.10 -User "Andrey" -Password "my favorite password"
现在我可以输入:
Connect-VIServer 192.168.10.10
当我没有指定用户和/或密码时,Connect-VIServer会检查凭据存储,找到我新存储的凭据并使用它。
默认情况下,凭据存储文件存储在用户配置文件目录下。它是加密的。如果我对您感兴趣,请查看“help * VICredentialStoreItem”了解详细信息。
-Andrey Anastasov, PowerCLI Architect
=============现在我修改了VIServer代码的版本========== $ Hostname = 192.168.10.10
New-VICredentialStoreItem -Host $Hostname -User $User -Password $pass
我是在正确的轨道上吗?
我应该怎么做只输入一次凭证,然后让脚本调用$ creds变量而不是每次都输入凭证?
答案 0 :(得分:1)
首先将凭据保存到磁盘,如下所示:
$credential = Get-Credential
$credential.Password | ConvertFrom-SecureString | Set-Content c:\temp\Cred.txt
然后从磁盘加载它并创建一个$ Credential Variable,如下所示:
$username = "Domain\UserName"
$encrypted = Get-Content C:\Temp\Cred.txt | ConvertTo-SecureString
$credential = New-Object System.Management.Automation.PsCredential($username, $encrypted)
然后您可以使用接收$ credential输入的函数:
function Connect-vCenter
{
Param (
[Parameter(Mandatory = $True)]
$vCenterServer,
[System.Management.Automation.PSCredential]$Credential
)
if ($Credential)
{
Add-PSSnapin VMware.VimAutomation.Core
Connect-VIServer $vCenterServer -Credential $Credential
}
else
{
Add-PSSnapin VMware.VimAutomation.Core
Connect-VIServer $vCenterServer
}
}
运行它:
Connect-vCenter -vCenterServer vCenter -Credential $Credential
当然只有加密凭证的用户才能使用它,如果你想用不同的密钥加密它(安全性较低)你可以添加-Key这样的参数:
$Key = [Byte]1..16
$credential.Password | ConvertFrom-SecureString -Key $Key | Set-Content c:\temp\Cred.txt
To Decrpyt:
$encrypted = Get-Content C:\Temp\Cred.txt | ConvertTo-SecureString -Key $Key
$credential = New-Object System.Management.Automation.PsCredential($username, $encrypted)
答案 1 :(得分:1)
我在这个问题的大多数答案中看到的问题是密码是以纯文本形式处理和存储的。安全方面,这是一个很大的禁忌。 PowerShell 可以确保这些凭据在内存中和存储时都是安全的。可以创建一个安全的 XML 文件,该文件只能由创建它的用户访问,并且只能在创建它的机器上访问。我没有创建所有这些脚本,我在不同的地方在网上找到了一些片段,所以我没有名字。
#Store-Credentials
#This script collects the credentials used by my other scripts and saves them into secure XML files.
#The XML files can only be imported by my user account, and only from the machine it was created on specifically.
#This script needs to be run any time you change your password, obviously...
$counter = 0
$again = $true
while($again){
if($counter -ge 3){
Write-Warning -Message ('You have entered your password {0} times incorrectly' -f $counter)
Write-Warning -Message ('Please wait until {0} to try again to avoid risking locking yourself out.' -f $((Get-Date).AddMinutes(+15).ToShortTimeString()))
Start-Sleep -Seconds 30
}
# Get username and password from user...
$username = Read-Host -Prompt 'Please enter your SSO using full path (Domain\SSO)'
$password = Read-Host -AsSecureString -Prompt 'Please enter your password'
try{
$creds = New-Object System.Management.Automation.PSCredential $username,$password
# Get the current domain
$domain = 'LDAP://{0}' -f $creds.GetNetworkCredential().Domain
# Try to get the username and password from the network...
$username = $creds.GetNetworkCredential().UserName
$password = $creds.GetNetworkCredential().Password
}
catch{
Write-Warning -Message ('There was a problem with what you entered: {0}' -f $_.exception.message)
continue
}
# Check against the domain to authenticate the user.
$UserObject = New-Object System.DirectoryServices.DirectoryEntry($domain,$username,$password)
# If we get a result back with a name property then we're good to go and we can store the credential.
if($UserObject.name){
Write-Host "Saving credentials..."
Export-Clixml -InputObject $creds -Path $env:userprofile\SSOCreds.xml
#Check for stored credentials...
$creds_stored = Test-Path -Path $env:userprofile\SSOCreds.xml
If ($creds_stored -eq $true)
{Write-Host "Credentials saved."}
Else
{Write-Host "There was a problem writing the file... your credentials were not saved."}
$again = $false
Remove-Variable password -Force
}
else{
$counter++
Write-Warning -Message ('The password you entered for {0} was incorrect. Attempts {1}. Please try again.' -f $userName,$counter)
}
}
存储凭据后,您可以通过将其包含在其他脚本的开头使用以下部分来提取它们
#Check for stored credentials to log onto the vCenter...
$creds_stored = Test-Path -Path $env:userprofile\SSOCreds.xml
If ($creds_stored -eq $true) {
Write-Host "Stored credentials found." -ForegroundColor Cyan
$creds = Import-Clixml -Path $env:userprofile\SSOCreds.xml
}
Else {
$creds = Get-Credential -Message "Please enter your credentials to acces the vCenter using full path (Domain\SSO)."
Write-Host "If you would like to store your credentials, use the Store-Credentials script." -ForegroundColor Cyan
}
#Connect-ViServer server.domain.com
Connect-VIServer -Server $vCenter -Credential $creds -Force
答案 2 :(得分:0)
根据您提供的内容,我可以看到的最简单的方法是将该命令包装在另一个脚本中。如果您要查找的条目不存在,则会检查凭据存储,然后提示您的信用。
您能告诉我您的工作流程是什么样的信息吗?