SATP check via Powershell

SATP stands for Storage Array Type Plugin, and it is a critical component in VMware vSphere environments that plays a key role in managing the paths to storage devices. SATP is part of the Pluggable Storage Architecture (PSA) framework, which provides an abstraction layer between the storage hardware and the VMware ESXi host. SATP is used to control the behavior of storage paths and devices in an ESXi host.

Here’s why SATP is used and its main functions:

  1. Path Management: SATP is responsible for managing the paths to storage devices, including detecting, configuring, and managing multiple paths. It ensures that the ESXi host can communicate with the storage devices through multiple paths for redundancy and improved performance.
  2. Path Failover: In a storage environment with redundant paths, SATP monitors the health of these paths. If a path becomes unavailable or fails, SATP can automatically redirect I/O traffic to an alternate path, ensuring continuous access to storage resources even in the event of a path failure.
  3. Storage Policy Enforcement: SATP enforces specific policies and behaviors for handling path failover and load balancing based on the characteristics of the storage array. These policies are defined by the storage array vendor and are unique to each array type.
  4. Multipathing: SATP enables multipathing, which allows an ESXi host to use multiple physical paths to access the same storage device. This improves performance and redundancy by distributing I/O traffic across multiple paths.
  5. Vendor-Specific Handling: Different storage array vendors have their own specific requirements and behaviors. SATP allows VMware to support a wide range of storage arrays by providing vendor-specific plugins that communicate with the storage array controllers.
  6. Load Balancing: SATP can balance I/O traffic across multiple paths to optimize performance and prevent overloading of any single path.
  7. Path Selection: SATP determines which path to use for I/O operations based on specific path selection policies defined by the array type and the administrator.

Here’s an example of how you can use PowerCLI to check and display the recommended SATP settings:

# Connect to your vCenter Server
Connect-VIServer -Server YourVCenterServer -User YourUsername -Password YourPassword

# Get the ESXi hosts you want to check
$ESXiHosts = Get-VMHost -Name "ESXiHostName1", "ESXiHostName2"  # Add ESXi host names

# Loop through ESXi hosts
foreach ($ESXiHost in $ESXiHosts) {
    Write-Host "Checking SATP settings for $($ESXiHost.Name)"

    # Get the list of storage devices
    $StorageDevices = Get-ScsiLun -VMHost $ESXiHost

    # Loop through storage devices
    foreach ($Device in $StorageDevices) {
        $SATP = $Device.ExtensionData.Config.StorageArrayTypePolicy
        Write-Host "Device: $($Device.CanonicalName)"
        Write-Host "Current SATP: $($SATP.Policy)"
        Write-Host "Recommended SATP: $($SATP.RecommendedPolicy)"
        Write-Host ""
    }
}

# Disconnect from the vCenter Server
Disconnect-VIServer -Server * -Confirm:$false

Replace YourVCenterServer, YourUsername, YourPassword, ESXiHostName1, ESXiHostName2 with your actual vCenter Server details and ESXi host names.

In this script:

  1. Connect to the vCenter Server using Connect-VIServer.
  2. Get the list of ESXi hosts using Get-VMHost.
  3. Loop through ESXi hosts and retrieve the list of storage devices using Get-ScsiLun.
  4. For each storage device, retrieve the current SATP settings and the recommended SATP settings.
  5. Display the device name, current SATP, and recommended SATP.

