retrieving drive details into variables
Moderator: DosItHelp
retrieving drive details into variables
I am writing a script to automate my windows installation.
So, from a batch script
After Windows is installed I need to reassign drive letters on several drives (Both removable and local).
I then run another script which does a multitude of things, but needs to have the drive letters in the right sequence for it to work.
There are 10 PCs I manage. There are a variable number of drives in each PC. On those drives there may be a variable number of partitions.
I can get the drive details using wmic logicaldisk where "drivetype =2" get value1,value2,value3...
Where drivetype; 2=Removable, 5=Optical
What I need to do is to locate optical drives. Reassign the drive letters based on how many optical drives are detected
Then I need to reassign the drive letter of the USB from which I did the install.
By default Windows will give the UEFI install USB a drive letter for the UEFI partition, which I need to remove.
I then need to create additional partitions on the boot drive (Only part of it is used for the Windows partition). After that, the second script will restore files to those partitions
I can pipe commands into diskpart with /s - I believe that's how I will have to reassign the drive letters. It'd be better if I could use wmic to do it though.
So, my boggle is that (a). I'm not sure how to get a variable number of drive letters into a variable for each optical drive and (b) As the USB will also present with two drive letters, the same applies.
I gather this is going to be a FOR loop, which I'm not real good with.
Would appreciate some help.
thanks
So, from a batch script
After Windows is installed I need to reassign drive letters on several drives (Both removable and local).
I then run another script which does a multitude of things, but needs to have the drive letters in the right sequence for it to work.
There are 10 PCs I manage. There are a variable number of drives in each PC. On those drives there may be a variable number of partitions.
I can get the drive details using wmic logicaldisk where "drivetype =2" get value1,value2,value3...
Where drivetype; 2=Removable, 5=Optical
What I need to do is to locate optical drives. Reassign the drive letters based on how many optical drives are detected
Then I need to reassign the drive letter of the USB from which I did the install.
By default Windows will give the UEFI install USB a drive letter for the UEFI partition, which I need to remove.
I then need to create additional partitions on the boot drive (Only part of it is used for the Windows partition). After that, the second script will restore files to those partitions
I can pipe commands into diskpart with /s - I believe that's how I will have to reassign the drive letters. It'd be better if I could use wmic to do it though.
So, my boggle is that (a). I'm not sure how to get a variable number of drive letters into a variable for each optical drive and (b) As the USB will also present with two drive letters, the same applies.
I gather this is going to be a FOR loop, which I'm not real good with.
Would appreciate some help.
thanks
Re: retrieving drive details into variables
I'm not sure how to get a variable number of drive letters into a variable for each optical drive
Code: Select all
@echo off
setlocal EnableDelayedExpansion
set "optcldsks="
set "idx=-1"
for /f "tokens=2 delims==:" %%i in ('wmic logicaldisk where "drivetype=2" get DeviceID /value') do set "optcldsks=!optcldsks!%%i"&set /a "idx+=1"
echo all in one string:
echo %optcldsks%
echo separated within a FOR /L loop:
for /l %%i in (0 1 %idx%) do echo !optcldsks:~%%i,1!
pause
You definitely have to learn it. You will be out of luck in any programming language if you don't know how to use loops.I gather this is going to be a FOR loop, which I'm not real good with.
Steffen
Re: retrieving drive details into variables
So close. USB drives respond to drivetype=2. Opticaldisks only respond to drivetype=5. That's OK, I need both
So if I am reading this right, the drive letters are in a single string. I then need to split them out into separate variables.
I tweaked your code thus;
for /l %%i in (0 1 %idx%) do (
Rem echo !optcldsks:~%%i,1!
set disk%%i=!optcldsks:~%%i,1!
)
I can then repeat for USB drives. The USB drive must be plugged in otherwise it reports "No instances found"
Now I just need a way to use the results to change the drive letter. Diskpart doesn't seem to work on optical drives.
So if I am reading this right, the drive letters are in a single string. I then need to split them out into separate variables.
I tweaked your code thus;
for /l %%i in (0 1 %idx%) do (
Rem echo !optcldsks:~%%i,1!
set disk%%i=!optcldsks:~%%i,1!
)
I can then repeat for USB drives. The USB drive must be plugged in otherwise it reports "No instances found"
Now I just need a way to use the results to change the drive letter. Diskpart doesn't seem to work on optical drives.
Re: retrieving drive details into variables
Batch doesn't support array types. The only kind of an array is a so-called associative array which still consists of single variables. That's something like you try to create using
The reason why I assembled the drive letters in a string is that you may want to process it later on or maybe several times. Usually you would not even do that in Batch, but rather process the drive letters directly in the first loop (where I created the string). Taking this string to make an associative array out of it is even worse. You still would need another FOR /L loop to process these variables. So, why not doing that using !optcldsks:~%%i,1! as already shown?
I wonder why DISKPART doesn't work for you btw.
Steffen
Code: Select all
set disk%%i=!optcldsks:~%%i,1!
I wonder why DISKPART doesn't work for you btw.
Steffen
Re: retrieving drive details into variables
Because DIskpart does not see optical drives.
I want to get each drive once. Processs them once.
I need the current drive letter so that when I call my powershell script it know which of the drives I want to reassign the drive letter for.
I want to get each drive once. Processs them once.
I need the current drive letter so that when I call my powershell script it know which of the drives I want to reassign the drive letter for.
Re: retrieving drive details into variables
Unfortunately I don't have optical drives on any machine I have access to. Don't have a use for them anymore. Maybe there is a possibility using WMI. But that's something I have to search in the internet, too.
Steffen
But that's exactly what you get in the body of the loop. I still don't see any reason for an associative array. Not even for my concatenated string of drive letters.I want to get each drive once. Processs them once.
Steffen
Re: retrieving drive details into variables
No problems. I did come here for help which you generously gave. It would be rude of me to presume that I'm right. I shall return it to it's original form.
As for optical drives, we all still use them extensively. I may have 100TB on my server, but I keep running out. When I run out of space I remove the oldest stuff, and people are forced to then rely on the original disks. As HDD disk prices are skyrocketing here due to a plummeting dollar, adding more storage is not viable at this stage. So - Optical drives abound
I've been searching for a way to do it with WMI. There are a couple of example powershell scripts I've come across but my knowledge of powershell is even worse than my knowledge of batch.
As for optical drives, we all still use them extensively. I may have 100TB on my server, but I keep running out. When I run out of space I remove the oldest stuff, and people are forced to then rely on the original disks. As HDD disk prices are skyrocketing here due to a plummeting dollar, adding more storage is not viable at this stage. So - Optical drives abound
I've been searching for a way to do it with WMI. There are a couple of example powershell scripts I've come across but my knowledge of powershell is even worse than my knowledge of batch.
Re: retrieving drive details into variables
What I meant is something like that:
Steffen
Code: Select all
for /f "tokens=2 delims==:" %%i in ('wmic logicaldisk where "drivetype=5" get DeviceID /value') do (
echo work with %%i here, rather than just echo-ing the drive letter as in this example line
)
It's likely that they can be translated into another WMIC command line. Where did you find them?There are a couple of example powershell scripts I've come across
Steffen
Re: retrieving drive details into variables
I'd have to go through my history to track down the powershell scripts.
But I have a rather good discovery to share...
Diskpart's list disk and list partition command work with hard disks and removable drives like USB drives, but not with optical drives. However, LIST VOL[ume] does list the optical drives. And they are always first listed (volume 0) for single drive systems. For multiple drives (my system has 3), they are volumes 0, 1 and 2. I've checked all 10 PCs here and they are always the same. That means I can use diskpart to rename the optical drives.
The USB drive, if it has a 2nd partition (usually defaults to UEFI_NTFS), which doesn't need a drive letter, can be removed with mountvol [drive:] /d. That leaves the primary partition on the USB to be renamed. That's where I'm now at.
The primary SSD with boot drive has 4 partitions, so using WMIC I can retrieve the drives with 4 partitions. As all other drives only have 2, I should get the bootdrive's number. I can then use a diskpart /s script to create and format the partitions. Once that's done, my post install script which does all the customization, restores and program installations can then proceed.
The batch snippet you provided tells me how many drives I'm dealing with. I followed your example to also get the drives for the USB.
All that remains now is how to rename the USB drive with wmic,
Almost there!
But I have a rather good discovery to share...
Diskpart's list disk and list partition command work with hard disks and removable drives like USB drives, but not with optical drives. However, LIST VOL[ume] does list the optical drives. And they are always first listed (volume 0) for single drive systems. For multiple drives (my system has 3), they are volumes 0, 1 and 2. I've checked all 10 PCs here and they are always the same. That means I can use diskpart to rename the optical drives.
The USB drive, if it has a 2nd partition (usually defaults to UEFI_NTFS), which doesn't need a drive letter, can be removed with mountvol [drive:] /d. That leaves the primary partition on the USB to be renamed. That's where I'm now at.
The primary SSD with boot drive has 4 partitions, so using WMIC I can retrieve the drives with 4 partitions. As all other drives only have 2, I should get the bootdrive's number. I can then use a diskpart /s script to create and format the partitions. Once that's done, my post install script which does all the customization, restores and program installations can then proceed.
The batch snippet you provided tells me how many drives I'm dealing with. I followed your example to also get the drives for the USB.
All that remains now is how to rename the USB drive with wmic,
Almost there!
Re: retrieving drive details into variables
You can process all these information at once
Steffen
Code: Select all
@echo off &setlocal
for /f tokens^=2^ delims^=^" %%i in (
'WMIC Path Win32_DiskDrive Assoc /assocclass:Win32_DiskDriveToDiskPartition 2^>nul ^|findstr /c:"Disk #"'
) do for /f tokens^=4^ delims^=^" %%j in (
'WMIC Path Win32_LogicalDiskToPartition 2^>nul ^|findstr /c:"%%i"'
) do for /f "tokens=2,4 delims=#," %%k in ("%%i") do for /f "tokens=2 delims==" %%m in (
'wmic logicaldisk where "DeviceID='%%j'" get DriveType /value'
) do for /f %%n in ("%%m") do (
if %%n==2 (
echo removable: letter %%j, disk %%k, partition %%l
) else if %%n==5 (
echo optical: letter %%j, disk %%k, partition %%l
)
)
pause
Right. Try to find the PS snippets again.All that remains now is how to rename the USB drive with wmic
Steffen
Re: retrieving drive details into variables
OMG! That's awesome code.
Doesn't return any results for optical drives though.
Snippet 1
Snippet 2 (For systems with only one optical drive I presume)
https://www.kittell.net/code/powershell ... ve-letter/
in the above examples. D: would need to be passed as a parameter for what ever drive was being changed. But as I said in my last post, I found a way around this with diskpart and the list volume command.
The point I'm at now (the last thing to do), is to change the USB drive's letter. The above code could be used if we changed the drivetype to 2.
Doesn't return any results for optical drives though.
Snippet 1
Code: Select all
# Set CD/DVD Drive to A:
$cd = $NULL
$cd = Get-WMIObject -Class Win32_CDROMDrive -ComputerName $env:COMPUTERNAME -ErrorAction Stop
if ($cd.Drive -eq "D:")
{
Write-Output "Changing CD Drive letter from D: to A:"
Set-WmiInstance -InputObject ( Get-WmiObject -Class Win32_volume -Filter "DriveLetter = 'd:'" ) -Arguments @{DriveLetter='a:'}
}
Code: Select all
# Set CD/DVD Drive to A:
Get-WmiObject -Class Win32_volume -Filter 'DriveType=5' |
Select-Object -First 1 |
Set-WmiInstance -Arguments @{DriveLetter='A:'}
in the above examples. D: would need to be passed as a parameter for what ever drive was being changed. But as I said in my last post, I found a way around this with diskpart and the list volume command.
The point I'm at now (the last thing to do), is to change the USB drive's letter. The above code could be used if we changed the drivetype to 2.
Re: retrieving drive details into variables
Code: Select all
WMIC Path Win32_Volume WHERE "DriveLetter='D:'" SET DriveLetter='A:'
All you have to do is, put it in the loop and use the FOR variable instead of D:
Steffen