Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

List Unmounted Volume #s in batch with Diskpart or WMI

2,263 views
Skip to first unread message

Sam Bul

unread,
Jan 21, 2012, 12:32:38 PM1/21/12
to
Hello,

I need to create a Win7 Console batch that lists only unmounted
volume "Numbers & Labels (if any)" for all or a given disk number.
Once volume numbers are found, I can use Diskpart or WMIC or Mountvol
to mount them with a drive letter, auto assigned by Windows. Can
someone suggest a shortest batch code to do that?

Frank P. Westlake

unread,
Jan 21, 2012, 1:24:12 PM1/21/12
to
On 2012-01-21 09:32, Sam Bul wrote:
> I need to create a Win7 Console batch that lists only unmounted
> volume "Numbers& Labels (if any)" for all or a given disk number.

You can evolve this script into that. Using it as it is you could read
it's output with a FOR circle and run it again with each volume ID to
see what the mount points are, but it would be much better to evolve it
into something more to the point.

Usage:
mountpoints
or
mountpoints \\?\Volume{18d25046-d81c-11e0-b360-806e6f2e6964}\
:: With a volume ID from your machine.

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: mountPoints.cmd
:: From the desk of Frank P. Westlake, 2011-11-11.
:: Gets the mount point paths given a volume designation.
::
@Echo OFF
SetLocal EnableExtensions EnableDelayedExpansion
Set "toFind=%~1"
Call :trim toFind
Set "volumeName="
Set "volumePath="
Set "space= "
:: A copy should be checked to ensure that 'tab' is a tab character.
Set "tab= "
For /F "delims= " %%a in ("1%TAB%") Do If "%%~a" EQU "1" (
(Echo The variable 'TAB' must be defined as a tab character.
Set /P "=LINE "<NUL:
FindStr /n /i /c:"TAB=" "%~f0"|FindStr /v "FindStr")>&2
Goto :EOF
)
For /F "delims=" %%A in ('%SystemRoot%\System32\mountvol.exe') Do (
For /F %%a in ("%%A") Do (
Set "item=%%a"
If NOT DEFINED toFind (
If "!item:~0,11!"=="\\?\Volume{" (Echo(%%a)
) Else If DEFINED volumeName (
If "!item:~0,11!"=="\\?\Volume{" (
Goto :break
) Else (
Set "volumePath=%%~A"
Call :trim volumePath
Echo(!volumePath!
)
) Else If "%%a"=="%toFind%" (
Set "volumeName=%%a"
)
)
)
:break
Goto :EOF
:trim
If "!%~1:~0,1!" EQU "%space%" (Set "%~1=!%~1:~1!" & Call %0 %1)
If "!%~1:~0,1!" EQU "%tab%" (Set "%~1=!%~1:~1!" & Call %0 %1)
If "!%~1:~-1!" EQU "%space%" (Set "%~1=!%~1:~0,-1!" & Call %0 %1)
If "!%~1:~-1!" EQU "%tab%" (Set "%~1=!%~1:~0,-1!" & Call %0 %1)
Goto :EOF
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

Frank

foxidrive

unread,
Jan 21, 2012, 1:58:42 PM1/21/12
to
Taking the info from Frank's post

mountvol|find "\"

will give you a list of the volumes and mountpoints if they exist.

If you need help to develop something that removes volumes that do have mountpoints then post back the output from above, including volumes without mountpoints.



--
Mic

Sambul32

unread,
Jan 21, 2012, 2:51:07 PM1/21/12
to
Thanks!

The problem is, I need to list & link unmounted volumes to a specific
physical or virtual disk. For example, a virtual disk was attached,
but some of its volumes weren't auto mounted. I know the disk number,
and need to find what its volumes don't have drive letters, then mount
them. Without affecting other unmounted volumes in the system.

LIST UNMOUNTED VOLUMES for DISK 3 or GUID... with Diskpart or WMIC
script? Its not that easy compare to listing all unmounted volumes,
since MS for some reason don't link volumes to disks in a simple way.

Frank P. Westlake

unread,
Jan 21, 2012, 3:30:20 PM1/21/12
to
On 2012-01-21 11:51, Sambul32 wrote:
> LIST UNMOUNTED VOLUMES for DISK 3 or GUID... with Diskpart or WMIC
> script?

So what you need is a script for DISKPART. Just walk through DISKPART
manually and keep track of all your commands. I don't have much
experience with it but is what you want at the following?

SELECT DISK 3
DETAIL DISK

Create a script with those two lines and feed it to 'DISKPART /S ...'.
Then you can read that with a FOR circle using FINDSTR to get lines
beginning with space, then set the line into a variable and check the
character at offset 15. A space is an unmounted volume.

Something like that.

Frank

Sambul32

unread,
Jan 21, 2012, 6:11:33 PM1/21/12
to
Thanks Frank,

That's exactly what I was trying to do, but get stack (literally). I'm
not that experienced in FOR circles. That's how it looks like:
Volume 13 F Test1 NTFS Partition 422 MB Healthy
Volume 14 Test2 NTFS Partition 100 MB Healthy
Volume 15 G Test3 NTFS Partition 499 MB Healthy

So, when I try using FOR:

for /L %%i in (%vol%,-1,%vlm%) do (
FOR /F "tokens=2,3,4,5 delims= " %%A IN ('%%diskpart%% ^| find
"Volume %%i"') DO (
set vlc=!vlc!%%A & set ltb=!ltb! %%B & set lbl=!lbl!%%C & set fst=!
fst! %%D)
)
echo %vlc% %ltb% %lbl% %fst%

Test2 goes in place of DriveLetter, and if there is no Label, NTFS
substitutes it. The problem is, "tokens" routing design substitutes
several "spaces" with "single space". How I can get it to work - can
you give a working example code for the above case?

Also, sorting content of the !expanded! variables - can you suggest
some example how?

Sambul32

unread,
Jan 21, 2012, 10:02:19 PM1/21/12
to
Hello Frank,

Forget to mention, Diskpart output can be more diverse:

Volume 8 F Windows Sev NTFS Partition 422 MB Healthy
System
Volume 9 1 NTFS Partition 100 MB
Healthy
Volume 10 G Test3 NTFS Partition 49 GB
Healthy
Volume 11 FAT32 Partition 0 B
Healthy
Volume 12 H DS1 NTFS Partition 499 MB
Healthy

The columns may look misaligned in the post, but they are aligned on
screen. But the volume Label can be shifted along its field on real
system - just try to rename a disk. :) What I really need is a working
example code.

Todd Vargo

unread,
Jan 22, 2012, 10:52:50 PM1/22/12
to
On 1/21/2012 6:11 PM, Sambul32 wrote:
> Thanks Frank,
>
> That's exactly what I was trying to do, but get stack (literally). I'm
> not that experienced in FOR circles. That's how it looks like:
> Volume 13 F Test1 NTFS Partition 422 MB Healthy
> Volume 14 Test2 NTFS Partition 100 MB Healthy
> Volume 15 G Test3 NTFS Partition 499 MB Healthy
>
> So, when I try using FOR:
>
> for /L %%i in (%vol%,-1,%vlm%) do (
> FOR /F "tokens=2,3,4,5 delims= " %%A IN ('%%diskpart%% ^| find
> "Volume %%i"') DO (
> set vlc=!vlc!%%A& set ltb=!ltb! %%B& set lbl=!lbl!%%C& set fst=!
> fst! %%D)
> )
> echo %vlc% %ltb% %lbl% %fst%
>
> Test2 goes in place of DriveLetter, and if there is no Label, NTFS
> substitutes it. The problem is, "tokens" routing design substitutes
> several "spaces" with "single space". How I can get it to work - can
> you give a working example code for the above case?
>
> Also, sorting content of the !expanded! variables - can you suggest
> some example how?

The following tested script allows you to assign the next available
drive letter to your specified volume label(Test2) if it is not mounted.
Feel free to modify to suit your needs.

@echo off&setlocal enabledelayedexpansion

::Set volume label of partition to mount below
set "label=Test2"

echo list vol>diskpart.scr
set "label=%label% "
set "label=%label:~0,11%"
for /f "delims=" %%a in ('diskpart /s diskpart.scr^|find "Volume"') do (
set "line=%%a"
if "!line:~15,1!" equ " " if /i "!line:~19,11!" equ "%label%" (
echo Mounting Volume !line:~19,11!
echo select vol !line:~9,3! >mountdrv.scr
echo assign >>mountdrv.scr
diskpart /s mountdrv.scr >nul
)
)
del diskpart.scr
del mountdrv.scr


--
Todd Vargo
(Post questions to group only. Remove "z" to email personal messages)

billious

unread,
Jan 22, 2012, 1:43:13 AM1/22/12
to

"Sambul32" <sambu...@gmail.com> wrote in message
news:becdc6a2-51f0-4a60...@v14g2000vbc.googlegroups.com...
Hmm - not really sure what's required here - existing drive letters or
unassigned volume numbers?

I'd suggest that a pure 'tokens' approach is going to be difficult - suppose
the label on volume 9 was "X" rather than "1" for example. Finding token 3
with a length of 1 won't work reliably.

I'd suggest tokenising a substring of the full line:

@echo off
setlocal enabledelayedexpansion
for /f "delims=" %%i in (sambul32.txt) do (
set line=%%i
for /f "tokens=3" %%j in ("!line:~0,16!") do echo %%j
)

echo --- unmounted

for /f "delims=" %%i in (sambul32.txt) do (
set line=%%i
for /f "tokens=2,3" %%j in ("!line:~0,16!") do if "%%k"=="" echo %%j
)


produced

F
G
H
--- unmounted
9
11


on the above (partial?) data (unwrapped into sambul32.txt)

Does this suggest a solution?


Sambul32

unread,
Jan 22, 2012, 10:56:40 AM1/22/12
to
Thank you very much!

I'll test both approaches, and with some extra code to find unused in
the system drive letters they seem to provide good solution for the
task: "mount unmounted volumes on a selected disk with auto assigned
drive letters". :)

Another question: when a drive letter is removed (i.e. volume
dismounted) with Mountvol or Diskpart, it no longer auto-mounts when
the disk is attached again to the system, despite Automount is On. Is
there a way to make it auto-mountable again without assigning a drive
letter to it (i.e. without mounting it)?

Frank P. Westlake

unread,
Jan 22, 2012, 11:40:56 AM1/22/12
to
On 2012-01-22 07:56, Sambul32 wrote:
> Another question: when a drive letter is removed (i.e. volume
> dismounted) with Mountvol or Diskpart, it no longer auto-mounts when
> the disk is attached again to the system, despite Automount is On. Is
> there a way to make it auto-mountable again without assigning a drive
> letter to it (i.e. without mounting it)?

I hope someone has an affirmative answer for that.

I eject the drive instead of unmounting it. There are freeware utilities
for this. When the drive is ejected via a system call (the freeware
utility) the system remounts it when it is reattached.

Frank

Sambul32

unread,
Jan 22, 2012, 1:55:35 PM1/22/12
to
I think Eject option only appears for removable drives in Win
Explorer, and it doesn't appear for a Volume of local physical or
virtual drive. Win32_Volume class (http://msdn.microsoft.com/en-us/
library/aa394515(v=vs.85).aspx) doesn't offer this method (basically
to deny write access & close handles) and neither Diskpart (which
probably works by using these libraries).

