All PowerShell versions
Try and avoid Invoke-Expression in your scripts. This cmdlet takes a string and executes it as if it was a command. In most scenarios, it is not needed, but introduces many risks.
Here is a–somewhat constructed–show case:
function Test-BadBehavior($Path) { Invoke-Expression "Get-ChildItem -Path $Path" }
This function uses Invoke-Expression to run a command and append a parameter value. So it would return a folder listing for the path entered as parameter.
Since Invoke-Expression accepts any string, you open up your environment to “SQL-Injection”-like attacks. Try running the function like this:
PS> Test-BadBehavior 'c:\;Get-Process'
It now would also run the second command and list all running processes. Invoke-Expression is often used by attackers when they download the evil payload as string from some outside URL and then execute the code on-the-fly.
Of course, Invoke-Expression would not have been necessary in the first place. It is hardly ever needed in typical production scripts. Make sure you hardcode the commands you want to execute:
function Test-BadBehavior($Path) { Get-ChildItem -Path $Path }