# Powershell script for Diskpart

I have a CSV File that contains the Disk number and Lun Name of disk I need mounted to my servers (hundreds of servers)

I want a powershell script that will parse the csv files (unique per server) in to a text file that will contain a series of diskpart commands.

so for example here is my CSV
Disk Number,Lun Name
Disk 002,D1_DB11_C1_data
Disk 003,D1_DB11_C1_log
Disk 004,D1_DB31_C2_data
Disk 005,D1_DB31_C2_log
Disk 006,D1_DB35_C1_data
Disk 007,D1_DB35_C1_log
Disk 008,D1_DB52_C2_data
Disk 009,D1_DB52_C2_log
Disk 010,D1_DB09_C2_data
Disk 011,D1_DB09_C2_log
Disk 012,D1_DB19_C1_data
Disk 013,D1_DB19_C1_log
Disk 014,D1_DB24_C2_data
Disk 015,D1_DB24_C2_log
Disk 016,D1_DB43_C1_data
Disk 017,D1_DB43_C1_log
Disk 018,D1_DB45_C2_data
Disk 019,D1_DB45_C2_log
Disk 020,Servername_restore
Disk 021,Servername_root_data
Disk 022,Servername_root_log
Disk 023,D1_DB02_C2_data
Disk 024,D1_DB02_C2_log
Disk 025,D1_DB03_C1_data
Disk 026,D1_DB03_C1_log
Disk 027,D1_DB27_C1_data
Disk 028,D1_DB27_C1_log
Disk 029,D1_DB38_C2_data
Disk 030,D1_DB38_C2_log
Disk 031,D1_DB51_C1_data
Disk 032,D1_DB51_C1_log


I need the scriptto go through and pick out the Root and restore disks and create them first and assing them to the D: L: R: drives.

Then it will go through and pick out the remainder of the drives and format them,

The Script will need to parse the lun name and create folder names for the disk to mount to.

so the end result for example would be:

D:\ <Disk 021 mounted for D:>
D:\D1_DB11 <disk 002 mounted to this folder>
D:\D1_DB31 <Disk 004 mounted to this folder>
...

The Log drives are more complicated
L:\ <disk 022 mounted for L:>
L:\D1_Log11 <disk 003 mounted to this folder>
.....

I know all the diskpart commands, what I don't know is how to get powershell to work with the CSV File, and do the Root/Restore Drives First.

Also How do I parse the volume name and pull out portions of it for volume names, folder names, etc.

If it matters the LUN name predeedign either  _log or _data will aways be the same characther length as well as the server name.
LVL 8
###### Who is Participating?

Batchelor and DeveloperCommented:
This script now generates a batch file (makepart.cmd) containing all necessary commands. Since many parts are very similar to each other, I have used functions (Roots, DataOrLog) doing the "real" stuff.
$disks = Import-Csv "c:\temp\ee\diskpart.txt" -header DiskNo, Lun$disks | ? {$_.Lun -like "*root_data"} | % { Roots D:$_.DiskNo $_.Lun | Out-File "makepart.cmd" }$disks | ? {$_.Lun -like "*root_log" } | % { Roots L:$_.DiskNo $_.Lun | Out-File -Append "makepart.cmd" }$disks | ? {$_.Lun -like "*_restore" } | % { Roots R:$_.DiskNo $_.Lun | Out-File -Append "makepart.cmd" }$disks | ? {$_.Lun -like "*_*_*_data"} | %  {$dir = "D:\" + ($_.Lun.Split("_")[0..1] -join "_") DataOrLog$dir $_.DiskNo$_.Lun | Out-File -Append "makepart.cmd"
}

$disks | ? {$_.Lun -like "*_*_*_log" } | %
{
$dir = "L:\" + ($_.Lun.Split("_")[0..1] -join "_").replace("DB","Log")
DataOrLog $dir$_.DiskNo $_.Lun | Out-File -Append "makepart.cmd" } function Roots ($Drive, $DiskNo,$Lun)
{
"(echo select $DiskNo" " echo online disk" " echo attribute disk clear readonly" " echo create partition primary" " echo format fs=ntfs Label=" +$Lun
" echo Assign Letter=$Drive" ") | diskpart " } function DataOrLog ($dir, $DiskNo,$Lun)
{
"md $dir" "(echo select$DiskNo"
" echo online disk"
" echo attribute disk clear readonly"
" echo create partition primary"
" echo format fs=ntfs Label=$Lun" " echo assign mount=$dir"
") | diskpart"
}

0

Batchelor and DeveloperCommented:
I'm not sure I'm getting what you are after. Are restore, root_data and root_log appearing only once per file?
What relevance has the server name?
What about the C1 and C2 part?

