├── Audit-vCenterOperation ├── Audit-vCenterOperation.psm1 └── README.md ├── ESXiLogDateTime ├── ESXiLogDateTime.format.ps1xml ├── ESXiLogDateTime.psd1 ├── ESXiLogDateTime.psm1 └── README.md ├── Get-MultihomingInfo ├── Get-MultihomingInfo.psm1 └── README.md ├── Get-StorageViewsReport ├── Get-StorageViewsReport.psm1 └── README.md ├── HpAmsVib ├── HpAmsVib.psm1 └── README.md ├── Install-VCSA6 ├── Install-VCSA6.psm1 └── README.md ├── NonDefaultHostSettings ├── NonDefaultHostSettings.psm1 └── README.md ├── PowerCLI Fundamentals Training └── Demo_Examples.ps1 ├── README.md ├── Register-AllOrphanedVmx ├── README.md └── Register-AllOrphanedVmx.psm1 ├── Reset-ISdatabase ├── README.md └── Reset-ISdatabase.psm1 ├── Set-VMHostRamDisk ├── README.md └── Set-VMHostRamDisk.psm1 ├── Test-VpxdCertificate ├── README.md └── Test-VpxdCertificate.psm1 ├── VMLocationbyDateTime ├── README.md ├── VMLocationbyDateTime.ps1xml ├── VMLocationbyDateTime.psd1 └── VMLocationbyDateTime.psm1 ├── vCenterTagging ├── README.md └── vCenterTagging.psm1 └── vSphereOvercommit ├── README.md └── vSphereOvercommit.psm1 /Audit-vCenterOperation/Audit-vCenterOperation.psm1: -------------------------------------------------------------------------------- 1 | #Requires -Version 3 2 | 3 | function Audit-vCenterOperation { 4 | <# 5 | .SYNOPSIS 6 | Obtains vCenter events and filters them to meaningful vCenter operations. 7 | It can filter the operations on a start date, an end date, the user who initiated the operations, the vCenter object(s) and the type of operations. 8 | 9 | .DESCRIPTION 10 | Obtains vCenter events and filters them to meaningful vCenter operations. 11 | It can filter the operations on a start date, an end date, the user who initiated the operations, the vCenter object(s) targeted by the operation, and the type of operations. 12 | 13 | It outputs relevant vCenter events and user-friendly information from these events. 14 | Also, for the VM "reconfigure" operations, it adds a property "NewConfigSettings" to the output objects, which contains the changed VM setting(s) and the new value. 15 | 16 | By default, the operations are sorted in chronological order to facilitate auditing and historical tracking of events or configuration changes. 17 | 18 | .PARAMETER VIServer 19 | To specify the vCenter Server to connect PowerCLI to. 20 | The default is Localhost. 21 | 22 | .PARAMETER Entity 23 | To filter the operations down to those which targeted the specified vCenter inventory object(s). 24 | It needs to be one or more PowerCLI object(s) representing one or more VM(s), VMHost(s), cluster(s) or datacenter(s). 25 | 26 | .PARAMETER Username 27 | To filter the operations down to those which were initiated by the specified user 28 | 29 | .PARAMETER Start 30 | To retrieve only the operations which occurred after the specified date (or date and time). The valid formats are dd/mm/yyyy or mm/dd/yyyy, depending on the local machine regional settings. 31 | 32 | .PARAMETER Finish 33 | To retrieve only the operations which occurred before the specified date (or date and time). The valid formats are dd/mm/yyyy or mm/dd/yyyy, depending on the local machine regional settings. 34 | 35 | .PARAMETER OperationType 36 | To filter the operations down to a specific type or topic. 37 | The possible values are : 38 | Create, Reconfigure, Remove, DRS, HA, Password, Migration, Snapshot, Power, Alarm, Datastore, Permission 39 | 40 | .EXAMPLE 41 | Get-Cluster Test-Cluster | Audit-vCenterOperation -OperationType Reconfigure 42 | 43 | To track when the configuration of the cluster "Test-Cluster" was changed and by who. 44 | 45 | .EXAMPLE 46 | Audit-vCenterOperation -OperationType Migration -Start (Get-Date).AddDays(-7) 47 | 48 | To track all the migrations (vMotion and Storage vMotion) for all VMs which occurred during the last 7 days. 49 | 50 | .EXAMPLE 51 | Get-VMHost | Audit-vCenterOperation -Username "User01" -OperationType Power 52 | 53 | To verify if the user "User01" has initiated a power operation on a ESXi host. 54 | #> 55 | 56 | [cmdletbinding()] 57 | param( 58 | [string]$VIServer = "localhost", 59 | [Parameter(ValueFromPipeline = $True,Position=0)] 60 | [ValidateScript({ $($_[0].GetType()).Namespace -eq "VMware.VimAutomation.ViCore.Impl.V1.Inventory" })] 61 | $Entity, 62 | [string]$Username, 63 | [datetime]$Start, 64 | [datetime]$Finish, 65 | [ValidateSet("Create","Reconfigure","Remove","DRS","HA","Password","Migration","Snapshot","Power","Alarm","Datastore","Permission")] 66 | [string]$OperationType 67 | ) 68 | 69 | Begin { 70 | # Checking if the required PowerCLI snapin (or module) is loaded, if not, loading it 71 | If (Get-Module VMware.VimAutomation.Core -ListAvailable -ErrorAction SilentlyContinue) { 72 | If (-not (Get-Module VMware.VimAutomation.Core -ErrorAction SilentlyContinue)) { 73 | Import-Module VMware.VimAutomation.Core 74 | } 75 | } 76 | Else { 77 | If (-not (Get-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue)) { 78 | Add-PSSnapin VMware.VimAutomation.Core 79 | } 80 | } 81 | Set-PowercliConfiguration -InvalidCertificateAction "Ignore" -DisplayDeprecationWarnings:$false -Confirm:$false | Out-Null 82 | 83 | If (-not($defaultVIServer)) { 84 | Connect-VIServer $VIServer | Out-Null 85 | } 86 | Else { 87 | Write-Verbose "Already connected the vCenter Server: $defaultVIServer" 88 | } 89 | 90 | # Modifying $PSBoundParameters to feed the parameters to Get-VIEvent 91 | $PSBoundParameters.Remove('VIServer') | Out-Null 92 | If ($PSBoundParameters.ContainsKey('OperationType')) { 93 | $PSBoundParameters.Remove('OperationType') | Out-Null 94 | } 95 | $MaxNumEvents = 1000000000 96 | $PSBoundParameters.Add('MaxSamples',$MaxNumEvents) 97 | 98 | Write-Verbose "Bound Parameters Sent to Get-VIEvent : $($PSBoundParameters.Keys)" 99 | 100 | # Preparing an empty collection to store the output objects 101 | $OutputObjectCollection = @() 102 | } 103 | Process { 104 | $AllEvents = Get-VIEvent @PSBoundParameters | Where-Object { $_.FullFormattedMessage -notlike "*Check Notification*" -and $_.FullFormattedMessage -notlike "*unknown agent*" -and $_.FullFormattedMessage -notlike "*Update Download*" -and $_.FullFormattedMessage -notlike "*API invocations*" } 105 | $AllActions = $AllEvents | Where-Object { $_.UserName -and $_.UserName -ne "vpxuser" } 106 | 107 | # Sorting the actions by date and time to facilitate historical tracking 108 | $SortedActions = $AllActions | Sort-Object -Property CreatedTime 109 | Write-Verbose "`$SortedActions contains $($SortedActions.Count) events" 110 | 111 | If ($OperationType) { 112 | Write-Verbose "Filtering for actions of the type : $OperationType " 113 | switch ($OperationType) 114 | { 115 | "Create" { 116 | $FilteredActions = $SortedActions | Where-Object { $_.FullFormattedMessage -like "*Creat*" -and $_.FullFormattedMessage -notlike "*Snapshot*" } 117 | } 118 | "Reconfigure" { 119 | $FilteredActions = $SortedActions | Where-Object { $_.FullFormattedMessage -like "*Reconfigur*" -or $_.FullFormattedMessage -like "*Modif*" -and $_.FullFormattedMessage -notlike "*Task*"} 120 | } 121 | "Remove" { 122 | $FilteredActions = $SortedActions | Where-Object { $_.FullFormattedMessage -like "*Remov*" -and $_.FullFormattedMessage -notlike "*Snapshot*" } 123 | } 124 | "DRS" { 125 | $FilteredActions = $SortedActions | Where-Object { $_.FullFormattedMessage -like "*DRS*" } 126 | } 127 | "HA" { 128 | $FilteredActions = $SortedActions | Where-Object { $_.FullFormattedMessage -like "*vSphere HA*" } 129 | } 130 | 131 | "Password" { 132 | $FilteredActions = $SortedActions | Where-Object { $_.FullFormattedMessage -like "*Password*" } 133 | } 134 | "Migration" { 135 | $FilteredActions = $SortedActions | Where-Object { $_.FullFormattedMessage -like "*Migrat*" } 136 | } 137 | "Snapshot" { 138 | $FilteredActions = $SortedActions | Where-Object { $_.FullFormattedMessage -like "*Snapshot*" -or $_.FullFormattedMessage -like "*consolidat*" } 139 | } 140 | "Power" { 141 | $FilteredActions = $SortedActions | Where-Object { $_.FullFormattedMessage -like "*Power*" -or $_.FullFormattedMessage -like "*Reset*" -or $_.FullFormattedMessage -like "*Restart*" -or $_.FullFormattedMessage -like "*Reboot*" -and $_.FullFormattedMessage -notlike "*Service*" -and $_.FullFormattedMessage -notlike "*No operating system*"} 142 | } 143 | "Alarm" { 144 | $FilteredActions = $SortedActions | Where-Object { $_.FullFormattedMessage -like "*Alarm*" -or $_.FullFormattedMessage -like "*Yellow*" -or $_.FullFormattedMessage -like "*Green*" } 145 | } 146 | "Datastore" { 147 | $FilteredActions = $SortedActions | Where-Object { $_.FullFormattedMessage -like "*Datastore*" } 148 | } 149 | "Permission" { 150 | $FilteredActions = $SortedActions | Where-Object { $_.FullFormattedMessage -like "*Permission*" -or $_.FullFormattedMessage -like "*Role*" } 151 | } 152 | } # End switch 153 | } # End If 154 | Else { 155 | $FilteredActions = $SortedActions 156 | } 157 | Write-Verbose "`$FilteredActions contains $($FilteredActions.Count) events" 158 | 159 | foreach ( $FilteredAction in $FilteredActions) { 160 | 161 | # Extracting only the properties which have a value from the ConfigSpec property of events of the type VmReconfiguredEvent 162 | # This will be used to get only settings which were changed for VM "reconfigure" operations 163 | $NewConfigSettingsProps = $($FilteredAction.ConfigSpec) | Get-Member -MemberType Properties -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Name 164 | $NewConfigSettingsRelevantProps = $NewConfigSettingsProps | Where-Object { $($FilteredAction.ConfigSpec).$_ } 165 | Write-Debug "$NewConfigSettingsRelevantProps" 166 | 167 | # Building the properties of our custom output object 168 | $Props = [ordered]@{ 169 | 'Key' = $FilteredAction.Key 170 | 'CreatedTime' = $FilteredAction.CreatedTime 171 | 'UserName' = $FilteredAction.UserName 172 | 'Datacenter' = $FilteredAction.Datacenter.Name 173 | 'ComputeResource' = $FilteredAction.ComputeResource.Name 174 | 'Host' = $FilteredAction.Host.Name 175 | 'Vm' = $FilteredAction.Vm.Name 176 | 'Message' = $FilteredAction.FullFormattedMessage 177 | 'NewConfigSettings' = If ($FilteredAction.ConfigSpec) { $($FilteredAction.ConfigSpec) | Select-Object -Property $NewConfigSettingsRelevantProps } 178 | } 179 | $OutputObject = New-Object -TypeName PSObject -Property $Props 180 | $OutputObjectCollection += $OutputObject 181 | } 182 | } 183 | End { 184 | Write-Debug "Executing End block" 185 | Write-Verbose "`$FilteredActions contains $($FilteredActions.Count) events" 186 | 187 | $OutputObjectCollection 188 | } 189 | } -------------------------------------------------------------------------------- /Audit-vCenterOperation/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuBuisson/Powershell-VMware/65ce79f625b48b9247f6c7e66f4c408631660483/Audit-vCenterOperation/README.md -------------------------------------------------------------------------------- /ESXiLogDateTime/ESXiLogDateTime.format.ps1xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Default 6 | 7 | ESXi.LogEntry 8 | 9 | 10 | 11 | 12 | 19 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | TimeStamp 23 | 24 | 25 | LogMessage 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /ESXiLogDateTime/ESXiLogDateTime.psd1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuBuisson/Powershell-VMware/65ce79f625b48b9247f6c7e66f4c408631660483/ESXiLogDateTime/ESXiLogDateTime.psd1 -------------------------------------------------------------------------------- /ESXiLogDateTime/ESXiLogDateTime.psm1: -------------------------------------------------------------------------------- 1 | #Requires -Version 3 2 | function Get-ESXiLogWithDate { 3 | <# 4 | .SYNOPSIS 5 | Transforms ESXi log entries from plain text to Powershell objects with a TimeStamp property which is itself, a datetime object. 6 | 7 | .DESCRIPTION 8 | Transforms ESXi log entries from plain text to Powershell objects for further manipulation. 9 | Each log entry object has a property called Timestamp which is itself a datetime object, this allows the log entry objects to be easily filtered, altered, sorted, grouped, measured... 10 | 11 | .PARAMETER LogFiles 12 | The path of one or more log files to parse. It can also be one or more folders containing the log files to parse. 13 | Accepts wildcards. 14 | 15 | .PARAMETER Before 16 | To retrieve only the log entries where the timestamp is before the specified point in time. 17 | It must be a string in a format that can be converted to a datetime object. 18 | 19 | .PARAMETER After 20 | To retrieve only the log entries where the timestamp is after the specified point in time. 21 | It must be a string in a format that can be converted to a datetime object. 22 | 23 | .PARAMETER Yesterday 24 | To retrieve only the entries where the timestamp is within the day before the current date. 25 | 26 | .PARAMETER FromLastDays 27 | To retrieve only the entries logged from the specified number of days ago 28 | 29 | .EXAMPLE 30 | Get-ESXiLogWithDate -LogFiles C:\esx-esx2-4\var\log\h*.log -After "12/09/2014 11:55:00" -Before "12/09/2014 11:59:00" 31 | Retrieves all log entries from log files with a filename starting with "h" where the timestamp is between 11:55 and 11:59 the 9th of December 2014. 32 | 33 | .EXAMPLE 34 | Get-ESXiLogWithDate -LogFiles C:\esx-esx2-4\var\log\vmkernel.log -Yesterday 35 | Retrieves all log entries from the vmkernel log where the timestamp is from the day before the current date. 36 | 37 | .EXAMPLE 38 | Get-ESXiLogWithDate -LogFiles C:\esx-esx2-4\var\log\ -FromLastDays 7 39 | Retrieves all log entries from all files in C:\esx-esx2-4\var\log\ where the timestamp is from the last 7 days. 40 | 41 | .OUTPUTS 42 | Custom objects with typeName: ESXi.LogEntry 43 | #> 44 | [CmdletBinding()] 45 | 46 | Param( 47 | 48 | [Parameter(Position=0, 49 | HelpMessage="Specify the path of one or more log files to parse. Accepts wildcards.")] 50 | [string[]]$LogFiles = ".", 51 | 52 | [datetime]$Before = (Get-Date), 53 | 54 | [datetime]$After = ((Get-Date).AddYears(-10)).date, 55 | 56 | [switch]$Yesterday, 57 | 58 | [int]$FromLastDays 59 | ) 60 | 61 | Begin { 62 | if ( $Yesterday ) { 63 | Write-Verbose "`$Yesterday : $Yesterday." 64 | $Before = (Get-Date).Date 65 | $After = ((Get-Date).AddDays(-1)).Date 66 | } 67 | if ( $FromLastDays ) { 68 | Write-Verbose "`$FromLastDays : $FromLastDays." 69 | $After = (Get-Date).AddDays(-$FromLastDays) 70 | } 71 | 72 | Write-Verbose "`$Before : $Before ." 73 | Write-Verbose "`$After : $After ." 74 | } 75 | Process { 76 | 77 | foreach ( $LogFile in (Get-ChildItem $LogFiles) ) { 78 | Write-Verbose "`$LogFile : $LogFile" 79 | 80 | $LogContent = Get-Content -Path $LogFile.FullName | Where-Object { $_ -match "\d{4}-\d{2}-\d{2}T" } 81 | 82 | foreach ( $LogEntry in $LogContent ) { 83 | $SplitLogEntry = $LogEntry -split 'Z' 84 | 85 | # Defining the custom properties for the log entry object 86 | $CustomProps = [ordered]@{'Logfile'=$LogFile.Name 87 | 'TimeStamp'=$SplitLogEntry[0].Substring(0,19) -replace 'T',' ' -as [datetime] 88 | 'LogMessage'=$SplitLogEntry[1]} 89 | 90 | $LogEntryObj = New-Object -TypeName psobject -Property $CustomProps 91 | 92 | # Setting a typename for the output object to link it to a custom view 93 | $LogEntryObj.PSObject.Typenames.Insert(0,'ESXi.LogEntry') 94 | 95 | if (($LogEntryObj.TimeStamp -le $Before) -and ($LogEntryObj.TimeStamp -ge $After)) { 96 | Write-Output $LogEntryObj 97 | } 98 | 99 | } 100 | 101 | } 102 | } 103 | End {} 104 | } 105 | 106 | function Convert-ESXiLogToLocalTime { 107 | <# 108 | .SYNOPSIS 109 | Convert ESXi log entries TimeStamp property from UTC to local time. 110 | 111 | .DESCRIPTION 112 | Convert ESXi log entries TimeStamp property from UTC time to local time. 113 | Uses the time zone information from the local operating system. 114 | 115 | .PARAMETER LogEntries 116 | one or more ESXi log entries to convert to local time. The log entries can be piped from Get-ESXiLogWithDate 117 | 118 | .EXAMPLE 119 | Get-ESXiLogWithDate -LogFiles C:\esx-esx2-4\var\log\vmkernel.log -Yesterday | Convert-ESXiLogToLocalTime 120 | Retrieves all log entries from the vmkernel log where the timestamp is from the day before the current date and converts them to local time. 121 | 122 | .EXAMPLE 123 | $MyLogs = Get-ESXiLogWithDate -LogFiles C:\esx-esx2-4\var\log\ -FromLastDays 7 124 | $MyLogs | Convert-ESXiLogToLocalTime 125 | 126 | Retrieves all log entries from all files in C:\esx-esx2-4\var\log\ where the timestamp is from the last 7 days and stores them in the variable MyLog. 127 | Then, all the log entries stored in MyLog are piped to Convert-ESXiLogToLocalTime to convert them to local time. 128 | 129 | .OUTPUTS 130 | Custom objects with typeName: ESXi.LogEntry 131 | #> 132 | [CmdletBinding()] 133 | 134 | Param( 135 | 136 | [Parameter(Mandatory=$True, 137 | ValueFromPipeline=$True, 138 | HelpMessage="Specify one or more ESXi log entries to convert to local time. The log entries can be piped from Get-ESXiLogWithDate", 139 | Position=0)] 140 | [PSObject]$LogEntries 141 | ) 142 | 143 | Begin { 144 | $LocalTimeZone = [System.TimeZoneInfo]::Local 145 | Write-Verbose "`$LocalTimeZone : $LocalTimeZone ." 146 | } 147 | 148 | Process { 149 | foreach ( $LogEntry in $LogEntries ) { 150 | 151 | $LogEntry.TimeStamp = ($LogEntry.TimeStamp).ToLocalTime() 152 | Write-Output $LogEntry 153 | } 154 | 155 | } 156 | End {} 157 | } 158 | 159 | function Measure-ESXiLogTimeSpan { 160 | <# 161 | .SYNOPSIS 162 | Takes ESXi log entries, piped from the Get-ESXiLogWithDate or Convert-ESXiLogToLocalTime cmdlets and measures the duration covered by the logs. 163 | 164 | .DESCRIPTION 165 | Takes ESXi log entries, piped from the Get-ESXiLogWithDate or Convert-ESXiLogToLocalTime cmdlets and measures the duration covered by the logs. 166 | This duration is presented as a timespan object and the precision is to the second. 167 | 168 | 169 | .PARAMETER LogEntries 170 | One or more ESXi log entries, preferably piped from the Get-ESXiLogWithDate or Convert-ESXiLogToLocalTime cmdlets 171 | 172 | .EXAMPLE 173 | Get-ESXiLogWithDate -LogFiles C:\esx-esx2-4\var\log\vmkernel.log | Convert-ESXiLogToLocalTime 174 | Measures the duration covered by the logs in the file vmkernel.log. 175 | 176 | .EXAMPLE 177 | $MyLogs = Get-ESXiLogWithDate -LogFiles C:\esx-esx2-4\var\log 178 | $MyLogs | Convert-ESXiLogToLocalTime 179 | 180 | Retrieves all log entries from all files in C:\esx-esx2-4\var\log\ and stores them in the variable MyLog. 181 | Then, it measures the duration covered by the logs stored in the variable MyLog. 182 | 183 | .OUTPUTS 184 | One object of the type : System.TimeSpan 185 | #> 186 | [CmdletBinding()] 187 | 188 | Param( 189 | 190 | [Parameter(Mandatory=$True, 191 | ValueFromPipeline=$True, 192 | HelpMessage="Specify one or more ESXi log entries to convert to local time.` 193 | The log entries can be piped from Get-ESXiLogWithDate or from Convert-ESXiLogToLocalTime", 194 | Position=0)] 195 | [PSObject]$LogEntries 196 | ) 197 | 198 | Begin { 199 | $LogEntryCollection = @() 200 | } 201 | 202 | Process { 203 | foreach ( $LogEntry in $LogEntries ) { 204 | $LogEntryCollection += $LogEntry 205 | 206 | } 207 | } 208 | End { 209 | $FirstAndLastEntry = $LogEntryCollection | Sort-Object -Property TimeStamp | Select-Object -first 1 -Last 1 210 | 211 | $FirstTimeStamp = $FirstAndLastEntry[0].Timestamp 212 | Write-Verbose "`$FirstTimeStamp : $FirstTimeStamp " 213 | 214 | $LastTimeStamp = $FirstAndLastEntry[1].Timestamp 215 | Write-Verbose "`$LastTimeStamp : $LastTimeStamp " 216 | 217 | New-TimeSpan -Start $FirstTimeStamp -End $LastTimeStamp 218 | } 219 | } 220 | -------------------------------------------------------------------------------- /ESXiLogDateTime/README.md: -------------------------------------------------------------------------------- 1 | ##Description 2 | 3 | Esxi log files are plain text, which makes them quite difficult to process with Powershell. 4 | This Powershell module converts each line in ESXi log files into a Powershell object, allowing further processing. 5 | This module contains 3 cmdlets : **Get-ESXiLogWithDate**, **Convert-ESXiLogToLocalTime** and **Measure-ESXiLogTimeSpan**. 6 | 7 | It works with the following log file types : auth.log, esxupdate.log, fdm.log, hostd.log, hostd-probe.log, shell.log, 8 | storagerm.log, syslog.log, usb.log, vmauthd.log, vmkdevmgr.log, vmkernel.log, vmksummary.log, vmkwarning.log, vobd.log 9 | and vpxa.log. 10 | 11 | ##Get-ESXiLogWithDate : 12 | 13 | Converts each line in ESXi log files into a Powershell object. 14 | Each log entry object has a property called Timestamp which is itself a datetime object, this allows the log entry 15 | objects to be easily filtered, altered, sorted, grouped, measured, etc... 16 | It takes one or more log files (or folders) as input and outputs custom objects with typename : ESXi.LogEntry. 17 | 18 | There is a custom formatting view for the ESXi.LogEntry object so that its default formatting looks like the line in 19 | the original log file. 20 | 21 | ##Convert-ESXiLogToLocalTime : 22 | 23 | Converts the ESXi log entries TimeStamp property from UTC time to local time, using the time zone information from the local operating system. 24 | It takes one or more objects of type ESXi.LogEntry, generally piped from the **Get-ESXiLogWithDate** cmdlet and outputs objects of the same type, only their **TimeStamp** property is converted. 25 | 26 | ##Measure-ESXiLogTimeSpan : 27 | 28 | Takes one or more objects of type ESXi.LogEntry, piped from the **Get-ESXiLogWithDate** or **Convert-ESXiLogToLocalTime** cmdlets and measures the duration covered by the input logs. 29 | It outputs one object of the type : System.TimeSpan and the precision is to the second. 30 | 31 | ##Usage : 32 | 33 | Requires Powershell version 3. 34 | 35 | To use this module, the folder ESXiLogDateTime should be copied to C:\Program Files\WindowsPowerShell\Modules to leverage 36 | module auto-loading and to avoid having to edit the path of the root module file in the module manifest (ESXiLogDateTime.psd1). 37 | 38 | For the full help information and usage examples, run : 39 | 40 | `Help Get-ESXiLogWithDate -Full` 41 | 42 | or 43 | `Help Convert-ESXiLogToLocalTime -Full` 44 | 45 | or 46 | `Help Measure-ESXiLogTimeSpan -Full` 47 | -------------------------------------------------------------------------------- /Get-MultihomingInfo/Get-MultihomingInfo.psm1: -------------------------------------------------------------------------------- 1 | #Requires -Version 3 2 | 3 | function ConvertTo-DottedDecimalIP { 4 | <# 5 | .SYNOPSIS 6 | Returns a dotted decimal IP address from either an unsigned 32-bit integer or a dotted binary string. 7 | .DESCRIPTION 8 | ConvertTo-DottedDecimalIP uses a regular expression match on the input string to convert to an IP address. 9 | This function commes from : http://www.indented.co.uk/2010/01/23/powershell-subnet-math/ 10 | (c) 2008-2014 Chris Dent. 11 | .PARAMETER IPAddress 12 | A string representation of an IP address from either UInt32 or dotted binary. 13 | #> 14 | 15 | [CmdLetBinding()] 16 | param( 17 | [Parameter(Mandatory = $True, Position = 0, ValueFromPipeline = $True)] 18 | [String]$IPAddress 19 | ) 20 | 21 | Process { 22 | Switch -RegEx ($IPAddress) { 23 | "([01]{8}.){3}[01]{8}" { 24 | return [String]::Join('.', $( $IPAddress.Split('.') | ForEach-Object { [Convert]::ToUInt32($_, 2) } )) 25 | } 26 | "\d" { 27 | $IPAddress = [UInt32]$IPAddress 28 | $DottedIP = $( For ($i = 3; $i -gt -1; $i--) { 29 | $Remainder = $IPAddress % [Math]::Pow(256, $i) 30 | ($IPAddress - $Remainder) / [Math]::Pow(256, $i) 31 | $IPAddress = $Remainder 32 | } ) 33 | 34 | return [String]::Join('.', $DottedIP) 35 | } 36 | default { 37 | Write-Error "Cannot convert this format" 38 | } 39 | } 40 | } 41 | } 42 | function ConvertTo-DecimalIP { 43 | <# 44 | .SYNOPSIS 45 | Converts a Decimal IP address into a 32-bit unsigned integer. 46 | .DESCRIPTION 47 | ConvertTo-DecimalIP takes a decimal IP, uses a shift-like operation on each octet and returns a single UInt32 value. 48 | This function commes from : http://www.indented.co.uk/2010/01/23/powershell-subnet-math/ 49 | (c) 2008-2014 Chris Dent. 50 | .PARAMETER IPAddress 51 | An IP Address to convert. 52 | #> 53 | 54 | [CmdLetBinding()] 55 | param( 56 | [Parameter(Mandatory = $True, Position = 0, ValueFromPipeline = $True)] 57 | [Net.IPAddress]$IPAddress 58 | ) 59 | 60 | Process { 61 | $i = 3; $DecimalIP = 0; 62 | $IPAddress.GetAddressBytes() | ForEach-Object { $DecimalIP += $_ * [Math]::Pow(256, $i); $i-- } 63 | 64 | return [UInt32]$DecimalIP 65 | } 66 | } 67 | function Get-NetworkAddress { 68 | <# 69 | .SYNOPSIS 70 | Takes an IP address and subnet mask then calculates the network address for the range. 71 | .DESCRIPTION 72 | Get-NetworkAddress returns the network address for a subnet by performing a bitwise AND 73 | operation against the decimal forms of the IP address and subnet mask. Get-NetworkAddress 74 | expects both the IP address and subnet mask in dotted decimal format. 75 | This function commes from : http://www.indented.co.uk/2010/01/23/powershell-subnet-math/ 76 | (c) 2008-2014 Chris Dent. 77 | .PARAMETER IPAddress 78 | Any IP address within the network range. 79 | .PARAMETER SubnetMask 80 | The subnet mask for the network. 81 | #> 82 | 83 | [CmdLetBinding()] 84 | param( 85 | [Parameter(Mandatory = $True, Position = 0, ValueFromPipeline = $True)] 86 | [Net.IPAddress]$IPAddress, 87 | 88 | [Parameter(Mandatory = $True, Position = 1)] 89 | [Alias("Mask")] 90 | [Net.IPAddress]$SubnetMask 91 | ) 92 | 93 | Process { 94 | return ConvertTo-DottedDecimalIP ((ConvertTo-DecimalIP $IPAddress) -band (ConvertTo-DecimalIP $SubnetMask)) 95 | } 96 | } 97 | 98 | function Get-MultihomingInfo { 99 | 100 | <# 101 | .SYNOPSIS 102 | Obtains IP configuration information relative to multihoming of all the VMkernel interfaces for one or more ESXi hosts. 103 | 104 | .DESCRIPTION 105 | Obtains IP configuration information of all the VMkernel interfaces for one or more ESXi hosts and determines if the Multihoming configuration of the ESXi host is correct or not. 106 | 107 | A correct Multihoming configuration means that the VMkernel interfaces for each type of traffic are in different IP subnets. 108 | 109 | This cmdlet obtains the following information for each VMkernel interface : 110 | Name, IP Address, SubnetMask, Subnet, Type of VMkernel traffic and whether or not Multihoming is correctly configured. 111 | 112 | .PARAMETER VIServer 113 | To specify the vCenter Server to connect PowerCLI to. 114 | The default is Localhost. 115 | 116 | .PARAMETER VMhosts 117 | To specify one or more ESXi hosts. 118 | The default will query all ESXi hosts managed by the vCenter Server you are connected to in PowerCLI. 119 | This parameter has 2 aliases : "Hosts" and "Servers". 120 | 121 | .PARAMETER Cluster 122 | To query all the ESXi hosts in the specified cluster. 123 | 124 | .PARAMETER Quiet 125 | This mode only outputs a boolean value for each ESXi host : $True if Multihoming is correctly configured, $False if not. 126 | 127 | .EXAMPLE 128 | Get-MultihomingInfo -Cluster Production 129 | 130 | Obtains IP configuration information relative to multihoming for each ESXi host in the Production cluster. 131 | 132 | .EXAMPLE 133 | Get-VMHost EsxDev5* | Get-MultihomingInfo 134 | 135 | Obtains IP configuration information relative to multihoming for each ESXi host with a name starting with EsxDev5, using pipeline input. 136 | 137 | .EXAMPLE 138 | mhi (Get-VMHost Rack12-Esx18) -Quiet 139 | 140 | Outputs a boolean value stating whether multihoming is correctly configured or not for the ESXi host called Rack12-Esx18 , using the cmdlet alias "mhi". 141 | 142 | .LINK 143 | http://kb.vmware.com/kb/2010877 144 | #> 145 | [cmdletbinding()] 146 | param( 147 | [string]$VIServer = "localhost", 148 | [Parameter(ValueFromPipeline=$True, 149 | ValueFromPipelineByPropertyName=$True, 150 | Position=0)] 151 | [Alias('Hosts','Servers')] 152 | [VMware.VimAutomation.ViCore.Impl.V1.Inventory.VMHostImpl[]]$VMhosts, 153 | [string]$Cluster, 154 | [switch]$Quiet 155 | ) 156 | Begin { 157 | Set-PowercliConfiguration -InvalidCertificateAction "Ignore" -DisplayDeprecationWarnings:$false -Confirm:$false | Out-Null 158 | 159 | # Connecting to the vCenter Server if not already connected 160 | If (-not($defaultVIServer)) { 161 | Connect-VIServer $VIServer 162 | } 163 | Else { 164 | Write-Verbose "Already connected the vCenter Server: $defaultVIServer" 165 | } 166 | # Clearing the default parameter values in the function's scope 167 | $PSDefaultParameterValues.Clear() 168 | 169 | If (-not ($PSBoundParameters.ContainsKey('VMhosts')) ) { 170 | $VMhosts = Get-VMHost 171 | } 172 | 173 | # Getting all hosts from the cluster(s) if the -Cluster parameter is specified 174 | If ($Cluster) { 175 | $VMhosts = Get-Cluster -Name $Cluster | Get-VMHost 176 | } 177 | } 178 | Process { 179 | Foreach ($VMhost in $VMhosts) { 180 | Write-Verbose "--------------------- HOST : $VMhost.Name -------------------" 181 | 182 | # Preparing a collection to store information for each individual VMkernel interface 183 | $MultihomingInfoCollection = @() 184 | 185 | $VMKinterfaces = Get-VMHostNetworkAdapter -VMHost $VMhost -VMkernel 186 | Foreach ( $VMKinterface in $VMKinterfaces) { 187 | 188 | $MultihomingInfoProperties = [ordered]@{'ESXi Host'=$VMhost.Name 189 | 'Name'=$VMKinterface.Name 190 | 'IP Address'=$VMKinterface.IP 191 | 'SubnetMask'=$VMKinterface.SubnetMask 192 | 'Subnet'=Get-NetworkAddress $VMKinterface.IP $VMKinterface.SubnetMask 193 | 'Management'=$VMKinterface.ManagementTrafficEnabled 194 | 'VMotion'=$VMKinterface.VMotionEnabled 195 | 'FaultTolerance'=$VMKinterface.FaultToleranceLoggingEnabled 196 | 'VSANTraffic'=$VMKinterface.VsanTrafficEnabled 197 | 'MultihomingOK'=$False 198 | } 199 | 200 | # Building a custom object from the list of properties above 201 | $MultihomingInfoObj = New-Object -TypeName PSObject -Property $MultihomingInfoProperties 202 | 203 | # Building a collection of MultihomingInfo object for each ESXi host 204 | $MultihomingInfoCollection += $MultihomingInfoObj 205 | } 206 | 207 | $UniqueSubnets = ($MultihomingInfoCollection.Subnet | Sort-Object -Unique).length 208 | $MultihomingOK = $UniqueSubnets -ge $VMKinterfaces.length 209 | $MultihomingInfoCollection | ForEach-Object { $_.MultihomingOK=$MultihomingOK } 210 | 211 | If ($Quiet) { 212 | Write-Output $MultihomingOK 213 | } 214 | Else { 215 | Write-Output $MultihomingInfoCollection 216 | } 217 | } 218 | } 219 | End {} 220 | } 221 | 222 | # Setting an alias for the function Get-MultihomingInfo 223 | New-Alias -Name mhi -Value Get-MultihomingInfo 224 | Export-ModuleMember -Function * 225 | Export-ModuleMember -Alias * 226 | -------------------------------------------------------------------------------- /Get-MultihomingInfo/README.md: -------------------------------------------------------------------------------- 1 | ##Description : 2 | 3 | This module contains one cmdlet : **Get-MultihomingInfo**, which has the alias **mhi**. 4 | 5 | Obtains IP configuration information of all the VMkernel interfaces for one or more ESXi hosts and determines if the Multihoming configuration of the ESXi host is correct or not. 6 | 7 | A correct Multihoming configuration means that the VMkernel interfaces for each type of traffic are in different IP subnets. 8 | More information : http://kb.vmware.com/kb/2010877 9 | 10 | This cmdlet obtains the following information for each VMkernel interface : 11 | Name, IP Address, SubnetMask, Subnet, Type of VMkernel traffic and whether or not Multihoming is correctly configured. 12 | 13 | It requires Powershell version 3 and the PowerCLI snap-ins for vSphere. 14 | 15 | ##Parameters : 16 | 17 | **VIServer :** To specify the vCenter Server to connect PowerCLI to. 18 | The default is Localhost. 19 | 20 | **VMhosts :** To specify one or more ESXi hosts. 21 | The default will query all ESXi hosts managed by the vCenter Server you are connected to in PowerCLI. 22 | This parameter has 2 aliases : "Hosts" and "Servers". 23 | 24 | **Cluster :** To query all the ESXi hosts in the specified cluster. 25 | 26 | **Quiet :** This mode only outputs a boolean value for each ESXi host : $True if Multihoming is correctly configured, $False if not. 27 | -------------------------------------------------------------------------------- /Get-StorageViewsReport/Get-StorageViewsReport.psm1: -------------------------------------------------------------------------------- 1 | #Requires -Version 3 2 | 3 | function Get-StorageViewsReport { 4 | 5 | <# 6 | .SYNOPSIS 7 | Obtains storage capacity and utilization information by datastore, by VM or by host. 8 | 9 | .DESCRIPTION 10 | Obtains storage capacity and utilization information by datastore, by VM or by ESXi host. 11 | The default mode is by datastore. 12 | 13 | .PARAMETER VIServer 14 | To specify the vCenter Server to connect PowerCLI to. 15 | The default value is Localhost. 16 | 17 | .PARAMETER ByVM 18 | To obtain storage capacity and utilization information by VM. 19 | 20 | .PARAMETER VM 21 | Used in the "ByVM" mode, to specify one or more VMs. 22 | The default obtains information for all the VMs in the connected vCenter. 23 | 24 | .PARAMETER ByDatastore 25 | To obtain storage capacity and utilization information by datastore. 26 | 27 | .PARAMETER Datastore 28 | Used in the "ByDatastore" mode, to specify one or more datastores. 29 | The default obtains information for all the datastores in the connected vCenter. 30 | 31 | .PARAMETER ByHost 32 | To obtain storage capacity and utilization information by ESXi host. 33 | 34 | .PARAMETER Host 35 | Used in the "ByHost" mode, to specify one or more ESXi hosts. 36 | The default obtains information for all the hosts in the connected vCenter. 37 | 38 | .EXAMPLE 39 | Get-StorageViewsReport 40 | 41 | Obtains storage capacity and utilization information by datastore, for all the datastores in the connected vCenter. 42 | 43 | .EXAMPLE 44 | Get-Datastore iSCSI* | Get-StorageViewsReport | Format-Table -Auto 45 | 46 | Obtains storage capacity and utilization information by datastore, for the datastores which have a name starting with iSCSI, using pipeline input. 47 | Output is displayed as a table. 48 | 49 | .EXAMPLE 50 | Get-StorageViewsReport -ByVM 51 | Obtains storage capacity and utilization information by VM, for all the VMs in the connected vCenter. 52 | 53 | .EXAMPLE 54 | Get-StorageViewsReport -ByHost 55 | 56 | Obtains storage capacity and utilization information by ESXi host, for all the hosts in the connected vCenter. 57 | 58 | .EXAMPLE 59 | Get-VMHost ESXi5* | Get-StorageViewsReport 60 | Obtains storage capacity and utilization information by ESXi host, for the hosts which have a name starting with ESXi5, using pipeline input. 61 | 62 | .NOTES 63 | Author : Mathieu Buisson 64 | 65 | .LINK 66 | For the latest version of this module and its documentation, please refer to : 67 | https://github.com/MathieuBuisson/Powershell-VMware/tree/master/Get-StorageViewsReport 68 | 69 | #> 70 | 71 | [cmdletbinding(DefaultParameterSetName="ByDatastore")] 72 | param( 73 | [string]$VIServer = "localhost", 74 | 75 | [Parameter(ParameterSetName='ByVM')] 76 | [switch]$ByVM, 77 | 78 | [Parameter(ValueFromPipeline = $True, 79 | ParameterSetName='ByVM', 80 | ValueFromPipelineByPropertyName=$True,Position=0)] 81 | [VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl[]]$VM = (Get-VM), 82 | 83 | [Parameter(ParameterSetName='ByDatastore')] 84 | [switch]$ByDatastore, 85 | 86 | [Parameter(ValueFromPipeline = $True, 87 | ParameterSetName='ByDatastore', 88 | ValueFromPipelineByPropertyName=$True,Position=0)] 89 | [ValidateScript({ $_[0] -is [VMware.VimAutomation.ViCore.Impl.V1.DatastoreManagement.VmfsDatastoreImpl] -or $_[0] -is [VMware.VimAutomation.ViCore.Impl.V1.DatastoreManagement.NasDatastoreImpl] })] 90 | $Datastore = (Get-Datastore), 91 | 92 | [Parameter(ParameterSetName='ByHost')] 93 | [switch]$ByHost, 94 | 95 | [Parameter(ValueFromPipeline = $True, 96 | ParameterSetName='ByHost',Position=0)] 97 | [VMware.VimAutomation.ViCore.Impl.V1.Inventory.VMHostImpl[]]$Host = (Get-VMHost) 98 | ) 99 | 100 | Begin { 101 | # Checking if the required PowerCLI snapin (or module) is loaded, if not, loading it 102 | If (Get-Module VMware.VimAutomation.Core -ListAvailable -ErrorAction SilentlyContinue) { 103 | If (-not (Get-Module VMware.VimAutomation.Core -ErrorAction SilentlyContinue)) { 104 | Import-Module VMware.VimAutomation.Core 105 | } 106 | } 107 | Else { 108 | If (-not (Get-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue)) { 109 | Add-PSSnapin VMware.VimAutomation.Core 110 | } 111 | } 112 | Set-PowercliConfiguration -InvalidCertificateAction "Ignore" -DisplayDeprecationWarnings:$false -Confirm:$false | Out-Null 113 | 114 | If (-not($defaultVIServer)) { 115 | Connect-VIServer $VIServer | Out-Null 116 | } 117 | Else { 118 | Write-Verbose "Already connected the vCenter Server: $defaultVIServer" 119 | } 120 | If (-not ($PSBoundParameters.ContainsKey('VM')) ) { 121 | $VM = Get-VM 122 | } 123 | # Clearing the default parameter values in the function's scope 124 | $PSDefaultParameterValues.Clear() 125 | } 126 | Process { 127 | If ($PSCmdlet.ParameterSetName -eq "ByVM") { 128 | 129 | foreach ($iVM in $VM) { 130 | 131 | $iVMSnap = Get-Snapshot -VM $iVM.Name 132 | 133 | # Building the properties of our custom output object 134 | $ByVMProps = [ordered]@{'VM' = $iVM.Name 135 | 'SpaceUsedGB' = [Math]::Round($iVM.UsedSpaceGB, 2) 136 | 'ProvisionedSpaceGB' = [Math]::Round($iVM.ProvisionedSpaceGB, 2) 137 | 'SnapshotSpaceGB' = If ($iVMSnap) {[Math]::Round(($iVMSnap.SizeGB | Measure-Object -Sum).Sum, 2)} Else {0} 138 | 'Virtual Disks' = $iVM.HardDisks.Count} 139 | 140 | $ByVMObj = New-Object -TypeName PSObject -Property $ByVMProps 141 | $ByVMObj 142 | } 143 | } 144 | If ($PSCmdlet.ParameterSetName -eq "ByDatastore") { 145 | 146 | $SnapView = Get-VM | Get-Snapshot | Get-View 147 | 148 | foreach ($iDatastore in $Datastore) { 149 | 150 | $ByDatastoreVMs = Get-VM -Datastore $iDatastore 151 | 152 | $iDatastoreView = $SnapView | Where-Object { $_.Config.datastoreURL.Name -eq $($iDatastore.Name) } 153 | If ($iDatastoreView) { 154 | $iDatastoreSnapshots = Get-Snapshot * | Where-Object { $_.Id -in $($iDatastoreView.MoRef) } 155 | } 156 | 157 | # Building the properties of our custom output object 158 | $ByDatastoreProps = [ordered]@{'Datastore' = $iDatastore.Name 159 | 'State' = $iDatastore.State 160 | 'FSType' = $iDatastore.Type 161 | 'CapacityGB' = [Math]::Round($iDatastore.CapacityGB, 2) 162 | 'SpaceUsedGB' = [Math]::Round(($iDatastore.CapacityMB - $iDatastore.FreeSpaceMB) / 1024, 2) 163 | 'FreeSpaceGB' = [Math]::Round($iDatastore.FreeSpaceGB, 2) 164 | 'ProvisionedSpaceGB' = If ($ByDatastoreVMs) {[Math]::Round(($ByDatastoreVMs.ProvisionedSpaceGB | Measure-Object -Sum).Sum, 2)} Else {0} 165 | 'SnapshotSpaceGB' = If ($iDatastoreSnapshots) {[Math]::Round(($iDatastoreSnapshots.sizeGB | Measure-Object -Sum).Sum, 2)} Else {0} 166 | } 167 | 168 | $ByDatastoreObj = New-Object -TypeName PSObject -Property $ByDatastoreProps 169 | $ByDatastoreObj 170 | } 171 | } 172 | If ($PSCmdlet.ParameterSetName -eq "ByHost") { 173 | 174 | foreach ($iHost in $Host) { 175 | 176 | $ByHostVMs = Get-VM -Location $iHost 177 | 178 | If ($ByHostVMs) { 179 | $HostSnaps = Get-Snapshot -VM $ByHostVMs 180 | } 181 | 182 | # Building the properties of our custom output object 183 | $ByHostProps = [ordered]@{'Host' = $($iHost.Name) 184 | 'SpaceUsedGB' = If ($ByHostVMs) {[Math]::Round(($ByHostVMs.UsedSpaceGB | Measure-Object -Sum).Sum, 2)} Else {0} 185 | 'SnapshotSpaceGB' = If ($HostSnaps) {[Math]::Round(($HostSnaps.sizeGB | Measure-Object -Sum).Sum, 2)} Else {0} 186 | 'ProvisionedSpaceGB' = If ($ByHostVMs) {[Math]::Round(($ByHostVMs.ProvisionedSpaceGB | Measure-Object -Sum).Sum, 2)} Else {0} 187 | 'Virtual Disks' = If ($ByHostVMs) { ($($ByHostVMs).HardDisks | Measure-Object).Count } Else {0} 188 | } 189 | 190 | $ByHostObj = New-Object -TypeName PSObject -Property $ByHostProps 191 | $ByHostObj 192 | 193 | } 194 | } 195 | } 196 | 197 | } 198 | -------------------------------------------------------------------------------- /Get-StorageViewsReport/README.md: -------------------------------------------------------------------------------- 1 | ##Description : 2 | 3 | Obtains storage capacity and utilization information by datastore, by VM or by ESXi host. 4 | This provides the same information as the Storage Views reports, feature which has been removed from vSphere 6.0. 5 | The default mode is by datastore. 6 | 7 | Requires PowerCLI 5.5 or later and Powershell 3.0 or later. 8 | 9 | ##Parameters : 10 | 11 | **VIServer :** To specify the vCenter Server to connect PowerCLI to. The default is Localhost. 12 | 13 | **ByVM :** To obtain storage capacity and utilization information by VM. 14 | 15 | **VM :** Used in the "ByVM" mode, to specify one or more VMs. 16 | The default obtains information for all the VMs in the connected vCenter. 17 | 18 | **ByDatastore :** To obtain storage capacity and utilization information by datastore. 19 | 20 | **Datastore :** Used in the "ByDatastore" mode, to specify one or more datastores. 21 | The default obtains information for all the datastores in the connected vCenter. 22 | 23 | **ByHost :** To obtain storage capacity and utilization information by ESXi host. 24 | 25 | **Host :** Used in the "ByHost" mode, to specify one or more ESXi hosts. 26 | The default obtains information for all the hosts in the connected vCenter. 27 | -------------------------------------------------------------------------------- /HpAmsVib/HpAmsVib.psm1: -------------------------------------------------------------------------------- 1 | #Requires -Version 3 2 | 3 | function Find-BadHpAmsVib { 4 | 5 | <# 6 | .SYNOPSIS 7 | Looks for the hp-ams VIB installed on one or more ESXi hosts and displays them if they are in a version affected by the "Can't fork" bug. 8 | 9 | .DESCRIPTION 10 | Looks for the hp-ams VIB installed on one or more ESXi hosts and displays them if they are in a version affected by the "Can't fork" bug. 11 | More information on this bug : http://kb.vmware.com/kb/2085618 12 | 13 | No output means that there is no ESXi host with the hp-ams VIB, or the installed version(s) of the hp-ams VIB(s) are not affected. 14 | 15 | .PARAMETER VIServer 16 | To specify the vCenter Server to connect PowerCLI to. 17 | The default is Localhost. 18 | 19 | .PARAMETER VMhosts 20 | To specify one or more ESXi hosts. 21 | The default will query all ESXi hosts managed by the vCenter Server you are connected to in PowerCLI. 22 | This parameter has 2 aliases : "Hosts" and "Servers". 23 | 24 | .PARAMETER Cluster 25 | To query all the ESXi hosts in the specified cluster. 26 | 27 | .EXAMPLE 28 | Find-BadHpAmsVib -Cluster Production 29 | 30 | Looks for the hp-ams VIB installed on all the ESXi hosts in the Production cluster. 31 | 32 | .EXAMPLE 33 | Get-VMHost EsxDev5* | Find-BadHpAmsVib 34 | 35 | Looks for the hp-ams VIB installed on the ESXi hosts with a name starting with EsxDev5, using pipeline input. 36 | 37 | .LINK 38 | http://kb.vmware.com/kb/2085618 39 | #> 40 | 41 | [cmdletbinding()] 42 | param( 43 | [string]$VIServer = "localhost", 44 | [Parameter(ValueFromPipeline = $True, 45 | ValueFromPipelineByPropertyName=$True, 46 | Position=0)] 47 | [Alias('Hosts','Servers')] 48 | [VMware.VimAutomation.ViCore.Impl.V1.Inventory.VMHostImpl[]]$VMhosts, 49 | [string]$Cluster 50 | ) 51 | 52 | Begin { 53 | if(-not (Get-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue)) { 54 | Add-PSSnapin VMware.VimAutomation.Core } 55 | 56 | Set-PowercliConfiguration -InvalidCertificateAction "Ignore" -DisplayDeprecationWarnings:$false -Confirm:$false | Out-Null 57 | 58 | If (-not($defaultVIServer)) { 59 | Connect-VIServer $VIServer | Out-Null 60 | } 61 | Else { 62 | Write-Verbose "Already connected the vCenter Server: $defaultVIServer" 63 | } 64 | If (-not ($PSBoundParameters.ContainsKey('VMhosts')) ) { 65 | $VMhosts = Get-VMHost 66 | } 67 | # Getting all hosts from the cluster(s) if the -Cluster parameter is specified 68 | If ($PSBoundParameters.ContainsKey('Cluster')) { 69 | $VMhosts = Get-Cluster -Name $Cluster | Get-VMHost 70 | } 71 | # Clearing the default parameter values in the function's scope 72 | $PSDefaultParameterValues.Clear() 73 | } 74 | Process { 75 | 76 | Foreach ($VMhost in $VMhosts) { 77 | 78 | $ESXiVersion = $VMhost.Version 79 | 80 | switch -Wildcard ($ESXiVersion) { 81 | "5.0*" { $ProblemVersions = "500.10.0.0","500.9" } 82 | "5.1*" { $ProblemVersions = "500.10.0.0","500.9" } 83 | "5.5*" { $ProblemVersions = "550.10.0.0","550.9" } 84 | } 85 | 86 | $Esxcli = Get-EsxCli -VMHost $VMhost 87 | $VibList = $Esxcli.software.vib.list() 88 | $HpAmsVib = $VibList | Where-Object { $_.Name -eq "hp-ams" } 89 | 90 | if ($HpAmsVib) { 91 | 92 | if ($ProblemVersions | ForEach-Object { $HpAmsVib.version -match $_ } | Where-Object { $_ }) { 93 | 94 | # Building the properties of our custom output object 95 | $Props = [ordered]@{ 96 | 'VMHost' = $VMhost.Name 97 | 'ID' = $HpAmsVib.ID 98 | 'Name' = $HpAmsVib.Name 99 | 'Vendor' = $HpAmsVib.Vendor 100 | 'Version' = $HpAmsVib.Version 101 | 'InstallDate' = $HpAmsVib.InstallDate 102 | } 103 | New-Object -TypeName PSObject -Property $Props 104 | } 105 | } 106 | } 107 | } 108 | End { 109 | } 110 | } 111 | 112 | function Remove-BadHpAmsVib { 113 | 114 | <# 115 | .SYNOPSIS 116 | Looks for and uninstalls the hp-ams VIB installed on one or more ESXi hosts if they are in a version affected by the "Can't fork" bug. 117 | 118 | .DESCRIPTION 119 | Looks for and uninstalls the hp-ams VIB installed on one or more ESXi hosts if they are in a version affected by the "Can't fork" bug. 120 | More information on this bug : http://kb.vmware.com/kb/2085618 121 | 122 | .PARAMETER VIServer 123 | To specify the vCenter Server to connect PowerCLI to. 124 | The default is Localhost. 125 | 126 | .PARAMETER VMhosts 127 | To specify one or more ESXi hosts. 128 | The default will query all ESXi hosts managed by the vCenter Server you are connected to in PowerCLI. 129 | This parameter has 2 aliases : "Hosts" and "Servers". 130 | 131 | .PARAMETER Cluster 132 | To query all the ESXi hosts in the specified cluster. 133 | 134 | .PARAMETER Reboot 135 | If a hp-ams VIB has been uninstalled, puts the host in maintenance mode and reboots it. 136 | 137 | Assumes the host is in a DRS cluster in fully automated mode. 138 | If it is not in a DRS cluster, the running VMs will need to be evacuated manually for the host to enter maintenance mode successfully. 139 | If it is in a DRS cluster but not in fully automated mode, the DRS recommendations will need to be applied manually for the host to enter maintenance mode successfully. 140 | 141 | CAUTION : It does not exit maintenance mode after the reboot, so all hosts end up in maintenance mode and it will not do an orchestrated "evacuate & reboot" for all hosts in a cluster. 142 | For this reason, this parameter is not recommended when the VMHosts parameter contains several hosts. 143 | 144 | .EXAMPLE 145 | Remove-BadHpAmsVib -Cluster Production 146 | 147 | Looks for and uninstalls the hp-ams VIB installed on all the ESXi hosts in the Production cluster. 148 | 149 | .EXAMPLE 150 | Get-VMHost EsxDev5* | Remove-BadHpAmsVib -Reboot 151 | 152 | Looks for and uninstalls the hp-ams VIB installed on the ESXi hosts with a name starting with EsxDev5 and reboots the hosts for which the VIB was removed. 153 | 154 | .LINK 155 | http://kb.vmware.com/kb/2085618 156 | #> 157 | 158 | [cmdletbinding()] 159 | param( 160 | [string]$VIServer = "localhost", 161 | [Parameter(ValueFromPipeline = $True, 162 | ValueFromPipelineByPropertyName=$True, 163 | Position=0)] 164 | [Alias('Hosts','Servers')] 165 | [VMware.VimAutomation.ViCore.Impl.V1.Inventory.VMHostImpl[]]$VMhosts, 166 | [string]$Cluster, 167 | [switch]$Reboot 168 | ) 169 | 170 | Begin { 171 | if(-not (Get-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue)) { 172 | Add-PSSnapin VMware.VimAutomation.Core } 173 | 174 | Set-PowercliConfiguration -InvalidCertificateAction "Ignore" -DisplayDeprecationWarnings:$false -Confirm:$false | Out-Null 175 | 176 | If (-not($defaultVIServer)) { 177 | Connect-VIServer $VIServer | Out-Null 178 | } 179 | Else { 180 | Write-Verbose "Already connected the vCenter Server: $defaultVIServer" 181 | } 182 | If (-not ($PSBoundParameters.ContainsKey('VMhosts')) ) { 183 | $VMhosts = Get-VMHost 184 | } 185 | # Getting all hosts from the cluster(s) if the -Cluster parameter is specified 186 | If ($PSBoundParameters.ContainsKey('Cluster')) { 187 | $VMhosts = Get-Cluster -Name $Cluster | Get-VMHost 188 | } 189 | # Clearing the default parameter values in the function's scope 190 | $PSDefaultParameterValues.Clear() 191 | } 192 | Process { 193 | 194 | Foreach ($VMhost in $VMhosts) { 195 | 196 | $ESXiVersion = $VMhost.Version 197 | 198 | switch -Wildcard ($ESXiVersion) { 199 | "5.0*" { $ProblemVersions = "500.10.0.0","500.9" } 200 | "5.1*" { $ProblemVersions = "500.10.0.0","500.9" } 201 | "5.5*" { $ProblemVersions = "550.10.0.0","550.9" } 202 | } 203 | 204 | $Esxcli = Get-EsxCli -VMHost $VMhost 205 | $VibList = $Esxcli.software.vib.list() 206 | $HpAmsVib = $VibList | Where-Object { $_.Name -eq "hp-ams" } 207 | 208 | if ($HpAmsVib) { 209 | 210 | if ($ProblemVersions | ForEach-Object { $HpAmsVib.version -match $_ } | Where-Object { $_ }) { 211 | 212 | Write-Warning "Uninstalling hp-ams VIB from $VMHost ..." 213 | $Esxcli.software.vib.remove($false,$true,$true,$true,$HpAmsVib.Name) | Out-Null 214 | Write-Warning "Uninstallation done, but the system needs to be rebooted for the changes to be effective." 215 | 216 | if ($Reboot) { 217 | Set-VMHost -VMHost $VMhost -State maintenance 218 | Restart-VMHost -VMHost $VMhost -Confirm:$False 219 | } 220 | } 221 | Else { 222 | Write-Output "The version of the hp-ams VIB on $VMhost is not affected." 223 | } 224 | } 225 | Else { Write-Output "No hp-ams VIB on $VMhost." } 226 | } 227 | } 228 | End { 229 | } 230 | } 231 | -------------------------------------------------------------------------------- /HpAmsVib/README.md: -------------------------------------------------------------------------------- 1 | ##Description : 2 | 3 | This module contains 2 cmdlets : **Find-BadHpAmsVib** and **Remove-BadHpAmsVib**. 4 | It requires Powershell version 3 (or later) and the PowerCLI 5.5 (or later). 5 | 6 | ##Find-BadHpAmsVib : 7 | 8 | Looks for the hp-ams VIB installed on one or more ESXi hosts and displays them if they are in a version affected by the "Can't fork" bug. 9 | 10 | More information on this bug : http://kb.vmware.com/kb/2085618 . 11 | 12 | No output means that there is no ESXi host with the hp-ams VIB, or the installed version(s) of the hp-ams VIB(s) are not affected. 13 | 14 | ###Parameters : 15 | 16 | **VIServer :** To specify the vCenter Server to connect PowerCLI to. 17 | The default is Localhost. 18 | 19 | **VMhosts :** To specify one or more ESXi hosts. 20 | The default will query all ESXi hosts managed by the vCenter Server you are connected to in PowerCLI. 21 | This parameter has 2 aliases : "Hosts" and "Servers". 22 | 23 | **Cluster :** To query all the ESXi hosts in the specified cluster. 24 | 25 | ##Remove-BadHpAmsVib : 26 | 27 | Looks for and uninstalls the hp-ams VIB installed on one or more ESXi hosts if they are in a version affected by the "Can't fork" bug. 28 | 29 | More information on this bug : http://kb.vmware.com/kb/2085618 30 | 31 | ###Parameters : 32 | 33 | **VIServer :** To specify the vCenter Server to connect PowerCLI to. 34 | The default is Localhost. 35 | 36 | **VMhosts :** To specify one or more ESXi hosts. The default will query all ESXi hosts managed by the vCenter Server you are connected to in PowerCLI. 37 | This parameter has 2 aliases : "Hosts" and "Servers". 38 | 39 | **Cluster :** To query all the ESXi hosts in the specified cluster. 40 | 41 | **Reboot :** If a hp-ams VIB has been uninstalled, puts the host in maintenance mode and reboots it. 42 | 43 | Assumes the host is in a DRS cluster in fully automated mode. 44 | If it is not in a DRS cluster, the running VMs will need to be evacuated manually for the host to enter maintenance mode successfully. 45 | If it is in a DRS cluster but not in fully automated mode, the DRS recommendations will need to be applied manually for the host to enter maintenance mode successfully. 46 | 47 | ###CAUTION : 48 | 49 | It does not exit maintenance mode after the reboot, so all hosts end up in maintenance mode and it will not do an orchestrated "evacuate & reboot" for all hosts in a cluster. 50 | For this reason, this parameter is not recommended when the VMHosts parameter contains several hosts. 51 | -------------------------------------------------------------------------------- /Install-VCSA6/Install-VCSA6.psm1: -------------------------------------------------------------------------------- 1 | function Install-VCSA6 { 2 | 3 | <# 4 | .SYNOPSIS 5 | Deploys a vCenter Server Appliance 6.0 using PowerCLI and a default OVA file from the vCenter Appliance 6.0 ISO file. 6 | 7 | .DESCRIPTION 8 | Deploys a vCenter Server Appliance 6.0 using PowerCLI and a default OVA file. 9 | Works for a vCenter Server Appliance with embedded Platform Services Controller, for an external (already deployed) Platform Services Controller and also for the Platform Services Controller only. 10 | It requires PowerCLI 5.8 or later because it uses the cmdlets Get-OvfConfiguration and Import-VApp. 11 | 12 | To get the default OVA file, first mount the vCenter Appliance ISO file (VMware_VCSA-all-6.0.0-xxxx.iso) and copy the file \Your_ISO_Content\vcsa\vmware-vcsa to a location of your choice. 13 | Rename the copy of the file vmware-vcsa to vmware-vcsa.ova . 14 | 15 | The resulting VM is powered off. 16 | 17 | .PARAMETER VIServer 18 | To specify the vCenter Server to connect PowerCLI to. 19 | The default is Localhost. 20 | 21 | .PARAMETER OVAFilePath 22 | To specify the full path for the vCenter Appliance OVA file. 23 | 24 | .PARAMETER Cluster 25 | The cluster to which the vCenter Appliance will be deployed. 26 | 27 | .PARAMETER VMName 28 | The name of the virtual machine which will be deployed as a new vCenter appliance. 29 | 30 | .PARAMETER VMNetwork 31 | The name of the portgroup the vCenter Appliance will be connected to. 32 | 33 | .PARAMETER DeploymentOption 34 | To specify a value representing an appliance size and deployment mode. 35 | 36 | Explanation of the possible values : 37 | 38 | tiny : a vCenter Server + embedded Platform Services Controller for up to 10 hosts and 100 VMs. 39 | small : a vCenter Server + embedded Platform Services Controller for up to 100 hosts and 1000 VMs. 40 | medium : a vCenter Server + embedded Platform Services Controller for up to 400 hosts and 4000 VMs. 41 | large : a vCenter Server + embedded Platform Services Controller for up to 1000 hosts and 10,000 VMs. 42 | management-tiny : vCenter Server only, for up to 10 hosts and 100 VMs. 43 | management-small : vCenter Server only, for up to 100 hosts and 1000 VMs. 44 | management-medium : vCenter Server only, for up to 400 hosts and 4000 VMs. 45 | management-large : vCenter Server only, for up to 1000 hosts and 10,000 VMs. 46 | infrastructure : Platform Services Controller only. 47 | 48 | .PARAMETER IPAddress 49 | IPV4 address of the vCenter Appliance 50 | 51 | .PARAMETER FQDN 52 | Full DNS name of the vCenter Appliance 53 | 54 | .PARAMETER SubnetMaskCIDR 55 | Subnet mask of the vCenter Appliance's IP address in CIDR notation. 56 | The default value is 24, which corresponds to 255.255.255.0 57 | 58 | .PARAMETER Gateway 59 | IP address of the vCenter appliance's default gateway 60 | 61 | .PARAMETER DNSServer 62 | IP address of the vCenter appliance's DNS server 63 | 64 | .PARAMETER RootPasswd 65 | vCenter Appliance root password 66 | 67 | .PARAMETER SSHEnabled 68 | To specify if SSH is enabled on the vCenter appliance or not. 69 | The default is $True. 70 | Set it to $False to disable SSH on the vCenter Appliance. 71 | 72 | .PARAMETER SSODomainName 73 | To specify the SSO domain name. 74 | The default is "vsphere.local". 75 | 76 | .PARAMETER SSOSiteName 77 | To specify the SSO site name. 78 | The default is "Default-First-Site". 79 | 80 | .PARAMETER SSOAdminPasswd 81 | Password for the administrator account in the SSO domain. 82 | 83 | .PARAMETER NTPServer 84 | To specify the NTP server which the vCenter Appliance will use to sync time. 85 | The default is : "0.pool.ntp.org". 86 | 87 | .PARAMETER DiskStorageFormat 88 | To specify the storage format for the disks of the imported VMs. 89 | When you set this parameter, you set the storage format for all virtual machine disks in the OVF package. 90 | 91 | This parameter accepts the following values : Thin, Thick, and EagerZeroedThick. 92 | The default is Thin. 93 | The vCenter Appliance has 11 virtual disks, so this parameter has a big impact on the storage space and the deployment time. 94 | 95 | 96 | .EXAMPLE 97 | Install-VCSA6 "C:\Deployment\vmware-vcsa.ova" -Cluster "Test-Cluster" -VMName "VCSA" -VMNetwork "Production" -DeploymentOption "tiny" -IPAddress "192.168.1.151" -Gateway "192.168.1.1" -DNSServer "192.168.1.1" -RootPasswd "Passw0rd!" -SSOAdminPasswd "Passw0rd!" 98 | 99 | Deploys a vCenter Appliance 6.0 using the OVA file C:\Deployment\vmware-vcsa.ova and the default parameter values. 100 | 101 | .EXAMPLE 102 | dir C:\Deployment\*.ova | Install-VCSA6 -Cluster "Test-Cluster" -VMName "VCSA" -VMNetwork "Production" -DeploymentOption "tiny" -IPAddress "192.168.1.151" -Gateway "192.168.1.1" -DNSServer "192.168.1.1" -RootPasswd "Passw0rd!" -SSOAdminPasswd "Passw0rd!" 103 | 104 | Deploys a vCenter Appliance 6.0 using pipeline input for -OVAFilePath and the default parameter values. 105 | 106 | .LINK 107 | https://github.com/lamw/PowerCLI-Deployment/tree/master/VCSA%206.0%20Embedded 108 | 109 | http://www.virtuallyghetto.com/2015/02/ultimate-automation-guide-to-deploying-vcsa-6-0-part-1-embedded-node.html 110 | #> 111 | [cmdletbinding()] 112 | param( 113 | [string]$VIServer = "localhost", 114 | [Parameter(Mandatory = $True,ValueFromPipeline = $True,Position=0)] 115 | [ValidateScript({ Test-Path $_ })] 116 | [String]$OVAFilePath, 117 | 118 | [Parameter(Mandatory = $True)] 119 | [string]$Cluster, 120 | 121 | [Parameter(Mandatory = $True)] 122 | [string]$VMName, 123 | 124 | [Parameter(Mandatory = $True)] 125 | [string]$VMNetwork, 126 | 127 | [Parameter(Mandatory = $True)] 128 | [ValidateSet('tiny','small','medium','large','management-tiny','management-small','management-medium','management-large','infrastructure', ignorecase=$False)] 129 | [string]$DeploymentOption, 130 | 131 | [Parameter(Mandatory = $True)] 132 | [ValidateScript({ [bool]($_ -as [ipaddress]) })] 133 | [string]$IPAddress, 134 | 135 | [string]$FQDN = "", 136 | 137 | [ValidateRange(8,31)] 138 | [int]$SubnetMaskCIDR = 24, 139 | 140 | [Parameter(Mandatory = $True)] 141 | [ValidateScript({ [bool]($_ -as [ipaddress]) })] 142 | [string]$Gateway, 143 | 144 | [Parameter(Mandatory = $True)] 145 | [ValidateScript({ [bool]($_ -as [ipaddress]) })] 146 | [string]$DNSServer, 147 | 148 | [Parameter(Mandatory = $True)] 149 | [string]$RootPasswd, 150 | 151 | [Boolean]$SSHEnabled = $True, 152 | 153 | [string]$SSODomainName = "vsphere.local", 154 | 155 | [string]$SSOSiteName = "Default-First-Site", 156 | 157 | [Parameter(Mandatory = $True)] 158 | [string]$SSOAdminPasswd, 159 | 160 | [string]$NTPServer = "0.pool.ntp.org", 161 | 162 | [ValidateSet('Thin','Thick','EagerZeroedThick')] 163 | $DiskStorageFormat = "Thin" 164 | ) 165 | 166 | Begin { 167 | # Checking if the required PowerCLI snapin is loaded, if not, loading it 168 | if(-not (Get-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue)) { 169 | Add-PSSnapin VMware.VimAutomation.Core } 170 | 171 | Set-PowercliConfiguration -InvalidCertificateAction "Ignore" -DisplayDeprecationWarnings:$false -Confirm:$false | Out-Null 172 | 173 | if (-not($defaultVIServer)) { 174 | Connect-VIServer $VIServer | Out-Null 175 | } 176 | Else { 177 | Write-Verbose "Already connected the vCenter Server: $defaultVIServer" 178 | } 179 | # Clearing the default parameter values in the function's scope 180 | $PSDefaultParameterValues.Clear() 181 | } 182 | Process { 183 | # Loading the OVA configuration into a variable for further manipulation 184 | $OvfConfig = Get-OvfConfiguration -Ovf $OVAFilePath 185 | 186 | $VMHost = Get-Cluster $Cluster | Get-VMHost | Sort-Object -Property MemoryGB | Select-Object -First 1 187 | $Datastore = $VMHost | Get-datastore | Sort-Object -Property FreeSpaceGB -Descending | Select -first 1 188 | $Network = Get-VirtualPortGroup -Name $VMNetwork -VMHost $VMHost 189 | 190 | # Filling out the OVF/OVA configuration properties 191 | 192 | $OvfConfig.NetworkMapping.Network_1.value = $Network 193 | $OvfConfig.DeploymentOption.value = $DeploymentOption 194 | $OvfConfig.IpAssignment.IpProtocol.value = "IPv4" 195 | $ovfconfig.Common.guestinfo.cis.appliance.net.addr.family.value = "ipv4" 196 | $OvfConfig.Common.guestinfo.cis.appliance.net.mode.value = "static" 197 | $OvfConfig.Common.guestinfo.cis.appliance.net.addr_1.value = $IPAddress 198 | $OvfConfig.Common.guestinfo.cis.appliance.net.pnid.value =if ($FQDN) {$FQDN} Else {$IPAddress} 199 | $OvfConfig.Common.guestinfo.cis.appliance.net.prefix.value = $SubnetMaskCIDR.ToString() 200 | $OvfConfig.Common.guestinfo.cis.appliance.net.gateway.value = $Gateway 201 | $OvfConfig.Common.guestinfo.cis.appliance.net.dns.servers.value = $DNSServer 202 | $OvfConfig.Common.guestinfo.cis.appliance.root.passwd.value = $RootPasswd 203 | $OvfConfig.Common.guestinfo.cis.appliance.ssh.enabled.value = $SSHEnabled.ToString() 204 | $OvfConfig.Common.guestinfo.cis.vmdir.domain_name.value = $SSODomainName 205 | $OvfConfig.Common.guestinfo.cis.vmdir.site_name.value = $SSOSiteName 206 | $OvfConfig.Common.guestinfo.cis.vmdir.password.value = $SSOAdminPasswd 207 | $OvfConfig.Common.guestinfo.cis.appliance.ntp.servers.value = $NTPServer 208 | 209 | # Deploying the OVF/OVA using the above configuration properties 210 | 211 | Import-VApp -Source $OVAFilePath -OvfConfiguration $OvfConfig -Name $VMName -VMHost $VMHost -Datastore $Datastore -DiskStorageFormat $DiskStorageFormat 212 | } 213 | End { 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /Install-VCSA6/README.md: -------------------------------------------------------------------------------- 1 | ##Description : 2 | 3 | This module contains 1 cmdlet : **Install-VCSA6** . 4 | 5 | Based on William Lam's scripts : Deployment-Embedded.ps1, Deployment-PSC.ps1 and Deployment-VCSA-Mgmt.ps1 in: https://github.com/lamw/PowerCLI-Deployment 6 | 7 | More information : 8 | http://www.virtuallyghetto.com/2015/02/ultimate-automation-guide-to-deploying-vcsa-6-0-part-1-embedded-node.html 9 | 10 | It deploys a vCenter Server Appliance 6.0 using PowerCLI and a default OVA file. 11 | 12 | It works for a vCenter Server Appliance with embedded Platform Services Controller, for an external (already deployed) Platform Services Controller and also for the Platform Services Controller only. 13 | 14 | It requires PowerCLI 5.8 or later because it uses the cmdlets **Get-OvfConfiguration** and **Import-VApp**. 15 | 16 | To get the default OVA file, first mount the vCenter Appliance ISO file (VMware_VCSA-all-6.0.0-xxxx.iso) and copy the file _**\Your_ISO_Content\vcsa\vmware-vcsa**_ to a location of your choice. Then, rename the copy of the file vmware-vcsa to vmware-vcsa.ova . 17 | 18 | The resulting VM is powered off. 19 | 20 | ##Parameters : 21 | 22 | **VIServer :** To specify the vCenter Server to connect PowerCLI to. 23 | The default is Localhost. 24 | 25 | **OVAFilePath :** To specify the full path for the vCenter Appliance OVA file. 26 | 27 | **Cluster :** The cluster to which the vCenter Appliance will be deployed. 28 | 29 | **VMName :** The name of the virtual machine which will be deployed as a new vCenter appliance. 30 | 31 | **VMNetwork :** The name of the portgroup the vCenter Appliance will be connected to. 32 | 33 | **DeploymentOption :** To specify a value representing an appliance size and deployment mode. 34 | 35 | Explanation of the possible values : 36 | 37 | tiny : a vCenter Server + embedded Platform Services Controller for up to 10 hosts and 100 VMs. 38 | small : a vCenter Server + embedded Platform Services Controller for up to 100 hosts and 1000 VMs. 39 | medium : a vCenter Server + embedded Platform Services Controller for up to 400 hosts and 4000 VMs. 40 | large : a vCenter Server + embedded Platform Services Controller for up to 1000 hosts and 10,000 VMs. 41 | management-tiny : vCenter Server only, for up to 10 hosts and 100 VMs. 42 | management-small : vCenter Server only, for up to 100 hosts and 1000 VMs. 43 | management-medium : vCenter Server only, for up to 400 hosts and 4000 VMs. 44 | management-large : vCenter Server only, for up to 1000 hosts and 10,000 VMs. 45 | infrastructure : Platform Services Controller only. 46 | 47 | **IPAddress :** IPV4 address of the vCenter Appliance 48 | 49 | **FQDN :** Full DNS name of the vCenter Appliance 50 | 51 | **SubnetMaskCIDR :** Subnet mask of the vCenter Appliance's IP address in CIDR notation. The default value is 24, which corresponds to 255.255.255.0 52 | 53 | **Gateway :** IP address of the vCenter appliance's default gateway 54 | 55 | **DNSServer :** IP address of the vCenter appliance's DNS server 56 | 57 | **RootPasswd :** vCenter Appliance root password 58 | 59 | **SSHEnabled :** To specify if SSH is enabled on the vCenter appliance or not. 60 | The default is $True. 61 | Set it to $False to disable SSH on the vCenter Appliance. 62 | 63 | **SSODomainName :** To specify the SSO domain name. 64 | The default is "vsphere.local". 65 | 66 | **SSOSiteName :** To specify the SSO site name. 67 | The default is "Default-First-Site". 68 | 69 | **SSOAdminPasswd :** Password for the administrator account in the SSO domain. 70 | 71 | **NTPServer :** To specify the NTP server which the vCenter Appliance will use to sync time. 72 | The default is : "0.pool.ntp.org". 73 | 74 | **DiskStorageFormat :** To specify the storage format for the disks of the imported VMs. 75 | When you set this parameter, you set the storage format for all virtual machine disks in the OVF package. 76 | This parameter accepts the following values : **Thin**, **Thick**, and **EagerZeroedThick**. 77 | The default is **Thin**. 78 | The vCenter Appliance has 11 virtual disks, so this parameter has a big impact on the storage space and the deployment time. 79 | -------------------------------------------------------------------------------- /NonDefaultHostSettings/NonDefaultHostSettings.psm1: -------------------------------------------------------------------------------- 1 | #Requires -Version 3 2 | 3 | function Get-NonDefaultAdvancedSettings { 4 | 5 | <# 6 | .SYNOPSIS 7 | Obtains all the advanced settings which are not at their default value for one or more host. 8 | 9 | .DESCRIPTION 10 | Obtains all the advanced settings which are not at their default value for one or more ESXi host. 11 | It output the setting(s) path, description, default value, and current value. 12 | 13 | .PARAMETER VIServer 14 | To specify the vCenter Server to connect PowerCLI to. 15 | The default value is Localhost. 16 | 17 | .PARAMETER VMHost 18 | To specify one or more ESXi hosts. 19 | The default will query all ESXi hosts managed by the vCenter Server you are connected to in PowerCLI. 20 | This parameter has 2 aliases : "Hosts" and "Servers". 21 | 22 | .EXAMPLE 23 | Get-NonDefaultAdvancedSettings 24 | 25 | Obtains the advanced settings which are not at their default value for all ESXi hosts managed by the connected vCenter. 26 | 27 | .EXAMPLE 28 | Get-VMHost esxi55ga-3.vcloud.local | Get-NonDefaultAdvancedSettings 29 | 30 | Obtains the advanced settings which are not at their default value for the host esxi55ga-3.vcloud.local, using pipeline input. 31 | #> 32 | 33 | [cmdletbinding()] 34 | param( 35 | [string]$VIServer = "localhost", 36 | 37 | [Parameter(ValueFromPipeline = $True, 38 | ValueFromPipelineByPropertyName=$True, 39 | Position=0)] 40 | [Alias('Hosts','Servers')] 41 | [VMware.VimAutomation.ViCore.Impl.V1.Inventory.VMHostImpl[]]$VMHost = (Get-VMHost) 42 | ) 43 | 44 | Begin { 45 | # Checking if the required PowerCLI snapin is loaded, if not, loading it 46 | If(-not (Get-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue)) { 47 | Add-PSSnapin VMware.VimAutomation.Core } 48 | 49 | Set-PowercliConfiguration -InvalidCertificateAction "Ignore" -DisplayDeprecationWarnings:$false -Confirm:$false -WhatIf:$False | Out-Null 50 | 51 | If (-not($defaultVIServer)) { 52 | Connect-VIServer $VIServer | Out-Null 53 | } 54 | Else { 55 | Write-Verbose "Already connected the vCenter Server: $defaultVIServer" 56 | } 57 | 58 | # Clearing the default parameter values in the function's scope 59 | $PSDefaultParameterValues.Clear() 60 | } 61 | 62 | Process { 63 | 64 | Foreach ($iVMhost in $VMhost) { 65 | 66 | $EsxCli = Get-EsxCli -VMHost $iVMhost 67 | 68 | $HostNonDefaultSettings = $($EsxCli.system.settings.advanced.list($True, $NUll, $Null)) 69 | $HostNonDefaultSettings | Add-Member -MemberType NoteProperty -Name "Host" -Value $($iVMhost.Name) 70 | $HostNonDefaultSettings 71 | } 72 | } 73 | End { 74 | } 75 | } 76 | function Set-AdvancedSettingsToDefault { 77 | 78 | <# 79 | .SYNOPSIS 80 | Sets the advanced settings which are not at their default value back to their default, for one or more host. 81 | 82 | .DESCRIPTION 83 | Sets the advanced settings which are not at their default value back to their default, for one or more ESXi host. 84 | Supports -WhatIf parameter to see what modification(s) it would perform, without actually performing them. 85 | Supports -Confirm parameter to prompt for confirmation before performing the modification(s). 86 | 87 | .PARAMETER VIServer 88 | To specify the vCenter Server to connect PowerCLI to. 89 | The default value is Localhost. 90 | 91 | .PARAMETER VMHost 92 | To specify one or more ESXi hosts. 93 | The default will query all ESXi hosts managed by the vCenter Server you are connected to in PowerCLI. 94 | This parameter has 2 aliases : "Hosts" and "Servers". 95 | 96 | .EXAMPLE 97 | Set-AdvancedSettingsToDefault 98 | 99 | Sets the advanced settings which are not at their default value back to their default, for all ESXi hosts managed by the connected vCenter. 100 | 101 | .EXAMPLE 102 | Get-VMHost esxi55ga-3.vcloud.local | Set-AdvancedSettingsToDefault 103 | 104 | Sets the advanced settings which are not at their default value back to their default, for the host esxi55ga-3.vcloud.local, using pipeline input. 105 | 106 | .EXAMPLE 107 | Get-VMHost "ESXi55*" | Set-AdvancedSettingsToDefault -WhatIf 108 | 109 | Displays the modification(s) it would perform on the hosts which have a name starting with "ESXi55", without actually performing them. 110 | #> 111 | 112 | [cmdletbinding(SupportsShouldProcess)] 113 | param( 114 | [string]$VIServer = "localhost", 115 | 116 | [Parameter(ValueFromPipeline = $True, 117 | ValueFromPipelineByPropertyName=$True, 118 | Position=0)] 119 | [Alias('Hosts','Servers')] 120 | [VMware.VimAutomation.ViCore.Impl.V1.Inventory.VMHostImpl[]]$VMHost = (Get-VMHost) 121 | ) 122 | 123 | Begin { 124 | # Checking if the required PowerCLI snapin is loaded, if not, loading it 125 | If(-not (Get-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue)) { 126 | Add-PSSnapin VMware.VimAutomation.Core } 127 | 128 | Set-PowercliConfiguration -InvalidCertificateAction "Ignore" -DisplayDeprecationWarnings:$false -Confirm:$false | Out-Null 129 | 130 | If (-not($defaultVIServer)) { 131 | Connect-VIServer $VIServer | Out-Null 132 | } 133 | Else { 134 | Write-Verbose "Already connected the vCenter Server: $defaultVIServer" 135 | } 136 | # Clearing the default parameter values in the function's scope 137 | $PSDefaultParameterValues.Clear() 138 | } 139 | 140 | Process { 141 | Foreach ($iVMhost in $VMhost) { 142 | 143 | $HostSettingsToRemediate = Get-NonDefaultAdvancedSettings -VMHost $iVMhost 144 | 145 | Foreach ($SettingToRemediate in $HostSettingsToRemediate) { 146 | 147 | $SettingToRemediate | Add-Member -MemberType NoteProperty -Name "SettingName" -Value $($SettingToRemediate.Path).Trim("/").replace("/",".") 148 | 149 | # The default value can be in the DefaultStringValue property if the type is "string" or in the DefaultIntValue if the type is "integer" 150 | # Building a custom property, named "DefaultValue", based on this logic 151 | 152 | If ( $($SettingToRemediate.Type) -eq "string" ) { 153 | $SettingToRemediate | Add-Member -MemberType NoteProperty -Name "DefaultValue" -Value $($SettingToRemediate.DefaultStringValue) 154 | } 155 | Else { 156 | $SettingToRemediate | Add-Member -MemberType NoteProperty -Name "DefaultValue" -Value $($SettingToRemediate.DefaultIntValue) 157 | } 158 | 159 | If ( $PSCmdlet.ShouldProcess("Advanced Setting : $($SettingToRemediate.SettingName) on $($iVMhost.Name)","Setting to value : $($SettingToRemediate.DefaultValue)") ) { 160 | Get-AdvancedSetting -Entity $iVMhost -Name $($SettingToRemediate.SettingName) | Set-AdvancedSetting -Value $($SettingToRemediate.DefaultValue) -Confirm:$false 161 | } 162 | } 163 | } 164 | } 165 | End { 166 | } 167 | } -------------------------------------------------------------------------------- /NonDefaultHostSettings/README.md: -------------------------------------------------------------------------------- 1 | ##Description : 2 | 3 | This module contains 2 cmdlets : **Get-NonDefaultAdvancedSettings** and **Set-AdvancedSettingsToDefault**. 4 | It requires PowerCLI 5.5 or later and Powershell 3.0 or later. 5 | 6 | ##Get-NonDefaultAdvancedSettings : 7 | 8 | Obtains all the advanced settings which are not at their default value for one or more ESXi host. 9 | It output the setting(s) path, description, default value, and current value. 10 | 11 | ###Parameters : 12 | 13 | **VIServer :** To specify the vCenter Server to connect PowerCLI to. The default is Localhost. 14 | 15 | **VMHost :** To specify one or more ESXi hosts. 16 | The default will query all ESXi hosts managed by the vCenter Server you are connected to in PowerCLI. 17 | This parameter has 2 aliases : "Hosts" and "Servers". 18 | 19 | ##Set-AdvancedSettingsToDefault : 20 | 21 | Sets the advanced settings which are not at their default value back to their default, for one or more ESXi host. 22 | Supports -WhatIf parameter to see what modification(s) it would perform, without actually performing them. 23 | Supports -Confirm parameter to prompt for confirmation before performing the modification(s). 24 | 25 | ###Parameters : 26 | 27 | **VIServer :** To specify the vCenter Server to connect PowerCLI to. The default is Localhost. 28 | 29 | **VMHost :** To specify one or more ESXi hosts. 30 | The default will query all ESXi hosts managed by the vCenter Server you are connected to in PowerCLI. 31 | This parameter has 2 aliases : "Hosts" and "Servers". -------------------------------------------------------------------------------- /PowerCLI Fundamentals Training/Demo_Examples.ps1: -------------------------------------------------------------------------------- 1 | ############################################## 2 | # Demo Preparation 3 | ############################################## 4 | Set-ExecutionPolicy -ExecutionPolicy Unrestricted 5 | Set-Location $env:USERPROFILE 6 | Remove-VIRole -Role "custom*" 7 | Get-VM | Get-Snapshot | Remove-Snapshot 8 | Get-VM | Get-Random -Count 2 | New-Snapshot -Name "Before_Demo_Snaps" 9 | Get-VM -Name VCSA,Debian7-VM | Set-VM -NumCpu 2 10 | 11 | Clear-Host 12 | 13 | ############################################### 14 | # What is Powershell 15 | ############################################### 16 | 17 | $PSVersionTable 18 | 19 | 20 | ################################################ 21 | # What is PowerCLI ? 22 | ################################################ 23 | 24 | Get-PSSnapin 25 | 26 | # What Powershell Snapins do we get with PowerCLI ? 27 | Get-PSSnapin -Registered 28 | 29 | #Let's load all of them into our Powershell session : 30 | Add-PSSnapin -Name vmware* 31 | 32 | Get-PSSnapin 33 | 34 | #How many cmdlets does the main PowerCLI snapin provide ? 35 | Get-Command -PSSnapin VMware.VimAutomation.Core | Measure-Object 36 | 37 | #How many cmdlets does PowerCLI provide in total ? 38 | Get-Command -PSSnapin VMware* | Measure-Object 39 | 40 | #Besides cmdlets , it also adds 2 Powershell providers 41 | Get-PSProvider | Where-Object { $_.Name -like "Vim*" } | 42 | Select-Object -Property Name,Drives 43 | 44 | cd vmstores: 45 | 46 | # Checking the PowerCLI version 47 | Get-PowerCLIVersion 48 | 49 | # Let's connect to a vCenter Server : 50 | Connect-VIServer 192.168.1.10 51 | 52 | # and verify our connection : 53 | $DefaultVIServer 54 | 55 | clear-host 56 | 57 | break 58 | 59 | ################################################### 60 | # Feature number 1 : discoverability 61 | ################################################### 62 | 63 | Get-Verb 64 | 65 | # Let's say we want to configure Distributed vSwitches but you are not sure of the cmdlet name 66 | Get-Command -Verb Set -noun "*switch*" 67 | 68 | # Let's find out how we can start SSH on a host with IntelliSense (Ctrl+Space) 69 | Get-VMHost esxi55ga-1.vcloud.local | Start-V 70 | 71 | # Learning how to use a cmdlet with a little bit of GUI 72 | Show-Command Set-VMHostAuthentication 73 | 74 | # Get the help information in a separate window 75 | Get-Help Set-VMHostAuthentication -ShowWindow 76 | 77 | # If you learn better by looking at examples : 78 | Get-Help Remove-Datastore -Examples 79 | 80 | # To get all sections from the cmdlet help : 81 | Get-Help Remove-Datastore -full | more 82 | 83 | # Help topics on specific concepts : 84 | Get-Help about_* 85 | 86 | # Search through all the helpfiles for a keyword 87 | Get-Help conditional 88 | 89 | Clear-Host 90 | 91 | break 92 | 93 | ##################################################### 94 | # Interpreting the cmdlet help 95 | ##################################################### 96 | 97 | Get-Help Set-VMHostAuthentication -Full | more 98 | 99 | # This cmdlet has 2 parameter sets : one to join a domain, and one to leave a domain 100 | 101 | # -WhatIf : to look at what a potentially destructive command would do, without actually doing it 102 | Get-VMHost | Remove-Inventory -WhatIf 103 | 104 | help Get-Snapshot -Full 105 | 106 | Get-Snapshot -VM (Get-VM) -Name "*snap*" 107 | 108 | # When parameter names are explicitly typed, the order doesn't matter : 109 | Get-Snapshot -Name "*snap*"-VM (Get-VM) 110 | 111 | # These are positional parameters : 112 | Get-Snapshot (Get-VM) "*snap*" 113 | 114 | # Now, the order (or position) matters : 115 | Get-Snapshot "*snap*" (Get-VM) 116 | 117 | Clear-Host 118 | 119 | break 120 | 121 | ##################################################### 122 | # Aliases 123 | ##################################################### 124 | 125 | # cd works just like in the traditional command prompt 126 | cd $env:USERPROFILE 127 | 128 | # dir as well 129 | dir 130 | 131 | # Even ls ! 132 | ls 133 | 134 | # But these are just aliases to a cmdlet 135 | Get-Alias -Name dir 136 | Get-Alias -name ls 137 | 138 | # Which itself, has yet another alias : gci 139 | Get-Alias -Definition Get-ChildItem 140 | 141 | # Listing all the alias using the Alias Powershell drive 142 | ls alias:\ 143 | 144 | # PowerCLI doesn't add any aliases : 145 | Get-Alias -Definition "*vm*" 146 | 147 | # But you can create your own : 148 | New-Alias -Name scratch -Value Set-VMHostDiagnosticPartition 149 | 150 | # TO DO IN THE CONSOLE 151 | # The path of our current Powershell profile 152 | $profile 153 | 154 | # Does this file actually exist ? 155 | Test-Path $profile 156 | 157 | # So let's open it : 158 | ise $profile 159 | 160 | Clear-Host 161 | 162 | break 163 | 164 | ##################################################### 165 | # What is an object and what is it made of ?​ 166 | ##################################################### 167 | 168 | # Everything is an object : 169 | $TextVariable = "I'm just plain text" 170 | 171 | # This is an object of the type [string] : 172 | $TextVariable.GetType() | Select-Object -Property Name, Fullname 173 | 174 | $NumberVariable = 19 175 | 176 | # This is an object of the type [int] : 177 | $NumberVariable | Get-Member 178 | 179 | # Apparently, [int] objects have no properties but they have quite a few methods 180 | 181 | # Let's see what we can do with a [datetime] object : 182 | Get-Date | Get-Member 183 | 184 | # Let's look at a few of its properties : 185 | Get-Date | Select-Object -Property Day, DayOfWeek, DayOfYear 186 | 187 | # We can very easily extract the month information from a date : 188 | Get-Date | Select-Object -Property Month 189 | 190 | # To see all the properties and thir values : 191 | Get-Date | Format-List * 192 | 193 | # Let's try one of its methods : 194 | (Get-Date).AddDays(-7) 195 | 196 | Clear-Host 197 | 198 | break 199 | 200 | ##################################################### 201 | # Variables 202 | ##################################################### 203 | 204 | $MyVar = Get-VMHost 205 | 206 | # Looking at its content : 207 | $MyVar 208 | 209 | # Looking at it by its name : 210 | Get-Variable -Name MyVar 211 | 212 | # Listing all the variables in the current Powershell session 213 | gci variable:\ 214 | 215 | # We can expand our variable from inside double quotes : 216 | Write-Output "Here is a list of ESXi hosts : $MyVar" 217 | 218 | # But not from inside single quotes : 219 | Write-Output 'Here is a list of ESXi hosts : $MyVar' # Expanding some variables but not all : Write-Output "Here are the hosts in `$MyVar : $MyVar" # Weird output in the ISE --> do it in a Powershell console # Browsing invidual objects in a collection : $MyVar[0] $MyVar[-1] $Myvar[-1].Name $MyVar.Name # PowerCLI-specific variables $DefaultVIServer and $DefaultVIServers $DefaultVIServer Clear-Host break ###################################################### # Filtering objects ###################################################### # Getting only the VMs which are powered on : Get-VM | Where-Object -FilterScript { $_.PowerState -eq "PoweredOn" } # Getting the ESXi hosts with the name starting with "esxi55" Get-VMHost | Where { $_.Name -like "esxi55*" } # If there are hundreds of hosts, the following is more efficient : Get-VMHost -Name esxi55* # Simplified Where-Object syntax introduced with Powershell version 3 : Get-VM | where NumCpu -gt 1 # -like is not case sensitive : Get-VMHost | Where-Object { $_.Name -like "EsXi55gA-1*" } # If you really want a case sensitive match, use -clike : Get-VMHost | Where-Object { $_.Name -clike "EsXi55gA-1*" } # Multiple conditions in the filterscript with "-and" : Get-VMHost | Where { $_.Parent -eq (Get-Cluster Test-Cluster) -and $_.MaxEVCMode -eq "intel-Westmere" } | Select-Object Name,MaxEVCMode # we can filter on something else than just a property # For example : getting all the VMs which have at least one snapshot : Get-VM | Where-Object { Get-Snapshot -VM $_ } # Checking if we have VMs reaching the 32 snapshots limit : Get-VM | Where-Object { (Get-Snapshot -VM $_).count -ge 32 } Clear-Host break ##################################################### # Building multi-commands one-liners ##################################################### # Out-default at the end of the pipeline : Get-VM | where NumCpu -gt 1 | Out-Default # output to file using the traditional syntax Get-VM | where NumCpu -gt 1 > SMP_VMs.txt # or, using the Powershell syntax Get-VM | where NumCpu -gt 1 | Out-File SMP_VMs.txt # Checking the file : notepad SMP_VMs.txt # Reading the file directly in the console : Get-Content -Path SMP_VMs.txt # output to file : there is nothing left in the pipeline : Get-VM | where NumCpu -gt 1 | Out-File SMP_VMs.txt | Get-Member # Output both to a file and to the pipeline : Get-VM | where NumCpu -gt 1 | Tee-Object -FilePath SMP_VMs.txt -Append # Checking the file again: notepad SMP_VMs.txt # Exporting to a CSV file : Get-VM | where NumCpu -gt 1 | Export-Csv -Path SMP_VMs.csv -NoTypeInformation notepad SMP_VMs.csv # Reconstructing the original objects from the CSV file : Import-Csv -Path SMP_VMs.csv Import-Csv -Path SMP_VMs.csv | Format-Table -Property Name,Powerstate,NumCPU,MemoryMB # VMHost objects are complex objects, with a whole hierarchy of sub-properties : $MyVar[0].NetworkInfo $MyVar[0].NetworkInfo.DnsAddress # XML is better at handling multi-value and hierarchical properties : $MyVar[0] | Export-Clixml -Path Host.xml notepad Host.xml # Complex One-liner : # Getting all powered off VMs with more than 1 vCPU and reduce their number of vCPU to 1 Get-VM | where NumCpu -gt 1 | where PowerState -eq PoweredOff | Set-VM -NumCpu 1 clear-Host break ###################################################### # Sorting, grouping, selecting, measuring ###################################################### # Getting the VMs which are consuming the most storage space Get-VM | Sort-Object -Property UsedSpaceGB -Descending # Now we see the property on which we are ordering : Get-VM | Sort-Object -Property UsedSpaceGB -Descending | Select-Object Name,UsedSpaceGB # Getting the 2 VMs which are consuming the most storage space Get-VM | Sort-Object -Property UsedSpaceGB -Descending | Select-Object Name,UsedSpaceGB -First 2 # Getting the VM which is consuming the least storage space : Get-VM | Sort-Object -Property UsedSpaceGB -Descending | Select-Object Name,UsedSpaceGB -Last 1 # Let's get all the vmkernel interfaces and group them by host : Get-VMHost | Get-VMHostNetworkAdapter -VMKernel | Group-Object -Property VMHost # Now, let's expand these groups : Get-VMHost | Get-VMHostNetworkAdapter -VMKernel | Group-Object -Property VMHost | Select-Object -ExpandProperty Group # The same information + the host name : Get-VMHost | Get-VMHostNetworkAdapter -VMKernel | Select-Object VMHost,Name,Mac,IP,SubnetMask | Sort-Object VMHost,Name # Counting the number of vCenter events in the last 7 days : Get-VIEvent -Start (Get-Date).AddDays(-7) | Measure-Object # Measuring on a specific property : Get-Datastore | Measure-Object -Property FreeSpaceGB -Maximum -Minimum -Average Clear-Host break ###################################################### # Creating custom objects ###################################################### # Getting the storage devices of one ESXi host : $Devices = Get-ScsiLun -VmHost esxi55ga-1.vcloud.local $Devices | Select-Object -prop CanonicalName,LunType,IsLocal # Let's what type of objects we have : $Devices | Get-Member $Select_Properties_Device = $Devices | Select-Object -prop CanonicalName,LunType,IsLocal -First 1 $Select_Properties_Device | Get-Member # Get-Member tells us the object type is preserved. # But the object only have the properties we have selected and all the methods are stripped out Get-Datastore | Select-Object -Property Name,FreeSpaceMB,CapacityMB # What if we want these values in Gigabytes ? Get-Datastore | Select-Object -Property Name, @{Label="FreeSpaceGB";Expression={ $_.FreeSpaceMB / 1024 }}, @{Label="CapacityMB";Expression={ $_.CapacityMB / 1024 }} # Let's round these ugly numbers at 2 decimal places : Get-Datastore | Select-Object -Property Name, @{Label="FreeSpaceGB";Expression={ [Math]::Round($_.FreeSpaceMB / 1024,2) }}, @{Label="CapacityMB";Expression={ [Math]::Round($_.CapacityMB / 1024,2) }} # If we just want the percentage of free space : Get-Datastore | Select-Object -Property Name, @{Label="FreeSpace %";Expression={ $_.FreeSpaceMB / $_.CapacityMB * 100 }} # Ugly numbers again, let's get rid of the decimals : Get-Datastore | Select-Object -Property Name, @{Label="FreeSpace %";Expression={ ($_.FreeSpaceMB / $_.CapacityMB * 100) -as [int] }} # A weird but very simple way to create a new object from scratch : $car = "" | Select-Object Color,Brand,model # Is it an actual object ? $car | Get-Member Clear-Host break ###################################################### # How the pipeline works ###################################################### # We need to restart the CIM service on the host esxi55ga-1.vcloud.local Get-VMHostService -vmhost esxi55ga-1.vcloud.local # We know the service is there, so why the below doesn't work ?? Get-VMHostService -vmhost esxi55ga-1.vcloud.local | Restart-VMHostService -HostService sfcbd-watchdog help Restart-VMHostService -Full # The only parameter which accepts pipeline input is -HostService # It accepts pipeline input by value (object type) # What object type is it expecting ? # So, this should work : Get-VMHostService -vmhost esxi55ga-1.vcloud.local | Where key -eq sfcbd-watchdog | Restart-VMHostService # Is this going to work ? Get-Process VpxClient | Get-ChildItem # Why ? # Let's look at which parameters of Get-ChildItem can take pipeline input : Get-Help ls -Full | more # -Path : by value and by property name # Does the object which was in the pipeline have a property named "Path" ? Get-Process VpxClient | Get-Member -Name Path Clear-Host break ###################################################### # Formatting the ouput ###################################################### Get-ResourcePool # Format as a list : Get-ResourcePool | Format-List -Property * # Format as a table : Get-ResourcePool | Format-Table # Same ouput as without display : Get-ResourcePool | Format-Table -Property Parent,MemLimitMB, @{Label="CpuLimitGhz";Expression={ $_.CpuLimitMHz / 1024 }} # automatically size the width of the columns : Get-ResourcePool | Format-Table -Property Parent,MemLimitMB, @{Label="CpuLimitGhz";Expression={ $_.CpuLimitMHz / 1024 }} -AutoSize # Now, let's sort it by our property "CpuLimitGhz" Get-ResourcePool | Format-Table -Property Parent,MemLimitMB, @{Label="CpuLimitGhz";Expression={ $_.CpuLimitMHz / 1024 }} | Sort-Object -Property CpuLimitGhz Get-VM | Format-Wide Get-VM | Format-Wide -Column 4 # Gotcha number 1 : Get-VM | Format-Wide | Start-VM # Why ? Get-VM | Format-Wide | Get-Member # Gotcha number 2 : Get-Command -verb Format | Format-Table -AutoSize # Let's try this formatting provided by VMware : Get-ScsiLun esxi55ga-1.vcloud.local -CanonicalName naa.6000eb360d5d81c000000000000000bb | Get-Vmhostdisk | Get-VMHostDiskPartition | Format-VMHostDiskPartition "PrettyFormatting" -WhatIf # Oops! Fortunately, we used the -WhatIf parameter Clear-Host break ##################################################### # Enumerating objects in a pipeline ##################################################### # Let's get the latest snapshot for each VM and add a description according to their place in the snapshot tree Get-VM | Get-Snapshot | ForEach-Object { if ( -not $_.children ) { Set-Snapshot $_ -Description "Latest Snap" } Else { Set-Snapshot $_ -Description "Not the latest snap. The latest is $_"}} # Checking the result : Get-VM | Get-Snapshot | Format-Table Name,Description -AutoSize # Creating an exact copy of the vCenter admins role for later customization Get-VIRole | Where-Object { $_.Name -like "*Admin*" } | ForEach-Object { New-VIRole -Name "custom_$_" -Privilege (Get-VIPrivilege -Role $_) } Clear-Host break ###################################################### # Comparing objects ###################################################### # Let's modify our role custom_ResourcePoolAdministrator # Let's add the privilege to manage the hosts' system resources $Priv = Get-VIPrivilege -Id Host.Config.Resources Set-VIRole -Role custom_ResourcePoolAdministrator -AddPrivilege $Priv # Now, let's compare our custom role with the original : $Original = Get-VIRole -Name ResourcePoolAdministrator $Custom = Get-VIRole -Name custom_ResourcePoolAdministrator # Let's see what we have in our variables : $custom $custom.PrivilegeList # So, what we want to compare is the property "PrivilegeList" of our roles : Compare-Object -ReferenceObject $Original.PrivilegeList -DifferenceObject $Custom.PrivilegeList Clear-Host break ###################################################### # Script security ###################################################### # Let's double-click the .psm1 files on the desktop # DO THIS IN THE CONSOLE cd C:\Users\Administrator\Desktop Get-ChildItem "*.ps*" # let's run our Hello_World script : Hello_World.ps1 # We know the file is in our current working directory and we know the file name is correct # We get a very instructive suggestion .\Hello_World.ps1 # What is our current executionPolicy : Get-ExecutionPolicy Set-ExecutionPolicy -ExecutionPolicy AllSigned # Now, let's see if we can run our Hello_World script : .\Hello_World.ps1 # Does it have a signature ? Get-Content .\Hello_World.ps1 Set-ExecutionPolicy -ExecutionPolicy RemoteSigned # Can we run our script, now ? .\Hello_World.ps1 Clear-Host break ###################################################### # Other types of pipeline ###################################################### Write-Error "This is an error !" Write-Warning "This is a warning !" Write-Verbose "This is verbose information." Write-Verbose "This is verbose information." -Verbose Write-Debug "Hardcore debugging info" -Debug # This command also acts as a breakpoint # Notice the nested prompt # To go out of this "debug mode" : exit Clear-Host break ###################################################### # PowerCLI views ###################################################### Get-VMHost -Name esxi55ga-1.vcloud.local | Get-View # Or : Get-View -ViewType Hostsystem -Filter @{"Name"="esxi55ga-1.vcloud.local"} # Let's store it into a variable to play with it $HostView = Get-View -ViewType Hostsystem -Filter @{"Name"="esxi55ga-1.vcloud.local"} $HostView.Hardware $HostView.Hardware.PciDevice $HostView.Hardware.PciDevice | Format-Table Id,VendorName,DeviceName $HostView.Config.MultipathState.path # No APD, good # Let's create a view for all our VMs : $VMsView = Get-View -ViewType VirtualMachine $VMsView | Select-Object -Property Guest.ToolsRunningStatus, @{ Label="VM Name";Expression={ (Get-VIObjectByVIView -VIView $_).Name }} # We need to build properties from hashtables to access sub-properties : $VMsView | Select-Object -Property @{ Label="ToolsStatus";Expression={ $_.Guest.ToolsRunningStatus }}, @{ Label="VM Name";Expression={ (Get-VIObjectByVIView -VIView $_).Name }} # Let's open a VM console to one VM in the vSphere client # Getting the number of console connections for each VM : $VMsView | select @{ Label="VM Name";Expression={ (Get-VIObjectByVIView -VIView $_).Name }}, @{ Label="MKS Connections";Expression={ $_.Runtime.NumMksConnections }} | ft -AutoSize # Extensiondata another way of generating a view from an existing object : $VMs = Get-VM $VMs.ExtensionData # We get the exact same information as a view $VMs.ExtensionData.Runtime.NumMksConnections Clear-Host break ###################################################### # Get-EsxCli ###################################################### # Storing the esxcli interface for a host into a variable $ESXCli = Get-EsxCli -VMHost esxi55ga-1.vcloud.local # Getting the system UUID (to troubleshoot a lock issue) $ESXCli.system.uuid.get() # getting the same information for all ESXi hosts : $VMHosts = Get-VMHost Foreach ($VMhost in $VMhosts) { $Esxcli = Get-EsxCli -VMHost $VMhost $ESXCli.system.uuid.get() } # Getting all installed VIBs from all hosts : $VMHosts = Get-VMHost Foreach ($VMhost in $VMhosts) { $Esxcli = Get-EsxCli -VMHost $VMhost $VibList = $Esxcli.software.vib.list() $VibList | Add-Member -MemberType NoteProperty -Name "Host" -Value $VMHost $VibList | ft Host,Name,Vendor,Version -AutoSize } # Uninstalling a VIB : $Esxcli.software.vib.remove($false,$true,$true,$true,"hp-ams") # What else can we do with our $ESXCli object ? A lot : explorer http://rvdnieuwendijk.com/2012/08/19/how-to-list-all-the-powercli-esxcli-commands/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Powershell-VMware 2 | ================= 3 | 4 | Powershell or PowerCLI modules for VMware administration/troubleshooting tasks 5 | -------------------------------------------------------------------------------- /Register-AllOrphanedVmx/README.md: -------------------------------------------------------------------------------- 1 | ##Description : 2 | 3 | 4 | 5 | This module contains 1 cmdlet : **Register-AllOrphanedVmx**. 6 | It requires PowerShell version 3 7 | (or later) and PowerCLI 5.5 (or later). 8 | 9 | 10 | 11 | ##Register-AllOrphanedVmx : 12 | 13 | 14 | 15 | ###Parameters : 16 | 17 | 18 | 19 | **VIServer :** To specify the vCenter Server to connect PowerCLI to. 20 | The default is Localhost. 21 | If not specified, it defaults to localhost . 22 | 23 | 24 | 25 | **ResourcePool :** To specify in which cluster or resource pool the VMs should be registered into. 26 | 27 | 28 | 29 | ###Examples : 30 | 31 | 32 | 33 | -------------------------- EXAMPLE 1 -------------------------- 34 | 35 | PS C:\>Register-AllOrphanedVmx -ResourcePool ( Get-Cluster DevCluster ) 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /Register-AllOrphanedVmx/Register-AllOrphanedVmx.psm1: -------------------------------------------------------------------------------- 1 | #Requires -Version 3 2 | 3 | function Register-AllOrphanedVmx { 4 | <# 5 | .PARAMETER VIServer 6 | To specify the vCenter Server to connect PowerCLI to. 7 | The default is Localhost. 8 | 9 | .PARAMETER ResourcePool 10 | To specify in which cluster or resource pool the VMs should be registered into. 11 | 12 | .EXAMPLE 13 | Register-AllOrphanedVmx -ResourcePool ( Get-Cluster DevCluster ) 14 | 15 | #> 16 | 17 | [cmdletbinding()] 18 | param( 19 | [string]$VIServer = "localhost", 20 | [Parameter(Position=0,Mandatory=$True)] 21 | $ResourcePool 22 | ) 23 | 24 | Begin { 25 | # Checking if the required PowerCLI snapin (or module) is loaded, if not, loading it 26 | If (Get-Module VMware.VimAutomation.Core -ListAvailable -ErrorAction SilentlyContinue) { 27 | If (-not (Get-Module VMware.VimAutomation.Core -ErrorAction SilentlyContinue)) { 28 | Import-Module VMware.VimAutomation.Core 29 | } 30 | } 31 | Else { 32 | If (-not (Get-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue)) { 33 | Add-PSSnapin VMware.VimAutomation.Core 34 | } 35 | } 36 | Set-PowercliConfiguration -InvalidCertificateAction "Ignore" -DisplayDeprecationWarnings:$false -Confirm:$false | Out-Null 37 | 38 | If (-not($defaultVIServer)) { 39 | Connect-VIServer $VIServer | Out-Null 40 | } 41 | Else { 42 | Write-Verbose "Already connected the vCenter Server: $defaultVIServer" 43 | } 44 | } 45 | Process { 46 | $SearchResult = @() 47 | foreach($Datastore in (Get-Datastore -Verbose:$False)) { 48 | # Set up Search for .VMX Files in Datastore 49 | $ds = Get-Datastore -Name $Datastore -Verbose:$False| %{Get-View $_.Id -Verbose:$False} 50 | $SearchSpec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec 51 | $SearchSpec.matchpattern = "*.vmx" 52 | $dsBrowser = Get-View $ds.browser -Verbose:$False 53 | $DatastorePath = "[" + $ds.Summary.Name + "]" 54 | 55 | # Find all .VMX file paths in Datastore, filtering out ones with .snapshot (Useful for NetApp NFS) 56 | 57 | If ($dsBrowser.SearchDatastoreSubFolders($DatastorePath, $SearchSpec) | 58 | Where-Object {$_.FolderPath -notmatch ".snapshot"} | %{$_.FolderPath + ($_.File | select Path).Path} | 59 | Where-Object {$_ -match '\.vmx$'}) { 60 | $SearchResult += $dsBrowser.SearchDatastoreSubFolders($DatastorePath, $SearchSpec) | 61 | Where-Object {$_.FolderPath -notmatch ".snapshot"} | %{$_.FolderPath + ($_.File | select Path).Path} | 62 | Where-Object {$_ -match '\.vmx$'} 63 | } 64 | } 65 | 66 | Write-Verbose "VMX files paths : `n" 67 | Foreach ($VmxFile in $SearchResult) { 68 | Write-Verbose "$VmxFile" 69 | } 70 | 71 | $RegisteredVMs = Get-VM 72 | Write-Verbose "Registered VMs names : `n" 73 | Foreach ($RegisteredVM in $RegisteredVMs) { 74 | Write-Verbose $($RegisteredVM.Name) 75 | } 76 | 77 | # Deriving the VM names from the VMX files name 78 | $TrimmedVmxPaths = $searchresult -replace '\.vmx$','' 79 | $NamesFromVmx = $TrimmedVmxPaths -replace '(?s)^.*/','' | Sort-Object 80 | $NamesFromRegisteredVMs = $RegisteredVMs | Sort-Object -Property Name | Select-Object -ExpandProperty Name 81 | 82 | $CompareResult = Compare-Object -ReferenceObject $NamesFromRegisteredVMs -DifferenceObject $NamesFromVmx 83 | 84 | $UnregisteredVMX = $CompareResult | Where-Object { $_.SideIndicator -eq "=>" } 85 | 86 | Foreach ($Unregistered in $UnregisteredVMX) { 87 | 88 | $VmxFilePath = $SearchResult | Where-Object { $_ -like "*$($Unregistered.InputObject)*.vmx" } 89 | Write-Verbose "Registering VM with name : $($Unregistered.InputObject) from VMX file : $($VmxFilePath)" 90 | New-VM -VMFilePath $VmxFilePath -ResourcePool $ResourcePool 91 | } 92 | } 93 | End { 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /Reset-ISdatabase/README.md: -------------------------------------------------------------------------------- 1 | ##Description : 2 | 3 | Powershell script (packaged as a module) to automate the procedure of http://kb.vmware.com/kb/2042200 . 4 | It reset the database of the Inventory Service for vCenter 5.1 and 5.5. 5 | It requires Powershell 2.0 or later. 6 | It works only if the Inventory Service and SSO are installed on the same machine as the vCenter Server. 7 | 8 | ##Usage : 9 | 10 | Because it is a module, you first need to import it, with the following command : 11 | `Import-Module C:\Path\To\Reset-ISdatabase.psm1` 12 | 13 | Then, you can use the **Reset-ISdatabase** command. 14 | You can also use its alias : **risdb**. 15 | 16 | It needs to be run as Administrator. 17 | 18 | It has quite a few parameters, but it can be run without any parameter if the vCenter server is in the 19 | default configuration. 20 | 21 | ##Parameters : 22 | 23 | **-NoPrompt :** By default, the script prompts you to confirm that you understand the potential consequences of resetting 24 | the Inventory Service database. 25 | If you want to suppress this prompt, use the -NoPrompt parameter. 26 | 27 | **-DBpath :** Allows you to specify the path to the Inventory Service Database, if it's not the default path. 28 | 29 | **-ScriptsPath :** Allows you to specify the path to the Inventory Service Scripts folder, if it's not the default path. 30 | 31 | **-vCenterPort :** Allows you to specify the vCenter HTTPS port, if it's not the default. 32 | 33 | **-ISport :** Allows you to specify the Inventory Service port, if it's not the default. 34 | 35 | **-LookupServicePort :** Allows you to specify the Lookup Service port, if it's not the default. 36 | 37 | **-Verbose :** By default, the function doesn't display much output on the console while running. 38 | If you want the function to display what it's doing on the console, use the -Verbose parameter 39 | 40 | For the full help and usage examples, run the command : 41 | `Get-Help Reset-ISdatabase -Full` 42 | -------------------------------------------------------------------------------- /Reset-ISdatabase/Reset-ISdatabase.psm1: -------------------------------------------------------------------------------- 1 | #Requires -Version 2 2 | function Reset-ISdatabase { 3 | <# 4 | .SYNOPSIS 5 | Resets the vCenter Inventory Service database. 6 | .DESCRIPTION 7 | This is a Powershell module, so you first need to run : Import-Module \Path\To\Reset-ISdatabase.psm1. 8 | Then, you can use the Reset-ISdatabase function just like a cmdlet. 9 | You can also use its alias : risdb. 10 | 11 | This script resets the vCenter Inventory Service database. 12 | IMPORTANT : For vCenter 5.1 and 5.5 only. 13 | IMPORTANT : It needs to be run as Administrator. 14 | Requires Powershell 2.0 or later (built into Windows Server 2008 R2). 15 | 16 | .PARAMETER NoPrompt 17 | By default, the function prompts you to confirm that you understand the potential consequences of resetting the Inventory Service database. 18 | If you want to suppress this prompt, use the -NoPrompt parameter. 19 | 20 | .PARAMETER Verbose 21 | By default, the function doesn't display much output on the console while running. 22 | If you want the function to display what it's doing on the console, use the -Verbose parameter 23 | 24 | .PARAMETER DBpath 25 | Allows you to specify the path to the Inventory Service Database, if it's not the default path. 26 | 27 | .PARAMETER ScriptsPath 28 | Allows you to specify the path to the Inventory Service Scripts folder, if it's not the default path. 29 | 30 | .PARAMETER vCenterPort 31 | Allows you to specify the vCenter HTTPS port, if it's not the default. 32 | 33 | .PARAMETER ISport 34 | Allows you to specify the Inventory Service port, if it's not the default. 35 | 36 | .PARAMETER LookupServicePort 37 | Allows you to specify the Lookup Service port, if it's not the default. 38 | 39 | .EXAMPLE 40 | Reset-ISdatabase -NoPrompt 41 | 42 | This resets vCenter Inventory Service database without prompting to confirm that you understand the potential consequences of resetting the Inventory Service database. 43 | .EXAMPLE 44 | Reset-ISdatabase -Verbose 45 | 46 | This resets vCenter Inventory Service database and displays verbose output on the console. 47 | .EXAMPLE 48 | Reset-ISdatabase -DBpath "D:\Program Files\VMware\Infrastructure\Inventory Service\data" -ScriptsPath "D:\Program Files\VMware\Infrastructure\Inventory Service\scripts" 49 | 50 | This resets vCenter Inventory Service database, specifying the paths to the database and the scripts folder, in case the Inventory Service was installed in the D: drive. 51 | .EXAMPLE 52 | Reset-ISdatabase -vCenterPort 1093 -ISport 1094 -LookupServicePort 1095 53 | 54 | This resets vCenter Inventory Service database, specifying custom ports for the vCenter URL, the Inventory Service URL, and the Lookup Service URL. 55 | .NOTES 56 | Author : Mathieu Buisson 57 | 58 | .LINK 59 | http://kb.vmware.com/kb/2042200 60 | #> 61 | 62 | [cmdletbinding()] 63 | 64 | param( 65 | [switch]$NoPrompt, 66 | [string]$DBpath = 'C:\Program Files\VMware\Infrastructure\Inventory Service\data', 67 | [string]$ScriptsPath = 'C:\Program Files\VMware\Infrastructure\Inventory Service\scripts', 68 | [int]$vCenterPort = 443, 69 | [int]$ISport = 10443, 70 | [int]$LookupServicePort = 7444 71 | ) 72 | if (!$NoPrompt) { 73 | $choice = read-host "As explained in http://kb.vmware.com/kb/2042200 , resetting the Inventory Service database deletes the Managed Object IDs and the vCenter tags, are you sure you want to continue ? (Y/N)" 74 | if ($choice -eq "Y") { 75 | Write-Verbose "Stopping the Inventory Service. This can take a few moments..." 76 | Stop-Service -Name vimQueryService | Out-Null 77 | Write-Verbose "The Inventory Service is now stopped" 78 | 79 | Write-Verbose "Saving the Inventory Service database hash to the variable `$DataHash." 80 | $DataHash = Get-Content -Path (Join-Path -Path $DBpath -ChildPath xdb.bootstrap) | Select-String -Pattern ' 44 | [cmdletbinding()] 45 | param( 46 | [string]$VIServer = "localhost", 47 | 48 | [Parameter(ValueFromPipeline = $True,Position=0)] 49 | [VMware.VimAutomation.ViCore.Impl.V1.Inventory.VMHostImpl[]]$Host = (Get-VMHost), 50 | 51 | [Parameter(Mandatory=$True,Position=1)] 52 | [ValidateSet("tmp","root","hostdstats")] 53 | [string]$RamDisk, 54 | 55 | [int]$Reservation, 56 | 57 | [int]$Limit, 58 | 59 | [switch]$ExpandableReservation 60 | ) 61 | 62 | Begin { 63 | # Checking if the required PowerCLI snapin (or module) is loaded, if not, loading it 64 | If (Get-Module VMware.VimAutomation.Core -ListAvailable -ErrorAction SilentlyContinue) { 65 | If (-not (Get-Module VMware.VimAutomation.Core -ErrorAction SilentlyContinue)) { 66 | Import-Module VMware.VimAutomation.Core 67 | } 68 | } 69 | Else { 70 | If (-not (Get-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue)) { 71 | Add-PSSnapin VMware.VimAutomation.Core 72 | } 73 | } 74 | Set-PowercliConfiguration -InvalidCertificateAction "Ignore" -DisplayDeprecationWarnings:$false -Confirm:$false | Out-Null 75 | 76 | If (-not($defaultVIServer)) { 77 | Connect-VIServer $VIServer | Out-Null 78 | } 79 | Else { 80 | Write-Verbose "Already connected the vCenter Server: $defaultVIServer" 81 | } 82 | # Clearing the default parameter values in the function's scope 83 | $PSDefaultParameterValues.Clear() 84 | 85 | } 86 | Process { 87 | 88 | # Building a new system resources configuration 89 | $Spec = New-Object VMware.Vim.HostSystemResourceInfo 90 | 91 | switch ($RamDisk) { 92 | 'tmp' {$Spec.Key = "host/system/kernel/kmanaged/visorfs/tmp"} 93 | 'root' {$Spec.Key = "host/system/kernel/kmanaged/visorfs/root"} 94 | 'hostdstats' {$Spec.Key = "host/system/kernel/kmanaged/visorfs/hostdstats"} 95 | } 96 | $Spec.Config = New-Object VMware.Vim.ResourceConfigSpec 97 | $Spec.Config.cpuAllocation = New-Object VMware.Vim.ResourceAllocationInfo 98 | $Spec.Config.memoryAllocation = New-Object VMware.Vim.ResourceAllocationInfo 99 | If ($Reservation) { 100 | $Spec.Config.memoryAllocation.Reservation = $Reservation 101 | } 102 | If ($Limit) { 103 | $Spec.Config.MemoryAllocation.Limit = $Limit 104 | } 105 | If ($PSBoundParameters.ContainsKey('ExpandableReservation')) { 106 | $Spec.Config.MemoryAllocation.ExpandableReservation = $True 107 | } 108 | 109 | Foreach ($VMHost in $Host) { 110 | 111 | # Applying the new system resources configuration 112 | $Spec.Config.ChangeVersion = $VMHost.ExtensionData.SystemResources.Config.ChangeVersion 113 | $VMHost.ExtensionData.UpdateSystemResources($Spec) 114 | } 115 | } 116 | End { 117 | } 118 | } -------------------------------------------------------------------------------- /Test-VpxdCertificate/README.md: -------------------------------------------------------------------------------- 1 | ## Description : 2 | 3 | 4 | 5 | This module contains 1 cmdlet : **Test-VpxdCertificate**. 6 | It requires PowerShell version 3 7 | (or later). 8 | 9 | 10 | 11 | ## Test-VpxdCertificate : 12 | 13 | 14 | 15 | 16 | Checks if a certificate file meets all the requirements for the vCenter Server 17 | certificate (5.x or 6.0). 18 | 19 | **Here is the list of requirements for vCenter Server 5.x :** 20 | 21 | * Certificate must be X.509 v3. 22 | * Certificate should begin with : "-----BEGIN CERTIFICATE-----". 23 | * Certificate should end with : "-----END CERTIFICATE-----". 24 | * Subject Alternative Name must contain "DNS Name=" with the fully qualified 25 | domain name of the vCenter server. 26 | * The certificate must be valid : the current date must be between the "Valid 27 | from" date and the "Valid to" date. 28 | * The Key usage must contain the following usages : Digital Signature, Key 29 | Encipherment, Data Encipherment 30 | * The Enhanced key usage must contain : "Server Authentication" and "Client 31 | Authentication". 32 | * The public key algorithm must be : RSA (2048 Bits). 33 | * The certificate must NOT be a wildcard certificate. 34 | * The signature hash algorithm must be SHA256, SHA384, or SHA512. 35 | 36 | **Here is the list of requirements for vCenter Server 6.0 :** 37 | 38 | * Certificate must be X.509 v3. 39 | * Certificate should begin with : "-----BEGIN CERTIFICATE-----". 40 | * Certificate should end with : "-----END CERTIFICATE-----". 41 | * Subject Alternative Name must contain "DNS Name=" with the fully qualified 42 | domain name of the vCenter server. 43 | * The certificate must be valid : the current date must be between the "Valid 44 | from" date and the "Valid to" date. 45 | * The Key usage must contain the following usages : Digital Signature, Key 46 | Encipherment 47 | * The public key algorithm must be : RSA (2048 Bits). 48 | * The certificate must NOT be a wildcard certificate. 49 | * The signature hash algorithm must be SHA256, SHA384, or SHA512. 50 | 51 | The cmdlet performs a test for each of the requirement mentioned above and 52 | outputs an object with a property corresponding to each of these tests. 53 | The value of all these properties is either True or False. 54 | True means that the certificate passed the corresponding test and False means that the certificate failed the corresponding test. 55 | 56 | If this function is run from the vCenter Server itself, it will detect the vCenter Server version by itself. 57 | If it is not run from the vCenter Server itself, the vCenter version ("5.x" or "6.0") needs to be specified using the -VpxdVersion parameter. 58 | 59 | ### Parameters : 60 | 61 | 62 | 63 | **CertFilePath :** To specify the full path of the certificate file to check. 64 | The default value corresponds to the default vCenter Server certificate path. 65 | If not specified, it defaults to C:\ProgramData\VMware\VMware VirtualCenter\SSL\rui.crt . 66 | 67 | 68 | 69 | **vCenterServerFQDN :** To specify the full DNS name of the vCenter Server. 70 | This is required if the cmdlet is not run from the vCenter Server itself or if the vCenter server is unable to resolve its own FQDN. 71 | If not specified, it defaults to [System.Net.Dns]::GetHostByName((hostname)).HostName . 72 | 73 | **VpxdVersion :** The vCenter Server certificate requirements are different between vCenter 5.x and 6.0. 74 | This parameter specifies the version of vCenter Server to define the requirements against which the certificate is checked. 75 | By default, if the function is run from the vCenter Server itself, it will detect the vCenter Server version by itself. 76 | 77 | 78 | 79 | **Quiet :** Instead of outputing the result of the test for each requirement, the "quiet" mode just outputs a boolean value : True or False. 80 | True means that the specified certificate meets all the requirements, False means that it doesn't meet all the requirements. 81 | 82 | 83 | 84 | ### Examples : 85 | 86 | 87 | 88 | -------------------------- EXAMPLE 1 -------------------------- 89 | 90 | PS C:\>Test-VpxdCertificate 91 | 92 | 93 | Checks if the certificate located in the default path on the local vCenter 94 | Server meets all the requirements for the detected version of vCenter Server. 95 | 96 | 97 | 98 | 99 | -------------------------- EXAMPLE 2 -------------------------- 100 | 101 | PS C:\>Test-VpxdCertificate -CertFilePath $env:USERPROFILE\Desktop\rui.crt 102 | -vCenterServerFQDN "VC.vcloud.local" -VpxdVersion 5.x -Verbose 103 | 104 | 105 | Checks if the certificate file on the user's desktop meets all the requirements 106 | for vCenter 5.x, displaying verbose information. 107 | The verbose information contains the properties checked for each test and their 108 | values. 109 | 110 | 111 | 112 | 113 | -------------------------- EXAMPLE 3 -------------------------- 114 | 115 | PS C:\>Test-VpxdCertificate -Quiet 116 | 117 | 118 | Checks if the certificate located in the default path on the local vCenter 119 | Server meets all the requirements for the detected version of vCenter Server. 120 | It outputs a boolean value : True or False. It is True only when the specified 121 | certificate meets all the requirements. 122 | 123 | 124 | -------------------------------------------------------------------------------- /Test-VpxdCertificate/Test-VpxdCertificate.psm1: -------------------------------------------------------------------------------- 1 | #Requires -Version 3 2 | function Test-VpxdCertificate { 3 | 4 | <# 5 | .SYNOPSIS 6 | Checks if a certificate file meets all the requirements for the vCenter Server certificate (5.x or 6.0). 7 | 8 | .DESCRIPTION 9 | Checks if a certificate file meets all the requirements for the vCenter Server certificate (5.x or 6.0). 10 | 11 | Here is the list of requirements which are checked by this cmdlet for vCenter Server 5.x : 12 | 13 | Certificate must be X.509 v3. 14 | Certificate should begin with : "-----BEGIN CERTIFICATE-----". 15 | Certificate should end with : "-----END CERTIFICATE-----". 16 | Subject Alternative Name must contain "DNS Name=" with the fully qualified domain name of the vCenter server. 17 | The certificate must be valid : the current date must be between the "Valid from" date and the "Valid to" date. 18 | The Key usage must contain the following usages : Digital Signature, Key Encipherment, Data Encipherment 19 | The Enhanced key usage must contain : "Server Authentication" and "Client Authentication". 20 | The public key algorithm must be : RSA (2048 Bits). 21 | The certificate must NOT be a wildcard certificate. 22 | The signature hash algorithm must be SHA256, SHA384, or SHA512. 23 | 24 | Here is the list of requirements which are checked by this cmdlet for vCenter Server 6.0 : 25 | 26 | Certificate must be X.509 v3. 27 | Certificate should begin with : "-----BEGIN CERTIFICATE-----". 28 | Certificate should end with : "-----END CERTIFICATE-----". 29 | Subject Alternative Name must contain "DNS Name=" with the fully qualified domain name of the vCenter server. 30 | The certificate must be valid : the current date must be between the "Valid from" date and the "Valid to" date. 31 | The Key usage must contain the following usages : Digital Signature, Key Encipherment 32 | The public key algorithm must be : RSA (2048 Bits). 33 | The certificate must NOT be a wildcard certificate. 34 | The signature hash algorithm must be SHA256, SHA384, or SHA512. 35 | 36 | 37 | The cmdlet performs a test for each of the requirement mentioned above and outputs an object with a property corresponding to each of these test. 38 | The value of all these properties is either True or False. True means that the certificate passed the corresponding test and False means that the certificate failed the corresponding test. 39 | 40 | If this function is run from the vCenter Server itself, it will detect the vCenter Server version by itself. 41 | If it is not run from the vCenter Server itself, the vCenter version ("5.x" or "6.0") needs to be specified using the -VpxdVersion parameter. 42 | 43 | 44 | .PARAMETER CertFilePath 45 | To specify the full path of the certificate file to check. 46 | The default value corresponds to the default vCenter Server certificate path. 47 | 48 | .PARAMETER vCenterServerFQDN 49 | To specify the full DNS name of the vCenter Server. 50 | This is required if the cmdlet is not run from the vCenter Server itself or if the vCenter server is unable to resolve its own FQDN. 51 | 52 | .PARAMETER VpxdVersion 53 | The vCenter Server certificate requirements are different between vCenter 5.x and 6.0. 54 | This parameter specifies the version of vCenter Server to define the requirements against which the certificate is checked. 55 | By default, if the function is run from the vCenter Server itself, it will detect the vCenter Server version by itself. 56 | 57 | .PARAMETER Quiet 58 | Instead of outputing the result of the test for each requirement, the "quiet" mode just outputs a boolean value : True or False. 59 | True means that the specified certificate meets all the requirements, False means that it doesn't meet all the requirements. 60 | 61 | .EXAMPLE 62 | Test-VpxdCertificate 63 | 64 | Checks if the certificate located in the default path on the local vCenter Server meets all the requirements for the detected version of vCenter Server. 65 | 66 | .EXAMPLE 67 | Test-VpxdCertificate -CertFilePath $env:USERPROFILE\Desktop\rui.crt -vCenterServerFQDN "VC.vcloud.local" -VpxdVersion 5.x -Verbose 68 | 69 | Checks if the certificate file on the user's desktop meets all the requirements for vCenter 5.x, displaying verbose information. 70 | The verbose information contains the properties checked for each test and their values. 71 | 72 | .EXAMPLE 73 | Test-VpxdCertificate -Quiet 74 | 75 | Checks if the certificate located in the default path on the local vCenter Server meets all the requirements for the detected version of vCenter Server. 76 | It outputs a boolean value : True or False. It is True only when the specified certificate meets all the requirements. 77 | 78 | .NOTES 79 | Author : Mathieu Buisson 80 | 81 | .LINK 82 | For the latest version of this module and its documentation, please refer to : 83 | https://github.com/MathieuBuisson/Powershell-VMware/tree/master/Test-VpxdCertificate 84 | 85 | #> 86 | 87 | [cmdletbinding()] 88 | param( 89 | [Parameter(Position=0)] 90 | [ValidateScript({ Test-Path $_ -PathType Leaf })] 91 | [string]$CertFilePath = "C:\ProgramData\VMware\VMware VirtualCenter\SSL\rui.crt", 92 | 93 | [Parameter(Position=1)] 94 | # This default value assumes that the function is run from the vCenter server and that it can resolve its own FQDN from its hostname 95 | [string]$vCenterServerFQDN = [System.Net.Dns]::GetHostByName((hostname)).HostName,` 96 | [Parameter(Position=2)] 97 | [ValidateSet("5.x","6.0")] 98 | [string]$VpxdVersion, 99 | 100 | [switch]$Quiet 101 | ) 102 | 103 | Begin { 104 | # Checking if we are on a vCenter Server 105 | $LocalVpxd = Get-WmiObject -Class Win32_service -Filter "Name='vpxd'" -ErrorAction SilentlyContinue 106 | 107 | # If VpxdVersion parameter was not used, setting a value for $VpxdVersion 108 | If (-not ($PSBoundParameters.ContainsKey('VpxdVersion')) ) { 109 | If (-not ($LocalVpxd)) { 110 | Throw "The vCenter version has to be specified using the -VpxdVersion parameter, whenever the cmdlet is not run from a vCenter Server." 111 | } 112 | Else { 113 | $VpxdFile = Get-ChildItem $($LocalVpxd.PathName).Replace('"','') 114 | $VpxdProductVersion = $VpxdFile.VersionInfo.ProductVersion 115 | Write-Verbose "Detected vCenter Server version : $VpxdProductVersion" 116 | 117 | If ($VpxdProductVersion -match "^5\.\d*") { 118 | $VpxdVersion = "5.x" 119 | } 120 | ElseIf ($VpxdProductVersion -match "^6\.\d*") { 121 | $VpxdVersion = "6.0" 122 | } 123 | Else { 124 | Write-Warning "The version of vCenter Server on the local machine is : $VpxdProductVersion" 125 | Write-Warning "The vCenter version should be either 5.x or 6.x ." 126 | Write-Warning "Falling back to `$VpxdVersion = 5.x" 127 | $VpxdVersion = "5.x" 128 | } 129 | } 130 | } 131 | Write-Verbose "`$VpxdVersion : $VpxdVersion" 132 | } 133 | Process { 134 | # Checking if the module Microsoft.PowerShell.Security is loaded, if not, loading it 135 | If (-not (Get-Module Microsoft.PowerShell.Security -ErrorAction SilentlyContinue)) { 136 | Import-Module Microsoft.PowerShell.Security 137 | } 138 | 139 | $CertObject = Get-PfxCertificate -FilePath $CertFilePath 140 | 141 | #region Testing X.509 version3 142 | $CertificateType = $($CertObject.GetType().name) 143 | Write-Verbose "`$CertificateType : $CertificateType" 144 | 145 | $X509 = $($CertObject.GetType().name) -like "X509Certificate*" 146 | Write-Verbose "`$X509 : $X509" 147 | 148 | $Version = $($CertObject.Version) -eq 3 149 | Write-Verbose "Version : $($CertObject.Version)" 150 | Write-Verbose "`$Version : $Version" 151 | 152 | $X509v3 = $X509 -and $Version 153 | #endregion Testing X.509 version3 154 | 155 | #region Testing begins with "-----BEGIN CERTIFICATE-----" 156 | 157 | # Importing the content of the certificate as plain text 158 | $CertContent = Get-Content -Path $CertFilePath 159 | $FirstLine = $CertContent | Select-Object -First 1 160 | Write-Verbose "`$FirstLine : $FirstLine" 161 | 162 | $BeginCertificate = $FirstLine -eq "-----BEGIN CERTIFICATE-----" 163 | #endregion Testing begins with "-----BEGIN CERTIFICATE-----" 164 | 165 | #region Testing ends with "-----END CERTIFICATE-----" 166 | $LastLine = $CertContent | Select-Object -Last 1 167 | Write-Verbose "`$LastLine : $LastLine" 168 | 169 | $EndCertificate = $LastLine -eq "-----END CERTIFICATE-----" 170 | #endregion Testing ends with "-----END CERTIFICATE-----" 171 | 172 | #region Testing Subject alternative names contain FQDN 173 | $SubjectAltNameExtension = $CertObject.Extensions | Where-Object {$_.Oid.FriendlyName -match "Subject Alternative Name"} 174 | $SubjectAltNameObj = New-Object -ComObject X509Enrollment.CX509ExtensionAlternativeNames 175 | $SubjectAltNameString = [System.Convert]::ToBase64String($SubjectAltNameExtension.RawData) 176 | $SubjectAltNameObj.InitializeDecode(1, $SubjectAltNameString) 177 | 178 | # Preparing an empty array to populate it with the subject alternative names 179 | $SubjectAltNames = @() 180 | 181 | Foreach ($AlternativeName in $($SubjectAltNameObj.AlternativeNames)) { 182 | Write-Verbose "`$AlternativeName : $($AlternativeName.strValue)" 183 | $SubjectAltNames += $($AlternativeName.strValue) 184 | } 185 | $SubjectAltNamesContainFQDN = $SubjectAltNames -contains $vCenterServerFQDN 186 | #endregion Testing Subject alternative name with FQDN 187 | 188 | #region Testing current date is between the "Valid from" date and the Valid to" date 189 | 190 | $CurrentDate = Get-Date 191 | $ValidFrom = $CertObject.NotBefore 192 | Write-Verbose "`$ValidFrom : $($ValidFrom.ToString())" 193 | 194 | $ValidTo = $CertObject.NotAfter 195 | Write-Verbose "`$ValidTo : $($ValidTo.ToString())" 196 | $BetweenValidFromAndValidTo = ($CurrentDate -ge $ValidFrom) -and ($CurrentDate -le $ValidTo) 197 | #endregion Testing current date is between the "Valid from" date and the Valid to" date 198 | 199 | #region Testing Key usages 200 | $KeyUsageExtension = $CertObject.Extensions | Where-Object { $_.Oid.FriendlyName -eq "Key Usage" } 201 | Write-Verbose "Key Usages : $($KeyUsageExtension.KeyUsages)" 202 | 203 | $KeyUsageString = $KeyUsageExtension.KeyUsages.ToString() 204 | 205 | If ($VpxdVersion -eq "5.x") { 206 | $RequiredKeyUsageFlags = "KeyEncipherment", "DigitalSignature", "DataEncipherment" 207 | Write-Verbose "Required key usages : KeyEncipherment, DigitalSignature, DataEncipherment" 208 | 209 | $KeyUsagesTest = ($KeyUsageString -match $RequiredKeyUsageFlags[0]) -and ($KeyUsageString -match $RequiredKeyUsageFlags[1]) -and ($KeyUsageString -match $RequiredKeyUsageFlags[2]) 210 | } 211 | Else { 212 | $RequiredKeyUsageFlags = "KeyEncipherment", "DigitalSignature" 213 | Write-Verbose "Required key usages : KeyEncipherment, DigitalSignature" 214 | 215 | $KeyUsagesTest = ($KeyUsageString -match $RequiredKeyUsageFlags[0]) -and ($KeyUsageString -match $RequiredKeyUsageFlags[1]) 216 | } 217 | #endregion Testing Key usages 218 | 219 | #region Testing Enhanced key usages 220 | $EnhancedKeyUsageExtension = $CertObject.Extensions | Where-Object { $_.Oid.FriendlyName -eq "Enhanced Key Usage" } 221 | $ServerAuth = $EnhancedKeyUsageExtension.EnhancedKeyUsages.FriendlyName -contains "Server Authentication" 222 | Write-Verbose "ServerAuth Enhanced key usage : $ServerAuth" 223 | 224 | $ClientAuth = $EnhancedKeyUsageExtension.EnhancedKeyUsages.FriendlyName -contains "Client Authentication" 225 | Write-Verbose "ClientAuth Enhanced key usage : $ClientAuth" 226 | 227 | $EnhancedKeyUsagesTest = $ServerAuth -and $ClientAuth 228 | #endregion Testing Enhanced key usages 229 | 230 | #region Testing Public key size and algorithm 231 | 232 | $PublicKey = $CertObject.PublicKey.key 233 | Write-Verbose "Public key size : $($PublicKey.KeySize)" 234 | 235 | $KeySize2048Bits = $PublicKey.KeySize -ge 2048 236 | Write-Verbose "`$KeySize2048Bits : $KeySize2048Bits" 237 | 238 | Write-Verbose "Public key algorithm : $($PublicKey.KeyExchangeAlgorithm)" 239 | $PublicKeyAlgorithm = $PublicKey.KeyExchangeAlgorithm -like "RSA*" 240 | Write-Verbose "`$PublicKeyAlgorithm : $PublicKeyAlgorithm" 241 | 242 | $PublicKeySizeAndAlgorithm = $KeySize2048Bits -and $PublicKeyAlgorithm 243 | #endregion Testing Public key algorithm 244 | 245 | #region Testing Not wildcard certificate 246 | $CertCN = $CertObject.Subject -split "," | Where-Object { $_ -match "CN=" } 247 | Write-Verbose "Certificate CN : $CertCN" 248 | 249 | $NotWildcardCert = $certCN -notmatch "CN=\*\." 250 | #endregion Testing Not wildcard certificate 251 | 252 | #region Testing Signature hash algorithm 253 | $SignatureAlgorithm = $CertObject.SignatureAlgorithm.FriendlyName 254 | Write-Verbose "Signature hash algorithm : $SignatureAlgorithm" 255 | 256 | $SignatureAlgorithmTest = $SignatureAlgorithm -match "^sha\d{3}\d*" 257 | #endregion Testing Signature hash algorithm 258 | 259 | If ($Quiet) { 260 | If ($VpxdVersion -eq "5.x") { 261 | $X509v3 -and $BeginCertificate -and $EndCertificate -and $SubjectAltNamesContainFQDN -and $BetweenValidFromAndValidTo ` -and $KeyUsagesTest -and $EnhancedKeyUsagesTest -and $PublicKeySizeAndAlgorithm -and $NotWildcardCert -and $SignatureAlgorithmTest 262 | } 263 | Else { 264 | $X509v3 -and $BeginCertificate -and $EndCertificate -and $SubjectAltNamesContainFQDN -and $BetweenValidFromAndValidTo ` 265 | -and $KeyUsagesTest -and $PublicKeySizeAndAlgorithm -and $NotWildcardCert -and $SignatureAlgorithmTest 266 | } 267 | } 268 | Else { 269 | # Properties of the custom output object will differ depending on the vCenter version 270 | If ($VpxdVersion -eq "5.x") { 271 | 272 | $TestResultProps = @{'Certificate is X.509 v3' = $X509v3 273 | 'Certificate begins with "-----BEGIN CERTIFICATE-----"' = $BeginCertificate 274 | 'Certificate ends with "-----END CERTIFICATE-----"' = $EndCertificate 275 | 'Subject alternative names contain the vCenter FQDN' = $SubjectAltNamesContainFQDN 276 | 'Current date is between the "Valid from" and "Valid to" dates' = $BetweenValidFromAndValidTo 277 | 'Certificate has the required key usages' = $KeyUsagesTest 278 | 'Certificate has the required enhanced key usages' = $EnhancedKeyUsagesTest 279 | 'Public key algorithm is RSA 2048 or higher' = $PublicKeySizeAndAlgorithm 280 | 'Certificate is NOT a wildcard certificate' = $NotWildcardCert 281 | 'Signature hash algorithm is SHA256 or higher' = $SignatureAlgorithmTest 282 | } 283 | } 284 | Else { 285 | $TestResultProps = @{'Certificate is X.509 v3' = $X509v3 286 | 'Certificate begins with "-----BEGIN CERTIFICATE-----"' = $BeginCertificate 287 | 'Certificate ends with "-----END CERTIFICATE-----"' = $EndCertificate 288 | 'Subject alternative names contain the vCenter FQDN' = $SubjectAltNamesContainFQDN 289 | 'Current date is between the "Valid from" and "Valid to" dates' = $BetweenValidFromAndValidTo 290 | 'Certificate has the required key usages' = $KeyUsagesTest 291 | 'Public key algorithm is RSA 2048 or higher' = $PublicKeySizeAndAlgorithm 292 | 'Certificate is NOT a wildcard certificate' = $NotWildcardCert 293 | 'Signature hash algorithm is SHA256 or higher' = $SignatureAlgorithmTest 294 | } 295 | } 296 | $TestResultObj = New-Object -TypeName PSObject -Property $TestResultProps 297 | $TestResultObj 298 | } 299 | } 300 | End { 301 | } 302 | } 303 | -------------------------------------------------------------------------------- /VMLocationbyDateTime/README.md: -------------------------------------------------------------------------------- 1 | ##Description : 2 | 3 | This module contains 1 cmdlet : **Get-VMHostbyDateTime** . 4 | It requires Powershell version 3 (or later) and the PowerCLI 5.5 (or later). 5 | 6 | For a better experience, it is recommended to use the module manifest **VMLocationbyDateTime.psd1** to automatically associate the custom formatting view **VMLocationbyDateTime.ps1xml** to the output object type : VMLocationbyDateTime.VMLocation. 7 | 8 | ##Get-VMHostbyDateTime : 9 | 10 | Tracks on which host was one (or more) VM(s) over a date or time range. 11 | 12 | Useful to track VM location and migrations in a cluster where DRS is in fully automated mode. 13 | It shows when the VM has changed host, the source and destination host, and the reason of the move. 14 | 15 | If the source and destination hosts are the same for an output entry, the migration was a Storage vMotion. 16 | If the source host is empty for an output entry, it was not a migration, but a start or restart of the VM. 17 | 18 | ##Parameters : 19 | 20 | **VIServer :** To specify the vCenter Server to connect PowerCLI to. 21 | The default is Localhost. 22 | 23 | **VM :** To specify one or more VMs. 24 | 25 | **After :** To get the VM location(s) and migration(s) during a time range starting from the specified point in time. 26 | If no value is specified, the default is 180 days ago, which is the default retention policy for events in the vCenter database. 27 | The precision is up to the second and it is using the vCenter local time. 28 | 29 | **Before :** To get the VM location(s) and migration(s) during a time range ending at the specified point in time. 30 | If no value is specified, the defaut is : now. The precision is up to the second and it is using the vCenter local time. 31 | 32 | ###CAUTION : 33 | The DateTime object formatting depends on the culture. 34 | Examples provided in the help were tested with the en-US culture. In this culture, the format is MM/dd/yy, this why "03/13/2015" can be cast as a valid DateTime object. 35 | 36 | For other cultures, like en-GB or en-IE, the format is dd/MM/yy so "03/13/2015" cannot be cast as a valid DateTime. 37 | You can use the cmdlet Get-Culture to obtain the culture of your current Powershell session. 38 | -------------------------------------------------------------------------------- /VMLocationbyDateTime/VMLocationbyDateTime.ps1xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | VMLocationbyDateTime.VMLocation 6 | 7 | VMLocationbyDateTime.VMLocation 8 | 9 | 10 | 11 | 12 | 15 13 | 14 | 15 | 21 16 | 17 | 18 | 25 19 | 20 | 21 | 25 22 | 23 | 24 | 19 25 | 26 | 27 | 28 | 29 | 30 | 31 | VM 32 | 33 | 34 | DateTime 35 | 36 | 37 | SourceHost 38 | 39 | 40 | DestinationHost 41 | 42 | 43 | Reason 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /VMLocationbyDateTime/VMLocationbyDateTime.psd1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuBuisson/Powershell-VMware/65ce79f625b48b9247f6c7e66f4c408631660483/VMLocationbyDateTime/VMLocationbyDateTime.psd1 -------------------------------------------------------------------------------- /VMLocationbyDateTime/VMLocationbyDateTime.psm1: -------------------------------------------------------------------------------- 1 | #Requires -Version 3 2 | 3 | function Get-VMHostbyDateTime { 4 | 5 | <# 6 | .SYNOPSIS 7 | Tracks on which host was one (or more) VM(s) over a date or time range. 8 | 9 | .DESCRIPTION 10 | Tracks on which host was one (or more) VM(s) over a date or time range. 11 | Useful to track VM location and migrations in a cluster where DRS is in fully automated mode. 12 | It shows when the VM has changed host , the source and destination host, and the reason of the move. 13 | 14 | If the source and destination hosts are the same for an output entry, the migration was a Storage vMotion. 15 | If the source host is empty for an output entry, it was not a migration, but a start or restart of the VM. 16 | 17 | .PARAMETER VIServer 18 | To specify the vCenter Server to connect PowerCLI to. 19 | The default is Localhost. 20 | 21 | .PARAMETER VM 22 | To specify one or more VMs. 23 | 24 | .PARAMETER After 25 | To get the VM location(s) and migration(s) during a time range starting from the specified point in time. 26 | If no value is specified, the default is 180 days ago, which is the default retention policy for events in the vCenter database. 27 | The precision is up to the second and it is using the vCenter local time. 28 | 29 | .PARAMETER Before 30 | To get the VM location(s) and migration(s) during a time range ending at the specified point in time. 31 | If no value is specified, the defaut is : now. 32 | The precision is up to the second and it is using the vCenter local time. 33 | 34 | .EXAMPLE 35 | Get-VM BigVM | Get-VMHostbyDateTime -After (Get-Date).AddMonths(-1) 36 | 37 | Tracks the location(s) and migration event(s) over the last month for the VM named BigVM 38 | 39 | .EXAMPLE 40 | Get-VM BigVM | Get-VMHostbyDateTime -After "01/16/2015 13:16" -Before "01/16/2015 18:04" 41 | 42 | Tracks the location(s) and migration event(s) the 16th of January between 13:16 and 18:04 for the VM named BigVM 43 | 44 | .EXAMPLE 45 | Get-VMHostbyDateTime -VM (Get-VM) -After "03/13/2015" 46 | 47 | Tracks the location(s) and migration event(s) for all VMs since the 13th of March 2015. 48 | 49 | .OUTPUTS 50 | One or more objects of the type VMLocationbyDateTime.VMLocation 51 | #> 52 | 53 | [cmdletbinding()] 54 | param( 55 | [string]$VIServer = "localhost", 56 | [Parameter(Mandatory = $True,ValueFromPipeline = $True, 57 | ValueFromPipelineByPropertyName=$True,Position=0)] 58 | [VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl[]]$VM, 59 | [datetime]$After = (Get-Date).AddDays(-180), 60 | [datetime]$Before = (Get-Date) 61 | ) 62 | 63 | Begin { 64 | # Checking if the required PowerCLI snapin is loaded, if not, loading it 65 | if (-not (Get-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue)) { 66 | Add-PSSnapin VMware.VimAutomation.Core } 67 | 68 | Set-PowercliConfiguration -InvalidCertificateAction "Ignore" -DisplayDeprecationWarnings:$false -Confirm:$false | Out-Null 69 | 70 | if (-not($defaultVIServer)) { 71 | Connect-VIServer $VIServer | Out-Null 72 | } 73 | Else { 74 | Write-Verbose "Already connected the vCenter Server: $defaultVIServer" 75 | } 76 | # Clearing the default parameter values in the function's scope 77 | $PSDefaultParameterValues.Clear() 78 | 79 | # Preparing a collection to store the output objects 80 | $LocationCollection = @() 81 | } 82 | Process { 83 | Foreach ($iVM in $VM) { 84 | 85 | $iVMEvents = Get-VIEvent -Entity $iVM -Start $After -Finish $Before | Where-Object { $_.GetType().name -eq "VmPoweredOnEvent" -or $_.GetType().name -eq "VmStartingEvent" -or $_.GetType().name -like "*VmMigrated*" } 86 | 87 | # Sorting the events for each VM in chronological order 88 | $iVMSortedEvents = $iVMEvents | Sort-Object -Property CreatedTime 89 | 90 | Foreach ($Event in $iVMSortedEvents) { 91 | 92 | # Building the properties of our custom output object 93 | $EventProps = [ordered]@{'VM' = $Event.VM.Name 94 | 'DateTime' = $Event.CreatedTime 95 | 'SourceHost' = $Event.SourceHost.Name 96 | 'DestinationHost' = $Event.Host.Name 97 | 'Reason' = $Event.GetType().Name 98 | } 99 | $VMHostobj = New-Object -TypeName PSObject -Property $EventProps 100 | 101 | # Adding a type for our custom output object to link that type to a custom formatting view defined in VMLocationbyDateTime.ps1xml 102 | $VMHostobj.PSObject.Typenames.Insert(0,'VMLocationbyDateTime.VMLocation') 103 | $LocationCollection += $VMHostobj 104 | } 105 | } 106 | } 107 | End { 108 | $LocationCollection 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /vCenterTagging/README.md: -------------------------------------------------------------------------------- 1 | ##Description : 2 | 3 | This module contains 2 cmdlets : **Export-TagAndAssignment** and **Import-TagAndAssignment**. 4 | 5 | It requires Powershell 3.0 (or later) and PowerCLI 5.5 R2 (or later). 6 | 7 | ##Export-TagAndAssignment : 8 | 9 | Exports all the tags, tag categories and tag assignments from a vCenter to a file. 10 | This file can be used later to import all the tags, categories and assignments back into a vCenter environment. 11 | 12 | One use case is backing up all the tagging information from a vCenter Server before resetting the Inventory Service database (which deletes all tagging information). 13 | 14 | ###Parameters : 15 | 16 | **VIServer :** To specify the vCenter Server to connect PowerCLI to. 17 | The default is Localhost. 18 | 19 | **Path :** To specify the path and name of the file the tagging data should be exported to. 20 | This parameter is mandatory. 21 | 22 | 23 | ##Import-TagAndAssignment : 24 | 25 | Imports all the tags, tag categories and tag assignments from a file to a vCenter Server. 26 | 27 | One use case is restoring all the tagging information from a vCenter Server after resetting the Inventory Service database (which deletes all tagging information). 28 | 29 | ###Parameters : 30 | 31 | **VIServer :** To specify the vCenter Server to connect PowerCLI to. 32 | The default is Localhost. 33 | 34 | **Path :** To specify the path and name of the file the tagging data should be imported from. 35 | This parameter is mandatory. 36 | -------------------------------------------------------------------------------- /vCenterTagging/vCenterTagging.psm1: -------------------------------------------------------------------------------- 1 | #Requires -Version 3 2 | 3 | function Export-TagAndAssignment { 4 | 5 | <# 6 | .SYNOPSIS 7 | Exports all the tags, tag categories and tag assignments from a vCenter to a file. This file can be used later to import all the tags, categories and assignments back into a vCenter environment. 8 | .NOTES 9 | Author : Mathieu Buisson 10 | #> 11 | 12 | [cmdletbinding()] 13 | param( 14 | [string]$VIServer = "localhost", 15 | 16 | [Parameter(Mandatory=$True, Position=1)] 17 | [string]$Path 18 | ) 19 | 20 | Begin { 21 | # Checking if the required PowerCLI snapin (or module) is loaded, if not, loading it 22 | If (Get-Module VMware.VimAutomation.Core -ListAvailable -ErrorAction SilentlyContinue) { 23 | If (-not (Get-Module VMware.VimAutomation.Core -ErrorAction SilentlyContinue)) { 24 | Import-Module VMware.VimAutomation.Core 25 | } 26 | } 27 | Else { 28 | If (-not (Get-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue)) { 29 | Add-PSSnapin VMware.VimAutomation.Core 30 | } 31 | } 32 | Set-PowercliConfiguration -InvalidCertificateAction "Ignore" -DisplayDeprecationWarnings:$false -Confirm:$false | Out-Null 33 | 34 | If (-not($defaultVIServer)) { 35 | Connect-VIServer $VIServer | Out-Null 36 | } 37 | Else { 38 | Write-Verbose "Already connected the vCenter Server: $defaultVIServer" 39 | } 40 | } 41 | Process { 42 | 43 | $TagCategories = Get-TagCategory 44 | $Tags = Get-Tag 45 | $TagAssignments = Get-TagAssignment 46 | 47 | # Grouping the tag categories, the tags and the tag assignments into an array 48 | $ExportArray = @($TagCategories,$Tags,$TagAssignments) 49 | 50 | try { 51 | Export-Clixml -InputObject $ExportArray -Path $Path -ErrorAction Stop 52 | } 53 | catch { 54 | Write-Error $_.Exception.Message 55 | } 56 | } 57 | End { 58 | } 59 | } 60 | 61 | function Import-TagAndAssignment { 62 | 63 | <# 64 | .SYNOPSIS 65 | Imports all the tags, tag categories and tag assignments from a file to a vCenter Server. 66 | .NOTES 67 | Author : Mathieu Buisson 68 | #> 69 | 70 | [cmdletbinding()] 71 | param( 72 | [string]$VIServer = "localhost", 73 | 74 | [Parameter(Mandatory=$True, Position=1)] 75 | [string]$Path 76 | ) 77 | 78 | Begin { 79 | # Checking if the required PowerCLI snapin (or module) is loaded, if not, loading it 80 | If (Get-Module VMware.VimAutomation.Core -ListAvailable -ErrorAction SilentlyContinue) { 81 | If (-not (Get-Module VMware.VimAutomation.Core -ErrorAction SilentlyContinue)) { 82 | Import-Module VMware.VimAutomation.Core 83 | } 84 | } 85 | Else { 86 | If (-not (Get-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue)) { 87 | Add-PSSnapin VMware.VimAutomation.Core 88 | } 89 | } 90 | Set-PowercliConfiguration -InvalidCertificateAction "Ignore" -DisplayDeprecationWarnings:$false -Confirm:$false | Out-Null 91 | 92 | If (-not($defaultVIServer)) { 93 | Connect-VIServer $VIServer | Out-Null 94 | } 95 | Else { 96 | Write-Verbose "Already connected the vCenter Server: $defaultVIServer" 97 | } 98 | } 99 | Process { 100 | 101 | $Import = Import-Clixml -Path $Path 102 | 103 | # Creating the tag categories from the imported XML data 104 | Foreach ( $category in $Import[0] ) { 105 | 106 | New-TagCategory -Name $category.Name -Description $category.Description ` 107 | -Cardinality $category.Cardinality -EntityType $category.EntityType 108 | } 109 | 110 | # Creating the tags from the imported XML data 111 | Foreach ( $tag in $Import[1] ) { 112 | 113 | New-Tag -Name $tag.Name -Category (Get-TagCategory -Name $tag.Category) ` 114 | -Description $tag.Description 115 | } 116 | 117 | # Creating the tag assignments from the imported XML data 118 | Foreach ( $assignment in $Import[2] ) { 119 | 120 | $AssignTag = (Get-Tag -Name $assignment.Tag.Name) 121 | $AssignEntity = Get-VIObjectByVIView -MORef ($assignment.Entity.Id) 122 | 123 | New-TagAssignment -Tag $AssignTag -Entity $AssignEntity 124 | } 125 | } 126 | End { 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /vSphereOvercommit/README.md: -------------------------------------------------------------------------------- 1 | ##Description : 2 | 3 | This module contains 3 cmdlets : **Get-CPUOvercommit**, **Get-MemoryOvercommit** and **Get-StorageOvercommit**. 4 | It requires Powershell version 3 (or later) and the PowerCLI 5.5 (or later). 5 | 6 | ##Get-CPUOvercommit : 7 | 8 | Obtains the number of vCPUs and the number of physical CPU cores for one or more ESXi hosts (or for a cluster if the Cluster parameter is used) and compares them to evaluate CPU overcommitment. 9 | 10 | The CPU overcommitment is evaluated by comparing the number of vCPUs of all the running VMs for each ESXi host and the number of physical cores on this host. 11 | 12 | ###Parameters : 13 | 14 | **VIServer :** To specify the vCenter Server to connect PowerCLI to. 15 | The default is Localhost. 16 | 17 | **VMhosts :** To specify one or more ESXi hosts. The default will query all ESXi hosts managed by the vCenter Server you are connected to in PowerCLI. 18 | This parameter has 2 aliases : "Hosts" and "Servers". 19 | 20 | **Cluster :** Outputs global values for the specified cluster 21 | 22 | **Quiet :** This mode only outputs a boolean value for each ESXi host (or for the cluster if the Cluster parameter is used) : $True if there is overcommitment, $False if not. 23 | 24 | ##Get-MemoryOvercommit : 25 | 26 | Obtains physical memory and virtual memory information for one or more ESXi hosts (or for a cluster if the Cluster parameter is used) and compares them to evaluate memory overcommitment. 27 | 28 | The memory overcommitment is evaluated by comparing the memory allocated to the running VMs for each ESXi host and the physical RAM on this host. 29 | 30 | ###Parameters : 31 | 32 | The same as for Get-CPUOvercommit 33 | 34 | ##Get-StorageOvercommit : 35 | 36 | Obtains the used space, provisioned space and capacity for one or more datastores and compares them to evaluate storage overcommitment. 37 | 38 | "Storage overcommitment" is evaluated by comparing the provisioned space for all VMs in the datastore (or datastore cluster) with its capacity. 39 | 40 | This storage overcommitment is possible only when there are thin provisioned VMDKs and this doesn't take into account thin provisioning at the LUN level which may be provided by the storage array. 41 | The VMs provisioned space includes the space provisioned for all VMDKs, snapshots, linked clones, swap files and VM logs. 42 | 43 | ###Parameters : 44 | 45 | **VIServer :** To specify the vCenter Server to connect PowerCLI to. 46 | The default is Localhost. 47 | 48 | **Datastore :** To specify one or more datastores. The default will query all datastores managed by the vCenter Server you are connected to in PowerCLI. 49 | This parameter has an alias : **Storage**. 50 | 51 | **Cluster :** Outputs global values for the specified datastore cluster 52 | 53 | **Quiet :** This mode only outputs a boolean value for each datastore (or for the datastore cluster if the Cluster parameter is used) : $True if there is overcommitment, $False if not. 54 | -------------------------------------------------------------------------------- /vSphereOvercommit/vSphereOvercommit.psm1: -------------------------------------------------------------------------------- 1 | #Requires -Version 3 2 | 3 | function Get-CPUOvercommit { 4 | <# 5 | .SYNOPSIS 6 | Obtains the number of vCPUs and the number of physical CPU cores for one or more ESXi hosts and compares them to evaluate CPU overcommitment. 7 | 8 | .DESCRIPTION 9 | Obtains the number of vCPUs and the number of physical CPU cores for one or more ESXi hosts (or for a cluster if the Cluster parameter is used) and compares them to evaluate CPU overcommitment. 10 | 11 | The CPU overcommitment is evaluated by comparing the number of vCPUs of all the running VMs for each ESXi host and the number of physical cores on this host. 12 | 13 | .PARAMETER VIServer 14 | To specify the vCenter Server to connect PowerCLI to. 15 | The default is Localhost. 16 | 17 | .PARAMETER VMhosts 18 | To specify one or more ESXi hosts. 19 | The default will query all ESXi hosts managed by the vCenter Server you are connected to in PowerCLI. 20 | This parameter has 2 aliases : "Hosts" and "Servers". 21 | 22 | .PARAMETER Cluster 23 | Outputs global values for the specified cluster 24 | 25 | .PARAMETER Quiet 26 | This mode only outputs a boolean value for each ESXi host (or for the cluster if the Cluster parameter is used) : 27 | $True if there is overcommitment, $False if not. 28 | 29 | .EXAMPLE 30 | Get-CPUOvercommit -Cluster Production 31 | 32 | Obtains vCPU, physical cores and overcommitment information, providing global values for the cluster called Production. 33 | 34 | .EXAMPLE 35 | Get-VMHost EsxDev5* | Get-CPUOvercommit 36 | 37 | Obtains vCPU, physical cores and overcommitment information for each ESXi host with a name starting with EsxDev5, using pipeline input. 38 | 39 | .EXAMPLE 40 | Get-CPUOvercommit -Quiet 41 | 42 | Outputs a boolean value stating whether there is CPU overcommitment or not, for each ESXi host managed by the connected vCenter Server. 43 | #> 44 | [cmdletbinding()] 45 | param( 46 | [string]$VIServer = "localhost", 47 | [Parameter(ValueFromPipeline = $True, 48 | ValueFromPipelineByPropertyName=$True, 49 | Position=0)] 50 | [Alias('Hosts','Servers')] 51 | [VMware.VimAutomation.ViCore.Impl.V1.Inventory.VMHostImpl[]]$VMhosts, 52 | [string]$Cluster, 53 | [switch]$Quiet 54 | ) 55 | 56 | Begin { 57 | if(-not (Get-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue)) { 58 | Add-PSSnapin VMware.VimAutomation.Core } 59 | 60 | Set-PowercliConfiguration -InvalidCertificateAction "Ignore" -DisplayDeprecationWarnings:$false -Confirm:$false | Out-Null 61 | 62 | If (-not($defaultVIServer)) { 63 | Connect-VIServer $VIServer 64 | } 65 | Else { 66 | Write-Verbose "Already connected the vCenter Server: $defaultVIServer" 67 | } 68 | # Clearing the default parameter values in the function's scope 69 | $PSDefaultParameterValues.Clear() 70 | 71 | If (-not ($PSBoundParameters.ContainsKey('VMhosts')) ) { 72 | $VMhosts = Get-VMHost 73 | } 74 | # Getting all hosts from the cluster(s) if the -Cluster parameter is specified 75 | If ($PSBoundParameters.ContainsKey('Cluster')) { 76 | $VMhosts = Get-Cluster -Name $Cluster | Get-VMHost 77 | } 78 | # Preparing a collection to store information for each individual ESXi host 79 | $OvercommitInfoCollection = @() 80 | } 81 | Process { 82 | 83 | Foreach ($VMhost in $VMhosts) { 84 | 85 | $HostPoweredOnvCPUs = (Get-VM -Location $VMhost | Where-Object {$_.PowerState -eq "PoweredOn" } | Measure-Object NumCpu -Sum).Sum 86 | Write-Verbose "`$HostPoweredOnvCPUs for $VMhost is : $HostPoweredOnvCPUs" 87 | 88 | # Building the properties for our custom object 89 | $OvercommitInfoProperties = [ordered]@{'ESXi Host'=$VMhost.Name 90 | 'CPU Cores'=$VMhost.NumCpu 91 | 'Total vCPUs'=(Get-VM -Location $VMhost | Measure-Object NumCpu -Sum).Sum 92 | 'PoweredOn vCPUs'=if ($HostPoweredOnvCPUs) {$HostPoweredOnvCPUs} Else { 0 -as [int] } 93 | 'vCPU/Core ratio'=if ($HostPoweredOnvCPUs) {[Math]::Round(($HostPoweredOnvCPUs / $VMhost.NumCpu), 3)} Else { $null } 94 | 'CPU Overcommit (%)'=if ($HostPoweredOnvCPUs) {[Math]::Round(100*(($HostPoweredOnvCPUs - $VMhost.NumCpu) / $VMhost.NumCpu), 3)} Else { $null } 95 | } 96 | 97 | # Building a custom object from the list of properties above 98 | $OvercommitInfoObj = New-Object -TypeName PSObject -Property $OvercommitInfoProperties 99 | 100 | If ($Quiet) { 101 | $OvercommitInfoBoolean = $HostPoweredOnvCPUs -gt $VMhost.NumCpu 102 | $OvercommitInfoCollection += $OvercommitInfoBoolean 103 | } 104 | Else { 105 | $OvercommitInfoCollection += $OvercommitInfoObj 106 | } 107 | } 108 | } 109 | End { 110 | If ($PSBoundParameters.ContainsKey('Cluster')) { 111 | 112 | $ClusterPoweredOnvCPUs = (Get-VM -Location $Cluster | Where-Object {$_.PowerState -eq "PoweredOn" } | Measure-Object NumCpu -Sum).Sum 113 | $ClusterCPUCores = ($VMhosts | Measure-Object NumCpu -Sum).Sum 114 | Write-Verbose "`$ClusterPoweredOnvCPUs for $Cluster is : $ClusterPoweredOnvCPUs" 115 | Write-Verbose "`$ClusterCPUCores for $Cluster is : $ClusterCPUCores" 116 | 117 | # Building a custom object specific to the -Cluster parameter 118 | $ClusterOvercommitProperties = [ordered]@{'Cluster Name'=$Cluster 119 | 'CPU Cores'=$ClusterCPUCores 120 | 'Total vCPUs'=($OvercommitInfoCollection."Total vCPUs" | Measure-Object -Sum).Sum 121 | 'PoweredOn vCPUs'=if ($ClusterPoweredOnvCPUs) {$ClusterPoweredOnvCPUs} Else { 0 -as [int] } 122 | 'vCPU/Core ratio'=if ($ClusterPoweredOnvCPUs) {[Math]::Round(($ClusterPoweredOnvCPUs / $ClusterCPUCores), 3)} Else { $null } 123 | 'CPU Overcommit (%)'=if ($ClusterPoweredOnvCPUs) {[Math]::Round(100*(( $ClusterPoweredOnvCPUs - $ClusterCPUCores) / $ClusterCPUCores), 3)} Else { $null } 124 | } 125 | 126 | $ClusterOvercommitObj = New-Object -TypeName PSObject -Property $ClusterOvercommitProperties 127 | 128 | If ($Quiet) { 129 | $ClusterOvercommitBoolean = $ClusterPoweredOnvCPUs -gt $ClusterCPUCores 130 | $ClusterOvercommitBoolean 131 | } 132 | 133 | Else { $ClusterOvercommitObj 134 | } 135 | } 136 | Else { $OvercommitInfoCollection } 137 | } 138 | } 139 | function Get-MemoryOvercommit { 140 | <# 141 | .SYNOPSIS 142 | Obtains physical memory and virtual memory information for one or more ESXi hosts and compares them to evaluate memory overcommitment. 143 | 144 | .DESCRIPTION 145 | Obtains physical memory and virtual memory information for one or more ESXi hosts (or for a cluster if the Cluster parameter is used) and compares them to evaluate memory overcommitment. 146 | 147 | The memory overcommitment is evaluated by comparing the memory allocated to the running VMs for each ESXi host and the physical RAM on this host. 148 | 149 | .PARAMETER VIServer 150 | To specify the vCenter Server to connect PowerCLI to. 151 | The default is Localhost. 152 | 153 | .PARAMETER VMhosts 154 | To specify one or more ESXi hosts. 155 | The default will query all ESXi hosts managed by the vCenter Server you are connected to in PowerCLI. 156 | This parameter has 2 aliases : "Hosts" and "Servers". 157 | 158 | .PARAMETER Cluster 159 | Outputs global values for the specified cluster 160 | 161 | .PARAMETER Quiet 162 | This mode only outputs a boolean value for each ESXi host (or for the cluster if the Cluster parameter is used) : 163 | $True if there is overcommitment, $False if not. 164 | 165 | .EXAMPLE 166 | Get-MemoryOvercommit -Cluster Production 167 | 168 | Obtains physical RAM, vRAM and overcommitment information, providing global values for the cluster called Production. 169 | 170 | .EXAMPLE 171 | Get-VMHost EsxDev5* | Get-MemoryOvercommit 172 | 173 | Obtains physical RAM, vRAM and overcommitment information for each ESXi host with a name starting with EsxDev5, using pipeline input. 174 | 175 | .EXAMPLE 176 | Get-MemoryOvercommit -Quiet 177 | 178 | Outputs a boolean value stating whether there is RAM overcommitment or not, for each ESXi host managed by the connected vCenter Server. 179 | #> 180 | [cmdletbinding()] 181 | param( 182 | [string]$VIServer = "localhost", 183 | [Parameter(ValueFromPipeline = $True, 184 | ValueFromPipelineByPropertyName=$True, 185 | Position=0)] 186 | [Alias('Hosts','Servers')] 187 | [VMware.VimAutomation.ViCore.Impl.V1.Inventory.VMHostImpl[]]$VMhosts, 188 | [string]$Cluster, 189 | [switch]$Quiet 190 | ) 191 | 192 | Begin { 193 | if(-not (Get-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue)) { 194 | Add-PSSnapin VMware.VimAutomation.Core } 195 | 196 | Set-PowercliConfiguration -InvalidCertificateAction "Ignore" -DisplayDeprecationWarnings:$false -Confirm:$false | Out-Null 197 | 198 | If (-not($defaultVIServer)) { 199 | Connect-VIServer $VIServer 200 | } 201 | Else { 202 | Write-Verbose "Already connected the vCenter Server: $defaultVIServer" 203 | } 204 | # Clearing the default parameter values in the function's scope 205 | $PSDefaultParameterValues.Clear() 206 | 207 | If (-not ($PSBoundParameters.ContainsKey('VMhosts')) ) { 208 | $VMhosts = Get-VMHost 209 | } 210 | # Getting all hosts from the cluster(s) if the -Cluster parameter is specified 211 | If ($PSBoundParameters.ContainsKey('Cluster')) { 212 | $VMhosts = Get-Cluster -Name $Cluster | Get-VMHost 213 | } 214 | # Preparing a collection to store information for each individual ESXi host 215 | $OvercommitInfoCollection = @() 216 | } 217 | 218 | Process { 219 | 220 | Foreach ($VMhost in $VMhosts) { 221 | 222 | $PhysRAM = [Math]::Round($VMhost.MemoryTotalGB, 2) 223 | $HostPoweredOnvRAM = [Math]::Round((Get-VM -Location $VMhost | Where-Object {$_.PowerState -eq "PoweredOn" } | Measure-Object MemoryGB -Sum).Sum, 2) 224 | Write-Verbose "`$PhysRAM for $VMhost is : $PhysRAM" 225 | Write-Verbose "`$HostPoweredOnvRAM for $VMhost is : $HostPoweredOnvRAM" 226 | 227 | # Building the properties for our custom object 228 | $OvercommitInfoProperties = [ordered]@{'ESXi Host'=$VMhost.Name 229 | 'Physical RAM (GB)'=$PhysRAM 230 | 'Total vRAM (GB)'=[Math]::Round((Get-VM -Location $VMhost | Measure-Object MemoryGB -Sum).Sum, 2) 231 | 'PoweredOn vRAM (GB)'=if ($HostPoweredOnvRAM) {$HostPoweredOnvRAM} Else { 0 -as [int] } 232 | 'vRAM/Physical RAM ratio'=if ($HostPoweredOnvRAM) {[Math]::Round(($HostPoweredOnvRAM / $PhysRAM), 3)} Else { $null } 233 | 'RAM Overcommit (%)'=if ($HostPoweredOnvRAM) {[Math]::Round(100*(($HostPoweredOnvRAM - $PhysRAM) / $PhysRAM), 2)} Else { $null } 234 | } 235 | 236 | # Building a custom object from the list of properties above 237 | $OvercommitInfoObj = New-Object -TypeName PSObject -Property $OvercommitInfoProperties 238 | 239 | If ($Quiet) { 240 | $OvercommitInfoBoolean = $HostPoweredOnvRAM -gt $PhysRAM 241 | $OvercommitInfoCollection += $OvercommitInfoBoolean 242 | } 243 | Else { 244 | $OvercommitInfoCollection += $OvercommitInfoObj 245 | } 246 | } 247 | } 248 | End { 249 | If ($PSBoundParameters.ContainsKey('Cluster')) { 250 | 251 | $ClusterPoweredOnvRAM = [Math]::Round((Get-VM -Location $Cluster | Where-Object {$_.PowerState -eq "PoweredOn" } | Measure-Object MemoryGB -Sum).Sum, 2) 252 | $ClusterPhysRAM = [Math]::Round(($VMhosts | Measure-Object MemoryTotalGB -Sum).Sum, 2) 253 | Write-Verbose "`$ClusterPoweredOnvRAM for $Cluster is : $ClusterPoweredOnvRAM" 254 | Write-Verbose "`$ClusterPhysRAM for $Cluster is : $ClusterPhysRAM" 255 | 256 | # Building a custom object specific to the -Cluster parameter 257 | $ClusterOvercommitProperties = [ordered]@{'Cluster Name'=$Cluster 258 | 'Physical RAM (GB)'=$ClusterPhysRAM 259 | 'Total vRAM (GB)'=[Math]::Round(($OvercommitInfoCollection."Total vRAM (GB)" | Measure-Object -Sum).Sum, 2) 260 | 'PoweredOn vRAM (GB)'=if ($ClusterPoweredOnvRAM) {$ClusterPoweredOnvRAM} Else { 0 -as [int] } 261 | 'vRAM/Physical RAM ratio'=if ($ClusterPoweredOnvRAM) {[Math]::Round(($ClusterPoweredOnvRAM / $ClusterPhysRAM), 3)} Else { $null } 262 | 'RAM Overcommit (%)'=if ($ClusterPoweredOnvRAM) {[Math]::Round(100*(( $ClusterPoweredOnvRAM - $ClusterPhysRAM) / $ClusterPhysRAM), 2)} Else { $null } 263 | } 264 | 265 | $ClusterOvercommitObj = New-Object -TypeName PSObject -Property $ClusterOvercommitProperties 266 | 267 | If ($Quiet) { 268 | $ClusterOvercommitBoolean = $ClusterPoweredOnvRAM -gt $ClusterPhysRAM 269 | $ClusterOvercommitBoolean 270 | } 271 | 272 | Else { $ClusterOvercommitObj 273 | } 274 | } 275 | Else { $OvercommitInfoCollection } 276 | } 277 | } 278 | function Get-StorageOvercommit { 279 | <# 280 | .SYNOPSIS 281 | Obtains the used space, provisioned space and capacity for one or more datastores to evaluate storage overcommitment. 282 | 283 | 284 | .DESCRIPTION 285 | Obtains the used space, provisioned space and capacity for one or more datastores and compares them to evaluate storage overcommitment. 286 | 287 | "Storage overcommitment" is evaluated by comparing the provisioned space for all VMs in the datastore (or datastore cluster) with its capacity. 288 | 289 | This storage overcommitment is possible only when there are thin provisioned VMDKs and this doesn't take into account thin provisioning at the LUN level which may be provided by the storage array. 290 | The VMs provisioned space includes the space provisioned for all VMDKs, snapshots, linked clones, swap files and VM logs. 291 | 292 | .PARAMETER VIServer 293 | To specify the vCenter Server to connect PowerCLI to. 294 | The default is Localhost. 295 | 296 | .PARAMETER Datastore 297 | To specify one or more datastores. 298 | The default will query all datastores managed by the vCenter Server you are connected to in PowerCLI. 299 | This parameter has an alias : "Storage". 300 | 301 | .PARAMETER Cluster 302 | Outputs global values for the specified datastore cluster 303 | 304 | .PARAMETER Quiet 305 | This mode only outputs a boolean value for each datastore (or for the datastore cluster if the Cluster parameter is used) : 306 | $True if there is overcommitment, $False if not. 307 | 308 | .EXAMPLE 309 | Get-StorageOvercommit -Cluster Production 310 | 311 | Obtains the used space, provisioned space and capacity, providing global values for the datastore cluster called Production. 312 | 313 | .EXAMPLE 314 | Get-Datastore iSCSI* | Get-StorageOvercommit 315 | 316 | Obtains the used space, provisioned space and capacity for each datastore with a name starting with iSCSI, using pipeline input. 317 | 318 | .EXAMPLE 319 | Get-StorageOvercommit -Quiet 320 | 321 | Outputs a boolean value stating whether there is storage overcommitment or not, for each datastore managed by the connected vCenter Server. 322 | #> 323 | 324 | [cmdletbinding()] 325 | param( 326 | [string]$VIServer = "localhost", 327 | [Parameter(ValueFromPipeline = $True, 328 | ValueFromPipelineByPropertyName=$True, 329 | Position=0)] 330 | [Alias('Storage')] 331 | [VMware.VimAutomation.ViCore.Impl.V1.DatastoreManagement.VmfsDatastoreImpl[]]$Datastore, 332 | [string]$Cluster, 333 | [switch]$Quiet 334 | ) 335 | 336 | Begin { 337 | if(-not (Get-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue)) { 338 | Add-PSSnapin VMware.VimAutomation.Core } 339 | 340 | Set-PowercliConfiguration -InvalidCertificateAction "Ignore" -DisplayDeprecationWarnings:$false -Confirm:$false | Out-Null 341 | 342 | If (-not($defaultVIServer)) { 343 | Connect-VIServer $VIServer 344 | } 345 | Else { 346 | Write-Verbose "Already connected the vCenter Server: $defaultVIServer" 347 | } 348 | # Clearing the default parameter values in the function's scope 349 | $PSDefaultParameterValues.Clear() 350 | 351 | If (-not ($PSBoundParameters.ContainsKey('Datastore')) ) { 352 | $Datastore = Get-Datastore 353 | } 354 | # Getting all hosts from the cluster(s) if the -Cluster parameter is specified 355 | If ($PSBoundParameters.ContainsKey('Cluster')) { 356 | $Datastore = Get-Datastore -Location $Cluster 357 | } 358 | # Preparing a collection to store information for each individual ESXi host 359 | $OvercommitInfoCollection = @() 360 | } 361 | 362 | Process { 363 | 364 | Foreach ($Store in $Datastore) { 365 | 366 | $UsedSpace = [Math]::Round(((Get-VM -Datastore $Store).UsedSpaceGB | Measure-Object -Sum).Sum, 2) 367 | $ProvisionedSpace = [Math]::Round(((Get-VM -Datastore $Store).ProvisionedSpaceGB | Measure-Object -Sum).Sum, 2) 368 | Write-Verbose "`$UsedSpace for $Store is : $UsedSpace" 369 | Write-Verbose "`$ProvisionedSpace for $Store is : $ProvisionedSpace" 370 | 371 | # Building the properties for our custom object 372 | $OvercommitInfoProperties = [ordered]@{'Datastore'=$Store.Name 373 | 'Capacity (GB)'=$Store.CapacityGB 374 | 'Used Space (GB)'=if ($UsedSpace) { $UsedSpace } Else { 0 -as [int] } 375 | 'Provisioned Space (GB)'=if ($ProvisionedSpace) { $ProvisionedSpace } Else { 0 -as [int] } 376 | 'Provisioned / Capacity ratio'=if ($ProvisionedSpace) {[Math]::Round(($ProvisionedSpace / $Store.CapacityGB), 3)} Else { $null } 377 | 'Storage Overcommit (%)'=if ($ProvisionedSpace) {[Math]::Round(100*(($ProvisionedSpace - $Store.CapacityGB) / $Store.CapacityGB), 2)} Else { $null } 378 | } 379 | 380 | # Building a custom object from the list of properties above 381 | $OvercommitInfoObj = New-Object -TypeName PSObject -Property $OvercommitInfoProperties 382 | 383 | If ($Quiet) { 384 | $OvercommitInfoBoolean = $ProvisionedSpace -gt $Store.CapacityGB 385 | $OvercommitInfoCollection += $OvercommitInfoBoolean 386 | } 387 | Else { 388 | $OvercommitInfoCollection += $OvercommitInfoObj 389 | } 390 | } 391 | } 392 | End { 393 | If ($PSBoundParameters.ContainsKey('Cluster')) { 394 | 395 | $ClusterCapacity = [Math]::Round(((Get-DatastoreCluster $Cluster).CapacityGB | Measure-Object -Sum).Sum, 2) 396 | $ClusterUsedSpace = [Math]::Round(((Get-VM -Datastore $Cluster).UsedSpaceGB | Measure-Object -Sum).Sum, 2) 397 | $ClusterProvisionedSpace = [Math]::Round(((Get-VM -Datastore $Cluster).ProvisionedSpaceGB | Measure-Object -Sum).Sum, 2) 398 | Write-Verbose "`$ClusterCapacity for $Cluster is : $ClusterCapacity" 399 | Write-Verbose "`$UsedSpace for $Cluster is : $UsedSpace" 400 | Write-Verbose "`$ProvisionedSpace for $Cluster is : $ProvisionedSpace" 401 | 402 | # Building a custom object specific to the -Cluster parameter 403 | $ClusterOvercommitProperties = [ordered]@{'Datastore Cluster'=$Cluster 404 | 'Capacity (GB)'=$ClusterCapacity 405 | 'Used Space (GB)'=if ($ClusterUsedSpace) { $ClusterUsedSpace } Else { 0 -as [int] } 406 | 'Provisioned Space (GB)'=if ($ClusterProvisionedSpace) { $ClusterProvisionedSpace } Else { 0 -as [int] } 407 | 'Provisioned / Capacity ratio'=if ($ClusterProvisionedSpace) {[Math]::Round(($ClusterProvisionedSpace / $ClusterCapacity), 3)} Else { $null } 408 | 'Storage Overcommit (%)'=if ($ClusterProvisionedSpace) {[Math]::Round(100*(( $ClusterProvisionedSpace - $ClusterCapacity) / $ClusterCapacity), 2)} Else { $null } 409 | } 410 | 411 | $ClusterOvercommitObj = New-Object -TypeName PSObject -Property $ClusterOvercommitProperties 412 | 413 | If ($Quiet) { 414 | $ClusterOvercommitBoolean = $ClusterProvisionedSpace -gt $ClusterCapacity 415 | $ClusterOvercommitBoolean 416 | } 417 | 418 | Else { $ClusterOvercommitObj 419 | } 420 | } 421 | Else { $OvercommitInfoCollection } 422 | } 423 | } 424 | --------------------------------------------------------------------------------