VMwareAdmin-Extras.psm1
function Get-VMInfo { <# .SYNOPSIS Get-VMInfo The Get-VMInfo function gathers Virtual Machine (VM) information such as Name, Hostname, Number of CPUs, Power State, Memory Size, IP Address, Creation Date, VLAN ID, Used Disk Space, Disk Size, Operating System, Folder Location and Cluster Name from multiple vCenters using PowerCLI module. .DESCRIPTION This function takes a string array of multiple hostnames or partial names. To use this function, you must install the PowerCLI module and provide credentials for the vCenters. This function can be used with multiple vCenters and multiple VMs. It also supports pipeline input. .EXAMPLE Get-VMInfo -VirtualMachines "server1", "server2" -VCenters "vc1" -Credential $cred This command gets the information for VMs "server1" and "server2" from the vCenter "vc1" using the credential $cred. .EXAMPLE vm1, vm2, vm3, vm4 | Get-VMInfo -VCenters "vc1" -Credential $cred This command gets the information for VMs vm1, vm2, vm3, and vm4 from the vCenter "vc1" using the credential $cred. .EXAMPLE Get-VMInfo -VirtualMachines "server1", "server2" -VCenters "vc1", "vc2" -Credential $cred This command gets the information for VMs "server1" and "server2" from the vCenters "vc1" and "vc2" using the credential $cred. .EXAMPLE vm1, vm2, vm3, vm4 | Get-VMInfo -VCenters "vc1", "vc2" -Credential $cred This command gets the information for VMs vm1, vm2, vm3, and vm4 from the vCenters "vc1" and "vc2" using the credential $cred .PARAMETER VirtualMachines The list of Virtual Machines to get information for. Accepts string arrays. Get-VMInfo -VirtualMachines "server1", "server2" vm1, vm2, vm3, vm4 | Get-VMInfo .PARAMETER VCenters The vCenter name or IP address to connect to. Accepts a string. Get-VMInfo vm1, vm2 -VCenter "vc1" .INPUTS String[] .OUTPUTS Custom Object with VM information. Name Hostname vCenter PowerState NumCpu MemoryGB IPAddress CreateDate VlanId UsedDiskSpaceGB DiskSizeGB OperatingSystem FolderLocation ClusterName VMHost Notes .LINK This script is a custom function created by Luis Carrillo. Github: https://github.com/LuisCarrilloTech #> [CmdletBinding()] Param ( # Parameter help description [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0)] [String[]]$VirtualMachines, # Parameter help description [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [String[]]$VCenters ) Begin { # Check if VMWare PowerCLI module is installed: $moduleName = "VMware.VimAutomation.Core" if (!(Get-Module -Name $moduleName)) { try { Import-Module -Name $moduleName -Force -ErrorAction Stop } catch { Write-Error "Error loading VMWare PowerCLI module" } } } Process { if ($global:DefaultVIServers.name -notcontains $VCenters) { [System.Management.Automation.PSCredential]$Credential = Get-Credential # Connect to vCenter server: foreach ($vcenter in $vCenters) { try { Connect-VIServer -Server $vCenter -Credential $Credential -ErrorAction Stop } catch [VMware.Vim.VimException] { Write-Error "Failed to connect to vCenter. Please verify your credentials and try again." return } catch { Write-Error "An error occurred. Please try again." return } Write-Verbose "Connected to vCenter $($vCenter)" } } # Gathers VM information: try { Foreach ($vc in $vCenters) { try { foreach ($VMs in $VirtualMachines) { Get-VM -Server $vc -ErrorAction Stop | Where-Object { $_.Name -match $VMs } | Select-Object Name, @{l = 'Hostname' ; e = { $_.ExtensionData.guest.hostname } }, @{l = 'vCenter'; e = { $_.UID -replace "(^.+@)", '' -replace "\:.+$" } }, PowerState, NumCpu, @{l = 'MemoryGB'; e = { '{0:N1}' -f $_.MemoryGB } }, @{l = 'IPAddress'; e = { $_.Guest.IPAddress } }, @{l = 'CreateDate'; e = { $_.CreateDate } }, @{l = 'VlanId'; e = { (Get-VM $_ | Get-VMGuest).ExtensionData.net.network } }, @{l = 'UsedDiskSpaceGB'; e = { '{0:N1}' -f $_.UsedSpaceGB } }, @{l = 'DiskSizeGB'; e = { ('{0:N0}' -f ($_).Guest.Disks.CapacityGB) } }, @{l = 'OperatingSystem'; e = { $_.Guest.OSFullName } }, @{l = 'FolderLocation'; e = { $_.Folder } }, @{l = 'ClusterName'; e = { (Get-Cluster -VM $_).Name } }, VMHost, Notes } } catch { "Error retrieving information for VM $($VMs) on vCenter: $vc" } } } catch { "Error retrieving information from vCenter: $($vc)" } } } function Get-VMTools { <# .SYNOPSIS Get-VMTools Function This PowerShell function retrieves information about VMware Tools for one or more virtual machines. It requires the VMware PowerCLI module to be installed. .DESCRIPTION This function gets the VMware tools status for one or more virtual machines. If VMware tools are not up to date or are not installed, this function will return the virtual machine name and the outdated tools version. For this function to work properly, VMware PowerCLI module needs to be installed. .PARAMETER VirtualMachine Specifies the name(s) of the virtual machine(s) to retrieve VMware Tools information for. This parameter is mandatory. .PARAMETER vCenters Specifies the vCenter Server(s) to connect to. This parameter is optional. If not provided, the function will prompt for the vCenter Server FQDN and credentials. .PARAMETER Disconnect Specifies whether to disconnect from the vCenter Server(s) after retrieving the information. This switch is optional. .EXAMPLE Retrieve VMware Tools information for a single virtual machine Get-VMTools -VirtualMachine "VM1" .EXAMPLE Retrieve VMware Tools information for multiple virtual machines Get-VMTools -VirtualMachine "TESTVM1", "TESTVM2", "TESTVM3" VMware Tools - out of date on VM1 VMware Tools - out of date on VM2 VMName ToolsVersion ToolsStatus ToolsVersionStatus ToolsRunningStatus ToolsInstallType ------ ------------ ----------- ------------------ ------------------ ---------------- VM1 11297 toolsOld guestToolsSupportedOld guestToolsRunning guestToolsTypeMSI VM2 11328 toolsOk guestToolsUnmanaged guestToolsRunning guestToolsTypeOpenVMTools VM3 11297 toolsOld guestToolsSupportedOld guestToolsRunning guestToolsTypeMSI .EXAMPLE Retrieve VMware Tools information for multiple virtual machines using wildcard * Get-VMTools -VirtualMachine *VM* VMware Tools - out of date on *VM* VMName ToolsVersion ToolsStatus ToolsVersionStatus ToolsRunningStatus ToolsInstallType ------ ------------ ----------- ------------------ ------------------ ---------------- VM1 11297 toolsOld guestToolsSupportedOld guestToolsRunning guestToolsTypeMSI VM2 11328 toolsOk guestToolsUnmanaged guestToolsRunning guestToolsTypeOpenVMTools VM3 11297 toolsOld guestToolsSupportedOld guestToolsRunning guestToolsTypeMSI .EXAMPLE Retrieve VMware Tools information for multiple virtual machines and specify vCenter Server(s) Get-VMTools -VirtualMachine "VM1", "VM2" -vCenters "vcenter1.example.com", "vcenter2.example.com" .EXAMPLE Retrieve VMware Tools information and disconnect from vCenter Server(s) Get-VMTools -VirtualMachine "VM1" -Disconnect .OUTPUTS The function returns a PowerShell object with the following properties for each virtual machine: ToolsVersion: The version of VMware Tools installed on the virtual machine. ToolsStatus: The status of VMware Tools on the virtual machine. ToolsVersionStatus: The status of the VMware Tools version on the virtual machine. ToolsRunningStatus: The running status of VMware Tools on the virtual machine. ToolsInstallType: The installation type of VMware Tools on the virtual machine. If VMware Tools is out of date, the function will display a warning message and highlight the virtual machine with outdated VMware Tools. .NOTES This function requires VMware PowerCLI module to be installed. The function also leverages PowerCLI’s Connect-VIServer cmdlet to connect to the vCenter server. Prompts the user to enter the vCenter server credentials. .ROLE This script checks the VMware tools status on one or more virtual machines. .FUNCTIONALITY This function checks the VMware tools status on one or more virtual machines. .LINK This script is a custom function created by Luis Carrillo. Github: https://github.com/LuisCarrilloTech #> [CmdletBinding()] param( [Parameter( Mandatory = $true, ValueFromPipeline = $true, Position = 0, HelpMessage = 'Enter a VM or list of VMs')] [ValidateNotNullOrEmpty()] [String[]]$VirtualMachine, [Parameter( Mandatory = $false, ValueFromPipeline = $true, Position = 1 )] [string]$vCenters, [switch]$Disconnect ) BEGIN { # Check if VMWare PowerCLI module is installed: $moduleName = "VMware.VimAutomation.Core" if (!(Get-Module -Name $moduleName)) { Import-Module -Name $moduleName -Force } else { Write-Verbose "VMWare PowerCLI module already installed." } # Prompt user to input vCenter FQDN and connect to server: if (($global:DefaultVIServers).name -match $vCenters) { Write-Output "Connected to vCenter..." } else { [System.Management.Automation.PSCredential]$Credential = Get-Credential foreach ($vcenter in $vCenters) { # Connect to vCenter server: try { Connect-VIServer -Server $vCenter -Credential $Credential -ErrorAction Stop } catch [VMware.Vim.VimException] { Write-Error "Failed to connect to vCenter. Please verify your credentials and try again." return } catch { Write-Error "An error occurred. Please try again." return } Write-Verbose "Connected to vCenter $($vCenter)" } } } PROCESS { foreach ($VM in $VirtualMachine) { try { $vmTools = Get-VM $VM -ErrorAction Stop if ($vmTools.ExtensionData.Guest.ToolsStatus -ne "ToolsOK") { Write-Verbose -Message "VMware Tools - out of date on VM $($VM)" Write-Host -ForegroundColor DarkYellow "VMware Tools - out of date on VM $($VM)" $vmTools | ForEach-Object { [PSCustomObject] @{ VMName = $_.Name ToolsVersion = $_.ExtensionData.Guest.Toolsversion ToolsStatus = $_.ExtensionData.Guest.ToolsStatus ToolsVersionStatus = $_.ExtensionData.Guest.ToolsVersionStatus2 ToolsRunningStatus = $_.ExtensionData.Guest.ToolsRunningStatus ToolsInstallType = $_.ExtensionData.Guest.ToolsInstallType } } } else { Write-Verbose -Message "VMTools - OK on VM $VM" Write-Host -ForegroundColor Green "VMTools - OK on VM $VM" $vmTools | ForEach-Object { [PSCustomObject] @{ VMName = $_.Name ToolsVersion = $_.ExtensionData.Guest.Toolsversion ToolsStatus = $_.ExtensionData.Guest.ToolsStatus ToolsVersionStatus = $_.ExtensionData.Guest.ToolsVersionStatus2 ToolsRunningStatus = $_.ExtensionData.Guest.ToolsRunningStatus ToolsInstallType = $_.ExtensionData.Guest.ToolsInstallType } } } } catch { Write-Error "An error occurred while trying to retrieve VMTools version for: $($VM). Please try again." Write-Output $($_.Exception.Message) } } # Disconnect from vCenter: if ($Disconnect) { $global:DefaultVIServers | Disconnect-VIServer -Force -Confirm:$false Write-Verbose "Disconnected from vCenter $($vCenter)." } else { Write-Verbose "vCenter $($vCenter) still connected." } } END { } } Function Update-VMAdvancedSetting { <# .SYNOPSIS Enables Change Block Tracking (CBT) for the specified virtual machines in a vCenter environment. .DESCRIPTION This script enables Change Block Tracking (CBT) for the specified virtual machines in a vCenter environment. CBT tracks disk changes in VMs and is used by backup solutions to determine which disk blocks need to be backed up, improving backup speed and efficiency. .EXAMPLE Enable-CBT -VirtualMachines "vm1, vm2" -vCenter "vcenter.domain.com" -AdvancedSetting "changeTrackingEnabled" -Value $TRUE This example sets the advanced setting "changeTrackingEnabled" to $TRUE on VMs "vm1" and "vm2" on vCenter server "vcenter.domain.com". .EXAMPLE Enable-CBT -VirtualMachines vm1, vm2, vm3 -vCenter "myvcenter.domain.com" -AdvancedSetting "changeTrackingEnabled" -Value $TRUE This example enables CBT for VMs "vm1", "vm2", and "vm3" on vCenter server "myvcenter.domain.com". .EXAMPLE Enable-CBT -VirtualMachines vm1, vm2, vm3 -vCenter "myvcenter.domain.com" -AdvancedSetting "changeTrackingEnabled" -Value $TRUE -Disconnect This example enables CBT for VMs "vm1", "vm2", and "vm3" on vCenter server "myvcenter.domain.com" and Disconnects from vCenter(s) by using the -Disconnect switch parameter. .INPUTS VirtualMachines: The virtual machines to enable CBT for. This parameter accepts an array of virtual machine names. vCenter: The vCenter server to connect to. AdvancedSetting: The advanced setting to configure for the specified virtual machine. Example: "changeTrackingEnabled". Value: The value to set for the advanced setting as either True or False. .OUTPUTS None, it enables CBT for the specified virtual machines. .LINK Author: Luis Carrillo Github: https://github.com/LuisCarrilloTech #> [CmdletBinding()] Param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] [string[]]$VirtualMachines, [Parameter(Mandatory = $true, ValueFromPipeline = $false)] [string]$vCenters, [Parameter(Mandatory = $true, ValueFromPipeline = $false)] [string]$AdvancedSetting, [Parameter(Mandatory = $true, ValueFromPipeline = $false)] $Value, [switch]$Disconnect ) # Check if VMWare PowerCLI module is installed: $moduleName = "VMware.VimAutomation.Core" if (!(Get-Module -Name $moduleName)) { Import-Module -Name $moduleName -Force } else { Write-Output "Loading module. Please wait..." } # Prompt user to input vCenter FQDN and connect to server: if (!($global:DefaultVIServers)) { [System.Management.Automation.PSCredential]$Credential = Get-Credential foreach ($vcenter in $vCenters) { # Connect to vCenter server: try { Connect-VIServer -Server $vCenter -Credential $Credential -ErrorAction Stop Write-Host "Connected to vCenter $($vCenter)" } catch [VMware.Vim.VimException] { Write-Error "Failed to connect to vCenter. Please verify your credentials and try again." break } catch { Write-Error "An error occurred. Please try again." break } } } # Enable CBT on each VM: foreach ($vm in $VirtualMachines) { try { # Check if VM exists and get view object: $vmview = Get-VM $vm -ErrorAction Stop | Get-View $vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec } catch { Write-Error "Failed to find VM $($vm). Please verify the VM name and try again." continue } # Create snapshot before enabling CBT and set setting: try { New-Snapshot $vm -Name "Prior to enabling setting $($AdvancedSetting)" -ea Stop } catch { Write-Error "Failed to create snapshot for $($vm). Please verify try again." continue } # Enable CBT: $vmConfigSpec.($AdvancedSetting) = $Value $vmview.reconfigVM($vmConfigSpec) # Wait for task to complete: Start-Sleep 15 # Verify settings has been configured, if so, delete pre-setting snapshot: if ((Get-VM $vm | Get-View).config.$AdvancedSetting -eq $value) { Write-Host "Setting $($AdvancedSetting) set to $($Value) on VM $($vm)." # Remove snapshot: try { Get-Snapshot -VM $vm -Name "Prior to enabling setting $($AdvancedSetting)" | Remove-Snapshot -Confirm:$false -ErrorAction Stop Write-Host "Snapshot removed." } catch { Write-Error "Failed to remove snapshot. Please check if the snapshot exists and try again." continue } } } # Disconnect from vCenter: if ($Disconnect) { $global:DefaultVIServers | Disconnect-VIServer -Force -Confirm:$false Write-Host "Disconnected from vCenter $($vCenter)." } else { Write-Error "Failed to disconnect from vCenter $($vCenter)." } } |