この投稿で説明したようなことをして、資格情報をセキュリティで保護されたファイルに保存して、自動化プロセスがそれを使用してInvoke-commandを介してリモートPSスクリプトを実行できるようにしました: http://blogs.technet.com/b/robcost /archive/2008/05/01/powershell-tip-storing-and-using-password-credentials.aspx
アカウントでこれを実行するとうまくいきます-パスワードは暗号化されたファイルから読み取られ、Invoke-commandに渡され、すべてがうまくいきます。
今日、スクリプトの準備が整ったときに、自動化されたプロセスで使用されるWindowsアカウントでスクリプトを実行しようとしましたが、スクリプトがファイルからセキュリティで保護されたパスワードを読み取ろうとしたときにこのエラーが発生しました:
ConvertTo-SecureString : Key not valid for use in specified state.
At \\remoted\script.ps1:210 char:87
+ $password = get-content $PathToFolderWithCredentials\pass.txt | convertto-sec
urestring <<<<
+ CategoryInfo : InvalidArgument: (:) [ConvertTo-SecureString], C
ryptographicException
+ FullyQualifiedErrorId : ImportSecureString_InvalidArgument_Cryptographic
Error,Microsoft.PowerShell.Commands.ConvertToSecureStringCommand
私の同僚に彼のアカウントで実行するように頼むと、彼は同じエラーを受け取りました。
これは、資格情報を保存するために使用しているコードです。
$PathToFolderWithCredentials = "\\path\removed"
write-Host "Enter login as domain\login:"
read-Host | out-file $PathToFolderWithCredentials\login.txt
write-Host "Enter password:"
read-Host -assecurestring | convertfrom-securestring | out-file $PathToFolderWithCredentials\pass.txt
write-Host "*** Credentials have been saved to $pathtofolder ***"
これは、Invokeコマンドで使用する自動プロセスによって実行されるスクリプト内のコードです。
$login= get-content $PathToFolderWithCredentials\login.txt
$password = get-content $PathToFolderWithCredentials\pass.txt | convertto-securestring
$credentials = new-object -typename System.Management.Automation.PSCredential -argumentlist $login,$password
行$ password = get-content $ PathToFolderWithCredentials\pass.txtでエラーが発生します|安全な文字列に変換
何か案は?
ConvertFrom-SecureString
は、Key
(およびSecureKey
)パラメーターを取ります。キーを指定して暗号化された標準文字列を保存し、ユーザーアカウントに関係なく、ConvertTo-SecureString
で再びキーを使用して安全な文字列を取得できます。
http://technet.Microsoft.com/en-us/library/dd315356.aspx
プロジェクトでは、公開鍵を使用してパスワードを暗号化し、自動化プロセスがパスワードを復号化する秘密鍵を使用する非対称暗号化を実装しました: 自動展開
同じコンピューター上で、それを実行するために使用するのと同じログインでパスワード文字列を作成する必要があります。
別のアプローチは、ConvertFrom-SecureStringが使用する「CurrentUser」ではなく、「LocalMachine」スコープを使用してデータを保護することです。
public static string Protect(SecureString input, DataProtectionScope dataProtectionScope = DataProtectionScope.CurrentUser, byte[] optionalEntropy = null)
{
byte[] data = SecureStringToByteArray(input);
byte[] data2 = ProtectedData.Protect(data, optionalEntropy, dataProtectionScope);
for (int i = 0; i < data.Length; i++)
{
data[i] = 0;
}
return ByteArrayToString(data2);
}
private static byte[] SecureStringToByteArray(SecureString s)
{
var array = new byte[s.Length * 2];
if (s.Length > 0)
{
IntPtr intPtr = Marshal.SecureStringToGlobalAllocUnicode(s);
try
{
Marshal.Copy(intPtr, array, 0, array.Length);
}
finally
{
Marshal.FreeHGlobal(intPtr);
}
}
return array;
}
private static string ByteArrayToString(byte[] data)
{
var stringBuilder = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
stringBuilder.Append(data[i].ToString("x2", CultureInfo.InvariantCulture));
}
return stringBuilder.ToString();
}
暗号化された文字列は、スコープ「CurrentUser」を使用しているConvertTo-SecureStringで使用できます。
以下では、資格情報をファイルとして保存し、それらの資格情報を別のユーザーがリモートで実行する別のスクリプトで使用できるようにします。
このコードは、David Leeが作成した素晴らしい記事から引用したものであり、自分自身からのわずかな調整のみを行っています https://blog.kloud.com.au/2016/04/21/using-saved-credentials-securely- in-powershell-scripts /
最初のステップは、AESを使用して安全なパスワードをファイルに保存することです。以下は、スタンドアロンスクリプトとして実行されます。
# Prompt you to enter the username and password
$credObject = Get-Credential
# The credObject now holds the password in a ‘securestring’ format
$passwordSecureString = $credObject.password
# Define a location to store the AESKey
$AESKeyFilePath = “aeskey.txt”
# Define a location to store the file that hosts the encrypted password
$credentialFilePath = “credpassword.txt”
# Generate a random AES Encryption Key.
$AESKey = New-Object Byte[] 32
[Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($AESKey)
# Store the AESKey into a file. This file should be protected! (e.g. ACL on the file to allow only select people to read)
Set-Content $AESKeyFilePath $AESKey # Any existing AES Key file will be overwritten
$password = $passwordSecureString | ConvertFrom-SecureString -Key $AESKey
Add-Content $credentialFilePath $password
次に、資格情報を使用する必要があるスクリプトで、次を使用します。
#set up path and user variables
$AESKeyFilePath = “aeskey.txt” # location of the AESKey
$SecurePwdFilePath = “credpassword.txt” # location of the file that hosts the encrypted password
$userUPN = "domain\userName" # User account login
#use key and password to create local secure password
$AESKey = Get-Content -Path $AESKeyFilePath
$pwdTxt = Get-Content -Path $SecurePwdFilePath
$securePass = $pwdTxt | ConvertTo-SecureString -Key $AESKey
#crete a new psCredential object with required username and password
$adminCreds = New-Object System.Management.Automation.PSCredential($userUPN, $securePass)
#use the $adminCreds for some task
some-Task-that-needs-credentials -Credential $adminCreds
ユーザーがパスワードファイルとキーファイルにアクセスできる場合、ユーザーのパスワードを解読できることに注意してください。
資格情報を使用するN人のユーザーの既知のリスト(1人の開発者userMe
とシステム/サービスユーザーuserSys
)があると仮定すると、 pass.txt
ファイル:各ユーザーに1つ。
したがって、userX
のパスワードは、たとえば2 *.pass.txt
ファイル:
userX.userMe.pass.txt
userX.userSys.pass.txt
UserMeが信任状を望んでいるとき、彼/彼女はuserX.userMe.pass.txt
など.