1239 lines
50 KiB
PowerShell
1239 lines
50 KiB
PowerShell
# Script Module : VMToolsManagement
|
|
# Version : 1.0
|
|
|
|
# Copyright © 2017 VMware, Inc. All Rights Reserved.
|
|
|
|
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
# this software and associated documentation files (the "Software"), to deal in
|
|
# the Software without restriction, including without limitation the rights to
|
|
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
# of the Software, and to permit persons to whom the Software is furnished to do
|
|
# so, subject to the following conditions:
|
|
|
|
# The above copyright notice and this permission notice shall be included in all
|
|
# copies or substantial portions of the Software.
|
|
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
# SOFTWARE.
|
|
|
|
New-VIProperty -Name ToolsBuildNumber -Object VirtualMachine -Value {
|
|
Param ($VM)
|
|
|
|
foreach ($item in $VM.ExtensionData.Config.ExtraConfig.GetEnumerator()) {
|
|
if ($item.Key -eq "guestinfo.vmtools.buildNumber") {
|
|
$toolsBuildNumber = $item.value
|
|
break
|
|
}
|
|
}
|
|
|
|
return $toolsBuildNumber
|
|
} -BasedOnExtensionProperty 'Config.ExtraConfig' -Force | Out-Null
|
|
|
|
Function Get-VMToolsInfo {
|
|
<#
|
|
.SYNOPSIS
|
|
This advanced function retrieves the VMTools info of specified virtual machines.
|
|
|
|
.DESCRIPTION
|
|
This advanced function retrieves the VMTools version and build number info of specified virtual machines.
|
|
|
|
.PARAMETER VM
|
|
Specifies the virtual machines which you want to get the VMTools info of.
|
|
|
|
.EXAMPLE
|
|
C:\PS> Import-Module .\VMToolsManagement.psm1
|
|
C:\PS> $VCServer = Connect-VIServer -Server <vCenter Server IP> -User <vCenter User> -Password <vCenter Password>
|
|
C:\PS> Get-VM -Server $VCServer | Get-VMToolsInfo
|
|
|
|
Retrieves VMTools info of all virtual machines which run in the $VCServer vCenter Server.
|
|
|
|
.EXAMPLE
|
|
C:\PS> Get-VM "*rhel*" | Get-VMToolsInfo
|
|
|
|
Name ToolsVersion ToolsBuildNumber
|
|
------ ------------ ----------------
|
|
111394-RHEL-6.8-0 10.2.0 6090153
|
|
111394-RHEL-6.8-1 9.0.15
|
|
111393-RHEL-Server-7.2 10.1.0
|
|
|
|
Retrieves VMTools info of virtual machines with name containing "rhel".
|
|
|
|
.EXAMPLE
|
|
C:\PS> Get-VM -Location "MyClusterName" | Get-VMToolsInfo
|
|
|
|
Retrieves VMTools info from virtual machines which run in the "MyClusterName" cluster.
|
|
|
|
.EXAMPLE
|
|
C:\PS> Get-VMHost "MyESXiHostName" | Get-VM | Get-VMToolsInfo
|
|
|
|
Retrieves VMTools info of virtual machines which run on the "MyESXiHostName" ESXi host.
|
|
|
|
.NOTES
|
|
This advanced function assumes that you are connected to at least one vCenter Server system.
|
|
The tools build number is not supported in VMTools before 10.2.0
|
|
|
|
.NOTES
|
|
Author : Daoyuan Wang
|
|
Author email : daoyuanw@vmware.com
|
|
Version : 1.0
|
|
==========Tested Against Environment==========
|
|
VMware vSphere Hypervisor(ESXi) Version : 6.5 (build 4564106)
|
|
VMware vCenter Server Version : 6.5 (build 4602587)
|
|
PowerCLI Version : PowerCLI 6.5 (build 4624819)
|
|
PowerShell Version : 5.1
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
|
|
Param (
|
|
[Parameter(Mandatory=$true,
|
|
ValueFromPipeLine = $true,
|
|
ValueFromPipelinebyPropertyName=$True,
|
|
Position = 0)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine[]] $VM
|
|
)
|
|
|
|
Process {
|
|
Get-VM $VM | Select-Object Name, @{Name="ToolsVersion"; Expression={$_.Guest.ToolsVersion}}, ToolsBuildNumber
|
|
}
|
|
}
|
|
|
|
Function Get-VMToolsInstallLastError {
|
|
<#
|
|
.SYNOPSIS
|
|
This advanced function retrieves the error code of last VMTools installation.
|
|
|
|
.DESCRIPTION
|
|
This advanced function retrieves the error code of last VMTools installation on specified virtual machines.
|
|
|
|
.PARAMETER VM
|
|
Specifies the virtual machines which you want to get the error code of.
|
|
|
|
.EXAMPLE
|
|
C:\PS> Import-Module .\VMToolsManagement.psm1
|
|
C:\PS> $VCServer = Connect-VIServer -Server <vCenter Server IP> -User <vCenter User> -Password <vCenter Password>
|
|
C:\PS> Get-VM -Server $VCServer | Get-VMToolsInstallLastError
|
|
|
|
Retrieves the last VMTools installation error code of all virtual machines which run in the $VCServer vCenter Server.
|
|
|
|
.EXAMPLE
|
|
C:\PS> Get-VM "*win*" | Get-VMToolsInstallLastError
|
|
|
|
Name LastToolsInstallErrCode
|
|
------ -----------------------
|
|
111167-Win-7-Sp1-64-Enterprise-NoTools
|
|
111323-Windows-8.1U3-32-Enterprise-Tools
|
|
111305-Windows-Server2016 1641
|
|
|
|
Retrieves the last VMTools installation error code of virtual machines with name containing "win".
|
|
|
|
.EXAMPLE
|
|
C:\PS> Get-VM -Location "MyClusterName" | Get-VMToolsInstallLastError
|
|
|
|
Retrieves the last VMTools installation error code of virtual machines which run in the "MyClusterName" cluster.
|
|
|
|
.EXAMPLE
|
|
C:\PS> Get-VMHost "MyESXiHostName" | Get-VM | Get-VMToolsInstallLastError
|
|
|
|
Retrieves the last VMTools installation error code of virtual machines which run on the "MyESXiHostName" ESXi host.
|
|
|
|
.NOTES
|
|
This advanced function assumes that you are connected to at least one vCenter Server system.
|
|
|
|
.NOTES
|
|
Author : Daoyuan Wang
|
|
Author email : daoyuanw@vmware.com
|
|
Version : 1.0
|
|
==========Tested Against Environment==========
|
|
VMware vSphere Hypervisor(ESXi) Version : 6.5 (build 4564106)
|
|
VMware vCenter Server Version : 6.5 (build 4602587)
|
|
PowerCLI Version : PowerCLI 6.5 (build 4624819)(build 4624819)
|
|
PowerShell Version : 5.1
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
|
|
Param (
|
|
[Parameter(Mandatory=$true,
|
|
ValueFromPipeLine = $true,
|
|
ValueFromPipelinebyPropertyName=$True,
|
|
Position = 0)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine[]] $VM
|
|
)
|
|
|
|
Process {
|
|
$result = @()
|
|
foreach ($_ in $VM) {
|
|
$errorCodeInfo = $_.ExtensionData.Config.ExtraConfig.GetEnumerator() | Where-Object {$_.Key -eq "guestinfo.toolsInstallErrCode"}
|
|
|
|
$info = New-Object PSObject
|
|
$info | Add-Member -type NoteProperty -name VmName -value $_.Name
|
|
$info | Add-Member -type NoteProperty -name LastToolsInstallErrCode -value $errorCodeInfo.Value
|
|
|
|
$result += $info
|
|
}
|
|
$result
|
|
}
|
|
}
|
|
|
|
Function Get-VMToolsGuestInfo {
|
|
<#
|
|
.SYNOPSIS
|
|
This advanced function retrieves the guest info of specified virtual machines.
|
|
|
|
.DESCRIPTION
|
|
This advanced function retrieves the guest info such as HostName, IP, ToolsStatus, ToolsVersion,
|
|
ToolsInstallType and GuestFamily of specified virtual machines.
|
|
|
|
.PARAMETER VM
|
|
Specifies the virtual machines which you want to get the guest info of.
|
|
|
|
.EXAMPLE
|
|
C:\PS> Import-Module .\VMToolsManagement.psm1
|
|
C:\PS> $VCServer = Connect-VIServer -Server <vCenter Server IP> -User <vCenter User> -Password <vCenter Password>
|
|
C:\PS> Get-VM -Server $VCServer | Get-VMToolsGuestInfo
|
|
|
|
Retrieves guest info of all virtual machines which run in the $VCServer vCenter Server.
|
|
|
|
.EXAMPLE
|
|
C:\PS> Get-VM "*win*" | Get-VMToolsGuestInfo
|
|
|
|
Name : 111323-Windows-8.1U3-32-Enterprise-Tools
|
|
HostName : win81u3
|
|
IP :
|
|
ToolsStatus : toolsNotRunning
|
|
ToolsVersion : 10.2.0
|
|
ToolsInstallType : guestToolsTypeMSI
|
|
GuestFamily : windowsGuest
|
|
VMPowerState : PoweredOff
|
|
|
|
Name : 111305-Windows-Server2016
|
|
HostName : WIN-ULETOOSSB7U
|
|
IP : 10.160.59.99
|
|
ToolsStatus : toolsOk
|
|
ToolsVersion : 10.1.0
|
|
ToolsInstallType : guestToolsTypeMSI
|
|
GuestFamily : windowsGuest
|
|
VMPowerState : PoweredOn
|
|
|
|
Retrieves guest info of virtual machines with name containing "win".
|
|
|
|
.EXAMPLE
|
|
C:\PS> Get-VM -Location "MyClusterName" | Get-VMToolsGuestInfo
|
|
|
|
Retrieves guest info of virtual machines which run in the "MyClusterName" cluster.
|
|
|
|
.EXAMPLE
|
|
C:\PS> Get-VMHost "MyESXiHostName" | Get-VM | Get-VMToolsGuestInfo
|
|
|
|
Retrieves guest info of virtual machines which run on the "MyESXiHostName" ESXi host.
|
|
|
|
.NOTES
|
|
This advanced function assumes that you are connected to at least one vCenter Server system.
|
|
|
|
.NOTES
|
|
Author : Daoyuan Wang
|
|
Author email : daoyuanw@vmware.com
|
|
Version : 1.0
|
|
==========Tested Against Environment==========
|
|
VMware vSphere Hypervisor(ESXi) Version : 6.5 (build 4564106)
|
|
VMware vCenter Server Version : 6.5 (build 4602587)
|
|
PowerCLI Version : PowerCLI 6.5 (build 4624819)(build 4624819)
|
|
PowerShell Version : 5.1
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
|
|
Param (
|
|
[Parameter(Mandatory=$true,
|
|
ValueFromPipeLine = $true,
|
|
ValueFromPipelinebyPropertyName=$True,
|
|
Position = 0)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine[]] $VM
|
|
)
|
|
|
|
Process {
|
|
Get-VM $VM | Select-Object Name, @{Name="HostName"; Expression={$_.Guest.HostName}},
|
|
@{Name="IP"; Expression={$_.Guest.ExtensionData.IpAddress}},
|
|
@{Name="ToolsStatus"; Expression={$_.Guest.ExtensionData.ToolsStatus}},
|
|
@{Name="ToolsVersion"; Expression={$_.Guest.ToolsVersion}},
|
|
@{Name="ToolsInstallType"; Expression={$_.Guest.ExtensionData.ToolsInstallType}},
|
|
@{Name="GuestFamily"; Expression={$_.Guest.GuestFamily}},
|
|
PowerState
|
|
}
|
|
}
|
|
|
|
Function Get-VMByToolsInfo {
|
|
<#
|
|
.SYNOPSIS
|
|
This advanced function retrieves the virtual machines with specified VMTools info.
|
|
|
|
.DESCRIPTION
|
|
This advanced function retrieves the virtual machines with specified VMTools version,
|
|
running status or version status.
|
|
|
|
.PARAMETER VM
|
|
Specifies the virtual machines which you want to query VMTools status of.
|
|
|
|
.PARAMETER ToolsVersion
|
|
Specifies the VMTools version.
|
|
|
|
.PARAMETER ToolsRunningStatus
|
|
Specifies the VMTools running status.
|
|
|
|
.PARAMETER ToolsVersionStatus
|
|
Specifies the VMTools version status.
|
|
|
|
.EXAMPLE
|
|
C:\PS> Import-Module .\VMToolsManagement.psm1
|
|
C:\PS> $VCServer = Connect-VIServer -Server <vCenter Server IP> -User <vCenter User> -Password <vCenter Password>
|
|
C:\PS> Get-VM -Server $VCServer | Get-VMByToolsInfo
|
|
|
|
Retrieves the virtual machines with VMTools not running in vCenter Server $VCServer.
|
|
|
|
.EXAMPLE
|
|
C:\PS> Get-VM | Get-VMByToolsInfo -ToolsRunningStatus guestToolsNotRunning
|
|
|
|
Name PowerState Num CPUs MemoryGB
|
|
---- ---------- -------- --------
|
|
111394-RHEL-6.8-1 PoweredOff 4 2.000
|
|
|
|
Retrieves all the virtual machines with VMTools not running.
|
|
|
|
.EXAMPLE
|
|
C:\PS> Get-VM | Get-VMByToolsInfo -ToolsVersion '10.1.0'
|
|
|
|
Name PowerState Num CPUs MemoryGB
|
|
---- ---------- -------- --------
|
|
111394-RHEL-6.8-1 PoweredOff 4 2.000
|
|
|
|
Retrieves the virtual machines with VMTools version 10.1.0.
|
|
|
|
.EXAMPLE
|
|
C:\PS> Get-VM -Location "MyClusterName" | Get-VMByToolsInfo -ToolsVersionStatus guestToolsNeedUpgrade
|
|
|
|
Retrieves the virtual machines with VMTools that need to upgrade in the "MyClusterName" cluster.
|
|
|
|
.EXAMPLE
|
|
C:\PS> Get-VMHost "MyESXiHostName" | Get-VM | Get-VMByToolsInfo -ToolsRunningStatus guestToolsRunning -ToolsVersionStatus guestToolsNeedUpgrade
|
|
|
|
Retrieves the virtual machines with VMTools that need to upgrade on the "MyESXiHostName" ESXi host.
|
|
|
|
.NOTES
|
|
This advanced function assumes that you are connected to at least one vCenter Server system.
|
|
|
|
.NOTES
|
|
Author : Daoyuan Wang
|
|
Author email : daoyuanw@vmware.com
|
|
Version : 1.0
|
|
==========Tested Against Environment==========
|
|
VMware vSphere Hypervisor(ESXi) Version : 6.5 (build 4564106)
|
|
VMware vCenter Server Version : 6.5 (build 4602587)(build 4602587)
|
|
PowerCLI Version : PowerCLI 6.5 (build 4624819)
|
|
PowerShell Version : 5.1
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
|
|
Param (
|
|
[Parameter(Mandatory=$true,
|
|
ValueFromPipeLine = $true,
|
|
ValueFromPipelinebyPropertyName=$True,
|
|
Position = 0)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine[]] $VM,
|
|
|
|
[Parameter(Mandatory=$false)]
|
|
[String] $ToolsVersion,
|
|
|
|
[Parameter(Mandatory=$false)]
|
|
[ValidateSet("guestToolsRunning",
|
|
"guestToolsNotRunning",
|
|
"guestToolsExecutingScripts")]
|
|
[String] $ToolsRunningStatus,
|
|
|
|
[Parameter(Mandatory=$false)]
|
|
[ValidateSet("guestToolsNotInstalled",
|
|
"guestToolsNeedUpgrade",
|
|
"guestToolsCurrent",
|
|
"guestToolsUnmanaged")]
|
|
[String] $ToolsVersionStatus
|
|
)
|
|
|
|
Process {
|
|
$vmList = Get-VM $VM
|
|
|
|
if ((-not $ToolsVersion) -and (-not $ToolsRunningStatus) -and (-not $ToolsVersionStatus)) {
|
|
Throw "Please specify at lease one parameter: ToolsVersion, ToolsRunningStatus or ToolsVersionStatus"
|
|
}
|
|
|
|
if ($ToolsVersion) {
|
|
$vmList = $vmList | Where-Object {$_.Guest.ToolsVersion -like $ToolsVersion}
|
|
}
|
|
|
|
if ($ToolsRunningStatus) {
|
|
$vmList = $vmList | Where-Object {$_.Guest.ExtensionData.ToolsRunningStatus -eq $ToolsRunningStatus}
|
|
}
|
|
|
|
if ($ToolsVersionStatus) {
|
|
$vmList = $vmList | Where-Object {$_.Guest.ExtensionData.ToolsVersionStatus -eq $ToolsVersionStatus}
|
|
}
|
|
|
|
$vmList
|
|
}
|
|
}
|
|
|
|
Function Get-VMToolsUpgradePolicy {
|
|
<#
|
|
.SYNOPSIS
|
|
This advanced function retrieves the VMTools upgrade policy info of specified virtual machines.
|
|
|
|
.DESCRIPTION
|
|
This advanced function retrieves the VMTools upgrade policy info of specified virtual machines.
|
|
|
|
.PARAMETER VM
|
|
Specifies the virtual machines which you want to query VMTools status of.
|
|
|
|
.EXAMPLE
|
|
C:\PS> Get-VM "*rhel*" | Get-VMToolsUpgradePolicy
|
|
Name VMToolsUpgradePolicy
|
|
------ ----------------------
|
|
111394-RHEL-6.8-0 manual
|
|
111394-RHEL-6.8-1 manual
|
|
111393-RHEL-Server-7.2 upgradeAtPowerCycle
|
|
Retrieves VMTools upgrade policy info of virtual machines with name containing "rhel".
|
|
|
|
.EXAMPLE
|
|
C:\PS> Get-VM -Location "MyClusterName" | Get-VMToolsUpgradePolicy
|
|
Retrieves VMTools upgrade policy info from virtual machines which run in the "MyClusterName" cluster.
|
|
|
|
.EXAMPLE
|
|
C:\PS> Get-VMHost "MyESXiHostName" | Get-VM | Get-VMToolsUpgradePolicy
|
|
Retrieves VMTools upgrade policyinfo of virtual machines which run on the "MyESXiHostName" ESXi host.
|
|
|
|
.NOTES
|
|
This advanced function assumes that you are connected to at least one vCenter Server system.
|
|
|
|
.NOTES
|
|
Author : Kyle Ruddy
|
|
Author email : kmruddy@gmail.com
|
|
Version : 1.0
|
|
==========Tested Against Environment==========
|
|
VMware vSphere Hypervisor(ESXi) Version : 6.5 (build 7388607)
|
|
VMware vCenter Server Version : 6.5 (build 7312210)
|
|
PowerCLI Version : PowerCLI 6.5 (build 7155375)
|
|
PowerShell Version : 5.1
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
|
|
Param (
|
|
[Parameter(Mandatory=$true,
|
|
ValueFromPipeLine = $true,
|
|
ValueFromPipelinebyPropertyName=$True,
|
|
Position = 0)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine[]] $VM
|
|
)
|
|
|
|
Process {
|
|
|
|
Get-VM $VM | Select-Object Name, @{Name="VMToolsUpgradePolicy"; Expression={$_.ExtensionData.Config.Tools.ToolsUpgradePolicy}}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Function Set-VMToolsUpgradePolicy {
|
|
<#
|
|
.SYNOPSIS
|
|
This advanced function sets the VMTool's upgrade policy to either "manual" or "upgradeAtPowerCycle".
|
|
|
|
.DESCRIPTION
|
|
This advanced function sets the VMTool's upgrade policy to either "manual" or "upgradeAtPowerCycle" of specified virtual machines.
|
|
|
|
.PARAMETER VM
|
|
Specifies the virtual machines which you want to set the VMTool's upgrade policy of.
|
|
|
|
.EXAMPLE
|
|
C:\PS> Import-Module .\VMToolsManagement.psm1
|
|
C:\PS> $VCServer = Connect-VIServer -Server <vCenter Server IP> -User <vCenter User> -Password <vCenter Password>
|
|
C:\PS> Get-VM -Server $VCServer | Set-VMToolsUpgradePolicy -UpgradePolicy manual
|
|
|
|
Sets VMTool's upgrade policy to "manual" of all virtual machines in the $VCServer vCenter Server.
|
|
|
|
.EXAMPLE
|
|
C:\PS> Get-VM "*win*" | Set-VMToolsUpgradePolicy -UpgradePolicy upgradeAtPowerCycle
|
|
|
|
Sets VMTool's upgrade policy to "upgradeAtPowerCycle" of virtual machines with name containing "win".
|
|
|
|
.EXAMPLE
|
|
C:\PS> Get-VM -Location "MyClusterName" | Set-VMToolsUpgradePolicy -UpgradePolicy upgradeAtPowerCycle
|
|
|
|
Sets VMTool's upgrade policy to "upgradeAtPowerCycle" of virtual machines in the "MyClusterName" cluster.
|
|
|
|
.EXAMPLE
|
|
C:\PS> Get-VMHost "MyESXiHostName" | Get-VM | Set-VMToolsUpgradePolicy -UpgradePolicy manual
|
|
|
|
Sets VMTool's upgrade policy to "manual" of virtual machines on the "MyESXiHostName" ESXi host.
|
|
|
|
.NOTES
|
|
This advanced function assumes that you are connected to at least one vCenter Server system.
|
|
|
|
.NOTES
|
|
Author : Daoyuan Wang
|
|
Author email : daoyuanw@vmware.com
|
|
Version : 1.1
|
|
Update Author : Kyle Ruddy
|
|
Update email : kmruddy@gmail.com
|
|
==========Tested Against Environment==========
|
|
VMware vSphere Hypervisor(ESXi) Version : 6.5 (build 4564106)(build 7388607)
|
|
VMware vCenter Server Version : 6.5 (build 4602587)(build 7312210)
|
|
PowerCLI Version : PowerCLI 6.5 (build 4624819)(build 7155375)
|
|
PowerShell Version : 5.1
|
|
#>
|
|
|
|
[CmdletBinding(SupportsShouldProcess)]
|
|
|
|
Param (
|
|
[Parameter(Mandatory=$true,
|
|
ValueFromPipeLine = $true,
|
|
ValueFromPipelinebyPropertyName=$True,
|
|
Position = 0)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine[]] $VM,
|
|
|
|
[Parameter(Mandatory=$false,
|
|
Position = 1)]
|
|
[ValidateSet("upgradeAtPowerCycle",
|
|
"manual")]
|
|
[String] $UpgradePolicy
|
|
)
|
|
Begin {
|
|
$vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
|
|
$vmConfigSpec.Tools = New-Object VMware.Vim.ToolsConfigInfo
|
|
$vmConfigSpec.Tools.ToolsUpgradePolicy = $UpgradePolicy
|
|
}
|
|
|
|
Process {
|
|
foreach ($_ in $VM) {
|
|
# Get current setting
|
|
$vmView = Get-View $_ -Property Config.Tools.ToolsUpgradePolicy
|
|
# Change if VMTools upgrade policy is not "upgradeAtPowerCycle"
|
|
if ($vmView.Config.Tools.ToolsUpgradePolicy -ne $UpgradePolicy) {
|
|
Write-Verbose "Applying 'upgradeAtPowerCycle' setting to $($_.Name)..."
|
|
$vmView.ReconfigVM($vmConfigSpec)
|
|
Get-VMToolsUpgradePolicy -VM $_
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Function Invoke-VMToolsListProcessInVM {
|
|
<#
|
|
.Synopsis
|
|
This advanced function lists the processes in the virtual machine.
|
|
|
|
.Description
|
|
This advanced function lists the running processes in the virtual machine.
|
|
|
|
.PARAMETER VM
|
|
Specifies the virtual machine which you want to list the processes of.
|
|
|
|
.Parameter GuestUser
|
|
Specifies the user name you want to use for authenticating with the guest OS.
|
|
|
|
.Parameter GuestPassword
|
|
Specifies the password you want to use for authenticating with the guest OS.
|
|
|
|
.Example
|
|
C:\PS> Import-Module .\VMToolsManagement.psm1
|
|
C:\PS> $SampleVM = get-vm "MyVMName"
|
|
C:\PS> Invoke-VMToolsListProcessInVM -VM $SampleVM -GuestUser <username> -GuestPassword <password>
|
|
|
|
ScriptOutput
|
|
-----------------------------------------------------------------------------------------------------------------------
|
|
| USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
|
|
| root 1 0.0 0.0 19360 1556 ? Ss Jul20 0:02 /sbin/init
|
|
| root 2 0.0 0.0 0 0 ? S Jul20 0:00 [kthreadd]
|
|
| root 3 0.0 0.0 0 0 ? S Jul20 0:06 [migration/0]
|
|
| root 4 0.0 0.0 0 0 ? S Jul20 0:00 [ksoftirqd/0]
|
|
| root 5 0.0 0.0 0 0 ? S Jul20 0:00 [stopper/0]
|
|
......
|
|
|
|
List the processes in the "MyVMName" VM.
|
|
|
|
.NOTES
|
|
This advanced function lists processes in the guest OS of virtual machine.
|
|
A VMTools should already be running in the guest OS.
|
|
|
|
.NOTES
|
|
Author : Daoyuan Wang
|
|
Author email : daoyuanw@vmware.com
|
|
Version : 1.0
|
|
==========Tested Against Environment==========
|
|
VMware vSphere Hypervisor(ESXi) Version : 6.5 (build 4564106)
|
|
VMware vCenter Server Version : 6.5 (build 4602587)
|
|
PowerCLI Version : PowerCLI 6.5 (build 4624819)
|
|
PowerShell Version : 5.1
|
|
Guest OS : RHEL6.8, Windows7
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
|
|
Param (
|
|
[Parameter(Mandatory=$true,
|
|
ValueFromPipeLine = $true,
|
|
ValueFromPipelinebyPropertyName=$True,
|
|
Position = 0)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM,
|
|
|
|
[Parameter(Mandatory=$true)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[String] $GuestUser,
|
|
|
|
[Parameter(Mandatory=$true)]
|
|
[AllowEmptyString()]
|
|
[String] $GuestPassword
|
|
)
|
|
|
|
Process {
|
|
$vmView = Get-VM $VM | Get-View -Property Guest
|
|
if ($vmView.Guest.State -eq 'NotRunning') {
|
|
Write-Error "$VM is Not Running, unable to list the processes!"
|
|
return
|
|
}
|
|
|
|
if ($vmView.Guest.GuestFamily -match 'windows') {
|
|
$command = 'Get-Process'
|
|
} elseif ($vmView.Guest.GuestFamily -match 'linux') {
|
|
$command = 'ps aux'
|
|
} else {
|
|
$command = 'ps'
|
|
}
|
|
|
|
Invoke-VMScript -VM $VM -ScriptText $command -GuestUser $GuestUser -GuestPassword $GuestPassword
|
|
}
|
|
}
|
|
|
|
Function Update-VMToolsImageLocation {
|
|
<#
|
|
.Synopsis
|
|
This advanced function updates the link /productLocker in ESXi host.
|
|
|
|
.Description
|
|
This advanced function updates the link /productLocker in ESXi host directly to avoid host reboot.
|
|
|
|
.Parameter VMHost
|
|
Specifies the ESXi host on which you want to update the /productLocker link.
|
|
|
|
.Parameter HostUser
|
|
Specifies the user name you want to use for authenticating with the ESXi host.
|
|
|
|
.Parameter HostPassword
|
|
Specifies the password you want to use for authenticating with the ESXi host.
|
|
|
|
.Parameter ImageLocation
|
|
Specifies the new image location Where-Object you want /producterLocker to link.
|
|
|
|
.Example
|
|
C:\PS> Import-Module .\VMToolsManagement.psm1
|
|
C:\PS> $SampleHost = get-vmhost <host ip>
|
|
C:\PS> Update-VMToolsImageLocation -VmHost $SampleHost -HostUser 'root' -HostPassword <host password> -ImageLocation '/locker/packages/6.5.0/'
|
|
|
|
Update link /productLocker successfully.
|
|
|
|
Update the link /producterLocker on $SampleHost to point to '/locker/packages/6.5.0/'.
|
|
|
|
.NOTES
|
|
This advanced function connects to ESXi host to execute shell command directly.
|
|
Make sure the SSH service on ESXi host is enabled, and a SSH library(Posh-SSH or SSH-Sessions etc.)
|
|
for powershell is already installed on client Where-Object you call this advanced function.
|
|
You can instal Posh-SSH by executing:
|
|
iex (New-Object Net.WebClient).DownloadString("https://gist.github.com/darkoperator/6152630/raw/c67de4f7cd780ba367cccbc2593f38d18ce6df89/instposhsshdev")
|
|
For SSH-Sessions installation and usage, please refer to
|
|
http://www.powershelladmin.com/wiki/SSH_from_PowerShell_using_the_SSH.NET_library
|
|
|
|
|
|
.NOTES
|
|
Author : Daoyuan Wang
|
|
Author email : daoyuanw@vmware.com
|
|
Version : 1.0
|
|
==========Tested Against Environment==========
|
|
VMware vSphere Hypervisor(ESXi) Version : 6.5 (build 4564106)
|
|
VMware vCenter Server Version : 6.5 (build 4602587)
|
|
PowerCLI Version : PowerCLI 6.5 (build 4624819)
|
|
PowerShell Version : 5.1
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
|
|
Param (
|
|
[Parameter(Mandatory=$true,
|
|
ValueFromPipeLine = $true,
|
|
ValueFromPipelinebyPropertyName=$True,
|
|
Position = 0)]
|
|
[VMware.VimAutomation.ViCore.Types.V1.Inventory.VMHost] $VMHost,
|
|
|
|
[Parameter(Mandatory=$true)]
|
|
[String] $HostUser,
|
|
|
|
[Parameter(Mandatory=$true)]
|
|
[AllowEmptyString()]
|
|
[String] $HostPassword,
|
|
|
|
[Parameter(Mandatory=$true)]
|
|
[String] $ImageLocation
|
|
)
|
|
|
|
Process {
|
|
if (-not (Get-Command New-SSHSession)) {
|
|
Throw "This advanced function depends on SSH library. Please ensure a SSH library is already installed!"
|
|
}
|
|
|
|
$password = new-object System.Security.SecureString
|
|
if ($HostPassword) {
|
|
$password = ConvertTo-SecureString -AsPlainText $HostPassword -Force
|
|
}
|
|
|
|
$crendential = New-Object System.Management.Automation.PSCredential -ArgumentList $HostUser, $password
|
|
$sshSession = New-SSHSession -ComputerName $VMHost -Credential $crendential -Force
|
|
|
|
$result = Invoke-SshCommand -SSHSession $sshSession -Command "readlink /productLocker" -EnsureConnection:$false
|
|
Write-Verbose "The link /productLocker before change: $($result.Output)"
|
|
|
|
$command = "rm /productLocker && ln -s $ImageLocation /productLocker"
|
|
Write-Verbose "Updating /productLocker on $VMHost..."
|
|
$result = Invoke-SshCommand -SSHSession $sshSession -Command $command -EnsureConnection:$false
|
|
if ($result.ExitStatus -eq 0) {
|
|
Write-Host "Update link /productLocker successfully." -ForegroundColor Green
|
|
} else {
|
|
Write-Error "Failed to update link /productLocker: $($result.Error)"
|
|
}
|
|
|
|
$result = Invoke-SshCommand -SSHSession $sshSession -Command "readlink /productLocker" -EnsureConnection:$false
|
|
Write-Verbose "The link /productLocker after change: $($result.Output)"
|
|
}
|
|
}
|
|
|
|
Function Set-VMToolsConfInVM {
|
|
<#
|
|
.Synopsis
|
|
This advanced function sets the tools.conf content in guest OS.
|
|
|
|
.Description
|
|
This advanced function copies the tools.conf in gueset OS of virtual machine to localhost,
|
|
then sets it locally by setting "vmtoolsd.level" to a valid level and copies it back to the guest OS.
|
|
|
|
.PARAMETER VM
|
|
Specifies the virtual machine to update.
|
|
|
|
.PARAMETER LogLevel
|
|
Specifies the desired log level to log.
|
|
|
|
.Parameter GuestUser
|
|
Specifies the user name you want to use for authenticating with the guest OS.
|
|
|
|
.Parameter GuestPassword
|
|
Specifies the password you want to use for authenticating with the guest OS.
|
|
|
|
.Example
|
|
C:\PS> Import-Module .\VMToolsManagement.psm1
|
|
C:\PS> $SampleVM = get-vm "MyVMName"
|
|
C:\PS> Update-VMToolsConfInVM -VM $SampleVM -GuestUser <username> -GuestPassword <password>
|
|
|
|
Update tools.conf of 111394-RHEL-6.8-0 successfully.
|
|
|
|
Updates the tools.conf in $SampleVM, changes the vmtoolsd log level to info ("vmtoolsd.level = info") for example.
|
|
|
|
.NOTES
|
|
This advanced function updates the tools.conf in guest OS. A VMTools should already be running in the guest OS.
|
|
|
|
.NOTES
|
|
Author : Daoyuan Wang
|
|
Author email : daoyuanw@vmware.com
|
|
Version : 1.1
|
|
Update Author : Kyle Ruddy
|
|
Update email : kmruddy@gmail.com
|
|
==========Tested Against Environment==========
|
|
VMware vSphere Hypervisor(ESXi) Version : 6.5 (build 4564106)(build 7388607)
|
|
VMware vCenter Server Version : 6.5 (build 4602587)(build 7312210)
|
|
PowerCLI Version : PowerCLI 6.5 (build 4624819)(build 7155375)
|
|
PowerShell Version : 5.1
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
|
|
Param (
|
|
[Parameter(Mandatory=$true,
|
|
ValueFromPipeLine = $true,
|
|
ValueFromPipelinebyPropertyName=$True,
|
|
Position = 0)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM,
|
|
|
|
[Parameter(Mandatory=$true,
|
|
Position = 1)]
|
|
[ValidateSet("none",
|
|
"critical",
|
|
"error",
|
|
"warning",
|
|
"message",
|
|
"info",
|
|
"debug")]
|
|
[String] $LogLevel,
|
|
|
|
[Parameter(Mandatory=$true)]
|
|
[String] $GuestUser,
|
|
|
|
[Parameter(Mandatory=$true)]
|
|
[AllowEmptyString()]
|
|
[String] $GuestPassword
|
|
)
|
|
|
|
Process {
|
|
$vmGuest = Get-VMGuest $VM
|
|
$OsName = $vmGuest.OSFullName
|
|
$guestToolsConfFile = ""
|
|
$localToolsConfFile = ".\tools.conf"
|
|
|
|
# Determine the tools.conf path in guest OS
|
|
if (($OsName -match "Linux") `
|
|
-or ($OsName -match "FreeBSD") `
|
|
-or ($OsName -match "Solaris")) {
|
|
$guestToolsConfFile = '/etc/vmware-tools/tools.conf'
|
|
} elseif (($OsName -match "Windows Server 2003") `
|
|
-or ($OsName -match "Windows Server 2000") `
|
|
-or ($OsName -match "Windows XP")) {
|
|
$guestToolsConfFile = 'C:\Documents and Settings\All Users\Application Data\VMware\VMware Tools\tools.conf'
|
|
} elseif ($OsName -match "Windows") {
|
|
$guestToolsConfFile = 'C:\ProgramData\VMware\VMware Tools\tools.conf'
|
|
} elseif ($OsName -match "Mac") {
|
|
$guestToolsConfFile = '/Library/Application Support/VMware Tools/tools.conf'
|
|
} else {
|
|
Throw "Unknown tools.conf path on OS: $OsName"
|
|
}
|
|
|
|
# Get the tools.conf from guest OS to localhost, ignore the error if tools.conf was not found in guest OS
|
|
Write-Verbose "Copy tools.conf from $VM to localhost..."
|
|
$lastError = $Error[0]
|
|
Copy-VMGuestFile -Source $guestToolsConfFile -Destination $localToolsConfFile -VM $VM -GuestToLocal `
|
|
-GuestUser $GuestUser -GuestPassword $GuestPassword -Force -ErrorAction:SilentlyContinue
|
|
|
|
# The tools.conf doesn't exist in guest OS, create an empty one locally
|
|
if (($Error[0] -ne $lastError) -and ($Error[0] -notmatch 'tools.conf was not found')) {
|
|
Write-Error "Failed to copy tools.conf from $VM"
|
|
return
|
|
} elseif (-not (Test-Path $localToolsConfFile)) {
|
|
Set-Content $localToolsConfFile $null
|
|
}
|
|
|
|
#############################################################################
|
|
# Updates tools.conf by setting vmtoolsd.level = info, just for example.
|
|
#############################################################################
|
|
$confContent = Get-Content $localToolsConfFile
|
|
$updatedContent = "vmtoolsd.level = $LogLevel"
|
|
|
|
Write-Verbose "Editing tools.conf (set 'vmtoolsd.level = info' for example)..."
|
|
if ($confContent -match "vmtoolsd\.level") {
|
|
$confContent -replace "vmtoolsd\.level.*", $updatedContent | Set-Content $localToolsConfFile
|
|
} elseif ($confContent -match "logging") {
|
|
Add-Content $localToolsConfFile $updatedContent
|
|
} else {
|
|
Add-Content $localToolsConfFile "[logging]`nlog=true"
|
|
Add-Content $localToolsConfFile $updatedContent
|
|
}
|
|
|
|
# Upload the changed tools.conf to guest OS
|
|
try {
|
|
Write-Verbose "Copy local tools.conf to $VM..."
|
|
Copy-VMGuestFile -Source $localToolsConfFile -Destination $guestToolsConfFile -VM $VM -LocalToGuest `
|
|
-GuestUser $GuestUser -GuestPassword $GuestPassword -Force -ErrorAction:Stop
|
|
} catch {
|
|
Write-Error "Failed to update tools.conf of $VM"
|
|
Write-Verbose "Removing the local tools configuration file"
|
|
Remove-Item $localToolsConfFile
|
|
return
|
|
}
|
|
Write-Host "The tools.conf updated in $VM successfully." -ForegroundColor Green
|
|
Write-Verbose "Removing the local tools configuration file"
|
|
Remove-Item $localToolsConfFile
|
|
}
|
|
}
|
|
|
|
Function Invoke-VMToolsVIBInstall {
|
|
<#
|
|
.SYNOPSIS
|
|
This advanced function installs VMTool VIB in ESXi hosts.
|
|
|
|
.DESCRIPTION
|
|
This advanced function installs VMTool VIB in specified ESXi hosts.
|
|
|
|
.PARAMETER VMHost
|
|
Specifies the ESXi hosts which you want to install VMTool VIB in.
|
|
|
|
.PARAMETER ToolsVibUrl
|
|
Specifies the URL of VMTools VIB package which you want to install in ESXi hosts.
|
|
|
|
.EXAMPLE
|
|
C:\PS> Import-Module .\VMToolsManagement.psm1
|
|
C:\PS> $VCServer = Connect-VIServer -Server <vCenter Server IP> -User <vCenter User> -Password <vCenter Password>.
|
|
C:\PS> $viBurl = "http://<YOUR URL>/VMware_locker_tools-light_6.5.0-10.2.0.6085460.vib"
|
|
C:\PS> Get-VMHost -Server $VCServer | Invoke-VMToolsVIBInstall -ToolsVibUrl $viBurl
|
|
|
|
Install VMTool VIB in $VCServer.
|
|
|
|
.EXAMPLE
|
|
C:\PS> Invoke-VMToolsVIBInstall -VMHost "MyESXiHostName" -ToolsVibUrl $viBurl
|
|
|
|
Installs VMTools VIB package successfully.
|
|
|
|
Installs VMTool VIB in the "MyESXiHostName" ESXi host.
|
|
|
|
.EXAMPLE
|
|
C:\PS> Get-VMHost -Location "MyClusterName" | Invoke-VMToolsVIBInstall -ToolsVibUrl $vib
|
|
|
|
Installs VMTool VIB in ESXi host of the "MyClusterName" cluster.
|
|
|
|
.NOTES
|
|
This advanced function assumes that you are connected to at least one vCenter Server system.
|
|
|
|
.NOTES
|
|
Author : Daoyuan Wang
|
|
Author email : daoyuanw@vmware.com
|
|
Version : 1.0
|
|
==========Tested Against Environment==========
|
|
VMware vSphere Hypervisor(ESXi) Version : 6.5 (build 4564106)
|
|
VMware vCenter Server Version : 6.5 (build 4602587)
|
|
PowerCLI Version : PowerCLI 6.5 (build 4624819)
|
|
PowerShell Version : 5.1
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
|
|
Param (
|
|
[Parameter(Mandatory=$true,
|
|
ValueFromPipeLine = $true,
|
|
ValueFromPipelinebyPropertyName=$True,
|
|
Position = 0)]
|
|
[VMware.VimAutomation.ViCore.Types.V1.Inventory.VMHost[]] $VMHost,
|
|
|
|
[Parameter(Mandatory=$true)]
|
|
[String] $ToolsVibUrl
|
|
)
|
|
|
|
Process {
|
|
foreach ($_ in $VMHost) {
|
|
$esxcli = Get-EsxCLI -VMHost $_ -V2
|
|
|
|
$result = $esxcli.software.vib.list.Invoke() | Where-Object {$_.name -match 'tools'}
|
|
Write-Verbose "Existing tools VIB on $_ before installing: $($result.Name)_$($result.Version)"
|
|
|
|
# Install VIBs
|
|
Write-Verbose "Installing $ToolsVibUrl on $($_.Name)..."
|
|
$Error.Clear()
|
|
$cliArgs = $esxcli.software.vib.install.CreateArgs()
|
|
$cliArgs.viburl = $ToolsVibUrl
|
|
$cliArgs.nosigcheck = $true
|
|
$cliArgs.force = $true
|
|
$result = $esxcli.software.vib.install.Invoke($cliArgs)
|
|
if ($Error) {
|
|
Write-Error "Failed to install VMTools VIB package!"
|
|
} else {
|
|
Write-Verbose $result.Message
|
|
$result = $esxcli.software.vib.list.Invoke() | Where-Object {$_.name -match 'tools'}
|
|
Write-Verbose "Tools VIB on $_ after installing: $($result.Name)_$($result.Version)"
|
|
Write-Host "VMTools VIB package installed on $_ successfully." -ForegroundColor Green
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Function Invoke-VMToolsUpgradeInVMs {
|
|
<#
|
|
.SYNOPSIS
|
|
This advanced function upgrades VMTools to the version bundled by ESXi host.
|
|
|
|
.DESCRIPTION
|
|
This advanced function upgrades VMTools of specified virtual machines to the version
|
|
bundled by ESXi host. You can also specify the number of virtual machines
|
|
to upgrade in parallel.
|
|
|
|
.PARAMETER VM
|
|
Specifies the virtual machines you want to upgrade VMTools of.
|
|
|
|
.PARAMETER GuestOSType
|
|
Specifies the guest OS type of the virtual machines.
|
|
|
|
.PARAMETER VersionToUpgrade
|
|
Specifies the current running VMTools version of virtual machines.
|
|
|
|
.PARAMETER MaxParallelUpgrades
|
|
Specifies the max virtual machine numbers to upgrade in parallel.
|
|
|
|
.EXAMPLE
|
|
C:\PS> Import-Module .\VMToolsManagement.psm1
|
|
C:\PS> $VCServer = Connect-VIServer -Server <vCenter Server IP> -User <vCenter User> -Password <vCenter Password>
|
|
C:\PS> Get-VM -Server $VCServer | Invoke-VMToolsUpgradeInVMs -MaxParallelUpgrades 5
|
|
|
|
Upgrades VMTools of all virtual machines in the $VCServer vCenter Server, 5 at a time in parallel.
|
|
|
|
.EXAMPLE
|
|
C:\PS> Get-VM | Invoke-VMToolsUpgradeInVMs -GuestOSType windows -MaxParallelUpgrades 1 | ft -Autosize
|
|
|
|
Upgrade result:
|
|
|
|
VmName UpgradeResult ToolsVersion ToolsVersionStatus TotalSeconds Message
|
|
------ ------------- ------------ ------------------ ------------ -------
|
|
111167-Win-7-Sp1-64-Enterprise-NoTools-2 Completed 10.1.0 guestToolsCurrent 102 Upgrade VMTools successfully
|
|
111393-RHEL-Server-7.2 Skipped 10.0.0 guestToolsNeedUpgrade 0 Guest OS type does not meet condtion 'windows'
|
|
111305-Windows-Server2016 Completed 10.1.0 guestToolsCurrent 144 Upgrade VMTools successfully
|
|
|
|
Upgrades VMTools of windows virtual machines one by one.
|
|
|
|
.EXAMPLE
|
|
C:\PS> Get-VM -Location "MyClusterName" | Invoke-VMToolsUpgradeInVMs -MaxParallelUpgrades 2 | ft -Autosize
|
|
|
|
Upgrade result:
|
|
|
|
VmName UpgradeResult ToolsVersion ToolsVersionStatus TotalSeconds Message
|
|
------ ------------- ------------ ------------------ ------------ -------
|
|
111167-Win-7-Sp1-64-Enterprise-NoTools-2 Failed 10.0.0 guestToolsNeedUpgrade 0 The required VMware Tools ISO image does not exist or is inaccessible.
|
|
111393-RHEL-Server-7.2 Completed 10.1.0 guestToolsCurrent 100 Upgrade VMTools successfully
|
|
|
|
Upgrades VMTools of virtual machines in the "MyClusterName" cluster, 2 at a time.
|
|
|
|
.EXAMPLE
|
|
C:\PS> Get-VMHost "MyESXiHostName" | Get-VM | Invoke-VMToolsUpgradeInVMs -MaxParallelUpgrades 5
|
|
|
|
Upgrades VMTools of virtual machines on the "MyESXiHostName" ESXi host, 5 at a time.
|
|
|
|
.NOTES
|
|
This advanced function assumes an old VMTools is already running in the virtual machine.
|
|
|
|
.NOTES
|
|
Author : Daoyuan Wang
|
|
Author email : daoyuanw@vmware.com
|
|
Version : 1.0
|
|
==========Tested Against Environment==========
|
|
VMware vSphere Hypervisor(ESXi) Version : 6.5 (build 4564106)
|
|
VMware vCenter Server Version : 6.5 (build 4602587)
|
|
PowerCLI Version : PowerCLI 6.5 (build 4624819)
|
|
PowerShell Version : 5.1
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
|
|
Param (
|
|
[Parameter(Mandatory=$true,
|
|
ValueFromPipeLine = $true,
|
|
ValueFromPipelinebyPropertyName=$True,
|
|
Position = 0)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine[]] $VM,
|
|
|
|
[Parameter(Mandatory=$false)]
|
|
[ValidateSet("linux", "windows")]
|
|
[String] $GuestOSType,
|
|
|
|
[Parameter(Mandatory=$false)]
|
|
[String] $VersionToUpgrade,
|
|
|
|
[Parameter(Mandatory=$false)]
|
|
[ValidateRange(1, 5)]
|
|
[Int] $MaxParallelUpgrades = 1
|
|
)
|
|
|
|
Begin {
|
|
$RunspacePool = [runspacefactory]::CreateRunspacePool(
|
|
1, #Min Runspaces
|
|
$MaxParallelUpgrades #Max Runspaces
|
|
)
|
|
|
|
$RunspacePool.Open()
|
|
|
|
$jobs = New-Object System.Collections.ArrayList
|
|
$result = @()
|
|
}
|
|
|
|
Process {
|
|
foreach ($_ in $VM) {
|
|
$vmView = Get-View $_ -Property Guest
|
|
$toolsVersion = $_.Guest.ToolsVersion
|
|
$toolsVersionStatus = $vmView.Guest.ToolsVersionStatus
|
|
|
|
# Skip if VMTools doesn't need to upgrade
|
|
if ($toolsVersionStatus -ne "guestToolsNeedUpgrade") {
|
|
Write-Host "No VMTools need to upgrade!`nVM: '$_', ToolsVersionStatus: '$toolsVersionStatus'"
|
|
$result += [pscustomobject]@{
|
|
VmName = $_.Name
|
|
UpgradeResult = "Skipped"
|
|
ToolsVersion = $toolsVersion
|
|
ToolsVersionStatus = $toolsVersionStatus
|
|
TotalSeconds = 0
|
|
Message = "No VMTools need to upgrade!"
|
|
}
|
|
continue
|
|
}
|
|
|
|
# Skip if current VMTools doesn't meet to specified version
|
|
if ($VersionToUpgrade -and ($toolsVersion -notmatch $VersionToUpgrade)) {
|
|
Write-Host "Current ToolsVersion in $_ is: $toolsVersion,"`
|
|
"does not meet condtion `'$VersionToUpgrade`', skipping it..." -ForegroundColor Yellow
|
|
$result += [pscustomobject]@{
|
|
VmName = $_.Name
|
|
UpgradeResult = "Skipped"
|
|
ToolsVersion = $toolsVersion
|
|
ToolsVersionStatus = $toolsVersionStatus
|
|
TotalSeconds = 0
|
|
Message = "Current VMTools version does not meet condtion `'$VersionToUpgrade`'"
|
|
}
|
|
continue
|
|
}
|
|
|
|
# Create a thread to upgrade VMTools for each virtual machine
|
|
$PSThread = [powershell]::Create()
|
|
$PSThread.RunspacePool = $RunspacePool
|
|
|
|
# Script content to upgrade VMTools
|
|
$PSThread.AddScript({
|
|
Param (
|
|
$vcServer,
|
|
$session,
|
|
$vmId,
|
|
$GuestOSType
|
|
)
|
|
# Load PowerCLI module and connect to VCServer, as child thread environment is independent with parent
|
|
if(-not $global:DefaultVIServer) {
|
|
$moduleName = "vmware.vimautomation.core"
|
|
if(-not (Get-Module | Where-Object {$_.name -eq $moduleName})) {
|
|
try {
|
|
Import-Module $moduleName -ErrorAction SilentlyContinue | Out-Null
|
|
}
|
|
catch {
|
|
Throw "Failed to load PowerCLI module('$moduleName')"
|
|
}
|
|
}
|
|
try {
|
|
$server = Connect-VIServer -Server $vcserver -session $session -Force
|
|
}
|
|
catch {
|
|
Throw "Failed to connect to VI server: $vcserver"
|
|
}
|
|
}
|
|
|
|
# Retrieves VM
|
|
$vm = Get-VM -Id $vmId
|
|
|
|
$ThreadID = [appdomain]::GetCurrentThreadId()
|
|
Write-Verbose “Thread[$ThreadID]: Beginning Update-Tools for $vm”
|
|
|
|
if ($vm.PowerState -ne 'PoweredOn') {
|
|
Write-Host "Powering on VM: $vm..."
|
|
Start-VM $vm | Out-Null
|
|
$vm = Get-VM $vm
|
|
}
|
|
|
|
# Wait for OS and VMTools starting up
|
|
$timeOut = 60*10 #seconds
|
|
$refreshInterval = 5 #seconds
|
|
$count = $timeOut/$refreshInterval
|
|
while (($vm.Guest.ExtensionData.ToolsRunningStatus -ne "guestToolsRunning") `
|
|
-or (-not $vm.Guest.GuestFamily)) {
|
|
$count -= 1
|
|
if ($count -lt 0) {
|
|
Write-Error "VMTools doesn't start up in $timeOut seconds, please check if $vm is hung!"
|
|
break
|
|
}
|
|
Write-Verbose "Waiting for VMTools running in $vm before upgrading..."
|
|
Start-Sleep -Seconds $refreshInterval
|
|
}
|
|
|
|
# Skip if virtual machine doesn't meet specified guest OS type
|
|
if ($GuestOSType -and ($vm.Guest.GuestFamily -notmatch $GuestOSType)) {
|
|
Write-Host "GuestFamily of $vm is: $($vm.Guest.GuestFamily),"`
|
|
"does not meet condition `'$GuestOSType`', skipping it..." -ForegroundColor Yellow
|
|
# upgrade result
|
|
[pscustomobject]@{
|
|
VmName = $vm.Name
|
|
UpgradeResult = "Skipped"
|
|
ToolsVersion = $vm.Guest.ToolsVersion
|
|
ToolsVersionStatus = $vm.Guest.ExtensionData.ToolsVersionStatus
|
|
TotalSeconds = 0
|
|
Message = "Guest OS type does not meet condtion `'$GuestOSType`'"
|
|
}
|
|
Disconnect-VIServer $server -Confirm:$false
|
|
return
|
|
}
|
|
|
|
# Upgrade VMTools and check the tools version status
|
|
Write-Host "Upgrading VMTools for VM: $vm..."
|
|
$task = Update-Tools -VM $vm -RunAsync
|
|
$task | Wait-Task
|
|
$task = Get-Task -Id $task.Id
|
|
|
|
if ($task.State -eq "Success") {
|
|
$upgradeResult = "Completed"
|
|
$message = "Upgrade VMTools successfully"
|
|
Write-Host "Upgrade VMTools successfully for VM: $vm" -ForegroundColor Green
|
|
} else {
|
|
$upgradeResult = "Failed"
|
|
$message = $task.ExtensionData.Info.Error.LocalizedMessage
|
|
Write-Error "Failed to upgrade VMTools for VM: $vm"
|
|
}
|
|
$vm = Get-VM $vm
|
|
# Upgrade result to return
|
|
[pscustomobject]@{
|
|
VmName = $vm.Name
|
|
UpgradeResult = $upgradeResult
|
|
ToolsVersion = $vm.Guest.ToolsVersion
|
|
ToolsVersionStatus = $vm.Guest.ExtensionData.ToolsVersionStatus
|
|
TotalSeconds = [math]::Floor(($task.FinishTime).Subtract($task.StartTime).TotalSeconds)
|
|
Message = $message
|
|
}
|
|
Write-Verbose “Thread[$ThreadID]: Ending Update-Tools for $vm”
|
|
}) | Out-Null
|
|
$vc = $Global:DefaultVIServer.ServiceUri.Host
|
|
$vcSession = $Global:DefaultVIServer.SessionSecret
|
|
$PSThread.AddArgument($vc).AddArgument($vcSession).AddArgument($_.Id).AddArgument($GuestOSType) | Out-Null
|
|
|
|
# Start thread
|
|
$Handle = $PSThread.BeginInvoke()
|
|
$job = New-Object System.Object
|
|
$job | Add-Member -type NoteProperty -name Thread -value $PSThread
|
|
$job | Add-Member -type NoteProperty -name Handle -value $Handle
|
|
$jobs.Add($job) | Out-Null
|
|
|
|
Write-Verbose (“Available Runspaces in RunspacePool: {0}” -f $RunspacePool.GetAvailableRunspaces())
|
|
}
|
|
}
|
|
|
|
End {
|
|
#Verify all threads completed
|
|
while (($jobs | Where-Object {$_.Handle.iscompleted -ne "Completed"}).Count -gt 0) {
|
|
Start-Sleep -Seconds 5
|
|
}
|
|
|
|
$upgradeResult = $jobs | foreach {
|
|
$_.Thread.EndInvoke($_.Handle)
|
|
$_.Thread.Dispose()
|
|
}
|
|
$result += $upgradeResult
|
|
$result
|
|
|
|
$RunspacePool.Close()
|
|
$RunspacePool.Dispose()
|
|
}
|
|
}
|
|
|
|
Export-ModuleMember *-*
|