I guess you're using a program like here: Eject USB disks using C#
(http://www.codeproject.com/Articles/13530/Eject-USB-disks-using-C)?
Did you use it to "eject" local disk Volumes too - what program is it?

Frank P. Westlake

unread,
Jan 22, 2012, 2:10:30 PM1/22/12
to
On 2012-01-22 10:55, Sambul32 wrote:
> Did you use it to "eject" local disk Volumes too - what program is it?

<http://www.freeeject.com/>

I us it to eject sdcards, USB hard drives, and other volumes. It isn't a
physical ejection for anything I do but it still tells the OS that the
volume has been ejected. The method to remount the volume depends on the
device. With my Android device, after the eject I tell it to unmount
then remount, other things need to be unplugged and reinserted, so it
might not be suitable for a permanent volume.

Frank


Sambul32

unread,
Jan 22, 2012, 2:28:36 PM1/22/12
to
Will try if it works for a local physical or virtual drive volume, and
can be called from a batch. To make the hidden volume visible again,
one can use from a batch:

echo rescan | diskpart

Sambul32

unread,
Jan 22, 2012, 2:38:07 PM1/22/12
to
No, it doesn't eject local volumes: "The drive type is incorrect".
Unless they can be marked as "Removable" in Registry right before
being ejected, and restored to "Partition" after rescanned - just
thinking whether possible.

foxidrive

unread,
Jan 22, 2012, 9:43:57 PM1/22/12
to
I use these here - see if they work for you.


RemoveDrive V2.2.0.0 - prepares removable drives for safe removal
Freeware by Uwe Sieber - www.uwe-sieber.de


EjectMedia V2.2.0.0 - ejects a media from a drive
Freeware by Uwe Sieber - www.uwe-sieber.de





--
Mic

Todd Vargo

unread,
Jan 22, 2012, 9:49:58 PM1/22/12
to
When you remove a drive via Mountvol or Diskpart you are in fact hiding
the partition. Unplugging and replugging the drive again, or even
rebooting, does not make the partition visible again. You must unhide
the partition to make it mountable again. I hope this explains why it
does not auto-mount.

Sambul32

unread,
Jan 23, 2012, 12:10:10 AM1/23/12
to
Thanks Todd,

It does explain it abundantly clear. :) The question then is: how to
remove (eject) a Volume temporary the same way as a removable or
virtual disk, since their volumes automount once the disk is
reattached (meaning their drive letters are preserved in Mounted
Devices jointly with GUIDs)?

