Dynamic PowerShell
November 23, 2010 14 Comments
I learned something new while giving my PowerShell session at the PASS Community Summit a couple of weeks ago.
One astute attendee asked if it was possible to create dynamic PowerShell in a script. Or put another way, can you define a PowerShell statement in a variable and then tell PowerShell to execute the contents of that variable. I’d never tried that so I didn’t know the answer. I said as much and speculated that it was possible and that I’d check into it for him.
Fortunately, there are a lot of really smart and knowledgeable people at conferences; not all of them speak. That can sometimes be intimidating; it can also be very helpful. Another attendee came up to me after the session and showed me this little script.
Executing Dynamic PowerShell
In the script, the $cmd variable is assigned a literal value that is itself a PowerShell statement. You could substitute any valid PowerShell statements in place of Get-Process. The second line is where it gets interesting. Enclosing the variable in parenthesis and prefacing it with an ampersand tells PowerShell to evaluate the contents of the variable and execute those dynamically.
$cmd = ‘Get-Process’;
&($cmd);
When I ran this script, I received a list of processes running on my local computer.
With this simple example, you may ask “What’s the point? Why not execute Get-Process directly?” I can see instances where you may need to dynamically build statements that include aspects that are not known at design-time. For example, passing in a sort or filter criteria, a machine name, or even a SQL Server instance name.
I wish I’d gotten the name of the attendee that showed this to me; I’d give him credit for this. So to the unknown Posher, thank you.
Glad I could help {=0)
Pingback: Biztalk Musings | Dynamic Powershell
You can also use the Invoke-Expression cmdlet.
Very cool. I’ll give that a try as well. Thanks for sharing.
and without parenthesises it works too
$cmd = ‘Get-Process’;
&$cmd;
Thanks, Joe, that will come in handy. A related topic that you probably covered in your session, but I’ll note here for other readers, is that there is also automatic variable substitution in strings if you use double-quotes instead of single-quotes. One example Allen White gave in his Pre-Con is this:
$instance = ‘(localhost)’
$db = ‘AdventureWorks’
$connString = “Data Source=$instance;Initial Catalog=$db;Integrated Security=SSPI”
This will put the values of the variables $instance and $db into the value assigned to $connString. This feature could come in handy, especially in conjunction with the dynamic execution you showed.
Yes, PowerShell does a great job with interpreting variables. Thanks for mentioning this, Mark!
Very cool. I’ll give that a try as well. Thanks for sharing.
Hello everybody,
I’m just trying to execute a dynamic powershell command, but I got an error.
If I do:
Get-ChildItem -path c:\temp
it works fine but if I do:
$cmd = ‘Get-ChildItem -path c:\temp’;
&($cmd)
I got the following error: “The term ‘Get-ChildItem -path c:\temp’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify the path is correct and try again.
Obviously I checked the path and the name and both are correct.
Any Idea ?
Thanks.
I’m not sure what the cause of the error is, but if you use Invoke-Expression (or iex for short) it will work. I have been trying to figure out why “&” works in some cases and not in others, but Invoke-Expression always seems to work.
Using “&” seems to evaluate the entire string as a single cmdlet inted of the cmdlet and related parameters.
I tried Invoke-Expression it and it works well.
Thanks a lot Michael.
I like what you guys are up too. Such clever work and exposure!
Keep up the wonderful works guys I’ve incorporated you guys to my personal
blogroll.
Pingback: Confluence: ECU Foglight APM Demo
Pingback: Confluence: Quick Exchange Migration