Remotely extend a partition using WMI

2019-05-23 18:09发布

问题:

I'm trying to use PowerShell and WMI to remotely extend a C drive partition on Windows VMs running on VMware.

These VM do not have WinRM enabled and that's not an option. What I'm trying to do is an equivalent of remotely managing an Active Directory computer object in an AD console to extend a partition, but in PowerShell.

I'v already managed to pull partition informations through Win32 WMI objects but not yet the extension part.

Does anyone know how to max out a C partition on a drive like that?

回答1:

Pre-requisites:

  • PsExec from SysInternals Suite
  • PowerShell 2.0 or greater for PowerShell modules feature on the remote computer(s)

First, enable PSRemoting via PsExec:

psexec \\[computer name] -u [admin account name] -p [admin account password] -h -d powershell.exe "enable-psremoting -force"

The following PowerShell script will do the trick, without WMI, via PowerShell Sessions instead, and will do it for as many computers as you want:

Here is the driver script:

$computerNames = @("computer1", "computer2");
$computerNames | foreach {
  $session = New-PSSession -ComputerName $_;
  Invoke-Command -Session $session -FilePath c:\path\to\Expand-AllPartitionsOnAllDisks.ps1
  Remove-PSSession $session
}

And here is Expand-AllPartitionsOnAllDisks.ps1:

Import-Module Storage;

$disks = Get-Disk | Where FriendlyName -ne "Msft Virtual Disk";

foreach ($disk in $disks)
{
    $DiskNumber = $disk.DiskNumber;
    $Partition = Get-Partition -DiskNumber $disk.DiskNumber;

    $PartitionActualSize = $Partition.Size;
    $DriveLetter = $Partition.DriveLetter;
    $PartitionNumber = $Partition.PartitionNumber
    $PartitionSupportedSize = Get-PartitionSupportedSize -DiskNumber $DiskNumber -PartitionNumber $PartitionNumber;

    if ($disk.IsReadOnly)
    {
        Write-Host -ForegroundColor DarkYellow "Skipping drive letter [$DriveLetter] partition number [$PartitionNumber] on disk number [$DiskNumber] because the disk is read-only!";
        continue;
    }

    if ($PartitionActualSize -lt $PartitionSupportedSize.SizeMax) {
        # Actual Size will be greater than the partition supported size if the underlying Disk is "maxed out".
        # For example, on a 50GB Volume, if all the Disk is partitioned, the SizeMax on the partition will be 53684994048.
        # However, the full Size of the Disk, inclusive of unpartition space, will be 53687091200.
        # In other words, it will still be more than partition and unlikely to ever equal the partition's MaxSize.
        Write-Host -ForegroundColor Yellow "Resizing drive letter [$DriveLetter] partition number [$PartitionNumber] on disk number [$DiskNumber] because `$PartitionActualSize [$PartitionActualSize] is less than `$PartitionSupportedSize.SizeMax [$($PartitionSupportedSize.SizeMax)]"

        Resize-Partition -DiskNumber $DiskNumber -PartitionNumber $PartitionNumber -Size $PartitionSupportedSize.SizeMax -Confirm:$false -ErrorAction SilentlyContinue -ErrorVariable resizeError
        Write-Host -ForegroundColor Green $resizeError
    }
    else {
        Write-Host -ForegroundColor White "The partition is already the requested size, skipping...";
    }
}

See also my related research into doing this:

  1. https://serverfault.com/questions/946676/how-do-i-use-get-physicalextent-on-get-physicaldisk
  2. https://stackoverflow.com/a/4814168/1040437 - Solution using diskpart, requires knowing the volume number