M
miproch
Guest
Historically, CredentialAttribute was an opt-in attribute that caused the PS parser to prompt for username and password when a PSCredential parameter was not supplied or malformed. Today, it is automatically added to all PSCredential parameters. (I am using PS 6.1.3)
This is all to the good when I am developing a script on my workstation, but it is a less than convenient behavior when I am executing a script in the cloud. There is no user to respond the prompts. In general, I would like to configure my scripts to fail, not prompt, when executing in the cloud. In specific, PSCredential parameters are the most challenging.
I have a workaround (listed) but I’ve lost the concept of “Mandatory parameters”, introduced a concept of “Required Parameters”, and have a minor code explosion that will be repeated in numerous cmdlets.
QUESTIONS: Is there a way to opt out? I’ve used Trace-Command, the prompt comes from binding. Am I missing something obvious?
Thanks,
~Michael
INITIAL CODE:
function Get-CloudResource.Prompts
{
[CmdletBinding()]
param
(
[Parameter(Position = 0,Mandatory = $true)]
[System.Management.Automation.PSCredential]$Credential
)
process {
# ...
PREVENT PROMPTING CODE:
function Get-CloudResource.NoPrompts
{
[CmdletBinding(DefaultParameterSetName = "UserNamePasswordSet")]
param
(
[Parameter(Position = 0,Mandatory = $false,ParameterSetName = "CredentialSet")]
# Mandatory=$true. This attribute causes the parser to prompt input.
# [ValidateNotNull()]. This attribute causes the parser to prompt input.
[System.Management.Automation.PSCredential]$Credential,
[Parameter(
Position = 0,Mandatory = $false,ParameterSetName = "UserNamePasswordSet")]
# Mandatory=$true. This attribute causes the parser to prompt input.
[ValidateNotNullOrEmpty()] # Validation attribute behavior differs from PSCredential parameters
[System.String]$UserName,
[Parameter(
Position = 1,Mandatory = $false,ParameterSetName = "UserNamePasswordSet")]
[AllowNull()]
[System.Security.SecureString]$Password
)
process {
if ('CredentialSet' -eq $PSCmdlet.ParameterSetName)
{
if ((!$Credential) -or ([System.Management.Automation.PSCredential]::Empty -eq $Credential))
{
# $Credential is null or Empty
throw [ArgumentNullException]::new("`$Credential")
}
$userNameValue = Convert-TrimNullToEmpty $Credential.UserName
if (!$userNameValue)
{
throw "`$Credential.UserName is required."
}
$credentialValue = $Credential
}
elseif ('UserNamePasswordSet' -eq $PSCmdlet.ParameterSetName)
{
$userNameValue = Convert-TrimNullToEmpty $UserName
if (!$userNameValue)
{
# $UserName is null or Empty or whitespace
throw "`$UserName is required."
}
[System.Security.SecureString]$passwordValue = $null;
if ($null -ne $Password)
{
$passwordValue = $Password
}
else
{
$passwordValue = [System.Security.SecureString]::new()
}
$credentialValue = [System.Management.Automation.PSCredential]::new($userNameValue,$passwordValue)
}
else
{
throw [System.NotSupportedException]::new('Could not the determine parameter set')
}
# ...
Continue reading...
This is all to the good when I am developing a script on my workstation, but it is a less than convenient behavior when I am executing a script in the cloud. There is no user to respond the prompts. In general, I would like to configure my scripts to fail, not prompt, when executing in the cloud. In specific, PSCredential parameters are the most challenging.
I have a workaround (listed) but I’ve lost the concept of “Mandatory parameters”, introduced a concept of “Required Parameters”, and have a minor code explosion that will be repeated in numerous cmdlets.
QUESTIONS: Is there a way to opt out? I’ve used Trace-Command, the prompt comes from binding. Am I missing something obvious?
Thanks,
~Michael
INITIAL CODE:
function Get-CloudResource.Prompts
{
[CmdletBinding()]
param
(
[Parameter(Position = 0,Mandatory = $true)]
[System.Management.Automation.PSCredential]$Credential
)
process {
# ...
PREVENT PROMPTING CODE:
function Get-CloudResource.NoPrompts
{
[CmdletBinding(DefaultParameterSetName = "UserNamePasswordSet")]
param
(
[Parameter(Position = 0,Mandatory = $false,ParameterSetName = "CredentialSet")]
# Mandatory=$true. This attribute causes the parser to prompt input.
# [ValidateNotNull()]. This attribute causes the parser to prompt input.
[System.Management.Automation.PSCredential]$Credential,
[Parameter(
Position = 0,Mandatory = $false,ParameterSetName = "UserNamePasswordSet")]
# Mandatory=$true. This attribute causes the parser to prompt input.
[ValidateNotNullOrEmpty()] # Validation attribute behavior differs from PSCredential parameters
[System.String]$UserName,
[Parameter(
Position = 1,Mandatory = $false,ParameterSetName = "UserNamePasswordSet")]
[AllowNull()]
[System.Security.SecureString]$Password
)
process {
if ('CredentialSet' -eq $PSCmdlet.ParameterSetName)
{
if ((!$Credential) -or ([System.Management.Automation.PSCredential]::Empty -eq $Credential))
{
# $Credential is null or Empty
throw [ArgumentNullException]::new("`$Credential")
}
$userNameValue = Convert-TrimNullToEmpty $Credential.UserName
if (!$userNameValue)
{
throw "`$Credential.UserName is required."
}
$credentialValue = $Credential
}
elseif ('UserNamePasswordSet' -eq $PSCmdlet.ParameterSetName)
{
$userNameValue = Convert-TrimNullToEmpty $UserName
if (!$userNameValue)
{
# $UserName is null or Empty or whitespace
throw "`$UserName is required."
}
[System.Security.SecureString]$passwordValue = $null;
if ($null -ne $Password)
{
$passwordValue = $Password
}
else
{
$passwordValue = [System.Security.SecureString]::new()
}
$credentialValue = [System.Management.Automation.PSCredential]::new($userNameValue,$passwordValue)
}
else
{
throw [System.NotSupportedException]::new('Could not the determine parameter set')
}
# ...
Continue reading...