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 This function checks the VMware tools status on one or more virtual machines and returns the name of the virtual machine and VMware tools version 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. .EXAMPLE Get-VMTools -VirtualMachine Luis-VM01 This example gets the VMware tools status for the virtual machine named "Luis-VM01". .EXAMPLE Get-VM | Get-VMTools This example gets all virtual machines and then checks the VMware tools status on each virtual machine. .INPUTS The function accepts an array of strings that specifies one or more virtual machine names. .OUTPUTS The function returns virtual machine name and VMware tools version installed. .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] @{ 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] @{ 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)." } } |