As part of an automated delivery of a virtual machine running Microsoft SQL Server I had a requirement to create a number of virtual machine hard disks and for each disk create a NTFS mounted folder.
In order to achieve this I was required to create two functions one to create the virtual machine hard disks and the second to create the NTFS mounted volume based on the SCSI Port and Target ID of the disk.
Firstly, once the virtual machine has been deployed from a base template, we want to add the virtual machine hard disks with the following requirements:
- Create four virtual machine hard disks attached to a new VMware Paravirtual SCSI (PVSCSI) adapter.
- Create two virtual machine hard disks attached to a new VMware Paravirtual SCSI (PVSCSI) adapter.
- Create two virtual machine hard disks attached to a new VMware Paravirtual SCSI (PVSCSI) adapter.
- Each group of virtual machine hard disks created are to be of the same capacity.
- Each virtual machine hard disk will be provisioned with the thick provision eager zeroed format.
- Each virtual machine hard disk will be created on the same datastore as the virtual machine.
As discussed, I have created a function for the above named ‘Create-VirtualHardDisks’ to which I have configured the mandatory parameters ‘Number’ for the count of virtual machine hard disks to create and ‘CapacityGB’ for the size of the virtual machine hard disk.
Function Create-VirtualHardDisks {
Param ([Parameter(Mandatory=$true)][int] $Number, [Parameter(Mandatory=$true)][string] $VM, [Parameter(Mandatory=$true)][int] $CapacityGB)
For the number of virtual machine hard disks to be create we will invoke a ForEach statement to repeat the action a specific number of times, in this case the number of virtual machine hard disks that are required to be created.
ForEach ($HardDisk in (1..$Number)) {
Now we will invoke the New-HardDisk cmdlet to create the virtual machine hard disks specifying the virtual machine, CapacityGB and the storage format.
New-HardDisk -VM $VM -CapacityGB $CapacityGB -StorageFormat EagerZeroedThick
Once the virtual machine hard disks have been created we now create the VMware Paravirtual SCSI (PVSCSI) adapter and attach the virtual machine hard disks. In order to retrieve the virtual machine hard disks we will invoke the Get-HardDisk cmdlet and invoke the Select-Object cmdlet to retrieve the virtual machine hard disks created by specifying the last number of objects whihc is equal to the number of virtual machine hard disks created.
$HardDisks = Get-HardDisk -VM $VM | Select-Object -Last $Number
Once the virtual machine hard disks have been retrieved we will invoke the ‘New-ScsiController’ and create the VMware Paravirtual SCSI (PVSCSI) adapter and attach the virtual machine hard disks.
New-ScsiController -Type ParaVirtual -HardDisk $HardDisks } }
Now that we have the virtual machine hard disks created, I am now required to create the NTFS mounted volumes based on the SCSI Port and SCSI Target ID of the disk, with the following requirements:
- Create the empty folder on the parent volume.
- Initialize the disk with the GPT partition style.
- Create a new partition and use the maximum size of the disk.
- Add a partition access path to the empty folder created.
- Perform a full format of the volume with the NTFS file system with a Unit Allocation Size of 64K and set the file system label to be that of the empty folder.
As previously, we will be creating a function to achieve this task, to which we will specify mandatory parameters for the virtual machine, NTFS mounted folder path and the SCSI Port and $SCSITargetID of the disk.
Function Create-NTFSMountedFolder { Param ([Parameter(Mandatory=$true)][String] $VM,[Parameter(Mandatory=$true)][String] $Folder,[Parameter(Mandatory=$true)][String] $SCSIPort,[Parameter(Mandatory=$true)][String] $SCSITargetID)
We will be invoking this action using the ‘Invoke-VMScript’ cmdlet so we create a script text string to perform the orchestration to create the NTFS mounted folder. Firstly we will invoke the ‘New-Item’ cmdlet to create the empty folder on the parent volume.
$ScriptText = "New-Item -ItemType Directory -Path $Folder;
Now we will be required to retrieve the disk based on the SCSI Port and TargetID. In order to retrieve the disk required we will invoke the ‘Get-Disk’ cmdlet where we will retrieve the disk number required by invoking the ‘Get-WMIObject’ cmdlet with the class Win32_Drive to filter the disks where the SCSI Port and TargetID are equal to the those specified in the mandatory parameter and return the Index value of the disk.
`$Disk = Get-Disk -Number (Get-WmiObject -Class Win32_DiskDrive | Where-Object {`$_.SCSIPort -eq $SCSIPort -and `$_.SCSITargetID -eq $SCSITargetID}).Index;
Once we have retrieved the disk, we will now initialize the disk with the GPT partition style by invoking the Initialize-Disk cmdlet where the disk number is retrieved from the above query by specifying the Number value.
Initialize-Disk -Number `$Disk.Number -PartitionStyle GPT -PassThru;
Next we will create a partition and use the maximum size of the disk by invoking the New-Partition cmdlet .
New-Partition -DiskNumber `$Disk.Number -UseMaximumSize;
For the empty folder created in the first step we will now create an access path by invoking the ‘Add-PartitionAccessPath’ cmdlet to create the access path on the disk and partition specified.
Add-PartitionAccessPath -DiskNumber `$Disk.Number -PartitionNumber 2 -AccessPath $Folder\;
Finally, we will retrieve the partition created using the ‘Get-Partition’ cmdlet and invoke the ‘Format-Volume’ cmdlet to perform a full format of the volume with Unit Allocation Size of 64K and set the file system label to be the name of the empty folder created.
Get-Partition -DiskNumber `$Disk.Number -PartitionNumber 2 | Format-Volume -FileSystem NTFS -AllocationUnitSize 65536 -Full -NewFileSystemLabel $Folder -Confirm:`$False"
Now we will invoke the ‘Invoke-VMScript’ cmdlet to run the above in the guest operating system to create the NTFS mounted folder.
Invoke-VMScript -VM $VM -ScriptText $ScriptText }
So by invoking the above functions we be able to create the virtual machine hard disks and create a NTFS mounted folder. In the below example, I will create three virtual machine hard disks and then create three NTFS mounted folders with the names D:\Databases1, D:\Databases2 and D:\Databases3.
Create-VirtualHardDisks -VM vm1 -Number 3 -CapacityGB 20 Create-NTFSMountedFolder -VM vm1 -Folder D:\Databases1 -SCSIPort 4 -SCSITargetID 3 Create-NTFSMountedFolder -VM vm1 -Folder D:\Databases2 -SCSIPort 4 -SCSITargetID 4 Create-NTFSMountedFolder -VM vm1 -Folder D:\Databases3 -SCSIPort 4 -SCSITargetID 5
The above functions, can be downloaded from the below:
Create-VirtualHardDisks – https://github.com/dean1609/scripts/blob/master/Create-VirtualHardDisks.ps1
Create-NTFSMountedFolder – https://github.com/dean1609/scripts/blob/e48d13eeb13baefa71777371f265d60d55d5a4a6/Create-NTFSMountedFolder.ps1