Replacing DiskPart with PowerShell

In my previous life, I was a deployment person. MDT, WDS, WinPE & bare-metal installation were all part of my life. For managing disks, physical or virtual I always used “diskpart.exe” to create the disk layout, create bootable partitions and everything surrounding the magic of disks and partitions. Since I am trying to do as much as possible now with PowerShell I thought it would be fun to see if “diskpart.exe” could be replaced with pure PowerShell CMDLET’s? To give you a heads-up, it can for 99%, almost there! Just one feature I could not find is setting GPT attributes. According to this article, a Recovery Partition should have the attribute of “GPT_ATTRIBUTE_PLATFORM_REQUIRED” & “GPT_BASIC_DATA_ATTRIBUTE_NO_DRIVE_LETTER” resulting in a value of “0x8000000000000001”. Using “diskpart.exe” to query for information from a default installation of Windows 10 results in the correct attributes.

PSDiskpart001

I did expect that setting a partition to the guid value for a recovery partition with PowerShell (“de94bba4-06d1-4d40-a16a-bfd50179d6ac”) ,would also take care of both the attributes. It partially does that, just the “GPT_BASIC_DATA_ATTRIBUTE_NO_DRIVE_LETTER” is set, so the drive is hidden for the OS. The other one is not set and according to my research, it is simply not available in PowerShell. Therefore, you will still need “diskpart.exe”.

During my experimentations, I have concluded that PowerShell’s “Disk”, “Partition” and “Volume” cmdlets are tricky to work with. It takes time to understand how to handle them, but it eventually works. In my opinion “diskpart.exe” is still more powerful when it comes down to pure handling disks, however PowerShell has far better support for handling the dynamics surrounding scripting and error handling. Still it is not so difficult to combine them both, as you will see in my example.

Here is my code or download the script below. Please note that I have put a “return” at the top of the script so you do not destroy your disk the first time you run the script.

# Define the disk
$Disk = Get-Disk | where Number -EQ "0"
$DiskNumber = $Disk.DiskNumber

# Clean the disk and convert to GPT
if ($disk.PartitionStyle -eq "RAW")
{

Initialize-Disk -Number $Disk.DiskNumber -PartitionStyle GPT

} Else {

Clear-Disk -Number $DiskNumber -RemoveData -RemoveOEM -Confirm:$false
 Initialize-Disk -Number $DiskNumber -PartitionStyle GPT

}

#Create the System Partition Partition
$SystemPartition = New-Partition -DiskNumber $DiskNumber -Size 512MB
$SystemPartition | Format-Volume -FileSystem FAT32 -NewFileSystemLabel "system"
$systemPartition | Set-Partition -GptType "{c12a7328-f81f-11d2-ba4b-00a0c93ec93b}"
$SystemPartition | Set-Partition -NewDriveLetter "S"

#Create Microsoft Reserved Partition
New-Partition -DiskNumber $DiskNumber -Size 128MB -GptType "{e3c9e316-0b5c-4db8-817d-f92df00215ae}"

#Create Primary Partition
$PrimaryPartition = New-Partition -DiskNumber $DiskNumber -UseMaximumSize
$PrimaryPartition | Format-Volume -FileSystem NTFS
$PrimaryPartition | Set-Partition -GptType "{ebd0a0a2-b9e5-4433-87c0-68b6b72699c7}"
$PrimaryPartition | Set-Partition -NewDriveLetter "W"

#Shrink Primary Partition by 500MB for the Recovery Partition
$newSize = ($PrimaryPartition.Size - 524288000)
$PrimaryPartition | Resize-Partition -Size $newSize

#Create the Recovery Partition
$RecoveryPartition = New-Partition -DiskNumber $DiskNumber -UseMaximumSize
$RecoveryPartition | Format-Volume -FileSystem NTFS
$RecoveryPartition | Set-Partition -GptType "{de94bba4-06d1-4d40-a16a-bfd50179d6ac}"
$RecoveryPartition | Set-Partition -NewDriveLetter "R"