Assuming each of the root and restore entries are unique, and you know the diskpart commands already, here is a simple approach, just to show the figure:
$disks = Import-Csv "c:\temp\ee\diskpart.txt" -header DiskNo, Lun$disks | ? {$_.Lun -like "*root_data"} {<# diskpart D:$_.DiskNo#>}
$disks | ? {$_.Lun -like "*root_log" } {<# diskpart L: $_.DiskNo#>}$disks | ? {$_.Lun -like "*_restore" } {<# diskpart R:$_.DiskNo#>}
$disks | ? {$_.Lun -like "*_*_*_data"} {<# diskpart mount ... #>}
$disks | ? {$_.Lun -like "*_*_*_log" } {<# diskpart mount ... #>}

0

Author Commented:
yes the roots and restore are once per file.

The C1, C2 Parts are not part of the Folder/Mount point names.

Thanks
0

Batchelor and DeveloperCommented:
To get the parts of the name, you can use (shown for line 6 of my skeleton above):
$disks | ? {$_.Lun -like "*_*_*_log" } {<# diskpart mount ... ($_ .Split("_")[0..1] -join "_") #>}  That is, your mount point name is constructed by the first and second part, separated by an underscore. We could also say to use only the first 6 characters: $disks | ? {$_.Lun -like "*_*_*_log" } {<# diskpart mount ... ($_[0..5] -join "") #>}

0

Author Commented:
Sorry I dont' know thie $disk | ? .... Format... I am looking to create text file that I can feed to diskpart. Can you give me an example on how to have what your saying export to a txt file? so that the Root drives are first then the moutn points. Am I correct in saying in how you have is structured here, it processes all entries in teh CSV are processed by the first line. Then they are all processed again by the second line .... to the end? 0 Batchelor and DeveloperCommented: You are not correct. That is why I used separate lines for each case. In detail: First line reads the complete CSV contents into a var, building an array of two strings "DiskNo" and "LUN". Second line processes the objects in the var, one by one. The ?... is the shortcut/alias for "where-object", and acts as a filter - only get those records for which the condition is true. In this case I ask for the LUN having "root_data" at the end. There should be only one record as a result. The following lines do the same for the log root, then restore, and last data and log. The sequence is hence: first create the root data, then root log, then restore, then other. I've not the time ATM to look for the precise diskpart commands, so could you provide an example for each case? 0 Author Commented: Sure for the Root_data drive it would be (may not be perfect but ti will give me what I need. Comments in (): select disk 021 (from the CSV) online disk attribute disk clear readonly create partition primary format fs=ntfs Label=$LUN (the name as is from the csv)
Assign Letter=D

(for a drive mounted to a point point I would first have to create the directory)
mkdir d:\d1_db11 (name parsed from the Disk 002 Full Name of D1_db11_c1_data
select disk 002 (from CSV)
online disk
create partition primary
format fs=ntfs Label=\$LUN (the name as is from the csv)
assign mount=D:\db1_db11

Then for the Log drives I need to parce the mountpoints a little farther as I can't have the db11 in the name rather it will need to be L:\db1_Log11 for disk 003
0

Batchelor and DeveloperCommented:
Hmm, that makedir part is difficult because you cannot do that in diskpart, and you can't do it before the root commands for diskpart are executed. We would have to create e.g. a batch file containing the diskpart and all other commands. It is much easier if we can just execute diskpart when parsing the file - or do you insist on creating a (batch) file doing the work later?
0

Batchelor and DeveloperCommented:
Then for the Log drives I need to parce the mountpoints a little farther as I can't have the db11 in the name rather it will need to be L:\db1_Log11 for disk 003

Is it really  L:\db1_Log11, or rather  L:\d1_Log11 ?
0

Author Commented:
It can be a series off files.
I
One to create roots
Then the second could create the mountpoints in powershell while it creates the second text file for diskpart.

Whatever you recommend
0

Batchelor and DeveloperCommented:
The sequence for creating L: is the same as for D:, I assume?
And besides an answer to http:#a36511846 I need the diskpart procedure for RESTORE.
0

Author Commented:
Yes the sequence is the same.  And yes it l:D1_###. Good catch

I don't follow the restore procedure you are looking for.
0

Batchelor and DeveloperCommented:
How do we create the R: partition?
0

Author Commented:
Same procedure as the others. Once you provide the script for creating the others I'll be able to modify it to create the R
0

Author Commented:
Wow, looks great!

when I run it however I get the following error:
The term 'DataOrLog' is not recognized as the name of a cmdlet, function, script file, or operable program.
0

Batchelor and DeveloperCommented:
That is strange, because I used the code exactly as posted, and it worked for me ... Try putting both function definitions at the top of the script.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.