I would like a command that I can put at the end of a batch file and that it could allow me to remove the usb device where the batch file is stored in safely.

I found a powershell command that can achieve this but when I try to run it from cmd it does not work ("%~d0" is the variable for the USB path):

powershell -command "$driveEject = New-Object -comObject Shell.Application ; $driveEject.Namespace(17).ParseName("%~d0").InvokeVerb("Eject")"

Here's the error message I get:

At line:1 char:93
+ ... ject Shell.Application ; $driveEject.Namespace(17).ParseName(E:).Invo ...
+                                                                  ~
Missing ')' in method call.
At line:1 char:93
+ ... ct Shell.Application ; $driveEject.Namespace(17).ParseName(E:).Invoke ...
+                                                                ~~
Unexpected token 'E:' in expression or statement.
At line:1 char:95
+ ... t Shell.Application ; $driveEject.Namespace(17).ParseName(E:).InvokeV ...
+                                                                 ~
Unexpected token ')' in expression or statement.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : MissingEndParenthesisInMethodCall

Along with what @JoseZ gave you, If you'd place this one-liner in the PoSH ISE or VSCode, you'll see that the color coding indicates syntax errors. Dotted properties should be black in color, So, your .Namespace, .ParseName and .InvokeVerb are shown as strings, indicated by the color and thus will fail.

Try it this way, just dropping all the variable stuff, thus eliminating all the extra quote escaping things.

powershell -command "(New-Object -comObject Shell.Application).NameSpace(17).ParseName('F:').InvokeVerb('Eject')"

Test on one of my systems, so I know this works as written.

Lastly, since you are able and plan to use PoSH for this, why the use of a batch file?


About Quoting Rules article describes rules for using single and double quotation marks in PowerShell. Use

…; $driveEject.Namespace(17).ParseName('%~d0').InvokeVerb('Eject')"

or (you need to escape inner double quotes for cmd as well)

…; $driveEject.Namespace(17).ParseName("""%~d0""").InvokeVerb("""Eject""")"

However, a Powershell Best Practice source deprecates the latter: It is recommended to avoid double quotes if there are no variables or escape sequences in strings, prefer single quotes.

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.