I have a few pointers that might help you out with what you're trying to do here.
First and foremost, if you are trying to execute an application in PowerShell using a full path and that path has a space in it, you must use the call operator. To show you what I mean, compare the results of this:
'C:\Program Files\Microsoft\Exchange Server\Bin\eseutil.exe'
with this:
& 'C:\Program Files\Microsoft\Exchange Server\Bin\eseutil.exe'
In the first case, PowerShell just outputs the string you gave it. Why? Because anything in quotes is treated as a string. In the second case, PowerShell actually knows that your string you've entered is a path to a command you're trying to execute. That's the purpose of the call operator in this case: to instruct PowerShell that the subsequent string is actually the path to an application you want to execute.
The same thing holds true for any path you have entered in quotes. If you want to execute the string path as if it is an application, you need the call operator. The error you are getting is simply trying to point out that fact, even if the error is not very clear. Look at this:
'Hello' /d 'Goodbye'
It will give you the same error. PowerShell sees the first token is a string, then it finds the / operator and when it looks for a valid expression on the right of the / operator it can't find it, so it raises an error saying so. Compare that error with the one that shows up from this command:
'Hello' / 'Goodbye'
This will raise an error saying that strings don't support the division operator. Maybe if PowerShell checked to see if the object on the left supported the operator and raised this error before it looked on the right hand side for a valid operand expression it would have helped you understand what is going on here.
Now, about how you're trying to build out your expression. People instinctively gravitate towards regular strings when they want to build out commands. It's probably the case because they think if they're trying to build a string command they need to use a string. The problem with doing this is that you have to escape quotation marks sometimes, insert newline characters, etc, depending on what you're trying to do. And if you're using a cool PowerShell script editor like PowerGUI, you lose the syntax highlighting and intellisense for anything you put in your string, making it easier to introduce typos and other formatting errors that would otherwise be obvious with the proper code highlighting in place.
Given that is the case, what's the alternative? Well, there are actually two alternatives: here-strings and script blocks. Here-strings are great when you really want to be able to see the command you are building as a string without worrying about escaping a bunch of quotes and the like. Script blocks are great when you want to execute a command or script with certain parameters dynamically and you don't want to make a named function for it, or when you want to take an existing command or script and convert it into a string. A script block is essentially an unnamed function. It can accept named parameters just like a function can, and it can be output in string format if you want to see it in string format.
Armed with those alternatives, let's take a closer look at your script. You indicated that you're trying to build out a command that uses dynamic SG numbers and DB numbers and it seems that you're trying to measure the performance of that command by using the Measure-Command cmdlet. Here's the sort of approach I recommend you take with this using script blocks and here-strings instead of regular strings:
$scriptBlock = {
param(
[int]$SgNumber = $(throw 'SgNumber is a required parameter!'),
[int]$DbNumber = $(throw 'DbNumber is a required parameter!'),
[Switch]$OutputCommandOnly
)
if ($OutputCommandOnly) {
@"
& 'C:\Program Files\Microsoft\Exchange Server\Bin\eseutil.exe' /d "I:\Exchange Store\SG$SgNumber DB$DbNumber\Store SG$SgNumber DB$DbNumber.edb" /t "I:\defrag\Store SG$SgNumber DB$DbNumber.edb"
"@
} else {
& 'C:\Program Files\Microsoft\Exchange Server\Bin\eseutil.exe' /d "I:\Exchange Store\SG$SgNumber DB$DbNumber\Store SG$SgNumber DB$DbNumber.edb" /t "I:\defrag\Store SG$SgNumber DB$DbNumber.edb"
}
}
# View the commands we will run first
& $scriptBlock 1 2 -OutputCommandOnly
& $scriptBlock 3 4 -OutputCommandOnly
& $scriptBlock 5 6 -OutputCommandOnly
& $scriptBlock 7 8 -OutputCommandOnly
& $scriptBlock 9 10 -OutputCommandOnly
# Now run the commands and measure their times
$cmdTime1 = Measure-Command {& $scriptBlock 1 2}
$cmdTime2 = Measure-Command {& $scriptBlock 3 4}
$cmdTime3 = Measure-Command {& $scriptBlock 5 6}
$cmdTime4 = Measure-Command {& $scriptBlock 7 8}
$cmdTime5 = Measure-Command {& $scriptBlock 9 10}
Give that script a look and let us know how you get along.
--
Kirk Munro [MVP]
Poshoholic
http://poshoholic.com |