我希望能够使用PowerShell登录到VIServer,并让它在脚本第一次运行时询问凭据,然后将这些凭据保存在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:devPassword.txt"
$pass = Get-Content "G:devPassword.txt" | ConvertTo-SecureString
$User = "MyUserName"
$File = "G:devPassword.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代码==========$主机名=192.168.10.10
New-VICredentialStoreItem -Host $Hostname -User $User -Password $pass
我走对了吗?
我应该怎么做才能只键入一次凭据,然后让脚本调用$creds变量,而不必每次都键入凭据?
我在这个问题的大多数答案中看到的问题是,密码是以纯文本处理和存储的。从安全角度来看,这是一个很大的禁忌。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 (DomainSSO)'
$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:userprofileSSOCreds.xml
#Check for stored credentials...
$creds_stored = Test-Path -Path $env:userprofileSSOCreds.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:userprofileSSOCreds.xml
If ($creds_stored -eq $true) {
Write-Host "Stored credentials found." -ForegroundColor Cyan
$creds = Import-Clixml -Path $env:userprofileSSOCreds.xml
}
Else {
$creds = Get-Credential -Message "Please enter your credentials to acces the vCenter using full path (DomainSSO)."
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
根据您提供的内容,我能看到的最简单的方法是将该命令封装在另一个脚本中。一个检查凭据存储,然后如果你要查找的条目不存在,则提示输入你的凭据。
你能告诉我你的工作流程是什么样子的吗?
首先将凭证保存到磁盘,如下所示:
$credential = Get-Credential
$credential.Password | ConvertFrom-SecureString | Set-Content c:tempCred.txt
然后从磁盘加载并创建一个$Credential变量,如下所示:
$username = "DomainUserName"
$encrypted = Get-Content C:TempCred.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 = [Byte]1..16
$credential.Password | ConvertFrom-SecureString -Key $Key | Set-Content c:tempCred.txt
要解密:
$encrypted = Get-Content C:TempCred.txt | ConvertTo-SecureString -Key $Key
$credential = New-Object System.Management.Automation.PsCredential($username, $encrypted)