Here are a few examples of storage vendors and their corresponding SATP plugins:

  1. VMW_SATP_DEFAULT_AA (VMware Default Active/Active):
    • Vendor: VMware (default)
    • Description: This is the default SATP provided by VMware and is used for active/active storage arrays.
    • Example: Many local and shared storage arrays in VMware environments use this default SATP.
  2. VMW_SATP_ALUA (Asymmetric Logical Unit Access):
    • Vendor: VMware (default)
    • Description: This SATP is used for arrays that support ALUA, a type of storage access where certain paths are optimized for I/O based on their proximity to the storage controller.
    • Example: EMC VNX, Hitachi HDS storage arrays.
  3. IBM_SATP_DEFAULT_AA (IBM Default Active/Active):
    • Vendor: IBM
    • Description: IBM’s SATP module for active/active storage arrays.
    • Example: IBM DS8000 series storage arrays.
  4. HP_SATP_ALUA (HP Asymmetric Logical Unit Access):
    • Vendor: Hewlett Packard Enterprise (HPE)
    • Description: HPE’s SATP module for ALUA-compatible storage arrays.
    • Example: HPE 3PAR, HPE Nimble Storage.
  5. NETAPP_SATP_ALUA (NetApp Asymmetric Logical Unit Access):
    • Vendor: NetApp
    • Description: NetApp’s SATP module for ALUA-based storage arrays.
    • Example: NetApp FAS, NetApp AFF.
  6. DGC_CLARiiON (Dell EMC CLARiiON):
    • Vendor: Dell EMC
    • Description: SATP module for Dell EMC CLARiiON storage arrays.
    • Example: Older Dell EMC CLARiiON storage systems.

These examples illustrate how different storage vendors provide their own SATP modules to enable proper communication and management of storage paths and devices in VMware environments. The specific SATP module used depends on the storage array being utilized. It’s important to consult the documentation provided by both VMware and the storage vendor to ensure proper configuration and compatibility in your vSphere environment.

Set-ScsiLunPath for multiple LUNs via powershell

In VMware PowerCLI, you can use the Set-ScsiLunPath cmdlet to modify the configuration of paths for a specific SCSI LUN. To modify paths for multiple LUNs, you can use a loop to iterate through the LUNs and apply the necessary changes. Here’s an example script that demonstrates how to set paths for multiple LUNs using PowerCLI:

# Connect to your vCenter Server
Connect-VIServer -Server YourVCenterServer -User YourUsername -Password YourPassword

# Get the ESXi hosts where the LUNs are presented
$ESXiHosts = Get-VMHost -Name "ESXiHostName1", "ESXiHostName2"  # Add ESXi host names

# Define the list of SCSI LUN IDs and paths to configure
$LUNPaths = @{
    "naa.6006016055502500d900000000000000" = "vmhba1:C0:T0:L0",
    "naa.6006016055502500d900000000000001" = "vmhba1:C0:T0:L1"
    # Add more LUN IDs and paths as needed
}

# Loop through ESXi hosts
foreach ($ESXiHost in $ESXiHosts) {
    # Get the list of LUNs for the host
    $LUNs = Get-ScsiLun -VMHost $ESXiHost

    # Loop through LUNs and set paths
    foreach ($LUN in $LUNs) {
        $LUNId = $LUN.CanonicalName

        if ($LUNPaths.ContainsKey($LUNId)) {
            $Path = $LUNPaths[$LUNId]
            Set-ScsiLunPath -ScsiLun $LUN -Path $Path -Confirm:$false
            Write-Host "Path set for LUN $($LUN.CanonicalName) on $($ESXiHost.Name)"
        } else {
            Write-Host "Path not configured for LUN $($LUN.CanonicalName) on $($ESXiHost.Name)"
        }
    }
}

# Disconnect from the vCenter Server
Disconnect-VIServer -Server * -Confirm:$false

Replace YourVCenterServer, YourUsername, YourPassword, ESXiHostName1, ESXiHostName2, and the example LUN IDs and paths with your actual vCenter Server details, ESXi host names, and the desired LUN configurations.

In this script:

  1. Connect to the vCenter Server using Connect-VIServer.
  2. Get the list of ESXi hosts using Get-VMHost.
  3. Define the LUN IDs and paths in the $LUNPaths hash table.
  4. Loop through ESXi hosts and retrieve the list of LUNs using Get-ScsiLun.
  5. Loop through LUNs, check if a path is defined in the $LUNPaths hash table, and use Set-ScsiLunPath to set the path.
  6. Disconnect from the vCenter Server using Disconnect-VIServer.

Set-NicTeamingPolicy in Esxi via Powershell