It looks like a Windows bug to me, or a gap in logical disks
treatment. But, their may be a *workaround* by preserving drive
letter(s) in Registry similar to how they are preserved for removable
disks. It can possibly be done via a batch that removes a Volume's
mount point, and then immediately writes its original drive letter to
Registry without remounting the Volume. That would allow to automount
the Volume next time the disk is attached (as if it was never hidden
before). :)

Todd Vargo

unread,
Jan 23, 2012, 6:40:15 AM1/23/12
to
I wish I had an answer for you, but why would you need to anyway? When I
Ghost an image to disk, it displays a message that the machine needs
rebooted to make the drive available. That may have been true in Win9x
but I have full access in XP without unplugging the drive or rebooting.
Message has been deleted

Sambul32

unread,
Jan 23, 2012, 11:49:08 AM1/23/12
to
Todd,

I tested your code 1st with some variations, it works OK in Win7 32-
bit (in a debugger, but prints Diskpart Help content 3 times before
assigning a drive letter), but in Win7 64-bit it can't calculate !
line:~15,1! resulting in ~15,1 . Any way to adapt to 64-bit? It does
find Volume lines correctly though... Why it prints Help 3 times in
32-
bit?

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS
SET "diskpart=echo exit|"%ComSpec%" /k prompt %%dsc%%$_|diskpart"
set dsk=7 & SET dsc=select$Sdisk$S%dsk%$_detail$Sdisk
for /f "tokens=* delims=" %%a in ('%%diskpart%% ^| find "Volume"')
do
(
set line=%%a
if "!line:~15,1!" equ " " (
echo Mounting Volume %line:~9,3% Label: %line:~19,11%
set dsc=select$Svolume$S%line:~9,3%$_assign$_exit & %diskpart%
)
)
endlocal
exit /b

