Quite a while ago I found [Wayback] windows 7 – How can I eject a CD via the cmd? – Super User, but forgot to document that in the batch-files I created from it.
It shows both this one-liner:
powershell "(new-object -COM Shell.Application).NameSpace(17).ParseName('D:').InvokeVerb('Eject')"
The hardcoded const 17 is for the ssfDRIVES element in the ShellSpecialFolderConstants, which is documented at [Wayback] ShellSpecialFolderConstants (shldisp.h) – Win32 apps | Microsoft Docs.
There is no PowerShell equivalent of that element, hence the hardcoded value 17.
The script invokes the verb Eject, which works on any kind of removable media (not just optical drives). If you want to limit it to only certain drive types, then you would need to compare the Type of the ParseName() result. However, that result has a Type property returns a string for which the possible values are not documented.
Here are some links I tried to find out what is returned:
- [Wayback] Shell.NameSpace method (Shldisp.h) – Win32 apps | Microsoft Docs (returned by
(new-object -COM Shell.Application)) - [Wayback] Folder object (Shldisp.h) – Win32 apps | Microsoft Docs (returned by
NameSpace(17)) - [Wayback] Folder.ParseName method (Shldisp.h) – Win32 apps | Microsoft Docs (returns a list of
FolderItemstructures) - [Wayback] FolderItem object (Shldisp.h) – Win32 apps | Microsoft Docs (returned by
ParseName('D:')) - [Wayback] FolderItem.InvokeVerb method (Shldisp.h) – Win32 apps | Microsoft Docs (executes the
Verbon theFolterItem) - [Wayback] FolderItem.Verbs method (Shldisp.h) – Win32 apps | Microsoft Docs (lists the verbs the
FolderItemsupports to be executed viaInvokeVerb) - [Wayback] FolderItem.Type property (Shldisp.h) – Win32 apps | Microsoft Docs (string indicating the type, which for a
FolderItemrepresenting a drive will be the drive type)
In addition to the Shell.Application, there also is Scripting.FileSystemObject, which allows enumerating the drives and filter on DriveType. This is the relevant documentation:
- [Wayback] FileSystemObject Object | Microsoft Docs
- [Wayback] Drives Property | Microsoft Docs which returns a
Drivescollection type where each item is aDrivetype. - [Wayback] Drives Collection | Microsoft Docs collection of
Drivetype elements - [Wayback] Drive Object | Microsoft Docs a single element of the
Drivescollection - [Wayback] DriveType Property | Microsoft Docs property of the
Drivetype indicating the type of drive:
Case 0: t = "Unknown" Case 1: t = "Removable" Case 2: t = "Fixed" Case 3: t = "Network" Case 4: t = "CD-ROM" Case 5: t = "RAM Disk"
The second example in the above mentioned answer shows how to use this to filter for optical drives.
It also shows a cool technique to have a hybrid batch-file/JScript script:
@if (@CodeSection == @Batch) @then @echo off setlocal cscript /nologo /e:JScript "%~f0" goto :EOF @end // end batch / begin JScript hybrid chimera // DriveType=4 means CD drive for a WScript FSO object. // See http://msdn.microsoft.com/en-us/library/ys4ctaz0%28v=vs.84%29.aspx // NameSpace(17) = ssfDRIVES, or My Computer. // See http://msdn.microsoft.com/en-us/library/windows/desktop/bb774096%28v=vs.85%29.aspx var oSH = new ActiveXObject('Shell.Application'), FSO = new ActiveXObject('Scripting.FileSystemObject'), CDdriveType = 4, ssfDRIVES = 17, drives = new Enumerator(FSO.Drives); while (!drives.atEnd()) { var x = drives.item(); if (x.DriveType == CDdriveType) { oSH.NameSpace(ssfDRIVES).ParseName(x.DriveLetter + ':').InvokeVerb('Eject'); while (x.IsReady) WSH.Sleep(50); } drives.moveNext(); }
–jeroen