# Add "Required" attribute to the GPT Recovery partition. (No .Net Function available)
$partitionNumber = $RecoveryPartition.PartitionNumber
$DiskPartCMD=@(
"select disk $DiskNumber"
"select partition $partitionNumber"
'gpt attributes=0x8000000000000001'
'exit'
)

$DiskpartCMD | diskpart.exe

If anyone reading has a PowerShell solution to setting the attributes, please let me know.

Downloads


Create-EFIPartitions

Reference


PARTITION_INFORMATION_GPT structure
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365449(v=vs.85).aspx

CREATE_PARTITION_PARAMETERS structure
https://technet.microsoft.com/en-us/library/aa381635.aspx

New-Partition
https://docs.microsoft.com/en-us/powershell/module/storage/new-partition?view=win10-ps

Customizing the recovery partition after upgrading the OS from Windows 8.1 to Windows 10
https://blogs.technet.microsoft.com/askcore/2016/04/26/customizing-the-recovery-partition-after-upgrading-the-os-from-windows-8-1-to-windows-10/

 

 

2 thoughts on “Replacing DiskPart with PowerShell

  1. Hi!
    for image deployment i’m using this part of code to format disk by selected type:

    if([string]::IsNullOrEmpty($tDskNum))
      {
        $dskprt_LsDk =  Get-disk|Select-Object Number, FriendlyName, operationalstatus;
        $dskprt_LsDk;
        $tDskNum=Read-Host "`n Please, type integer disk number from the list above";
      }
      Write-Host "`n Selected Disk Number: $tDskNum";
      if([string]::IsNullOrEmpty($MBRorGpt))
      {
        $MBRorGpt=Read-Host "Please, type here which partition style to use in format, MBR or GPT?"
      }
      switch($MBRorGpt)
      {
       GPT{
            "Selected Disk type: $MBRorGpt";
            #clear disk
            Get-Disk -Number $tDskNum | Get-Partition | Remove-partition -confirm:$false;
            Clear-Disk -Number $tDskNum -RemoveData -RemoveOEM -confirm:$false;
            Get-Disk -number $tDskNum|Initialize-Disk -PartitionStyle GPT -PassThru;
            #create the system partition
            New-Partition -DiskNumber $tDskNum -GptType '{c12a7328-f81f-11d2-ba4b-00a0c93ec93b}' -Size 512MB -DriveLetter 'S'| `
            Format-Volume -FileSystem FAT32 -NewFileSystemLabel 'System' -Confirm:$false;
            #create MSR
            New-Partition -DiskNumber $tDskNum -Size 128MB -GptType "{e3c9e316-0b5c-4db8-817d-f92df00215ae}";
            #create Primary (Windows) Partition
            New-Partition -DiskNumber $tDskNum -GptType '{ebd0a0a2-b9e5-4433-87c0-68b6b72699c7}' -UseMaximumSize -DriveLetter 'W'| `
            Format-Volume -FileSystem NTFS -NewFileSystemLabel 'Windows' -Confirm:$false;
            break
          }
       MBR{
            "Selected Disk type: $MBRorGpt";
            #clear disk
            Get-Disk -Number $tDskNum | Get-Partition | Remove-partition -confirm:$false;
            Clear-Disk -Number $tDskNum -RemoveData -RemoveOEM -confirm:$false;
            Get-Disk -number $tDskNum|Initialize-Disk -PartitionStyle MBR -PassThru;
    	      #create the system partition
            New-Partition -DiskNumber $tDskNum -Size 512MB -DriveLetter 'S' -IsActive | `
            Format-Volume -FileSystem NTFS -NewFileSystemLabel 'System' -Confirm:$false;
            #create Primary (Windows) Partition
            New-Partition -DiskNumber $tDskNum -UseMaximumSize -DriveLetter 'W'| `
            Format-Volume -FileSystem NTFS -NewFileSystemLabel 'Windows' -Confirm:$false;
            break
          }
        default{"getting wrong disk type";}
        }
    

    Liked by 1 person

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s