Frank P. Westlake

unread,
Jan 23, 2012, 11:51:55 AM1/23/12
to
On 2012-01-23 08:32, Sambul32 wrote:

> ... in Win7 64-bit it can't calculate !
> line:~15,1! resulting in ~15,1 .

> SETLOCAL ENABLEEXTENSIONS

Frank

foxidrive

unread,
Jan 23, 2012, 12:19:46 PM1/23/12
to
FWIW you can eject media from non-removable drives.

There are other tools there too.



--
Mic

Frank P. Westlake

unread,
Jan 23, 2012, 12:49:08 PM1/23/12
to
I don't know what you are doing with the prompt -- I've never used it
for that -- but there is a problem with the delayed expansion. It looks
like you're trying to avoid writing a script file so try this:

@Echo OFF
SetLocal EnableExtensions EnableDelayedExpansion

For /F "tokens=2" %%a in (
'Echo(list disk^|DiskPart^|FindStr /B /c:" Disk"^|findstr /v /c:"###"'
) Do (
For /F "delims=" %%b in (
'(Echo select disk %%a^&Echo detail disk^)^|DiskPart^|FindStr /b
/C:" Volume"^|findstr /v /c:"###"'
) Do (
Set "line=%%b"
If "!line:~15,1!" EQU " " (
Echo Mounting Volume !line:~9,3! Label !line:~19,11!
(
Call Echo select volume %%line:~9,3%%
Echo assign
) | DiskPart
)
)
)

