PowerShell — работа с паролями

  • Михаил
  • 12 мин. на прочтение
  • 94
  • 12 Dec 2014
  • 12 Dec 2014

PowerShell вполне нормально работает с паролями и даже умеет их хранить. Причем в различных форматах:

  • String — Текстовая строка. Большинство командлетов, из соображений безопасности, вас пошлют и будут совершенно правы. Эта методика применима, но не желательна.
  • System.Security.SecureString — содержимое храниться в памяти, в зашифрованном виде. Для работы используется реверсивный encryptiong так что пароль может быть расшифрован, когда это необходимо.
  • System.Management.Automation.PSCredential — класс, состоящий из имени пользователя (в виде строки) и пароля (в формате SecureString). Используется большинством командлетов для работы.

Стандартным методом для указания Credential-ов, в интерактивном режиме, во множестве командлетов является ключ -Credential. В скриптах это применяется следующим образом

$credential = Get-Credential ("DOMAIN\USER")  Get-WMIObject win32_logicaldisk -ComputerName SRV—LAB01 -Credential $credential

Примечание: Методику хранения пароля в тексте скрипта рассматривать не будем, не потому что и так все ясно, просто это неспортивно.

Переходим сразу ко второму типу — System.Security.SecureString

Вводим пароль в интерактивном варианте.

$SecurePassword = Read-Host -Prompt "Enter password" -AsSecureString

Можно, но не очень правильно, скормить текстовую переменную командлету ConvertTo-SecureString

$PlainPassword = "P@ssw0rd"
$SecurePassword = $PlainPassword | ConvertTo-SecureString -AsPlainText -Force

Что бы не было заблуждений, скажу что пароль извлекается следующим образом

$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword)
$PlainPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)

Теперь о «правильном» и полезном — создадим PSCredentials

$UserName = "Domain\User"
$Credentials = New-Object System.Management.Automation.PSCredential -ArgumentList $UserName, $SecurePassword

Отсюда пароль извлекается так

$PlainPassword = $Credentials.GetNetworkCredential().Password

Где это применяется?

В первую очередь для автоматизации заданий.

Сохраняем пароль в «зашифрованном» виде на диск.

$credential = Get-Credential ("DOMAIN\USER")
$credential.Password | ConvertFrom-SecureString | Set-Content c:\temp\password.txt

При этом используется методика сохранения пароля на диск, в файл. Файл сохраняется в неудобочитаемом виде

01000000d08c9ddf0115d1118c7a00c04fc297eb010000006121b0a6ed698a4cae97d8d78ef671f
20000000002000000000003660000c000000010000000ff5d4067962147f39e4019701be1bc8c00000000048000
00a00000001000000008d228629f1fd67f3f35a41ee31e9788100000008c0d64657c326ebc9656b1679196bbcc1
4000000ffba85c0796a06f1cefd4d3fdbcbf9aa6ad45e49

но мы должны помнить что из него совершенно легко выдергивается пароль, причем в открытом виде. Поэтому не надо увлекаться сохранением паролей пользователей из группы Domain Admins и прочих, в месте где его можно прочитать.

Для того что бы использовать полученный файл, в скрипте используем следующий код.

$password = Get-Content c:\temp\password.txt | ConvertTo-SecureString
$credential = New-Object System.Management.Automation.PSCredential "CachedUser",$password