In VMware vSphere, you can use PowerCLI (PowerShell module for VMware) to manage various aspects of ESXi hosts and virtual infrastructure. To set NIC teaming policies on a vSwitch or port group, you can use the Set-NicTeamingPolicy cmdlet. Here’s an example of how you can use it:

# Connect to your vCenter Server
Connect-VIServer -Server YourVCenterServer -User YourUsername -Password YourPassword

# Get the ESXi host
$ESXiHost = Get-VMHost -Name "YourESXiHostName"

# Get the vSwitch or port group
$vSwitchName = "vSwitch0"           # Specify the name of your vSwitch
$portGroupName = "Management Network"  # Specify the name of your port group

# Retrieve the existing NIC teaming policy
$nicTeamingPolicy = Get-NicTeamingPolicy -VMHost $ESXiHost -VSwitch $vSwitchName -PortGroup $portGroupName

# Modify the NIC teaming policy settings
$nicTeamingPolicy.LoadBalancing = "iphash"  # Set load balancing policy (example: "iphash")
$nicTeamingPolicy.NotifySwitches = $true     # Set switch notification setting

# Apply the modified NIC teaming policy
Set-NicTeamingPolicy -NicTeamingPolicy $nicTeamingPolicy -VMHost $ESXiHost -VSwitch $vSwitchName -PortGroup $portGroupName

# Disconnect from the vCenter Server
Disconnect-VIServer -Server * -Confirm:$false

Remember to replace YourVCenterServer, YourUsername, YourPassword, YourESXiHostName, vSwitch0, and Management Network with your actual vCenter Server details, ESXi host name, vSwitch name, and port group name.

In this script:

  1. Connect to the vCenter Server using Connect-VIServer.
  2. Get the ESXi host using Get-VMHost.
  3. Retrieve the existing NIC teaming policy using Get-NicTeamingPolicy.
  4. Modify the NIC teaming policy settings as needed.
  5. Apply the modified NIC teaming policy using Set-NicTeamingPolicy.
  6. Disconnect from the vCenter Server using Disconnect-VIServer.

Use Remove-Snapshot to get rid of snapshots for all VMs > 2 snapshots

To remove snapshots from all VMs that have more than two snapshots using VMware PowerCLI (PowerShell module for managing VMware environments), you can use the following PowerShell script as a starting point:

# Connect to your vCenter Server
Connect-VIServer -Server YourVCenterServer -User YourUsername -Password YourPassword

# Get all VMs with more than two snapshots
$VMs = Get-VM | Where-Object { $_.ExtensionData.Snapshot.RootSnapshotList.Count -gt 2 }

# Loop through VMs and remove snapshots
foreach ($VM in $VMs) {
    $Snapshots = $VM | Get-Snapshot
    $Snapshots | Sort-Object -Property Created -Descending | Select-Object -Skip 2 | Remove-Snapshot -Confirm:$false
    Write-Host "Snapshots removed from $($VM.Name)"
}

# Disconnect from the vCenter Server
Disconnect-VIServer -Server * -Confirm:$false

Please note the following points about this script:

  1. Replace YourVCenterServer, YourUsername, and YourPassword with your actual vCenter Server details.
  2. The script retrieves all VMs with more than two snapshots using Get-VM and filters them using Where-Object.
  3. The snapshots are sorted by their creation date in descending order, and the two most recent snapshots are skipped (to retain the two most recent snapshots).
  4. The -Confirm:$false parameter is used with Remove-Snapshot to avoid confirmation prompts for each snapshot removal.

Before running this script, make sure you have VMware PowerCLI installed and that you are using it in a controlled environment, as removing snapshots can impact VMs and their data. Test the script on a smaller scale or non-production environment to ensure it behaves as expected.

Always ensure you have backups and a proper understanding of the impact of snapshot removal on your VMs before performing such operations in a production environment.

Install VAAI plugin using Powershell to all the Esxi hosts in one VC

Install VMware PowerCLI: If you haven’t installed PowerCLI already, you can download and install it from the PowerShell Gallery. Open a PowerShell session with Administrator privileges and run the following command:

