Increase VMware VM Disk Size with PowerShell

In this post, I will cover how to use PowerShell to increase the disk size of a Windows 10 VM running in a VMware vCenter environment. Automating simple but time consuming tasks like this can save precious time for your support staff or yourself. There are two parts to accomplishing this task; first we need to increase the disk size of the VM and then we will expand the partition inside the Windows 10 OS.


Prerequisites

PowerShell Remoting will need to be enabled on the Windows 10 VM that you want to increase the disk on. I am not going to go into detail on how to accomplish that in this post, there are several great resources to help if the Invoke-Command gives you an error. Having admin rights on the Windows 10 VM will also be needed to modify the partition. In addition, you will need rights to run commands against the vCenter server. We also need to install VMware PowerCLI. To do so, you can install it from the PowerShell Gallery with the below command.

Install-Module VMware.PowerCLI

Code

GitHub

We will start out by declaring the variables needed to perform the automated tasks outlined in this post. In this example, I am using the GUI text box that I wrote about in a previous post. I am using the text box as one method you could use to accept a list of VM names. The $Target_Disk variable is the final size that you want the disk to be. For example, if the disk is currently 160 GB and you want to expand it by 20 GB, then you would enter 180. The vCenter server can be hard coded in a variable if that is more convenient for you. For this example I used read-host to allow for more flexibility.

### Launch GUI textbox to accept input from user
$VMs = GUI_TextBox "VM Name(s):" ### This function was introduced in previous blog post
$VM_Count = $VMs | Measure-Object | % {$_.Count}
If ($VM_Count -eq 0){ ### If nothing was inputed, the script will not continue
    Write-Host "Nothing was inputed, script is exiting..." -BackgroundColor Red -ForegroundColor White
    Return
}
Else{
    $Target_Disk = Read-Host "Enter the target disk size in GB (ie: 180)"
    $vCenter = Read-Host "Enter the vCenter FQDN you want to connect to"
}

This section of code is used as the final confirmation and to ensure the information entered was typed accurately.

Write-Host "Below are the variables that will be fed into the script:" -ForegroundColor Black -BackgroundColor Yellow
Write-Host "Number of VMs to increase disk:" $VM_Count -ForegroundColor White -BackgroundColor Blue
Write-Host "vCenter to connect to:" $vCenter -ForegroundColor White -BackgroundColor Blue
Write-Host "Target disk size in GB:" $Target_Disk -ForegroundColor White -BackgroundColor Blue
$final_confirm = (Read-Host "Do you want to Continue? (Y/N)").ToUpper()

Next we will connect to the vCenter server specified in the variable. In order to connect to the vCenter we need to provide the credentials to use. Here we are using Get-Credential to manually input the username and password we want to utilize. There are other methods to securely passing credentials, but for simplicity, I went this route.

$VIcred = Get-Credential
Write-Host "Please wait while the script connects to vCenter: $vCenter" -BackgroundColor Cyan -ForegroundColor Black
Connect-VIServer -Server $vCenter -Credential $VIcred -ErrorAction Stop -Force

Finally, we get to the section of code that resizes the VM disk and expands the OS partition for the given list of VMs. You may need to adjust the name of the VM disk for your environment. For this example I use “Hard Disk 1” which is how my VMs are configured. Also, if the drive letter you want to expand is something other than C, that will have to be modified in your code.

