I am getting an issue when trying to pass a securestring in to a powershell script, but it's coming back with this error?
Cannot process argument transformation on parameter 'Password'.
Cannot convert the "ConvertTo-SecureString" value
of type "System.String" to type "System.Security.SecureString".
$SecureServiceAccountPassword = ConvertTo-SecureString "somethingstong!" `
-AsPlainText -Force
$AgentAccount = "myAccount"
$ServiceAccountOU = "MYOU"
POWERSHELL -COMMAND $ADAccountScript `
-ServiceAccountOU $ServiceAccountOU `
-Account $AgentAccount `
-Password $SecureAgentAccountPassword
The script that it's calling is this.
param(
##MasterKey for KeePass currently stored in a DB.
[Parameter(Position=0,mandatory=$true)] [string] $ServiceAccountOU,
##Account to be created in AD
[Parameter(Position=1,mandatory=$true)] [string] $Account,
[Parameter(Position=2,mandatory=$true)] [SecureString] $Password
)
NEW-ADUSER -Name $Account `
-AccountPassword $Password `
-Path $SrviceAccountOU `
-Enabled $True `
-PasswordNeverExpires $True `
-CannotChangePassword $True
To pass a [securestring] (System.Security.SecureString) instance as such via PowerShell's CLI (powershell.exe in Windows PowerShell, pwsh in PowerShell (Core) 7+), you must pass the command to execute (-Command / -c) as a script block.[1]
[securestring] - assuming the input string wasn't obtained via a plain-text representation (as shown in the question) - is undoubtedly better than using plain-text passwords, use of [securestring] in new projects is discouraged, because it offers no protection on Unix-like platforms and only limited protection on Windows. See this .NET platform-compatibility recommendation and this answer.Note that this passing a script block as the command to execute only works when you call from an existing PowerShell session - where the need to invoke a script via another PowerShell instance (the child process created by the CLI call) rather than by direct invocation (in-process in the same session) is unusual, however.
In your case, the simplest solution is:
powershell -c {
$scriptFile, $passThruArgs = $args
& $scriptFile @passThruArgs
} -args $ADAccountScript, $ServiceAccountOU, $AgentAccount, $SecureServiceAccountPassword
Note that this relies on positional argument-passing.
If you wanted to use named arguments, as in your own attempt, you'd have to resort to hashtable-based splatting
# Create the hashtable whose entries map onto the target
# script's parameters.
$htArgs = @{
ServiceAccountOU = 'foo'
Account = 'bar'
Password = ConvertTo-SecureString "somethingstrong!" -AsPlainText -Force
}
powershell -c {
$scriptFile, $passThruArgs = $args
& $scriptFile @passThruArgs
} -args $ADAccountScript, $htArgs
[1] If you pass the -Command / -c argument as a string - which is the only option when calling PowerShell's CLI from outside PowerShell - a [securestring] is passed as its string representation, which is its full type name, verbatim: 'System.Security.SecureString'; that is, the actual, "secure" content is lost.
By contrast, passing a script block triggers CLIXML-based serialization behind the scenes, where passing and receiving objects rather than only text is supported - see this answer for more information.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With