I can't seem to pass a securestring to my cmdlet

1.3k views Asked by At

I've got a function which calls a cmdlet

Function connect-app([string]$host, [string]$user, [SecureString]$password, [switch]$passwordfile, [switch][alias("q")]$quiet)

Inside of this function, I've got a check for if $passwordfile or $password is provided

if ( -Not $passwordfile -and ($password -eq $null -or $password -eq "")) 
{
    # prompt for a password
    [SecureString]$passwordenc = Read-Host -AsSecureString "Password";
} 
else 
{
    $hash = Hash($host + "-" + $user);
    [SecureString]$passwordenc = Get-Content "$env:USERPROFILE\$hash" | ConvertTo-SecureString;
}

Ultimately, if $quiet is supplied, then a variation of the cmdlet below is called

$expression = "Connect-Appliance -host " + $host + " -user " + $user + " -Password " + $passwordenc  + " -Quiet";
Invoke-Express $expression

But for some reason, I keep running into this issue

Connect-Appliance : Cannot bind parameter 'Password'. Cannot convert the "System.Security.SecureString" value of type "System.String" to type "System.Security.SecureString". At line:1 char:69 + Connect-Appliance -host 172.25.2.110 -user admin -Password System.Secur ... + ~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) [Connect-Appliance], ParameterBindingException + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,CPowerCLI.ConnectAppliance

And I can't figure out why. I thought at first, it's because I'm providing a string but the variable is declared as a SecureString.

Is it possible to do this?

What I can do is

$password = Read-Host -AsSecureString "Pass"
Connect-Appliance -host 172.25.2.110 -user admin -password $password -quiet

And that seems to work just fine. But when I call that from the psm1 file, it doesn't work with the error above.

thanks

3

There are 3 answers

0
Chand On BEST ANSWER

u should convert back the secure string to Bstring

$Password = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($passwordenc))

Connect-Appliance -host 172.25.2.110 -user admin -password $password -quiet

i hope this helps.

0
anoopb On

I didn't need the

Invoke-Expression

part in the code

This worked just fine

Connect-Appliance -host $host -user $user -Password $passwordenc -Quiet

Since I wasn't capturing the output, i didn't need Invoke-Expression

0
Gus Whitehouse On

anoopb, I've faced the same issue before. More an FYI, but here is essentially the answer wrapped in a function:

function ConvertFrom-SecureToPlain {

        param(
            [Parameter(Mandatory=$true)][System.Security.SecureString] $SecurePassword
        )

        # Create a "password pointer"
        $PasswordPointer = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword)

        # Get the plain text version of the password
        $PlainTextPassword = [Runtime.InteropServices.Marshal]::PtrToStringAuto($PasswordPointer)

        # Free the pointer
        [Runtime.InteropServices.Marshal]::ZeroFreeBSTR($PasswordPointer)

        # Return the plain text password
        return $PlainTextPassword

}