If ($final_confirm -eq "Y") { ### executes if the user entered y or Y on the final confiramtion question
    Foreach ($VM in $VMs){ ### going through each VM in the VMs variable
        Write-Host $VM "- Increasing disk to $Target_Disk GB" -BackgroundColor Yellow -ForegroundColor Black
        try{
            ### Resize the VM disk through VMware PowerCLI
            Get-HardDisk -Server $vCenter -VM $VM | Where-Object {$_.Name -eq "Hard Disk 1"} | Set-HardDisk -Server $vCenter -CapacityGB $Target_Disk -Confirm:$false
            ### Utilize invoke-command to expand the C partition within windows 10
            $ScriptBlock = { ### The commands that will be executed on the remote windows 10 VM
                $MaxSize = (Get-PartitionSupportedSize -DriveLetter C).Sizemax  ### This grabs the max size which should now be larger than the current partition
                Resize-Partition -DriveLetter C -Size $MaxSize ### command to expand the parition
            }
            Invoke-Command -ComputerName $VM -ScriptBlock $ScriptBlock ### execution of the scriptblock commands on the remote windows 10 VM
        }
        Catch [Exception]{ ### If the command inside the try statement fails the error will be outputted
            $errormessage = $_.Exception.Message
            Write-Host $errormessage -BackgroundColor Red -ForegroundColor White
            Return
        }
        Write-Host "$VM - Process Complete" -BackgroundColor Cyan -ForegroundColor Black
    }
}
Else{Write-Host "You selected Cancel or Nothing Present" -BackgroundColor Red -ForegroundColor White}

To keep things clean we disconnect from the vCenter.

Disconnect-VIServer -Server $vCenter -Confirm:$false

That’s it for now, thanks for reading!


Check out my other blog posts:

Media Sync: Organize Your Photos and Videos with PowerShell

Do you have photos and videos that you have taken over the years that are scattered all over the place? Do you want to have all your photos and videos organized? Do you want all your photos and videos to have a standardized naming scheme? If you answered YES to these questions, then this is…

NetNeighbor Watch: The PowerShell Alternative To Arpwatch

In this post, we are going to setup NetNeighbor Watch on a Raspberry Pi. NetNeighbor Watch can keep an eye on your network and send you an email when a new host is discovered. NetNeighbor Watch is done completely in PowerShell. The results are very similar to those of arpwatch. NetNeighbor Watch is for anyone…

Generate a Citrix Desktop Report Based on Active Directory Users

In this post, we are going to merge data from two different sources to generate a report that can provide insight into your Citrix environment. I will show you how to combine Active Directory data for the users in your domain with Citrix data. This report will provide you with the following knowledge: Users that…

Creating a PowerShell Module to Improve Your Code

Do you have PowerShell code that you reuse in your scripts over and over? Do you have server names hard coded in variables? Are you using a text file or CSV file to import server names? Do you find yourself only utilizing one server out of a cluster of servers to make your PowerShell commands?…

Generate a DHCP Report Via PowerShell

Today we are going to look at how to generate a DHCP scope statistics HTML report by using PowerShell. This report will give you one location to see all of your DHCP scope statistics across all of your Windows DHCP servers. It will dynamically pull the DHCP servers and associated DHCP scopes within your Active…

Manage Citrix Tags with PowerShell

In this post, we are going to cover how to manage Citrix tags with PowerShell. Citrix Studio is a great tool, but it can be very time consuming especially if you have to do bulk tag actions. Citrix tags can be used in several methods, but this post is focused on desktop tagging. This post…

Create a Text Box to Accept User Input for PowerShell GUI

Do you have a PowerShell GUI that needs to accept text input? Maybe you want to be able to copy and paste a list of computers, ip addresses, user names or some other data. I will show you how to add a text box into your PowerShell GUI to handle that input. If you haven’t…

Utilizing PowerShell Out-GridView as a GUI Alternative

In my previous post, I showed how you can build a simple menu driven PowerShell GUI; check it out here. To further improve upon that simple GUI, we will go over how to use Out-GridView. Out-GridView is a built-in powershell cmdlet that sends the output from a given command to an interactive window. This post…

How to Create a Simple PowerShell GUI

Have you ever wanted to create a menu driven PowerShell GUI to conduct a series of automated tasks? You are in luck, because that is exactly what we are going to cover in this post. This very simple PowerShell GUI will help you easily distribute your code to other team members or maybe you just…

Leave a comment