Сервісний центр VPSGroup ремонт комп'ютерної техніки, заправка картриджів, ремонт оргтехніки, Київ, Виставковий центр, Васильківська, 55

Збереження облікових даних в PowerShell.

Збереження облікових даних досить часто використовується в PowerShell скриптах для автоматизації завдань, або у разі делегування повноважень для виконання будь-яких адміністративних завдань.

За замовчуванням скрипти виконується від імені користувача \ процесу, його запустив.Однак багато командлети мають параметр Credential, що дозволяє вказувати альтернативні облікові дані. Для прикладу візьмемо командлет Get-WmiObject і спробуємо подивитися тип процесора на віддаленому комп'ютері SRV1 за допомогою команди:

Get-WmiObject -Class win32_processor -ComputerName SRV1

Як і очікувалося, команда завершилася з помилкою (Access is denied), адже у поточного користувача немає прав на віддаленому комп'ютері.Ситуація цілком стандартна, для її вирішення достатньо вказати альтернативні облікові дані. Збережемо облікові дані в змінній $ credentials, а потім додамо їх в командлет Get-WmiObject за допомогою параметра Credential:

$ credentials = Get-Credential contoso \ administrator
Get-WmiObject -Class win32_processor -ComputerName SRV1 -Credential $ credentials

Як бачите, тепер віддалена команда виконалася успішно.



Щоб краще зрозуміти, що з себе представляють збережені облікові дані в PowerShell, подивимося властивості змінної $ credentials. Мінлива має тип даних Automation.PSCredential, а самі облікові дані зберігаються в її властивості UserName і Password. Ім'я користувача зберігається у відкритому вигляді (string), а пароль - в форматі захищеної рядки (securestring).



Оскільки щоразу пароль не завжди можливо, то нам треба якось зберегти його. Наприклад, вивести в зашифрованому вигляді в звичайний текстовий файл:

$ credentials.Password | ConvertFrom-SecureString | Set-Content pass.txt



Тепер для того щоб використовувати збережений пароль, треба витягнути вміст файлу і перетворити назад в формат Securestring.Виглядати це буде приблизно так:

$ user = "contoso \ administrator"
$ password = Get-Content pass.txt | ConvertTo-SecureString
$ credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $ user, $ password

Отримані таким чином Credentials можна використовувати для виконання віддаленої команди.



Начебто все вийшло, облікові дані збережені.Однак не все так просто. Якщо ми зберемо всі команди в скрипт, скопіюємо його (разом з файлом, що містить пароль) на інший комп'ютер і там спробуємо виконати, то отримаємо помилку. Якщо придивитися уважніше, то видно, що помилка сталася через відсутність пароля (argument "password" is null).



Справа в тому, що при збереженні в файл пароль шифрується за допомогою механізму Windows Data Protection API (DPAPI). Це вбудований в систему програмний інтерфейс, що використовується для шифрування і забезпечення безпеки Internet Explorer, Outlook, IIS і багатьох інших компонентів Windows.

Шифрування пароля проводиться за допомогою ключів, створюваних операційною системою.Ключі ці створюються з користувацьких облікових даних і зберігаються локально, в профілі користувача. Без цих ключів зашифровані дані неможливо використовувати. Простіше кажучи, збережені таким чином облікові дані можна перенести на інший комп'ютер або файлову кулі, їх можна використовувати тільки локально, на тому комп'ютері, на якому вони були отримані.

Щоб відв'язати зашифровані дані від локальної машини ключ, яким будуть зашифровані дані, можна задати вручну. Робиться це за допомогою параметра key, допустима довжина ключа 16, 24 або 32 біт. Наприклад:

$ credentials = Get-Credential contoso \ administrator
$ key = @ (1..24)
$ credentials.Password | ConvertFrom-SecureString -Key $ key | Set-Content pass.txt



Ключ необхідно запам'ятати \ зберегти і при зворотному перетворенні вказати його. Вийде як то так:

$ user = "contoso \ administrator"
$ password = Get-Content pass.txt | ConverTo-SecureString -Key $ key
$ credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $ user, $ password



Тепер ми можемо спокійно переносити скрипт і без перешкод використовувати його на інших комп'ютерах.



І на завершення, щоб у вас не було особливих ілюзій з приводу безпеки - зашифровані паролі легко висмикуються зі збережених облікових даних, причому відкритим текстом. Наприклад, з PSCredential пароль витягується дуже просто:

$ credentials.GetNetworkCredential (). Password

І трохи складніше з SecureString:

$ BSTR = [System.Runtime.InteropServices.Marchall] :: SecureStringToBSTR ($ credentials.Password)
[System.Runtime.InteropServices.Marchall] :: PtrToStringAuto ($ BSTR)



Як бачите, збереження облікових даних небезпечно, тому намагайтеся використовувати облікові записи з мінімальним необхідним набором прав. Не варто так само зберігати паролі користувачів, що входять в групу Domain \ Enterprise Admins (і їм подібних)..