Repeated with line numbers:
01:@Echo OFF
02:SetLocal EnableExtensions EnableDelayedExpansion
03:For /F "tokens=2" %%a in (
04: 'Echo(list disk^|DiskPart^|FindStr /B /c:" Disk"^|findstr /v /c:"###"'
05:) Do (
06: For /F "delims=" %%b in (
07: '(Echo select disk %%a^&Echo detail disk^)^|DiskPart^|FindStr /b
/C:" Volume"^|findstr /v /c:"###"'
08: ) Do (
09: Set "line=%%b"
10: If "!line:~15,1!" EQU " " (
11: Echo Mounting Volume !line:~9,3! Label !line:~19,11!
12: (
13: Call Echo select volume %%line:~9,3%%
14: Echo assign
15: ) | DiskPart
16: )
17: )
18:)

Frank

billious

unread,
Jan 23, 2012, 1:29:14 PM1/23/12
to

"Sambul32" <sambu...@gmail.com> wrote in message
news:f13dd303-8861-454d...@o9g2000yqa.googlegroups.com...
This code differs from what you posted 17 minutes earlier. The outstanding
change is that you've now included the ENABLEDELAYEDEXPANSION keyword. That
should have cured the problem with the !line:~15,1!

* Without ENABLEDELAYEDEXPANSION,
if "!line:~15,1!" equ " " (
should have been evaluated as FALSE because "!line:~15,1!" is a literal and
NOT equal to " "

Whereas with ENABLEDELAYEDEXPANSION, "!line:~15,1!" would be evaluated to
the 15th character of the CURRENT value of LINE(starting the count at 0)

*** However, since you use %line:~m,n% in the two following lines, the value
of LINE at the time that the FOR/F statement was PARSED will be used, not
the RUN-TIME value.

I'd suggest that you require the RUN-TIME value and hence you should use
!line:~m,n! instead of %line:~m,n% in these two lines, too.


Sambul32

unread,
Jan 23, 2012, 2:12:09 PM1/23/12
to
Thanks Frank,

Your code doesn't work: "Unbalanced Parentheses". But this one
apparently does: :)

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS
SET "diskpart=echo exit|"%ComSpec%" /k prompt %%dsc%%$_|diskpart"
set dsk=7
SET dsc=select$Sdisk$S%dsk%$_detail$Sdisk
for /f "tokens=* delims=" %%a in ('%%diskpart%% ^| findstr "Volume"')
do (
set line=%%a
if "!line:~15,1!" equ " " (
echo Mounting Volume !line:~9,3! Label: !line:~19,11!
set dsc=select$Svolume$S!line:~9,3!$_assign & %diskpart% >nul
)
)
ENDLOCAL
exit /b

