How to set Batch variable to the volume label of specific drive letter? - cmd

I want to write a .BAT file (on Win 10) which gets the volume label of the optical disk mounted at E: and assigns it to a variable so that I can then create a folder on another drive which has the same name as the volume label.
The vol command returns 2 lines of text (with the volume label at the end of the first line). Is there a command which will return the volume label only?

FOR /F "tokens=6" %a IN ('vol c:') DO SET var=%a
This should do. When you run echo %var% it will show the volume label only
Make sure to change the vol c: to your desired volume!
EDIT:
If the Volume label has 2 words, use FOR /F "tokens=6-7" %a IN ('vol c:') DO SET var=%a
If it has 3 words Just change the "tokens=6" to "tokens=6-7,8"
Hope this helps! 😇

Related

How to get disk GUID using drive letter from a Windows command script?

I'm looking to be able to supply a drive letter and get back the disk GUID within a Windows command script. From the command line I can do the following but I am not sure how to script this:
diskpart
list disk
select disk #
uniqueid disk
The closest I could find was this snippet that pulls the volume number based on the drive letter but I believe there would need to be a nested loop to select each of the disks and I can't figure out how to incorporate that:
for /f "tokens=2,3" %%a in ('echo list volume ^| diskpart') do (
if %%b==%driveletter% (
echo Volume number is %%a
)
)
Also since list disk doesn't specify the volume letters there would need to be something translating the disk # to the volume #, is that even possible?
Besides select volume 1, you can also use select volume C or selct volume C: (note the response mentions the corresponding volume number).
Also you don't have to find and select the corresponding disk manually. Uniqueid disk translates the selected volume to the disk.
This makes it quite easy:
#echo off
setlocal
set "Drive=C:"
for /f "tokens=2 delims={}" %%a in ('(echo select volume %Drive%^&echo uniqueid disk^)^|diskpart') do set "GUID=%%a"
echo Disk GUID for %Drive% is %guid%
Based on the discussion with Compo, I adapted the for loop to take care of the different output with MBR vs. GPT drives:
#echo off
setlocal
set "Drive=C:"
for /f "delims=" %%a in ('(echo select volume %Drive%^&echo uniqueid disk^)^|diskpart^|find ":"') do (
for %%b in (%%a) do set "GUID=%%b"
)
echo Disk GUID for %Drive% is %guid%
With this change, the output format now looks either like:
Disk GUID for C: is {DC8DD71C-31B8-4B04-9FB6-C66A325B738B}
or like:
Disk GUID for F: is DB72E293

Why is this Windows Batch script not able to find the program net.exe?

I'm creating what was meant to be a very simple batch script to map a drive based on user input and check that the drive doesn't already exist first.
#echo off
:EnterInfo
set /P path=Please Enter The Path You Want To Map(EG: \\server\folder)
set /P z=Please Chose A drive Letter To Map.(EG Z)
goto :CheckExist
:CheckExist
%z%:\
pause
if exist %z%:\ (
set /P Sure=A Drive Is Already Using Drive Letter %path%:\ Are You Sure You Want To Replace It?[Y/N]
if /I "%Sure%" EQU "Y" goto :SetDrive
if /I "%Sure%" EQU "N" exit)
goto :SetDrive
:SetDrive
C:
dir
net use z: "%path%"
pause
Here is the code so far.
I'm getting an error:'net' is not recognized as an internal or external command,
when the script gets to the(Net use Z: "%path%")
Although the input to the command would work if i were to run it in a cmd window.
I've checked the location the script and it's running from C:\Users\%username%\ like a cmd box would default it's location too.
I'm really confused as to why it's not recognising net Use. Thanks in advance
The problem is this line:
set /P path=Please Enter The Path You Want To Map(EG: \\server\folder)
The PATH environment variable is already used by Windows. It tells the command interpreter where to find programs like net.exe, which is in your sys(tem32|wow64) folder. You can't just overwrite it as you please and expect everything to work properly afterward. You set the variable PATH to be the network path for the drive you want the user to map, which overwrites the actual PATH variable.
Solution: Use a different variable name, like, say, mypath.

How to find the non space version of a file name with spaces

