对于VIServer和PowerCLI,如何仅在PowerShell中第一次提示凭据,然后存储凭据并用于下一次脚本运行



我希望能够使用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)

相关内容

  • 没有找到相关文章

最新更新