Sambul32

unread,
Jan 23, 2012, 6:40:53 PM1/23/12
to
Thanks everyone for the input! It was a notable time saver and
learning experience. You're the best. :)

Todd Vargo

unread,
Jan 23, 2012, 10:48:00 PM1/23/12
to
On 1/23/2012 6:40 PM, Sambul32 wrote:
> Thanks everyone for the input! It was a notable time saver and
> learning experience. You're the best. :)

Glad to see you got the bugs in your modified code worked out.

Sambul32

unread,
Jan 24, 2012, 12:09:02 AM1/24/12
to
Just wanted to clarify for novices, the above code has 14 lines -
meaning FOR ...DO ( on the same line. Its crazy how this Board wraps
lines. :)

Sambul32

unread,
Jan 24, 2012, 10:47:26 AM1/24/12
to
Frank,

I changed your code a bit just to see if it works, and it does now
here (19 lines, all ) DO ( on separate lines):

@echo off
SetLocal EnableExtensions EnableDelayedExpansion
For /F "tokens=2" %%a in (
'Echo list disk ^| DiskPart ^| FindStr /b /c:" Disk" ^| findstr /
v /c:"###"'
) Do (
set dsk=%%a
For /F "delims=" %%b in (
'^(Echo select disk %%a ^& Echo detail disk^) ^| DiskPart ^|
FindStr /b /c:" Volume" ^| findstr /v /c:"###"'
) Do (
set line=%%b
If "!line:~15,1!" EQU " " (
Echo Mounting Volume !line:~9,3! Label !line:~19,11!
(
Call Echo select volume %%line:~9,3%%
Echo assign
) | DiskPart >nul
)
)
)

Frank P. Westlake

unread,
Jan 24, 2012, 11:30:46 AM1/24/12
to
The curious part is here:

Call Echo select volume %%line:~9,3%%

The variable 'line' did not expand using delayed expansion:

Echo select volume !line:~9,3!

Perhaps Jeb can explain that. I'm using Windows 7/64 and I'm noticing a
few other differences between it and previous versions. MS has added
this CONHOST.EXE service (Console Window Host) which seems to be hosting
CMD.EXE, so maybe these errors are due to changes made to run CMD in the
host environment.

Frank

Sambul32

unread,
Jan 24, 2012, 6:40:19 PM1/24/12
to
I does not expand, but for some reason it works without !expansion! -
meaning it mounts several unmounted volumes. I didn't get this part
either?

Todd Vargo

unread,
Jan 24, 2012, 9:16:36 PM1/24/12
to
I would say it is possible that variables could be set from previous
testing sessions. Try adding code near the top to ensure that the
variables are cleared before use.

Sambul32

unread,
Jan 25, 2012, 1:22:42 AM1/25/12
to
What I meant, this line allows to mount as many unmounted volumes as
there are in the system despite its not expandable:

Call Echo select volume %%line:~9,3%%

Does calling it as a subroutine allow to use run-time values?

billious

unread,
Jan 25, 2012, 2:29:32 AM1/25/12
to

"Frank P. Westlake" <frank.w...@gmail.net> wrote in message
news:jfmmbq$bcp$1...@news.albasani.net...
Well, I'm thoroughly confused now about quite what is under discussion.

at 1201240032, Sambul complained to Todd (paraphrased)

...in Win7 64-bit it can't calculate !line:~15,1! resulting in ~15,1 .