Install-Module -Name VMware.PowerCLI

Connect to vCenter: Connect to your vCenter server using PowerCLI. Replace “vcenter_server” with the IP or FQDN of your vCenter server and enter your vCenter credentials when prompted:

Connect-VIServer -Server vcenter_server

Get a List of ESXi Hosts: Run the following command to retrieve a list of all ESXi hosts managed by the vCenter server:

$esxiHosts = Get-VMHost

Install VAAI Plugin on Each ESXi Host: Loop through each ESXi host and install the VAAI plugin using the “esxcli” command. Replace “esxi_username” and “esxi_password” with the ESXi host’s root credentials:

foreach ($esxiHost in $esxiHosts) {
    $esxiConnection = Connect-VIServer -Server $esxiHost -User esxi_username -Password esxi_password
    if ($esxiConnection) {
        $esxiHostName = $esxiHost.Name
        Write-Host "Installing VAAI plugin on $esxiHostName..."
        $installScript = "esxcli software vib install -v /path/to/vaaipackage.vib --no-sig-check"
        Invoke-SSHCommand -SSHHost $esxiHostName -SSHUser esxi_username -SSHPassword esxi_password -SSHCommand $installScript
    }
}

Make sure to replace “/path/to/vaaipackage.vib” with the actual path to the VAAI plugin file (e.g., “esxcli software vib install -v /vmfs/volumes/datastore1/vaaipackage.vib –no-sig-check”).

  1. Disconnect from vCenter: Finally, disconnect from the vCenter server when the installation process is complete:
Disconnect-VIServer -Server $esxiHosts.Server -Force -Confirm:$false

Clone Operation (New-VM) and Storage vMotion(Move-VM)

In VMware PowerCLI, New-VM and Move-VM are two distinct cmdlets used for different purposes related to virtual machines. VAAI (vStorage APIs for Array Integration) is a VMware feature that offloads certain storage operations to the storage array to improve performance and efficiency. While VAAI is not directly related to the New-VM and Move-VM cmdlets, I will provide examples of how these cmdlets are used, and then explain the relationship between VAAI and storage operations.

  1. New-VM: The New-VM cmdlet is used to create a new virtual machine (VM) within a specified host or cluster. It allows you to define various configuration settings for the new VM, such as the VM name, guest operating system, CPU, memory, disk, network settings, and more.

Example of New-VM:

# Create a new virtual machine
New-VM -Name "NewVM" -VMHost "ESXiHost" -Datastore "Datastore1" -MemoryGB 4 -NumCPU 2 -NetworkName "VM Network" -DiskGB 50

In this example, the New-VM cmdlet is used to create a new VM named “NewVM” on the host “ESXiHost,” with 4GB of memory, 2 CPUs, connected to the “VM Network” for networking, and a 50GB virtual disk on “Datastore1.”

  1. Move-VM: The Move-VM cmdlet is used to migrate a VM from one host or datastore to another. It allows you to perform live migrations (vMotion) or cold migrations (Storage vMotion) of VMs across hosts or datastores in a vSphere environment.

Example of Move-VM:

# Migrate a virtual machine to a different datastore
Move-VM -VM "MyVM" -Datastore "NewDatastore"

In this example, the Move-VM cmdlet is used to migrate the VM named “MyVM” to a different datastore named “NewDatastore.”

Now, let’s briefly discuss VAAI:

VAAI (vStorage APIs for Array Integration): VAAI is a set of APIs provided by VMware that allows vSphere to offload certain storage operations from the ESXi hosts to the storage array. This offloading improves performance and efficiency by leveraging the capabilities of the underlying storage hardware.

Examples of storage operations offloaded to VAAI-enabled storage arrays include:

  • Hardware Accelerated Copy (HWCOPY): Improves VM cloning and snapshot operations by using the storage array to perform data copies.
  • Zero Block Detection (Zero): Allows the storage array to automatically handle zeroed-out blocks, reducing the burden on the ESXi host and improving storage efficiency.
  • Full Copy (HWFCOPY): Facilitates storage vMotion by performing fast and efficient data movement between datastores using the storage array’s capabilities.

