- Kubernetes DaemonSets - Wed, Sep 6 2023
- Static Pods in Kubernetes - Fri, Sep 1 2023
- Encrypt Kubernetes Secrets at rest - Mon, Aug 28 2023
Windows 10 and and Windows 11 has the storage module in PowerShell, which offers various cmdlets related to disk storage management. To see the list of all the cmdlets, you can use Get-Command, as shown below:
Get-Command -Module Storage
You can see that the list is really long. You can use -Verb or -Noun parameters with this command to further trim the list, as shown in the following command:
Get-Command -Module Storage -Noun "*disk*"
The Get-Command cmdlet with the -Module Storage and -Noun disk parameters gives us all the cmdlets from the "Storage" module that have "disk" in their "Noun" section. I hope this makes sense in understanding the "Verb–Noun" nomenclature of PowerShell.
Covering all these commands is beyond the scope of this article. Therefore, I will try to cover the commands that an administrator would most often use to perform routine disk management operations.
View disk and partition information with Get-Disk
As discussed previously, the partitioning scheme is very important when it comes to disks. To show the partitioning scheme for all the disks in your system, you can use the following command:
Get-Disk | Format-Table -Auto
- The command shows information about three disks that are connected to the system.
- The Partition Style column at the end shows the partitioning scheme for all the disks.
The PowerShell Storage module also offers the Get-PhysicalDisk cmdlet. Let's take a look at the output of this command:
So, what's the difference between the Get-Disk and Get-PhysicalDiskcommands?
The Get-Disk command shows only the logical disks, whereas the Get-PhysicalDisk command returns all the physical disk devices that are attached to the system. The Get-PhysicalDisk command is particularly useful when creating and managing storage spaces. We will not discuss storage spaces in this article. Let's just focus on disk management.
To view the partition information for a disk, use the Get-Partition command, as shown below:
Get-Partition -DiskNumber 0
- The output of the Get-Disk command shows the disk number in the first column under the "Number" column.
- We used the Get-Partition command with the -DiskNumber parameter to view the partition details for disk 0.
- The output of Get-Partition gave us DriveLetter for the partitions that are available on that disk.
To get information about a particular partition based on its drive letter, you can use the Get-Partition command with the -DriveLetter parameter.
Get-Partition -DriveLetter D
There are numerous commands that you can use to get the information, but I cannot cover them all here. Now that we have enough information about the disks, let's move to the next section.
Initialize the disk with Initialize-Disk
When you attach a new disk to your system for the first time, you need to initialize that disk before you can start using it. Remember the following screen in your disk management tool?
To initialize the disk using PowerShell, we can use the Initialize-Disk with the -PartitionStyle parameter, as shown in the following command:
Get-Disk | where PartitionStyle -eq 'raw' | Initialize-Disk -PartitionStyle GPT
Take a look at the following image:
- I used the Get-Disk command to list all disks. The Partition Style column tells me that the disk that is not initialized is marked as RAW.
- So, I ran Get-Disk again with a filter to get only "RAW" disks and piped the result to the Initialize-Disk command. The -PartitionStyle GPT parameter initialized the disk as GPT. To initialize the disk as MBR, you could replace GPT with MBR.
Partition the disk with New-Partition
Now that our disk is initialized, we need to create partition(s) before Windows can start using it. To create partitions, we can use the New-Partition cmdlet as shown below:
New-Partition -DiskNumber 3 -Size 20GB -AssignDriveLetter
- The -DiskNumber parameter is used to specify a particular disk.
- The -Size parameter is used to specify the size of the partition. To use all the unallocated space available on the disk, you could use the -UseMaximumSize parameter.
- The -AssignDriveLetter parameter is used to let Windows choose a drive letter automatically. To specify the particular drive letter of your choice, you could use the -DriveLetter parameter.
To create another partition on the same drive, I will use the following command:
New-Partition -DiskNumber 3 -UseMaximumSize -DriveLetter G
- My disk was 50 GB, and the first partition that I created was 20 GB.
- The -UseMaximumSize parameter for the second partition created a new partition of an approximate size of 30 GB with a manually specified "G" drive letter.
Format the disk with Format-Volume
Before we can start saving our files on the partitions that we just created, they need to be formatted. In the previous section, we assigned the "F" and "G" drive letters to our new partitions. To format the volume, we can use the Format-Volume command, as shown below:
Format-Volume -DriveLetter F -FileSystem NTFS -NewFileSystemLabel "DATA1"
The -DriveLetter parameter is used to specify the partition we are going to format.
- The -FileSystem parameter is used to specify the file system. You can specify the NTFS, ReFS, exFAT, FAT32, and FAT file system types.
- The -NewFileSystemLabel parameter is used to specify the volume label.That is all for initializing, partitioning, and formatting the disk. The best thing about PowerShell is its pipelining ability. We can combine all the commands to initialize, partition, and format the disk into a single command, which will look as shown below:
Get-Disk | where PartitionStyle -eq 'raw' | Initialize-Disk -PartitionStyle GPT -PassThru | New-Partition -AssignDriveLetter -UseMaximumSize | Format-Volume -FileSystem NTFS -NewFileSystemLabel "MYDATA"
- The only new thing you will notice in the above command is the -PassThru parameter, which sends the output of the Initialize-Disk command down the pipeline. The -PassThru parameter is needed because Initialize-Disk does not produce any output by default.
- The command takes all the "RAW" disks, initializes them with the "GPT" scheme, creates a single partition with the -UseMaximumSize parameter, automatically assigns a drive letter, and then formats the volume with the NTFS file system.Take a look at the following image:
Format USB storage
To format the removable storage disk, use the following command:
Format-Volume -DriveLetter E -FileSystem NTFS -NewFileSystemLabel "USBDATA"
PowerShell also offers a Clear-Disk cmdlet that cleans the disk by removing all partition information and data and uninitializing it. You can use the -Number or the -FriendlyName parameter to specify the disk to clear.
Warning: Please use extra care while using the "Clear-Disk" command on a disk. A little mistake in specifying the correct disk could potentially erase all your important data.
The following command will clear my USB drive, initialize it, create a partition, format it with the NTFS file system, and assign a volume label to it:
Clear-Disk -FriendlyName "SanDisk Cruzer Blade" -RemoveData -RemoveOEM -Confirm:$False -PassThru | Initialize-Disk -PartitionStyle MBR -PassThru | New-Partition -AssignDriveLetter -UseMaximumSize | Format-Volume -FileSystem NTFS -NewFileSystemLabel "USBDATA"
Clear, initialize, partition, and format disk
- The -FriendlyName parameter is used to specify the disk to clean.
- The -RemoveData parameter is used to remove the data from the disk.
- The -RemoveOEM parameter is used to remove the OEM recovery partitions, if any, from the disk.
- The -Confirm:$false parameter is used to disable the confirmation message before clearing the disk.
- The -PassThru parameter sends the output object from one command down the pipeline. This parameter is needed when a command does not produce any output by default, but you still want to pass the output object down the pipeline to the next command.
When you try to run the Clear-Disk cmdlet on a disk that is in the Not Initialized state, you will get an error stating, The disk has not been initialized, as shown in the following screenshot:
To get around this error, you need to use the Get-Disk command. In this case, you can directly initialize, partition, and format the disk using a single command, as shown below:
Get-Disk | where {$_.FriendlyName -eq 'SanDisk Cruzer Blade'} | Initialize-Disk -PartitionStyle MBR -PassThru | New-Partition -AssignDriveLetter -UseMaximumSize | Format-Volume -FileSystem NTFS -NewFileSystemLabel "USBDATA"
When you use Clear-Disk and then try to use the Set-Disk command to define the partition style, you will get a Not Supported error.
Clear-Disk -FriendlyName 'SanDisk Cruzer Blade' -RemoveData -RemoveOEM -Confirm:$False -PassThru | Set-Disk -PartitionStyle MBR
The Not Supported error occurs because the Clear-Disk command has already cleaned and set the disk in the "Not Initialized" state. To fix this error, you need to use the Initialize-Disk command. You can initialize, partition, and format the disk using a single command, as follows:
Get-Disk | where {$_.FriendlyName -eq 'SanDisk Cruzer Blade'} | Initialize-Disk -PartitionStyle MBR -PassThru | New-Partition -AssignDriveLetter -UseMaximumSize | Format-Volume -FileSystem NTFS -NewFileSystemLabel "USBDATA"
Get disk usage Information with Get-CimInstance
To display storage usage statistics for all the disks in your system, you can use the following command:
Get-CimInstance Win32_LogicalDisk | Format-Table DeviceId, VolumeName, @{n="TotalSize (GB)";e={[math]::Round($_.Size/1GB,2)}}, @{n="UsedSpace (GB)";e={[math]::Round($_.Size/1GB - $_.FreeSpace/1GB,2)}}, @{n="FreeSpace (GB)";e={[math]::Round($_.FreeSpace/1GB,2)}}
This command shows the DriveLetter, VolumeName, Total Size, Used Space, and Free Space for each partition in the system in a nice tabular format.
Take a look at the UsedSpace column. The F drive shows 8.42 GB storage used.
Resize disk operations with Resize-Partition
In the previous section, we created a single partition of 50 GB on disk 3 and assigned the F drive letter to it.
In the above image, you can see that the F drive has 8.42 GB space used. So, if you want to resize this partition, you cannot resize it below 8.42 GB.
To resize the partition to 25 GB, use the Resize-Partition command, as shown below:
Resize-Partition -DriveLetter F -Size 25GB
The partition was successfully resized to 25 GB.
If you try to set the value of the -Size parameter to lower than the used space, you will get the Size Not Supported error.
To fix this error, you need to set the value of the -Size parameter to a higher value than the space used.
Similarly, if you try to set the value of the -Size parameter to something higher than the Total Size, you will get the Not enough available capacity error.
To get around this error, you need to set the value of the -Size parameter to a lower value than the "Total Size".
Now, suppose you want to resize the partition to its maximum capacity. Unfortunately, no parameter is available with the Resize-Partition cmdlet to support this operation. But there is always a way. The storage module offers a Get-PartitionSupportedSize cmdlet that returns two values: SizeMin and SizeMax.
We can use this command, along with Resize-Partition, to obtain the desired result. Let's take a look at the following commands:
$supportedSize = (Get-PartitionSupportedSize -DriveLetter F) Resize-Partition -DriveLetter F -Size $supportedSize.SizeMax
After running the above commands, the partition is resized to its maximum supported capacity. To view the disk usage statistics again, use the following command:
Get-CimInstance Win32_LogicalDisk | Format-Table DeviceId, VolumeName, @{n="TotalSize (GB)";e={[math]::Round($_.Size/1GB,2)}}, @{n="UsedSpace (GB)";e={[math]::Round($_.Size/1GB - $_.FreeSpace/1GB,2)}}, @{n="FreeSpace (GB)";e={[math]::Round($_.FreeSpace/1GB,2)}}
In my next post in this series about Windows PowerShell disk management, I will explain how you can modify partition information with PowerShell.
Excellent follow-up article Surender. I really like how you’re gradually progressing into this. I did see one mistake.
“To get around this error, you need to use the Clear-Disk command. In this case, you can directly initialize, partition, and format the disk using a single command, as shown below:”
I think it should be “use the Get-Disk command” instead.
Other than that, it’s great!
The error has been corrected. Thank you Marc for pointing that out. 🙂
Good article! Thanks! But it would be even better to change the scripts to use Get-CimInstance instead of Get-WmiObject. This is a Microsoft recommendation. This is the Microsoft recommendation from the help for the Get-WmiObject cmdlet. It is also detailed here: https://www.pdq.com/blog/powershell-guide-get-ciminstance-and-get-wmiobject/
Oh, yes… I did read that Get-WmiObject cmdlet is superseded with Get-CimInstance starting from PSv3, but forgot to update my script.
Thank you for the tip.