text: Q:
  
  Windows batch file does not wait for commands to complete
  
  I have a batch file, which exists as soon as start it (run as admin) and does not execute commands that are in it, but if I specify it at the command-line, it runs fine and executes all commands. 
  Here's what's in it:
  start /wait msiexec /x SetupServices.msi /qn /l* "SetupServices.uninstall.log"
  
  start /wait msiexec /i SetupServices.msi /qn /l* "SetupServices.install.log"
  
  A:
  
  (Corrected answer)
  First, if you start .exe files in a batch, it is safer, to prefix it with "call".
  Sometimes this is necessary to assure, that the batch is waiting to complete.
  Using "start" is another possibility, but for this simple usecase not necessary.
  You write that the commands are not executed. So, obviously, you have another problem, instead of the "does not wait.. to complete" problem.
  Taking a look of your newly provided example, this is the case. In admin mode, you have to provide a full path. With my small trick below ("%~dp0", including already backslash), you can still use the current directory in batchfiles.
  Most times, if such a problem occurs with admin rights, this is a problem of the "current directory" path. A batch file with admin rights is not using it in the same way as we were used to, it does not start in it's own directory (but in System32 mostly). Not relying on the CD is an important matter of writing bullet-proof batch files.
  A good example batch , combining other answers here, and solving a number of possible problems in your case is:
  call msiexec /i "%~dp0MySetup.msi" /qb /L*v "%~dp0MySetup.log"
  echo Returncode: %ERRORLEVEL%
  pause
  
  It uses the current directory correctly, and assumes an install commandline including a logfile (works only, if you have write access in the current directory, if not specify a path for the logfile with write access like "%TEMP%\MySetup.log".
  Attention: Remember to really start the batch file with admin rights (right mouse menu or opening an admin command shell before:)
  
  A:
  
  Coming back to this question I think the "correct way" to do it is via PowerShell
  Start-Process -Wait -FilePath msiexec -ArgumentList /i, "setup.msi", /qn, /l*v, "install.log"   
  
  Or just prefix it with PowerShell; to invoke directly from CMD
  PowerShell; Start-Process -Wait -FilePath msiexec -ArgumentList /i, "setup.msi", /qn, /l*v, "install.log"
  
  No hacks and no tricks :-)
  
  