In VMware PowerCLI, the Move-VM cmdlet automatically leverages VAAI (vStorage APIs for Array Integration) if the underlying storage array supports VAAI and the necessary VAAI primitives are enabled. VAAI allows the storage array to offload certain storage operations, making VM migrations faster and more efficient. Let’s take a look at an example of using Move-VM with VAAI:

# Connect to vCenter Server
Connect-VIServer -Server "vcenter.example.com" -User "username" -Password "password"

# Define the source VM and its current datastore
$sourceVM = Get-VM -Name "MyVM"
$sourceDatastore = Get-Datastore -VM $sourceVM

# Define the destination datastore
$destinationDatastore = Get-Datastore -Name "NewDatastore"

# Perform the VM migration using VAAI (Storage vMotion)
Move-VM -VM $sourceVM -Datastore $destinationDatastore -Force -DiskStorageFormat Thin

# Disconnect from vCenter Server
Disconnect-VIServer -Server "vcenter.example.com" -Confirm:$false

In this example, we perform a Storage vMotion using the Move-VM cmdlet with VAAI. Here’s what each step does:

  1. We start by connecting to the vCenter Server using Connect-VIServer.
  2. We define the source VM ($sourceVM) for the migration and get the current datastore ($sourceDatastore) where the VM is located.
  3. Next, we define the destination datastore ($destinationDatastore) where we want to move the VM.
  4. Finally, we use the Move-VM cmdlet to perform the VM migration. The -DiskStorageFormat Thin parameter specifies that the virtual disks should be moved with thin provisioning. The -Force parameter is used to suppress any confirmation prompts during the migration.

The Move-VM cmdlet will automatically utilize VAAI primitives if they are supported and enabled on the underlying storage array. VAAI accelerates the data movement between datastores, resulting in faster and more efficient VM migrations.

Re-IP’ing ESXi hosts in vCenter using a PowerShell script

Re-IP’ing ESXi hosts in vCenter using a PowerShell script involves several steps and should be handled with caution, as it can disrupt the virtualized environment. The following script assumes you have VMware PowerCLI installed and connected to your vCenter server.

Before running the script, ensure you have a backup of your current configuration, and understand the implications of re-IP’ing your ESXi hosts.

# Connect to vCenter server
Connect-VIServer -Server YOUR_VCENTER_SERVER -User YOUR_USERNAME -Password YOUR_PASSWORD

# Define the old and new IP addresses
$oldIP = "OLD_IP_ADDRESS"
$newIP = "NEW_IP_ADDRESS"
$subnetMask = "NEW_SUBNET_MASK"
$gateway = "NEW_GATEWAY"

# Retrieve all ESXi hosts managed by vCenter
$esxiHosts = Get-VMHost

# Reconfigure network settings for each ESXi host
foreach ($esxiHost in $esxiHosts) {
    Write-Host "Reconfiguring network settings for $($esxiHost.Name)..."
    $esxiHostNic = Get-VMHostNetworkAdapter -VMHost $esxiHost | Where-Object { $_.Type -eq "Management" }

    # Set new IP address, subnet mask, and gateway
    $esxiHostNic | Set-VMHostNetworkAdapter -IP $newIP -SubnetMask $subnetMask -Gateway $gateway -Confirm:$false

    # Test the new connection and make sure it is responding
    if (Test-Connection -ComputerName $newIP -Count 1 -Quiet) {
        Write-Host "ESXi host $($esxiHost.Name) has been reconfigured successfully."
    } else {
        Write-Host "Failed to reconfigure ESXi host $($esxiHost.Name). Please verify the new network settings manually."
    }
}

# Disconnect from vCenter server
Disconnect-VIServer -Server $null

Replace the placeholders YOUR_VCENTER_SERVER, YOUR_USERNAME, YOUR_PASSWORD, OLD_IP_ADDRESS, NEW_IP_ADDRESS, NEW_SUBNET_MASK, and NEW_GATEWAY with appropriate values.

