Параметры Powershell

10

У меня есть блок Param в моем скрипте

Param (
    [Parameter(Mandatory=$True)]
    [string]$FileLocation,

    [Parameter(Mandatory=$True)]
    [string]$password = Read-Host "Type the password you would like to set all the users to" -assecurestring
)

Могу ли я использовать CmdLet Read-Host в обязательном поле Parameter? если нет, что я могу сделать, чтобы убедиться, что я использую правильный тип переменной, чтобы я мог передать ее процессу создания пользователя?

TechGuyTJ
источник

Ответы:

16

Достаточно указать правильный тип пароля, попробуйте:

Param (
    [Parameter(Mandatory=$True)]
    [string]$FileLocation,

    [Parameter(Mandatory=$True)]
    [Security.SecureString]$password
)

PowerShell будет «маскировать» пароль (так же, как для read-host -asSecureString), и тип результата будет тем, который может потребоваться другим командлетам.

РЕДАКТИРОВАТЬ: После недавних комментариев: решение, которое дает обе опции, чтобы предоставить простой текстовый пароль, или заставить пользователя вводить пароль (но замаскировать его таким же образом, как Read-Host -AsSecureString) и в обоих случаях получить [Security.SecureString] в конце , И, в качестве бонуса, вы получите некоторую причудливую подсказку для вашего секретного пароля. ;)

[CmdletBinding(
    DefaultParameterSetName = 'Secret'
)]
Param (
    [Parameter(Mandatory=$True)]
    [string]$FileLocation,

    [Parameter(
        Mandatory = $True,
        ParameterSetName = 'Secret'
    )]
    [Security.SecureString]${Type your secret password},
    [Parameter(
        Mandatory = $True,
        ParameterSetName = 'Plain'
    )]
    [string]$Password
)

if ($Password) {
    $SecretPassword = $Password | ConvertTo-SecureString -AsPlainText -Force
} else {
    $SecretPassword = ${Type your secret password}
}

Do-Stuff -With $SecretPassword

Я использовал трюк Джайкула, чтобы обмануть вас, попросив ввести безопасный пароль. ;) Из-за этого этот параметр будет очень трудно использовать в режиме CLI (-Тип вашего секретного пароля не будет работать должным образом), поэтому он должен заставить пользователей скрипта либо пропустить пароль (и получить подсказку в маске), либо указать его с помощью -password параметр, который принимает обычную строку и преобразует ее в защищенную строку внутри логики скрипта.

BartekB
источник
Это приводит к ошибке для меня.
Райан Райс
1
Не могу помочь с такой расплывчатой ​​информацией. ;) Какая у вас ошибка? Я протестировал это как на v2, так и на v3, и у меня все заработало. Не знаете, где может быть источник вашей проблемы, если вы не укажете сообщение об ошибке ...
BartekB
Нет, нет, ты прав - прости. Ваш код верен, но я все еще думаю, что OP будет нужен способ передать SecureString в сценарий из командной строки, а не просто строку.
Райан Райс
Я получаю следующую ошибку при использовании этого блока Param [PS] C: \ Windows \ system32> C: \ Util \ Create-MailboxUsers.ps1 -FileLocation C: \ Util \ Users.csv -password P @ ssword C: \ Util \ Create-MailboxUsers.ps1: Невозможно обработать преобразование аргумента для параметра «пароль». Невозможно преобразовать значение "P @ssword" типа "System.String" в тип "System.Security.SecureString". В строке: 1 символ: 74 + C: \ Util \ Create-MailboxUsers.ps1 -FileLocation C: \ Util \ Users.csv -password <<<< P @ ssword
TechGuyTJ
1
Это потому, что вы не можете преобразовать обычную строку в безопасную строку, подобную этой. Я обновил свой ответ чем-то, что, вероятно, позволит вам получить и то, и другое: маскированное приглашение и опционально возможность указать встроенный пароль с параметром -password P @ ssword.
BartekB
4

Немного трудно понять, что ты пытаешься сделать ...

Редактировать; как упомянуто Райаном, вы в настоящее время уже указываете его как строку ...

Но в некотором коде я использовал следующую функцию при использовании Read-Host и SecureStrings

function AskSecureQ ([String]$Question, [String]$Foreground="Yellow", [String]$Background="Blue") {
    Write-Host $Question -ForegroundColor $Foreground -BackgroundColor $Background -NoNewLine
    Return (Read-Host -AsSecureString)
}

В вашем случае вы бы назвали это, выполнив следующее;

Param (
    [Parameter(Mandatory=$True)]
    [string]$FileLocation,

    [Parameter(Mandatory=$True)]
    [string]$password = AskSecureQ "Type the password you would like to set all the users to"
)

РЕДАКТИРОВАТЬ: учитывая комментарии, и просто черт возьми ... вот альтернативный метод, используемый для преобразования вышеупомянутой безопасной строки в простой текст в Powershell;

# Taking a secure password and converting to plain text
Function ConvertTo-PlainText( [security.securestring]$secure ) {
    $marshal = [Runtime.InteropServices.Marshal]
    $marshal::PtrToStringAuto( $marshal::SecureStringToBSTR($secure) )
}

Вы бы использовали это так;

$PWPlain = ConvertTo-PlainText $password

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

fenneh
источник
1

Я не уверен , что понимаю ... кажется , что вы уже будут делать это. Установив параметр на обязательный, Powershell запросит его, если вы не предоставите его в командной строке, и с помощью [string] вы гарантируете, что единственный тип данных, который может входить в эту переменную, - это System.string.

РЕДАКТИРОВАТЬ: Основываясь на ответе Бартека, сделайте это в вашем сценарии:

Param ([Parameter(Mandatory=$true,ValueFromPipeline=$true)][Security.SecureString]$Password)       

Затем вы должны передать вашему сценарию объект SecureString следующим образом:

PS:> Read-Host -AsSecureString | .\YourScript.ps1
Райан Райс
источник