3

I'm working with a batch script that needs admin rights and I borrowed some get-admin-rights code from the 'net. I'm trying to figure out what the last part of a particular line does:

set params = %*:"=""

I know the first part creates a variable, then retrieves the whole set of parameters passed to the script;

set params = %*

But what on earth is this doing?

:"=""
  • My get-admin-rights code, which works properly, contains set "User=#" rather than set params = %*:"="". – Matthew Wai Sep 23 at 2:16
5

Assuming you have copied the code correctly - it does nothing special at all. The :"="" literal is simply appended to the expanded argument string.

If you had %*:"=""% (note the additional percent), then it would expand an environment variable named *, substituting two quotes for every one.

The Find/Replace expansion feature is only available to variable expansion, not argument expansion.

I'd be willing to bet it is a bug introduced by someone who has very little experience with the batch language.

There is almost surely another bug - All spaces in the assignment are significant. So it is creating a variable named "params " (without the quotes, note the trailing space). Also, the value will have a leading space. I'm pretty sure neither space is wanted.

Updated, more complete answer

Now that we know the source of the code, it is possible to give a more complete picture as to what is going on. More code context is needed.

The original relevant lines are:

set params = %*:"=""
echo UAC.ShellExecute "cmd.exe", "/c ""%~s0"" %params%", "", "runas", 1 >> "%temp%\getadmin.vbs"

The original batch script required that it be run with elevated admin privileges. The script was able to determine if admin privs were available, and if not, then it created a temporary VBS script that when run, would create a new cmd.exe session with admin privs, and rerun the original batch script with the same original arguments. The command to rerun the script is embedded in a VBS string, and the string may include quoted arguments. VBS requires that quote literals within a string be escaped by doubling them.

The original answer did not preserve the arguments, and did not have any params variable. One year later, the OP attempted to extend the answer to support preservation of the calling arguments. Unfortunately, the modified code was never properly tested, and the "enhancement" was seriously bugged. If you look at the many comments to that answer, you can see many reports that the argument preservation was still not working.

First off, the code defines a variable named "params " (with trailing space), and then attempts to use an undefined variable named "params" (without trailing space). That obviously can't work. But simply removing the spaces from the definition does not solve anything.

set params=%*:"=""

The OP must have thought that syntax would expand to the original argument string, with all quotes doubled. But find/replace only works when expanding variables, not arguments.

Assume the original batch script is c:\test\test.bat, and it is called using

test arg1 "arg 2" "arg 3"

The "corrected" line set params=%*:"="" simply gets a copy of the arguments with %*, and then appends the :"="" string. So when complete, the variable is defined as follows:

params=arg1 "arg 2" "arg 3":"=""

But the OP actually wanted:

params=arg1 ""arg 2"" ""arg 3""

The next line that is used to re-execute the script with admin privileges would fail. It would expand to:

echo UAC.ShellExecute "cmd.exe", "/c ""c:\test\test.bat"" arg1 "arg 2" "arg 3":"=""", "", "runas", 1 >> "someTempPath\getadmin.vbs"

Here is the code as it should have been written:
EDIT 2018-9-23: added space to params assignment to make sure it is always defined, even if no arguments

set params= %*
echo UAC.ShellExecute "cmd.exe", "/c ""%~s0"" %params:"=""%", "", "runas", 1 >> "%temp%\getadmin.vbs"

The first line simply defines params as

params= arg1 "arg 2" "arg 3"

And the next line uses the :"="" syntax to double all quotes while expanding the params variable:

echo UAC.ShellExecute "cmd.exe", "/c ""c:\test\test.bat""  arg1 ""arg 2"" ""arg 3""", "", "runas", 1 >> "someTempPath\getadmin.vbs"

The original arguments are preserved, and all quotes have been properly doubled.

I have edited the original answer to incorporate the bug fixes.

  • Some more research into this shows that this answer is incorrect. %* is a reference to all parameters passed through a .cmd file. So: myfile.cmd 1 2 3 4 5 will give "1 2 3 4 5" inside %*, similar to %1 giving just 1. – LPChip Sep 14 '17 at 8:19
  • @LPChip - And what is incorrect about my answer? When I referred to the "expanded argument string", that is exactly what I meant. In your example, the expansion of %* (the argument string) is indeed 1 2 3 4 5, and then :"="" is appended. Perhaps I could have given an example to make things more clear, but I fail to see any incorrect statements in my answer. – dbenham Sep 14 '17 at 15:01
  • There was a bug in my original fix if no arguments were passed. I added a space to the params assignment to fix the bug. – dbenham Sep 23 '18 at 16:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.