This script will loop through all ESXi hosts managed by vCenter, reconfigure the network settings for the management interface with the new IP address, subnet mask, and gateway, and then test the new connection to ensure it is responsive.

Again, exercise extreme caution when using this script, and always have a backup and a rollback plan ready before making any changes to your production environment.

To check and generate a report of backup, cloning, snapshot, or any other task of VM/ESXi/datastore in vSphere using PowerCLI

  1. Install VMware PowerCLI: If you haven’t installed VMware PowerCLI yet, download and install it from the official VMware website: https://code.vmware.com/web/dp/tool/vmware-powercli/12.5.0
  2. Connect to vCenter Server: Open PowerShell or PowerShell ISE and connect to your vCenter Server using the Connect-VIServer cmdlet. Replace 'YOUR_VCENTER_SERVER' with the IP address or FQDN of your vCenter Server:
Connect-VIServer -Server 'YOUR_VCENTER_SERVER' -User 'YOUR_USERNAME' -Password 'YOUR_PASSWORD'

Generate the report for tasks: You can use the Get-VIEvent cmdlet in PowerCLI to retrieve events and filter them based on the task type (e.g., backup, clone, snapshot, etc.). Here’s a PowerShell script to generate the report:

# Define the output file path for the report
$outputFile = "C:\Path\To\Your\Report.txt"

# Get all VMs
$vms = Get-VM

# Initialize an empty array to store the events
$taskEvents = @()

# Get events for each VM and filter the ones related to tasks (backup, clone, snapshot, etc.)
foreach ($vm in $vms) {
    $events = Get-VIEvent -Entity $vm | Where-Object { $_.GetType().Name -match "TaskEvent" }
    $taskEvents += $events
}

# Generate a report and write it to the output file
$report = @()

foreach ($event in $taskEvents) {
    $vmName = $event.Vm.Name
    $eventType = $event.GetType().Name
    $eventFullType = $event.GetType().FullName
    $eventCreated = $event.CreatedTime
    $eventUserName = $event.UserName
    $eventFullData = $event | Format-List | Out-String

    $reportLine = @"
VM Name: $vmName
Event Type: $eventType
Event Full Type: $eventFullType
Event Created: $eventCreated
Event User Name: $eventUserName
Event Details:
$eventFullData
"@

    $report += $reportLine
}

# Save the report to the output file
$report | Out-File -FilePath $outputFile

# Display success message
Write-Host "Report generated successfully. Check $outputFile for the report."

Disconnect from vCenter Server: After generating the report, it’s a good practice to disconnect from the vCenter Server using the Disconnect-VIServer cmdlet:

Disconnect-VIServer -Server 'YOUR_VCENTER_SERVER' -Force -Confirm:$false

Please make sure to replace 'YOUR_VCENTER_SERVER', 'YOUR_USERNAME', and 'YOUR_PASSWORD' in the script with your vCenter server details. Additionally, modify the $outputFile variable to specify the path and filename for the generated report. The script will search for task-related events for each VM, extract relevant details, and save the report to the specified output file.

Get the maximum size of VMDKs (Virtual Machine Disk) in a vCenter environment

To get the maximum size of VMDKs (Virtual Machine Disk) in a vCenter environment using PowerCLI and print the information to a file, you can use the following PowerShell script:

# Connect to the vCenter Server
Connect-VIServer -Server vcenter.example.com -User administrator -Password your_password

# Output file path to save the results
$outputFile = "C:\Path\To\Output\File.txt"

# Get all VMs in the vCenter
$allVMs = Get-VM

# Create an empty array to store the maximum VMDK sizes
$maxVmdkSizes = @()

# Loop through each VM and get the maximum size of its VMDKs
foreach ($vm in $allVMs) {
    $vmdks = Get-HardDisk -VM $vm
    $maxVmdkSizeGB = $vmdks | Measure-Object -Property CapacityGB -Maximum | Select-Object -ExpandProperty Maximum
    $maxVmdkSizes += [PSCustomObject]@{
        "VM Name" = $vm.Name
        "Maximum VMDK Size (GB)" = $maxVmdkSizeGB
    }
}

