I’ve got a wrapper powershell script that I’m hoping to use to automate a few things. It’s pretty basic, and accepts a parameter that I want the script to run as if it were a line in the script. I absolutely cannot get it to work.
example:
param( [string[]] $p)
echo $p
# Adds the base cmdlets
Add-PSSnapin VMware.VimAutomation.Core
# Add the following if you want to do things with Update Manager
Add-PSSnapin VMware.VumAutomation
# This script adds some helper functions and sets the appearance. You can pick and choose parts of this file for a fully custom appearance.
. "C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\Scripts\Initialize-VIToolkitEnvironment.ps1"
$p
In the example above, I want $p to execute as if it were a line in the script. I know this isn’t secure, and that’s probably where the problem lies.
Here is how I try running the script and passing in a parameter for $p:
D:\ps\test>powershell -command "D:\ps\test\powershell_wrapper.ps1" 'Suspend-VM servername -Verbose -Confirm:$False'
How can I get my parameter of ‘Suspend-VM servername -Verbose -Confirm:$False’ to run inside my script? If I just include the value in the script instead of pass it in as a parameter it runs without any issues…
You can basically approach this two ways, depending on what your needs really are and how you want to structure your code.
Approach #1 – Invoke-Expression
Invoke-Expressionbasically allows you to treat a string like an expression and evaluate it. Consider the following trivial example:That will evaluate the string as if it were an expression typed in directly, and place the string “Hello World” on the pipeline. You could use that to take your string parameter and run it on-the-fly in your script.
Approach #2 – Using a ScriptBlock
PowerShell has a special data type called a ScriptBlock, where you can bind a script to a variable, and then invoke that script as part of your code. Again, here is a trivial example:
This example creates a function with a single parameter $sb that is of type ScriptBlock. Notice the parameter is bound to the actual chunk of code
{"Hello World"}? That code is assigned to the $sb parameter, and then a call to the .Invoke method actually executes the code. You could adapt your code to take in a ScriptBlock and invoke it as part of your script.Approach #3 – Updating your profile
OK, so I said there were two ways to approach it. There is actually a third… sort of… You could add the VMWare cmdlets to your
$profileso they are always present and you don’t need your wrapper to load in those libraries. Granted, this is a pretty big hammer – but it might make sense if this is the environment you are constantly working in. You could also just create a shortcut to PowerShell that runs a .ps1 on startup that includes those libraries and hangs around (this is what MS did with the SharePoint admin shell and several others). Take a look at this TechNet page to get more info on the $profile and if it can help you out:http://msdn.microsoft.com/en-us/library/windows/desktop/bb613488.aspx