I have a few build scripts that call non-powershell EXEs to do work simply because of the lack of cmdlets available and my unwillingness to reverse engineer exactly what the supplied command line programs do. I tend to call them using invoke-expression after building the exact syntax in a variable. So for example, a very little snippet:
$cmd = 'certutil.exe -setreg CA\CRLPublicationURLs "1:'+$env:SystemRoot+'\system32\CertSrv\CertEnroll\%3%8%9.crl\n2:http://'+$FQDN+'/pki/%3%8%9.crl"'
Invoke-Expression $cmd | Write-Verbose
I’ve noticed PSScriptAnalyzer really doesn’t like me using Invoke-Expression like … at all. So while I correct most of the recommendations this is one I’ve ignored over time.
What is the best -practice reasoning for avoiding invoke-expression? Is it because of a code-injection risk? I think the context would help me to determine under which cases I should indeed go down the path of making my own tools vs. saying “meh, for this scenario it’s fine”.
Yes, Invoke-Expression opens you up to code injection attacks. Even when calling an external command like certutil.exe, you don’t need to use Invoke-Expression; this is safe, and accomplishes the same thing:
certutil.exe -setreg CA\CRLPublicationURLs "1:$env:SystemRoot\system32\CertSrv\CertEnroll\%3%8%9.crl\n2:http://$FQDN/pki/%3%8%9.crl" |
That said, if you completely control the variables that are being used to construct your command (no outside input at all), then there is not really any risk involved. However, here’s an example of what might happen if $FQDN were loaded up from some potentially untrusted source (registry key, config file, whatever):
$FQDN = '" > $null 2>&1; Write-Host -ForegroundColor Green "gotcha!"; #'
I never responded to this but thank you: I guess I merely assumed cmd/DOS based programs would not integrate that seamlessly into PowerShell so the “correct” way to do it was to wrap the command into an invoke.
A good overview of running executables is available here: http://social.technet.microsoft.com/wiki/contents/articles/7703.powershell-running-executables.aspx
Worth checking out depending on your needs.