# Export the results to a CSV file
$maxVmdkSizes | Export-Csv -Path $outputFile -NoTypeInformation

# Disconnect from the vCenter Server
Disconnect-VIServer -Server vcenter.example.com -Confirm:$false

Write-Host "Maximum VMDK sizes have been saved to $outputFile."

In this script, replace "vcenter.example.com" with the hostname or IP address of your vCenter Server. Also, provide the correct path for $outputFile to save the results.

The script connects to the vCenter Server using Connect-VIServer, retrieves all VMs using Get-VM, and then loops through each VM to get the VMDKs using Get-HardDisk. It calculates the maximum VMDK size in gigabytes (GB) using Measure-Object, stores the results in the $maxVmdkSizes array as a custom PowerShell object, and finally exports the results to a CSV file using Export-Csv.

The script then disconnects from the vCenter Server using Disconnect-VIServer. The maximum VMDK sizes for each VM are saved in the specified output file, and a message is displayed on the PowerShell console to indicate the completion of the script.

To get the maximum size VMDKs in a vCenter environment and print them to a file using Python, you’ll need to use the VMware vSphere API. We can achieve this by using the pyVmomi library, which is a Python SDK for the VMware vSphere API. First, you’ll need to install the pyVmomi library:

pip install pyVmomi

Next, you can use the following Python script to connect to your vCenter server, retrieve the virtual machines, and find the largest VMDK size for each VM:

from pyVim.connect import SmartConnect, Disconnect
from pyVmomi import vim
import ssl

def get_max_vmdk_size(virtual_machine):
    max_vmdk_size = 0
    for device in virtual_machine.config.hardware.device:
        if isinstance(device, vim.vm.device.VirtualDisk):
            size_bytes = device.capacityInBytes
            if size_bytes > max_vmdk_size:
                max_vmdk_size = size_bytes
    return max_vmdk_size

def main():
    # Set your vCenter server details
    vcenter_server = 'YOUR_VCENTER_SERVER'
    username = 'YOUR_USERNAME'
    password = 'YOUR_PASSWORD'

    # Ignore SSL certificate verification
    context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
    context.verify_mode = ssl.CERT_NONE

    try:
        # Connect to vCenter
        service_instance = SmartConnect(host=vcenter_server, user=username, pwd=password, sslContext=context)
        if not service_instance:
            raise SystemExit("Unable to connect to vCenter server.")

        # Get all virtual machines in the vCenter environment
        content = service_instance.RetrieveContent()
        container = content.rootFolder
        viewType = [vim.VirtualMachine]
        recursive = True
        containerView = content.viewManager.CreateContainerView(container, viewType, recursive)
        virtual_machines = containerView.view

        # Find the maximum size VMDK for each virtual machine
        vm_max_vmdk_sizes = {}
        for virtual_machine in virtual_machines:
            vm_max_vmdk_sizes[virtual_machine.name] = get_max_vmdk_size(virtual_machine)

        # Print the results to a file
        with open('max_vmdk_sizes.txt', 'w') as f:
            for vm_name, max_vmdk_size in vm_max_vmdk_sizes.items():
                f.write(f"{vm_name}: {max_vmdk_size / (1024 ** 3)} GB\n")

        print("Maximum VMDK sizes saved to 'max_vmdk_sizes.txt'.")

    except Exception as e:
        print("Error:", e)

    finally:
        # Disconnect from vCenter
        if service_instance:
            Disconnect(service_instance)

if __name__ == "__main__":
    main()

Replace 'YOUR_VCENTER_SERVER', 'YOUR_USERNAME', and 'YOUR_PASSWORD' with your vCenter server details. The script will connect to your vCenter server, retrieve all virtual machines, find the largest VMDK size for each VM, and then print the results to a file named max_vmdk_sizes.txt in the same directory as the script. The VMDK sizes will be printed in gigabytes (GB).