I am using windows and need to access a directory and file name that contains spaces. Right clicking the file and choosing properties use to show the non space short name, but it seems windows 7 no longer does this. I'm also at work so I can't install dosbox.
I'm trying to create a file:// url for the file. The path is:
myserver\SHARED ITEMS\My File.txt
How do I get the name that looks something like
file://myserver/shared~1/My~1.txt
Read about spaces in URL and percent encoding. However, % has special meaning in Windows CLI and cmd batch files...
Read 8.3 file name creation on NTFS partitions. You could see 8.3 filenames using dir /X supposing those are enabled for a particular volume. However, it will work on local drives only: under administrator command prompt, one can query NTFS filesystem using the fsutil.exe utility:
C:\Windows\system32>fsutil.exe behavior query Disable8dot3 c:
The volume state is: 0 (8dot3 name creation is enabled).
The registry state is: 2 (Per volume setting - the default).
Based on the above two settings, 8dot3 name creation is enabled on c:
C:\Windows\system32>fsutil.exe behavior query Disable8dot3 d:
The volume state is: 1 (8dot3 name creation is disabled).
The registry state is: 2 (Per volume setting - the default).
Based on the above two settings, 8dot3 name creation is disabled on d:
C:\Windows\system32>net use y: \\SERVER-PC\VB_scripts_help
The command completed successfully.
C:\Windows\system32>fsutil.exe behavior query Disable8dot3 y:
Error: Access is denied.
Here the FSUTIL behavior query against a mapped drive raises the Access is denied error because it can't query remote filesystem (which may not be NTFS nota bene)...
But even on a local drive with 8dot3 name creation enabled, next example shows that 8.3 names are not solvable unambiguously:
==>D:\bat\StackOverflow\30453582.bat
Directory of C:\testC\New Folder 12
26.05.2015 15:34 0 NEWTEX~1 New Text File 1
26.05.2015 15:34 0 NEWTEX~2 New Text File 2
2 File(s) 0 bytes
Directory of C:\testC\New Folder 21
26.05.2015 15:34 0 NEWTEX~2 New Text File 1
26.05.2015 15:34 0 NEWTEX~1 New Text File 2
2 File(s) 0 bytes
Previous output comes from next batch script:
#ECHO OFF >NUL
MD C:\testC 2>nul
pushd C:\testC
MD "New Folder 12" 2>nul
type NUL>"New Folder 12\New Text File 1"
type NUL>"New Folder 12\New Text File 2"
dir /X "New Folder 12" | findstr /I /V "Volume"| findstr /I /V "<DIR> free"
MD "New Folder 21" 2>nul
type NUL>"New Folder 21\New Text File 2"
type NUL>"New Folder 21\New Text File 1"
dir /X "New Folder 21" | findstr /I /V "Volume"| findstr /I /V "<DIR> free"
popd

Using windows REN command to remove a prefix from filenames

I'm trying to come up with a solution for this issue using only windows cmd line if it's possible.
I have a series of files that look like the following,
[sometexthere233] Tv episode 1
[sometexthere233] Tv episode 2
[sometexthere233] Tv episode 3
I would like to detect any file names in the current directory that contain text within brackets as the prefix, and remove that portion of the file name.
Tv episode 1
Tv episode 2
Tv episode 3
I've done some research using the windows REN command, but I can seem to approach the right syntax or wild card for it to execute.
Any help on how to do this, or to create a bat file that is able to do this would be greatly appreciated.
The following script searches the current directory for files matching the mask [*] * and renames them by removing the bracketed part and the space after it:
#ECHO OFF
FOR %%F IN ("[*] *") DO CALL :process "%%F"
GOTO :EOF
:process
SET oldname=%1
SET "newname=%~nx1"
SET "newname=%newname:*] =%"
RENAME %oldname% "%newname%"

Resolve Windows drive letter to a path (subst and network)

I wonder if there is a universal way of resolving a path using a drive letter (such as X:\foo\bar.txt) into its equivalent UNC path, which might be one of the following:
X:\foo\bar.txt if X: is a real drive (i.e. hard disk, USB stick, etc.)
\\server\share\foo\bar.txt if X: is a network drive mounted on \\server\share
C:\xyz\foo\bar.txt if X: is the result of a SUBST command mapping X: to C:\xyz
I know that there are partial solutions which will:
Resolve a network drive (see for instance question 556649 which relies on WNetGetUniversalName)
Resolve the SUBST drive letter (see QueryDosDevice which works as expected, but does not return UNC paths for things such as local drives or network drives).
Am I missing some straightforward way of implementing this drive letter resolution in Win32? Or do I really have to mess with both WNetGetUniversalName and QueryDosDevice to get what I need?
Here is a batch to translate drive letters to UNC paths or reverse substed paths. Not guaranteed it works though.
Example of use: script.cmd echo Z: Y: W:
#echo off
:: u is a variable containing all arguments of the current command line
set u=%*
:: enabledelayedexpansion: exclamation marks behave like percentage signs and enable
:: setting variables inside a loop
setlocal enabledelayedexpansion
:: parsing result of command subst
:: format: I: => C:\foo\bar
:: variable %G will contain I: and variable H will contain C:\foo\bar
for /f "tokens=1* delims==> " %%G IN ('subst') do (
set drive=%%G
:: removing extra space
set drive=!drive:~0,2!
:: expanding H to a short path in order not to break the resulting command line
set subst=%%~sfH
:: replacing command line.
call set u=%%u:!drive!=!subst!%%
)
:: parsing result of command net use | findstr \\ ; this command is not easily tokenized because not always well-formatted
:: testing whether token 2 is a drive letter or a network path.
for /f "tokens=1,2,3 delims= " %%G IN ('net use ^| findstr \\') do (
set tok2=%%H
if "!tok2:~0,2!" == "\\" (
set drive=%%G
set subst=%%H
) else (
set drive=%%H
set subst=%%I
)
:: replacing command line.
call set u=%%u:!drive!=!subst!%%
)
call !u!
Yes, you would need to resolve the drive letter independently.
WNetGetUniversalName() comes close, but only works for drive letters that are mapped to actual UNC shares, which is not always the case. There is no single API function that does all of the work for you.

Resources