SETLOCAL ENABLEEXTENSIONS
...
for /f "tokens=* delims=" %%a in ('%%diskpart%% ^| find "Volume"') do
(
set line=%%a
if "!line:~15,1!" equ " " (
echo Mounting Volume %line:~9,3% Label: %line:~19,11%
set dsc=select$Svolume$S%line:~9,3%$_assign$_exit & %diskpart%
...

Fair enough - missing ENABLEDELAYEDEXPANSION so !substring! won't be
correctly evaluated.

at 1201240049,

SETLOCAL ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS
...
for /f "tokens=* delims=" %%a in ('%%diskpart%% ^| find "Volume"') do
(
set line=%%a
if "!line:~15,1!" equ " " (
echo Mounting Volume %line:~9,3% Label: %line:~19,11%
set dsc=select$Svolume$S%line:~9,3%$_assign$_exit & %diskpart%
...


The complaint was unchanged, but the missing ENABLEDELAYEDEXPANSION had been
included.

Then at 1201240312,

Your code doesn't work: "Unbalanced Parentheses". But this one
apparently does: :)

SETLOCAL ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS
...
for /f "tokens=* delims=" %%a in ('%%diskpart%% ^| findstr "Volume"') do
(
set line=%%a
if "!line:~15,1!" equ " " (
echo Mounting Volume !line:~9,3! Label: !line:~19,11!
set dsc=select$Svolume$S!line:~9,3!$_assign & %diskpart% >nul
...

So - FIND has become FINDSTR and "%" corrected to "!" in the ECHO and SET
lines.

Problem solved??

What do you mean by

> Call Echo select volume %%line:~9,3%%
>
> The variable 'line' did not expand using delayed expansion:
>
> Echo select volume !line:~9,3!


These two should yield identical results because ...%%line:~9,3%% would be
executed as
ECHO...%line:~9,3% in the context of the CALL, hence LINE has the run-time
value assigned by the FOR.

Does it not do that for you? It does for me in both XP and W7/64. What are
these 'errors' you refer to in your final paragraph? Contaminated
environment as Todd suggests, perhaps?


Frank P. Westlake

unread,
Jan 25, 2012, 9:54:58 AM1/25/12
to
On 2012-01-24 22:22, Sambul32 wrote:
> What I meant, this line allows to mount as many unmounted volumes as
> there are in the system despite its not expandable:
>
> Call Echo select volume %%line:~9,3%%

I don't understand. The script I presented was modeled after your
script, which seemed to me was intended to mount all unmounted volumes,
so my script tries to mount all unmounted volumes.

> Does calling it as a subroutine allow to use run-time values?

Yes. If you 'set line=%%a' in the FOR circle the 'call :subroutine',
:subroutine can directly use '%line%'. This is standard procedure with
NT4, which does not normally[note] have delayed expansion.

Frank

Note: CMD.EXE from XP runs well on NT4 and gives it the same capabilities.

Frank P. Westlake

unread,
Jan 25, 2012, 10:26:04 AM1/25/12
to
On 2012-01-24 23:29, billious wrote:
> Well, I'm thoroughly confused now about quite what is under discussion.

I think it has been a discussion which hasn't been concerned about
continuity of detail, but in general was attempting to create a usable
script.


>> Call Echo select volume %%line:~9,3%%
>>
>> The variable 'line' did not expand using delayed expansion:
>>
>> Echo select volume !line:~9,3!

> These two should yield identical results ...

They should but did not. Whether the environment was contaminated or not
is irrelevant because the variable 'line' was defined by that same line
of script. As you can see below there were three previous expansions of
'line'; all worked except the fourth, which I changed to a 'call'
expansion.

For /F "tokens=2" %%a in (
'Echo(list disk^|DiskPart^|FindStr /B /c:" Disk"^|findstr /v /c:"###"'
) Do (
For /F "delims=" %%b in (
'(Echo select disk %%a^&Echo detail disk^)^|DiskPart^|FindStr /b
/C:" Volume"^|findstr /v /c:"###"'
) Do (
Set "line=%%b"
If "!line:~15,1!" EQU " " (
Echo Mounting Volume !line:~9,3! Label !line:~19,11!
(
Call Echo select volume %%line:~9,3%%
Echo assign
) | DiskPart
)
)
)

Frank

Sambul32

unread,
Jan 25, 2012, 10:29:16 AM1/25/12
to
Frank,

I'm fine, no issues, and this line is working fine here in Win7 64-bit
too: :)

Echo select volume !line:~9,3!

So now I know this workaround.

Sambul32

unread,
Jan 25, 2012, 10:56:26 AM1/25/12
to
Another question about the same topic... How to verify that a drive
letter obtained in FOR command is 1 character in length, and not a
world?

foxidrive

unread,
Jan 25, 2012, 11:09:51 AM1/25/12
to
Using delayedexpansion


@echo off
setlocal enabledelayedexpansion

set variable=a
if "!variable:~1,1!"=="" echo A: it's not greater than one character

set variable=ab
if "!variable:~1,1!"=="" echo B: it's not greater than one character






--
Mic

Tom Lavedas

unread,
Jan 25, 2012, 11:30:16 AM1/25/12
to
On Jan 25, 11:09 am, foxidrive <foxidr...@gotcha.woohoo.invalid>
wrote:
Or maybe ...

echo.abc|findstr "^.$">nul &&echo OK||echo Too long or too short

No delayed expansion needed ;^)
________________________
Tom Lavedas

Frank P. Westlake

unread,
Jan 25, 2012, 1:14:32 PM1/25/12
to
On 2012-01-25 07:56, Sambul32 wrote:
> How to verify that a drive letter obtained in FOR command is 1 character in length...

@Echo OFF
SetLocal EnableExtensions EnableDelayedExpansion
For %%a in ("" "A" "A:") Do (
Set /P "=Is '%%~a' one char? "<NUL:
Set "one=%%~a"
Set "two=!one:~1!"
If DEFINED one (
If NOT DEFINED two (Echo Yes.) Else (Echo No.)
) Else (
Echo No..
)
)
goto :EOF

Frank

Todd Vargo

unread,
Jan 25, 2012, 6:17:22 PM1/25/12
to
<snip>

>
> Does it not do that for you? It does for me in both XP and W7/64. What are
> these 'errors' you refer to in your final paragraph? Contaminated
> environment as Todd suggests, perhaps?
>
>

It would help greatly if OP would include a relevant portion of the post
being responded to as well as provide a complete batch code being for us
to examine for possible bugs earlier in the batch.

FWIW, the batch that I posted works for the label that was provided. To
allow mounting of *all* unmounted drives (how many are actually
disabled?) is a simple modification to eliminate the second IF
condition, not a complete convoluted overhaul to eliminate temp files.
I'm willing to help out but only to a point.

Sambul32

unread,
Jan 25, 2012, 7:39:40 PM1/25/12
to
Todd,

I didn't have the problem Frank mentioned, namely:

The variable 'line' did not expand using delayed expansion:

>> Echo select volume !line:~9,3!

But I do agree that in different OS versions the code may run
differently. In fact, I had several times similar issues running the
code fine in a Debugger, only to have errors in Commandline Console.

I did use your code the most to the degree rational for the larger
app. Since it uses "dsc" variable in many places outside of the
discussed here small section, such flexible while repeatable approach
was the best. Thank you again for the feedback. :)

Todd Vargo

unread,
Jan 25, 2012, 10:30:45 PM1/25/12
to
I see what you mean. But why not KISS?
This works in XP. Does it not work in 7?

::MountDrives.cmd
::Assigns drive letters to all hidden partitions.
@echo off&setlocal enabledelayedexpansion
for /f "delims=" %%a in (
'echo list vol^|diskpart^|find "V"^|find/v "###"'
) do (
set "line=%%a"
if "!line:~15,1" equ " " (
Echo Mounting Volume !line:~9,3! Label !line:~19,11!
(
Call Echo select volume %%line:~9,3%%
Echo assign
) | DiskPart
)
)


Sambul32

unread,
Jan 26, 2012, 8:38:14 AM1/26/12
to
That's probably a matter of choice leading to code diversity. :) These
"dsc" variable sequences can be quite long and diverse, yet work very
fast. In fact, a better question might be "Why not use WMIC, since it
uses the same API and queries as Diskpart, which is more suited as a
user tool. Or use PowerShell & WMI instead of Commandline? Well,
anything is possible, but WMI classes choice depends on OS version, so
programming may get even more convoluted.
0 new messages