Error when using SecureString variable with Invoke-Expression

I have the below script which uses Set-ADAccountPassword to change the AD password of a user. I am getting the following error when running the script:

Cannot bind parameter ‘NewPassword’. Cannot convert the “System.Security.SecureString” value of type “System.String” to type “System.Security.SecureString”.

The error occurs at the line: Invoke-Expression $command. I used Write-Output $command before this line to debug it and its output is Set-ADAccountPassword -Identity 12345678 -Reset -NewPassword System.Security.SecureString (where 1234568 is the redacted user account). If I run Set-ADAccountPassword -Identity $id -Reset -NewPassword $pass directly in powershell, it works. Why isn’t this command working with Invoke-Expression?

The full script is:

function Run-Command
param ($command)

Write-Output $command # debugging output
Invoke-Expression $command # error occurs here

catch [System.Exception]
Write-Host $_ -foreground red


$pass = Read-Host ‘Enter new password’ -AsSecureString

Run-Command -command “Set-ADAccountPassword -Identity $id -Reset -NewPassword $pass”

What’s the purpose of Run-Command!!??

Your Run-Command function here doesn’t work because $pass is a SecureString (TypeName: System.Security.SecureString)
This expression

"Set-ADAccountPassword -Identity $id -Reset -NewPassword $pass"

sends a String after -NewPassword

Again, What’s the purpose of Run-Command!!??

I am also running other AD cmdlets such as Unlock-ADAccount and Get-ADUser, and am passing these commands and their parameters to Run-Command so that I don’t repeat the error handling with try catch.

I also tried passing $pass to Run-Command, but not sure how to get it to work as the only thing that comes to mind is concatenating $pass with $command, but this obviously won’t work as $pass is a SecureString.