diff --git a/Modules/PSvLIMessage.psm1 b/Modules/PSvLIMessage.psm1
new file mode 100644
index 0000000..9cab209
--- /dev/null
+++ b/Modules/PSvLIMessage.psm1
@@ -0,0 +1,123 @@
+add-type @"
+ using System.Net;
+ using System.Security.Cryptography.X509Certificates;
+ public class TrustAllCertsPolicy : ICertificatePolicy {
+ public bool CheckValidationResult(
+ ServicePoint srvPoint, X509Certificate certificate,
+ WebRequest request, int certificateProblem) {
+ return true;
+ }
+ }
+"@
+[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
+
+<#
+ .NOTES
+ ===========================================================================
+ Created by: Markus Kraus
+ Organization: Private
+ Personal Blog: mycloudrevolution.com
+ Twitter: @vMarkus_K
+ ===========================================================================
+ Tested Against Environment:
+ vRealize Log Insight 3.3.1
+ PowerShell Version: 4.0, 5.0
+ OS Version: Windows 8.1, Server 2012 R2
+ Keyword: vRealize, RestAPI
+
+ Dependencies:
+ PowerCLI Version: PowerCLI 6.3 R1
+
+ .SYNOPSIS
+ Push Messages to VMware vRealize Log Insight.
+
+ .DESCRIPTION
+ Creates a Messages in VMware vRealize Log Insight via the Ingestion API
+
+ .EXAMPLE
+ Push-vLIMessage -vLIServer "loginsight.lan.local" -vLIAgentID "12862842-5A6D-679C-0E38-0E2BE888BB28" -Text "My Test"
+
+ .EXAMPLE
+ Push-vLIMessage -vLIServer "loginsight.lan.local" -vLIAgentID "12862842-5A6D-679C-0E38-0E2BE888BB28" -Text "My Test" -Hostname MyTEST -FieldName myTest -FieldContent myTest
+
+ .PARAMETER vLIServer
+ Specify the FQDN of your vRealize Log Insight Appliance
+
+ .PARAMETER vLIAgentID
+ Specify the vRealize Log Insight Agent ID, e.g. "12862842-5A6D-679C-0E38-0E2BE888BB28"
+
+ .PARAMETER Text
+ Specify the Event Text
+
+ .PARAMETER Hostname
+ Specify the Hostanme displayed in vRealize Log Insight
+
+ .PARAMETER FieldName
+ Specify the a Optional Field Name for vRealize Log Insight
+
+ .PARAMETER FieldContent
+ Specify the a Optional FieldContent for the Field in -FieldName for vRealize Log Insight
+ If FielName is missing and FieldContent is given, it will be ignored
+
+ #Requires PS -Version 3.0
+
+ #>
+function Push-vLIMessage {
+
+ [cmdletbinding()]
+ param (
+ [parameter(Mandatory=$true)]
+ [string]$Text,
+ [parameter(Mandatory=$true)]
+ [string]$vLIServer,
+ [parameter(Mandatory=$true)]
+ [string]$vLIAgentID,
+ [parameter(Mandatory=$false)]
+ [string]$Hostname = $env:computername,
+ [parameter(Mandatory=$false)]
+ [string]$FieldName,
+ [parameter(Mandatory=$false)]
+ [string]$FieldContent = ""
+ )
+ Process {
+ $Field_vLI = [ordered]@{
+ name = "PS_vLIMessage"
+ content = "true"
+ }
+ $Field_HostName = [ordered]@{
+ name = "hostname"
+ content = $Hostname
+ }
+
+ $Fields = @($Field_vLI, $Field_HostName)
+
+ if ($FieldName) {
+ $Field_Custom = [ordered]@{
+ name = $FieldName
+ content = $FieldContent
+ }
+ $Fields += @($Field_Custom)
+ }
+
+ $Restcall = @{
+ messages = ([Object[]]([ordered]@{
+ text = ($Text)
+ fields = ([Object[]]$Fields)
+ }))
+ } | convertto-json -Depth 4
+
+ $Resturl = ("http://" + $vLIServer + ":9000/api/v1/messages/ingest/" + $vLIAgentID)
+ try
+ {
+ $Response = Invoke-RestMethod $Resturl -Method Post -Body $Restcall -ContentType 'application/json' -ErrorAction stop
+ Write-Information "REST Call to Log Insight server successful"
+ Write-Verbose $Response
+ }
+ catch
+ {
+ Write-Error "REST Call failed to Log Insight server"
+ Write-Verbose $error[0]
+ Write-Verbose $Resturl
+ }
+ }
+}
\ No newline at end of file
diff --git a/Modules/Vi-Module/README.md b/Modules/Vi-Module/README.md
new file mode 100644
index 0000000..f7a1f2f
--- /dev/null
+++ b/Modules/Vi-Module/README.md
@@ -0,0 +1,34 @@
+##  VMware infrastructure Module
+
+### [Vi-Module.psm1] (https://github.com/vmware/PowerCLI-Example-Scripts/tree/master/Modules/Vi-Module)
+
+To install this module, drop the entire 'Vi-Module' folder into one of your module directories.
+
+The default PowerShell module paths are listed in the `$env:PSModulePath` environment variable.
+
+To make it look better, split the paths in this manner `$env:PSModulePath -split ';'`
+
+The default per-user module path is: `"$env:HOMEDRIVE$env:HOMEPATH\Documents\WindowsPowerShell\Modules"`.
+
+The default computer-level module path is: `"$env:windir\System32\WindowsPowerShell\v1.0\Modules"`.
+
+To use the module, type following command: `Import-Module Vi-Module -Force -Verbose`.
+
+To see the commands imported, type `Get-Command -Module Vi-Module`.
+
+For help on each individual cmdlet or function, run `Get-Help CmdletName -Full [-Online][-Examples]`.
+
+#### Vi-Module Cmdlets:
+
+|No|Cmdlet|Description|
+|----|----|----|
+|1|[Get-RDM] (http://www.ps1code.com/single-post/2015/10/16/How-to-get-RDM-Raw-Device-Mappings-disks-using-PowerCLi)|Report all VM with their RDM disks|
+|2|[Convert-VmdkThin2EZThick] (http://www.ps1code.com/single-post/2015/11/05/How-to-convert-Thin-Provision-VMDK-disks-to-Eager-Zeroed-Thick-using-PowerCLi)|Inflate thin virtual disks|
+|3|[Find-VcVm] (https://cloud.githubusercontent.com/assets/6964549/17361776/d5dff80e-597a-11e6-85a2-a782db875f78.png)|Search VCenter VM throw direct connection to group of ESXi hosts. Thanks to VMGU.ru for the [article] (http://www.vmgu.ru/news/vmware-vcenter-how-to-find-powered-off)|
+|4|[Set-PowerCLiTitle] (http://www.ps1code.com/single-post/2015/11/17/ConnectVIServer-deep-dive-or-%C2%ABWhere-am-I-connected-%C2%BB)|Write connected VI servers info to PowerCLi window title bar|
+|5|[Get-VMHostFirmwareVersion] (http://www.ps1code.com/single-post/2016/1/9/How-to-know-ESXi-servers%E2%80%99-BIOSFirmware-version-using-PowerCLi)|Get a Firmware version and release date of your ESXi hosts|
+|6|[Compare-VMHostSoftwareVib] (http://www.ps1code.com/single-post/2016/1/10/How-to-compare-installed-VIB-packages-between-two-or-more-ESXi-hosts)|Compare installed VIB packages between two or more ESXi hosts|
+|7|[Get-VMHostBirthday] (https://cloud.githubusercontent.com/assets/6964549/12399803/c8439dfa-be24-11e5-8141-09199caa301e.png)|Get ESXi hosts' installation date. Thanks to Magnus Andersson for his [idea] (http://vcdx56.com/2016/01/05/find-esxi-installation-date/)|
+|8|[Enable-VMHostSSH/Disable-VMHostSSH] (http://www.ps1code.com/single-post/2016/02/07/How-to-enabledisable-SSH-on-all-ESXi-hosts-in-a-cluster-using-PowerCLi)|Enable/Disable SSH on all ESXi hosts in a cluster|
+|9|[Set-VMHostNtpServer] (http://www.ps1code.com/single-post/2016/03/10/How-to-configure-NTP-servers-setting-on-ESXi-hosts-using-PowerCLi)|Set `NTP Servers` setting on ESXi hosts|
+|10|[Get-Version] (http://www.ps1code.com/single-post/2016/05/25/How-to-know-any-VMware-object%E2%80%99s-version-Use-GetVersion)|Get VMware Virtual Infrastructure objects' version info: `VM`, `ESXi Hosts`, `VDSwitches`, `Datastores`, `VCenters`, `PowerCLi`, `License Keys`|
diff --git a/Modules/Vi-Module/Vi-Module.psd1 b/Modules/Vi-Module/Vi-Module.psd1
new file mode 100644
index 0000000..70a5df1
--- /dev/null
+++ b/Modules/Vi-Module/Vi-Module.psd1
@@ -0,0 +1,120 @@
+#
+# Module manifest for module 'Vi-Module'
+#
+# Generated by: Roman Gelman @rgelman75
+#
+# Generated on: 8/1/2016
+#
+
+@{
+
+# Script module or binary module file associated with this manifest.
+RootModule = 'Vi-Module'
+
+# Version number of this module.
+ModuleVersion = '1.0'
+
+# ID used to uniquely identify this module
+GUID = 'a5ad4817-fbef-41b9-b5e2-714a7a16fb26'
+
+# Author of this module
+Author = 'Roman Gelman @rgelman75'
+
+# Company or vendor of this module
+CompanyName = 'Taldor Israel'
+
+# Copyright statement for this module
+Copyright = '(c) 2016 Roman Gelman @rgelman75. All rights reserved.'
+
+# Description of the functionality provided by this module
+Description = 'VMware Virtual Infrastructure Management functions'
+
+# Minimum version of the Windows PowerShell engine required by this module
+PowerShellVersion = '3.0'
+
+# Name of the Windows PowerShell host required by this module
+# PowerShellHostName = ''
+
+# Minimum version of the Windows PowerShell host required by this module
+# PowerShellHostVersion = ''
+
+# Minimum version of Microsoft .NET Framework required by this module
+# DotNetFrameworkVersion = ''
+
+# Minimum version of the common language runtime (CLR) required by this module
+# CLRVersion = ''
+
+# Processor architecture (None, X86, Amd64) required by this module
+# ProcessorArchitecture = ''
+
+# Modules that must be imported into the global environment prior to importing this module
+# RequiredModules = @()
+
+# Assemblies that must be loaded prior to importing this module
+# RequiredAssemblies = @()
+
+# Script files (.ps1) that are run in the caller's environment prior to importing this module.
+# ScriptsToProcess = @()
+
+# Type files (.ps1xml) to be loaded when importing this module
+# TypesToProcess = @()
+
+# Format files (.ps1xml) to be loaded when importing this module
+# FormatsToProcess = @()
+
+# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
+# NestedModules = @()
+
+# Functions to export from this module
+FunctionsToExport = '*'
+
+# Cmdlets to export from this module
+CmdletsToExport = '*'
+
+# Variables to export from this module
+VariablesToExport = '*'
+
+# Aliases to export from this module
+AliasesToExport = '*'
+
+# DSC resources to export from this module
+# DscResourcesToExport = @()
+
+# List of all modules packaged with this module
+# ModuleList = @()
+
+# List of all files packaged with this module
+# FileList = @()
+
+# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
+PrivateData = @{
+
+ PSData = @{
+
+ # Tags applied to this module. These help with module discovery in online galleries.
+ # Tags = @()
+
+ # A URL to the license for this module.
+ # LicenseUri = ''
+
+ # A URL to the main website for this project.
+ ProjectUri = 'https://github.com/rgel/PowerCLi'
+
+ # A URL to an icon representing this module.
+ # IconUri = ''
+
+ # ReleaseNotes of this module
+ # ReleaseNotes = ''
+
+ } # End of PSData hashtable
+
+} # End of PrivateData hashtable
+
+# HelpInfo URI of this module
+# HelpInfoURI = ''
+
+# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
+# DefaultCommandPrefix = ''
+
+}
+
diff --git a/Modules/Vi-Module/Vi-Module.psm1 b/Modules/Vi-Module/Vi-Module.psm1
new file mode 100644
index 0000000..cb1d252
--- /dev/null
+++ b/Modules/Vi-Module/Vi-Module.psm1
@@ -0,0 +1,1241 @@
+Function Get-RDM {
+
+<#
+.SYNOPSIS
+ Get all RDMs.
+.DESCRIPTION
+ This function reports all VMs with their RDM disks.
+.PARAMETER VM
+ VM's collection, returned by Get-VM cmdlet.
+.EXAMPLE
+ C:\PS> Get-VM -Server VC1 |Get-RDM
+.EXAMPLE
+ C:\PS> Get-VM |? {$_.Name -like 'linux*'} |Get-RDM |sort VM,Datastore,HDLabel |ft -au
+.EXAMPLE
+ C:\PS> Get-Datacenter 'North' |Get-VM |Get-RDM |? {$_.HDSizeGB -gt 1} |Export-Csv -NoTypeInformation 'C:\reports\North_RDMs.csv'
+.EXAMPLE
+ C:\PS> $res = Get-Cluster prod |Get-VM |Get-ViMRDM
+ C:\PS> $res |Export-Csv -NoTypeInformation 'C:\reports\ProdCluster_RDMs.csv'
+ Save the results in variable and than export them to a file.
+.INPUTS
+ [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine[]] Get-VM collection.
+.OUTPUTS
+ [System.Management.Automation.PSCustomObject] PSObject collection.
+.NOTES
+ Author: Roman Gelman.
+ Version 1.0 :: 16-Oct-2015 :: Release
+ Version 1.1 :: 03-Dec-2015 :: Bugfix :: Error message appear while VML mismatch,
+ when the VML identifier does not match for an RDM on two or more ESXi hosts.
+ VMware [KB2097287].
+ Version 1.2 :: 03-Aug-2016 :: Improvement :: GetType() method replaced by -is for type determine.
+.LINK
+ http://www.ps1code.com/single-post/2015/10/16/How-to-get-RDM-Raw-Device-Mappings-disks-using-PowerCLi
+#>
+
+[CmdletBinding()]
+
+Param (
+
+ [Parameter(Mandatory=$false,Position=1,ValueFromPipeline=$true,HelpMessage="VM's collection, returned by Get-VM cmdlet")]
+ [ValidateNotNullorEmpty()]
+ [Alias("VM")]
+ [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine[]]$VMs = (Get-VM)
+
+)
+
+Begin {
+
+ $Object = @()
+ $regxVMDK = '^\[(?.+)\]\s(?.+)$'
+ $regxLUNID = ':L(?\d+)$'
+}
+
+Process {
+
+ Foreach ($vm in ($VMs |Get-View)) {
+ Foreach ($dev in $vm.Config.Hardware.Device) {
+ If ($dev -is [VMware.Vim.VirtualDisk]) {
+ If ("physicalMode","virtualMode" -contains $dev.Backing.CompatibilityMode) {
+
+ Write-Progress -Activity "Gathering RDM ..." -CurrentOperation "Hard disk - [$($dev.DeviceInfo.Label)]" -Status "VM - $($vm.Name)"
+
+ $esx = Get-View $vm.Runtime.Host
+ $esxScsiLun = $esx.Config.StorageDevice.ScsiLun |? {$_.Uuid -eq $dev.Backing.LunUuid}
+
+ ### Expand 'LUNID' from device runtime name (vmhba2:C0:T0:L12) ###
+ $lunCN = $esxScsiLun.CanonicalName
+ $Matches = $null
+ If ($lunCN) {
+ $null = (Get-ScsiLun -VmHost $esx.Name -CanonicalName $lunCN -ErrorAction SilentlyContinue).RuntimeName -match $regxLUNID
+ $lunID = $Matches.LUNID
+ } Else {$lunID = ''}
+
+ ### Expand 'Datastore' and 'VMDK' from file path ###
+ $null = $dev.Backing.FileName -match $regxVMDK
+
+ $Properties = [ordered]@{
+ VM = $vm.Name
+ VMHost = $esx.Name
+ Datastore = $Matches.Datastore
+ VMDK = $Matches.Filename
+ HDLabel = $dev.DeviceInfo.Label
+ HDSizeGB = [math]::Round(($dev.CapacityInKB / 1MB), 3)
+ HDMode = $dev.Backing.CompatibilityMode
+ DeviceName = $dev.Backing.DeviceName
+ Vendor = $esxScsiLun.Vendor
+ CanonicalName = $lunCN
+ LUNID = $lunID
+ }
+ $Object = New-Object PSObject -Property $Properties
+ $Object
+ }
+ }
+ }
+ }
+}
+
+End {
+ Write-Progress -Completed $true -Status "Please wait"
+}
+
+} #EndFunction Get-RDM
+New-Alias -Name Get-ViMRDM -Value Get-RDM -Force:$true
+
+Function Convert-VmdkThin2EZThick {
+
+<#
+.SYNOPSIS
+ Inflate thin virtual disks.
+.DESCRIPTION
+ This function converts all Thin Provisioned VM' disks to type 'Thick Provision Eager Zeroed'.
+.PARAMETER VM
+ Virtual Machine(s).
+.EXAMPLE
+ C:\PS> Get-VM VM1 |Convert-VmdkThin2EZThick
+.EXAMPLE
+ C:\PS> Get-VM VM1,VM2 |Convert-VmdkThin2EZThick -Confirm:$false |sort VM,Datastore,VMDK |ft -au
+.INPUTS
+ [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine[]] Objects, returned by Get-VM cmdlet.
+.OUTPUTS
+ [System.Management.Automation.PSCustomObject] PSObject collection.
+.NOTES
+ Author: Roman Gelman.
+ Version 1.0 :: 05-Nov-2015 :: Release.
+ Version 1.1 :: 03-Aug-2016 :: Improvements ::
+ [1] GetType() method replaced by -is for type determine.
+ [2] Parameter 'VMs' renamed to 'VM', parameter alias renamed from 'VM' to 'VMs'.
+.LINK
+ http://www.ps1code.com/single-post/2015/11/05/How-to-convert-Thin-Provision-VMDK-disks-to-Eager-Zeroed-Thick-using-PowerCLi
+#>
+
+[CmdletBinding(ConfirmImpact='High',SupportsShouldProcess=$true)]
+
+Param (
+
+ [Parameter(Mandatory=$true,Position=1,ValueFromPipeline=$true,HelpMessage="VM's collection, returned by Get-VM cmdlet")]
+ [ValidateNotNullorEmpty()]
+ [Alias("VMs")]
+ [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine[]]$VM
+
+)
+
+Begin {
+
+ $Object = @()
+ $regxVMDK = '^\[(?.+)\]\s(?.+)$'
+
+}
+
+Process {
+
+ Foreach ($vmv in ($VM |Get-View)) {
+
+ ### Ask confirmation to proceed if VM is PoweredOff ###
+ If ($vmv.Runtime.PowerState -eq 'poweredOff' -and $PSCmdlet.ShouldProcess("VM [$($vmv.Name)]","Convert all Thin Provisioned VMDK to Type: 'Thick Provision Eager Zeroed'")) {
+
+ ### Get ESXi object where $vmv is registered ###
+ $esx = Get-View $vmv.Runtime.Host
+
+ ### Get Datacenter object where $vmv is registered ###
+ $parentObj = Get-View $vmv.Parent
+ While ($parentObj -isnot [VMware.Vim.Datacenter]) {$parentObj = Get-View $parentObj.Parent}
+ $datacenter = New-Object VMware.Vim.ManagedObjectReference
+ $datacenter.Type = 'Datacenter'
+ $datacenter.Value = $parentObj.MoRef.Value
+
+ Foreach ($dev in $vmv.Config.Hardware.Device) {
+ If ($dev -is [VMware.Vim.VirtualDisk]) {
+ If ($dev.Backing.ThinProvisioned -and $dev.Backing.Parent -eq $null) {
+
+ $sizeGB = [math]::Round(($dev.CapacityInKB / 1MB), 1)
+
+ ### Invoke 'Inflate virtual disk' task ###
+ $ViDM = Get-View -Id 'VirtualDiskManager-virtualDiskManager'
+ $taskMoRef = $ViDM.InflateVirtualDisk_Task($dev.Backing.FileName, $datacenter)
+ $task = Get-View $taskMoRef
+
+ ### Show task progress ###
+ For ($i=1; $i -lt [int32]::MaxValue; $i++) {
+ If ("running","queued" -contains $task.Info.State) {
+ $task.UpdateViewData("Info")
+ If ($task.Info.Progress -ne $null) {
+ Write-Progress -Activity "Inflate virtual disk task is in progress ..." -Status "VM - $($vmv.Name)" `
+ -CurrentOperation "$($dev.DeviceInfo.Label) - $($dev.Backing.FileName) - $sizeGB GB" `
+ -PercentComplete $task.Info.Progress -ErrorAction SilentlyContinue
+ Start-Sleep -Seconds 3
+ }
+ }
+ Else {Break}
+ }
+
+ ### Get task completion results ###
+ $tResult = $task.Info.State
+ $tStart = $task.Info.StartTime
+ $tEnd = $task.Info.CompleteTime
+ $tCompleteTime = [math]::Round((New-TimeSpan -Start $tStart -End $tEnd).TotalMinutes, 1)
+
+ ### Expand 'Datastore' and 'VMDK' from file path ###
+ $null = $dev.Backing.FileName -match $regxVMDK
+
+ $Properties = [ordered]@{
+ VM = $vmv.Name
+ VMHost = $esx.Name
+ Datastore = $Matches.Datastore
+ VMDK = $Matches.Filename
+ HDLabel = $dev.DeviceInfo.Label
+ HDSizeGB = $sizeGB
+ Result = $tResult
+ StartTime = $tStart
+ CompleteTime = $tEnd
+ TimeMin = $tCompleteTime
+ }
+ $Object = New-Object PSObject -Property $Properties
+ $Object
+ }
+ }
+ }
+ $vmv.Reload()
+ }
+ }
+}
+
+End {
+ Write-Progress -Completed $true -Status "Please wait"
+}
+
+} #EndFunction Convert-VmdkThin2EZThick
+New-Alias -Name Convert-ViMVmdkThin2EZThick -Value Convert-VmdkThin2EZThick -Force:$true
+
+Function Find-VcVm {
+
+<#
+.SYNOPSIS
+ Search VC's VM throw direct connection to group of ESXi Hosts.
+.DESCRIPTION
+ This script generates a list of ESXi Hosts with common suffix in a name,
+ e.g. (esxprod1,esxprod2, ...) or (esxdev01,esxdev02, ...) etc. and
+ searches VCenter's VM throw direct connection to this group of ESXi Hosts.
+.PARAMETER VC
+ VC's VM Name.
+.PARAMETER HostSuffix
+ ESXi Hosts' common suffix.
+.PARAMETER PostfixStart
+ ESXi Hosts' postfix number start.
+.PARAMETER PostfixEnd
+ ESXi Hosts' postfix number end.
+.PARAMETER AddZero
+ Add ESXi Hosts' postfix leading zero to one-digit postfix (from 01 to 09).
+.EXAMPLE
+ PS C:\> Find-VcVm vc1 esxprod 1 20 -AddZero
+.EXAMPLE
+ PS C:\> Find-VcVm -VC vc1 -HostSuffix esxdev -PostfixEnd 6
+.EXAMPLE
+ PS C:\> Find-VcVm vc1 esxprod |fl
+.NOTES
+ Author :: Roman Gelman.
+ Limitation :: [1] The function uses common credentials for all ESXi hosts.
+ [2] The hosts' Lockdown mode should be disabled.
+ Version 1.0 :: 03-Sep-2015 :: Release.
+ Version 1.1 :: 03-Aug-2016 :: Improvement :: Returned object properties changed.
+.OUTPUTS
+ [System.Management.Automation.PSCustomObject] PSObject collection.
+.LINK
+ http://ps1code.com
+#>
+
+Param (
+
+ [Parameter(Mandatory=$true,Position=1,HelpMessage="vCenter's VM Name")]
+ [Alias("vCenter","VcVm")]
+ [string]$VC
+ ,
+ [Parameter(Mandatory=$true,Position=2,HelpMessage="ESXi Hosts' common suffix")]
+ [Alias("VMHostSuffix","ESXiSuffix")]
+ [string]$HostSuffix
+ ,
+ [Parameter(Mandatory=$false,Position=3,HelpMessage="ESXi Hosts' postfix number start")]
+ [ValidateRange(1,98)]
+ [Alias("PostfixFirst","Start")]
+ [int]$PostfixStart = 1
+ ,
+ [Parameter(Mandatory=$false,Position=4,HelpMessage="ESXi Hosts' postfix number end")]
+ [ValidateRange(2,99)]
+ [Alias("PostfixLast","End")]
+ [int]$PostfixEnd = 9
+ ,
+ [Parameter(Mandatory=$false,Position=5,HelpMessage="Add ESXi Hosts' postfix leading zero")]
+ [switch]$AddZero = $false
+)
+
+Begin {
+
+ Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -Scope Session -Confirm:$false |Out-Null
+ If ($PostfixEnd -le $PostfixStart) {Throw "PostfixEnd must be greater than PostfixStart"}
+}
+
+Process {
+
+ $cred = Get-Credential -UserName root -Message "Common VMHost Credentials"
+ If ($cred) {
+ $hosts = @()
+
+ For ($i=$PostfixStart; $i -le $PostfixEnd; $i++) {
+ If ($AddZero -and $i -match '^\d{1}$') {
+ $hosts += $HostSuffix + '0' + $i
+ } Else {
+ $hosts += $HostSuffix + $i
+ }
+ }
+
+ Connect-VIServer $hosts -WarningAction SilentlyContinue -ErrorAction SilentlyContinue -Credential $cred `
+ |select @{N='VMHost';E={$_.Name}},IsConnected |ft -AutoSize
+
+ If ($global:DefaultVIServers.Length -ne 0) {
+ $TargetVM = Get-VM -ErrorAction SilentlyContinue |? {$_.Name -eq $VC}
+ $VCHostname = $TargetVM.Guest.HostName
+ $PowerState = $TargetVM.PowerState
+ $VMHostHostname = $TargetVM.VMHost.Name
+ Disconnect-VIServer -Server '*' -Force -Confirm:$false
+ }
+ }
+}
+
+End {
+
+ If ($TargetVM) {
+ $Properties = [ordered]@{
+ VC = $VC
+ Hostname = $VCHostname
+ PowerState = $PowerState
+ VMHost = $VMHostHostname
+ }
+ $Object = New-Object PSObject -Property $Properties
+ $Object
+ }
+}
+
+} #EndFunction Find-VcVm
+New-Alias -Name Find-ViMVcVm -Value Find-VcVm -Force:$true
+
+Function Set-PowerCLiTitle {
+
+<#
+.SYNOPSIS
+ Write connected VI servers info to PowerCLi window title bar.
+.DESCRIPTION
+ This function write connected VI servers info to PowerCLi window/console title bar [Name :: Product (VCenter/ESXi) ProductVersion].
+.EXAMPLE
+ C:\PS> Set-PowerCLiTitle
+.NOTES
+ Author: Roman Gelman.
+.LINK
+ http://www.ps1code.com/single-post/2015/11/17/ConnectVIServer-deep-dive-or-%C2%ABWhere-am-I-connected-%C2%BB
+#>
+
+$VIS = $global:DefaultVIServers |sort -Descending ProductLine,Name
+
+If ($VIS) {
+ Foreach ($VIObj in $VIS) {
+ If ($VIObj.IsConnected) {
+ Switch -exact ($VIObj.ProductLine) {
+ vpx {$VIProduct = 'VCenter'; Break}
+ embeddedEsx {$VIProduct = 'ESXi'; Break}
+ Default {$VIProduct = $VIObj.ProductLine; Break}
+ }
+ $Header += "[$($VIObj.Name) :: $VIProduct$($VIObj.Version)] "
+ }
+ }
+} Else {
+ $Header = ':: Not connected to Virtual Infra Services ::'
+}
+
+$Host.UI.RawUI.WindowTitle = $Header
+
+} #EndFunction Set-PowerCLiTitle
+New-Alias -Name Set-ViMPowerCLiTitle -Value Set-PowerCLiTitle -Force:$true
+
+Filter Get-VMHostFirmwareVersion {
+
+<#
+.SYNOPSIS
+ Get ESXi host BIOS version.
+.DESCRIPTION
+ This filter returns ESXi host BIOS/UEFI Version and Release Date as a single string.
+.EXAMPLE
+ PS C:\> Get-VMHost 'esxprd1.*' |Get-VMHostFirmwareVersion
+ Get single ESXi host's Firmware version.
+.EXAMPLE
+ PS C:\> Get-Cluster PROD |Get-VMHost |select Name,@{N='BIOS';E={$_ |Get-VMHostFirmwareVersion}}
+ Get ESXi Name and Firmware version for single cluster.
+.EXAMPLE
+ PS C:\> Get-VMHost |sort Name |select Name,Version,Manufacturer,Model,@{N='BIOS';E={$_ |Get-VMHostFirmwareVersion}} |ft -au
+ Add calculated property, that will contain Firmware version for all registered ESXi hosts.
+.EXAMPLE
+ PS C:\> Get-View -ViewType 'HostSystem' |select Name,@{N='BIOS';E={$_ |Get-VMHostFirmwareVersion}}
+.EXAMPLE
+ PS C:\> 'esxprd1.domain.com','esxdev2' |Get-VMHostFirmwareVersion
+.INPUTS
+ [VMware.VimAutomation.ViCore.Types.V1.Inventory.VMHost[]] Objects, returned by Get-VMHost cmdlet.
+ [VMware.Vim.HostSystem[]] Objects, returned by Get-View cmdlet.
+ [System.String[]] ESXi hostname or FQDN.
+.OUTPUTS
+ [System.String[]] BIOS/UEFI version and release date.
+.NOTES
+ Author: Roman Gelman.
+ Version 1.0 :: 09-Jan-2016 :: Release.
+ Version 1.1 :: 03-Aug-2016 :: Improvement :: GetType() method replaced by -is for type determine.
+.LINK
+ http://www.ps1code.com/single-post/2016/1/9/How-to-know-ESXi-servers%E2%80%99-BIOSFirmware-version-using-PowerCLi
+#>
+
+Try
+ {
+ If ($_ -is [VMware.VimAutomation.ViCore.Types.V1.Inventory.VMHost]) {$BiosInfo = ($_ |Get-View).Hardware.BiosInfo}
+ ElseIf ($_ -is [VMware.Vim.HostSystem]) {$BiosInfo = $_.Hardware.BiosInfo}
+ ElseIf ($_ -is [string]) {$BiosInfo = (Get-View -ViewType HostSystem -Filter @{"Name" = $_}).Hardware.BiosInfo}
+ Else {Throw "Not supported data type as pipeline"}
+
+ $fVersion = $BiosInfo.BiosVersion -replace ('^-\[|\]-$', $null)
+ $fDate = [Regex]::Match($BiosInfo.ReleaseDate, '(\d{1,2}/){2}\d+').Value
+ If ($fVersion) {return "$fVersion [$fDate]"} Else {return $null}
+ }
+Catch
+ {}
+} #EndFilter Get-VMHostFirmwareVersion
+New-Alias -Name Get-ViMVMHostFirmwareVersion -Value Get-VMHostFirmwareVersion -Force:$true
+
+Function Compare-VMHostSoftwareVib {
+
+<#
+.SYNOPSIS
+ Compares the installed VIB packages between VMware ESXi Hosts.
+.DESCRIPTION
+ This function compares the installed VIB packages between reference ESXi Host and
+ group of difference/target ESXi Hosts or single ESXi Host.
+.PARAMETER ReferenceVMHost
+ Reference VMHost.
+.PARAMETER DifferenceVMHosts
+ Target VMHosts to compare them with the reference VMHost.
+.EXAMPLE
+ PS C:\> Compare-VMHostSoftwareVib -ReferenceVMHost (Get-VMHost 'esxprd1.*') -DifferenceVMHosts (Get-VMHost 'esxprd2.*')
+ Compare two ESXi hosts.
+.EXAMPLE
+ PS C:\> Get-VMHost 'esxdev2.*','esxdev3.*' |Compare-VMHostSoftwareVib -ReferenceVMHost (Get-VMHost 'esxdev1.*')
+ Compare two target ESXi Hosts with the reference Host.
+.EXAMPLE
+ PS C:\> Get-Cluster DEV |Get-VMHost |Compare-VMHostSoftwareVib -ReferenceVMHost (Get-VMHost 'esxdev1.*')
+ Compare all HA/DRS cluster members with the reference ESXi Host.
+.EXAMPLE
+ PS C:\> Get-Cluster PRD |Get-VMHost |Compare-VMHostSoftwareVib -ReferenceVMHost (Get-VMHost 'esxhai1.*') |Export-Csv -NoTypeInformation -Path '.\VibCompare.csv'
+ Export the comparison report to the file.
+.INPUTS
+ [VMware.VimAutomation.ViCore.Types.V1.Inventory.VMHost[]] Objects, returned by Get-VMHost cmdlet.
+.OUTPUTS
+ [System.Management.Automation.PSCustomObject] PSObject collection.
+.NOTES
+ Author :: Roman Gelman.
+ Dependencies :: ESXCLI V2 works on vCenter 5.0/ESXi 5.0 and later.
+ Version 1.0 :: 10-Jan-2016 :: Release.
+ Version 1.1 :: 01-May-2016 :: Improvement :: Added support for PowerCLi 6.3R1 and ESXCLI V2 interface.
+.LINK
+ http://www.ps1code.com/single-post/2016/1/10/How-to-compare-installed-VIB-packages-between-two-or-more-ESXi-hosts
+#>
+
+Param (
+
+ [Parameter(Mandatory,Position=1,HelpMessage="Reference VMHost")]
+ [Alias("ReferenceESXi")]
+ [VMware.VimAutomation.ViCore.Types.V1.Inventory.VMHost]$ReferenceVMHost
+ ,
+ [Parameter(Mandatory,Position=2,ValueFromPipeline,HelpMessage="Difference VMHosts collection")]
+ [Alias("DifferenceESXi","DifferenceVMHosts")]
+ [VMware.VimAutomation.ViCore.Types.V1.Inventory.VMHost[]]$DifferenceVMHost
+)
+
+Begin {
+ $PcliVer = Get-PowerCLIVersion -ErrorAction SilentlyContinue
+ $PcliMM = ($PcliVer.Major.ToString() + $PcliVer.Minor.ToString()) -as [int]
+}
+
+Process {
+
+ Try
+ {
+ If ($PcliMM -ge 63) {
+ $esxcliRef = Get-EsxCli -V2 -VMHost $ReferenceVMHost -ErrorAction Stop
+ $refVibId = ($esxcliRef.software.vib.list.Invoke()).ID
+ }
+ Else {
+ $esxcliRef = Get-EsxCli -VMHost $ReferenceVMHost -ErrorAction Stop
+ $refVibId = ($esxcliRef.software.vib.list()).ID
+ }
+ }
+ Catch
+ {
+ "{0}" -f $Error.Exception.Message
+ }
+
+ Foreach ($esx in $DifferenceVMHosts) {
+
+ Try
+ {
+ If ($PcliMM -ge 63) {
+ $esxcliDif = Get-EsxCli -V2 -VMHost $esx -ErrorAction Stop
+ $difVibId = ($esxcliDif.software.vib.list.Invoke()).ID
+ }
+ Else {
+ $esxcliDif = Get-EsxCli -VMHost $esx -ErrorAction Stop
+ $difVibId = ($esxcliDif.software.vib.list()).ID
+ }
+ $diffObj = Compare-Object -ReferenceObject $refVibId -DifferenceObject $difVibId -IncludeEqual:$false
+ Foreach ($diff in $diffObj) {
+ If ($diff.SideIndicator -eq '=>') {$diffOwner = $esx} Else {$diffOwner = $ReferenceVMHost}
+ $Properties = [ordered]@{
+ VIB = $diff.InputObject
+ VMHost = $diffOwner
+ }
+ $Object = New-Object PSObject -Property $Properties
+ $Object
+ }
+ }
+ Catch
+ {
+ "{0}" -f $Error.Exception.Message
+ }
+ }
+}
+
+} #EndFunction Compare-VMHostSoftwareVib
+New-Alias -Name Compare-ViMVMHostSoftwareVib -Value Compare-VMHostSoftwareVib -Force:$true
+
+Filter Get-VMHostBirthday {
+
+<#
+.SYNOPSIS
+ Get ESXi host installation date (Birthday).
+.DESCRIPTION
+ This filter returns ESXi host installation date.
+.EXAMPLE
+ PS C:\> Get-VMHost 'esxprd1.*' |Get-VMHostBirthday
+ Get single ESXi host's Birthday.
+.EXAMPLE
+ PS C:\> Get-Cluster DEV |Get-VMHost |select Name,Version,@{N='Birthday';E={$_ |Get-VMHostBirthday}} |sort Name
+ Get ESXi Name and Birthday for single cluster.
+.EXAMPLE
+ PS C:\> 'esxprd1.domain.com','esxprd2' |select @{N='ESXi';E={$_}},@{N='Birthday';E={$_ |Get-VMHostBirthday}}
+ Pipe hostnames (strings) to the function.
+.EXAMPLE
+ PS C:\> Get-VMHost |select Name,@{N='Birthday';E={($_ |Get-VMHostBirthday).ToString('yyyy-MM-dd HH:mm:ss')}} |sort Name |ft -au
+ Format output using ToString() method.
+ http://blogs.technet.com/b/heyscriptingguy/archive/2015/01/22/formatting-date-strings-with-powershell.aspx
+.INPUTS
+ [VMware.VimAutomation.ViCore.Types.V1.Inventory.VMHost[]] Objects, returned by Get-VMHost cmdlet.
+ [System.String[]] ESXi hostname or FQDN.
+.OUTPUTS
+ [System.DateTime[]] ESXi installation date/time.
+.NOTES
+ Original idea: Magnus Andersson
+ Author: Roman Gelman
+ Requirements: vSphere 5.x or above
+.LINK
+ http://vcdx56.com/2016/01/05/find-esxi-installation-date/
+#>
+
+Try
+ {
+ $EsxCli = Get-EsxCli -VMHost $_ -ErrorAction Stop
+ $Uuid = $EsxCli.system.uuid.get()
+ $bdHexa = [Regex]::Match($Uuid, '^(\w{8,})-').Groups[1].Value
+ $bdDeci = [Convert]::ToInt64($bdHexa, 16)
+ $bdDate = [TimeZone]::CurrentTimeZone.ToLocalTime(([DateTime]'1/1/1970').AddSeconds($bdDeci))
+ If ($bdDate) {return $bdDate} Else {return $null}
+ }
+Catch
+ { }
+} #EndFilter Get-VMHostBirthday
+New-Alias -Name Get-ViMVMHostBirthday -Value Get-VMHostBirthday -Force:$true
+
+Function Enable-VMHostSSH {
+
+<#
+.SYNOPSIS
+ Enable SSH on all ESXi hosts in a cluster.
+.DESCRIPTION
+ This function enables SSH on all ESXi hosts in a cluster.
+ It starts the SSH daemon and opens incoming TCP connections on port 22.
+.EXAMPLE
+ PS C:\> Get-Cluster PROD |Enable-VMHostSSH
+.EXAMPLE
+ PS C:\> Get-Cluster DEV,TEST |Enable-VMHostSSH |sort Cluster,VMHost |Format-Table -AutoSize
+.INPUTS
+ [VMware.VimAutomation.ViCore.Impl.V1.Inventory.ClusterImpl[]] Clusters collection, returtned by Get-Cluster cmdlet.
+.OUTPUTS
+ [System.Management.Automation.PSCustomObject] PSObject collection.
+.NOTES
+ Author :: Roman Gelman.
+ Version 1.0 :: 07-Feb-2016 :: Release.
+ Version 1.1 :: 02-Aug-2016 :: -Cluster parameter data type changed to the portable type.
+.LINK
+ http://www.ps1code.com/single-post/2016/02/07/How-to-enabledisable-SSH-on-all-ESXi-hosts-in-a-cluster-using-PowerCLi
+#>
+
+Param (
+
+ [Parameter(Mandatory=$false,Position=0,ValueFromPipeline=$true)]
+ [ValidateNotNullorEmpty()]
+ [VMware.VimAutomation.ViCore.Types.V1.Inventory.Cluster[]]$Cluster = (Get-Cluster)
+)
+
+Process {
+
+ Foreach ($container in $Cluster) {
+ Foreach ($esx in Get-VMHost -Location $container) {
+
+ If ('Connected','Maintenance' -contains $esx.ConnectionState -and $esx.PowerState -eq 'PoweredOn') {
+
+ $sshSvc = Get-VMHostService -VMHost $esx |? {$_.Key -eq 'TSM-SSH'} |Start-VMHostService -Confirm:$false -ErrorAction Stop
+ If ($sshSvc.Running) {$sshStatus = 'Running'} Else {$sshStatus = 'NotRunning'}
+ $fwRule = Get-VMHostFirewallException -VMHost $esx -Name 'SSH Server' |Set-VMHostFirewallException -Enabled $true -ErrorAction Stop
+
+ $Properties = [ordered]@{
+ Cluster = $container.Name
+ VMHost = $esx.Name
+ State = $esx.ConnectionState
+ PowerState = $esx.PowerState
+ SSHDaemon = $sshStatus
+ SSHEnabled = $fwRule.Enabled
+ }
+ }
+ Else {
+
+ $Properties = [ordered]@{
+ Cluster = $container.Name
+ VMHost = $esx.Name
+ State = $esx.ConnectionState
+ PowerState = $esx.PowerState
+ SSHDaemon = 'Unknown'
+ SSHEnabled = 'Unknown'
+ }
+ }
+ $Object = New-Object PSObject -Property $Properties
+ $Object
+ }
+ }
+
+}
+
+} #EndFunction Enable-VMHostSSH
+New-Alias -Name Enable-ViMVMHostSSH -Value Enable-VMHostSSH -Force:$true
+
+Function Disable-VMHostSSH {
+
+<#
+.SYNOPSIS
+ Disable SSH on all ESXi hosts in a cluster.
+.DESCRIPTION
+ This function disables SSH on all ESXi hosts in a cluster.
+ It stops the SSH daemon and (optionally) blocks incoming TCP connections on port 22.
+.PARAMETER BlockFirewall
+ Try to disable "SSH Server" firewall exception rule.
+ It might fail if this rule categorized as "Required Services" (VMware KB2037544).
+.EXAMPLE
+ PS C:\> Get-Cluster PROD |Disable-VMHostSSH -BlockFirewall
+.EXAMPLE
+ PS C:\> Get-Cluster DEV,TEST |Disable-VMHostSSH |sort Cluster,VMHost |Format-Table -AutoSize
+.INPUTS
+ [VMware.VimAutomation.ViCore.Impl.V1.Inventory.ClusterImpl[]] Clusters collection, returtned by Get-Cluster cmdlet.
+.OUTPUTS
+ [System.Management.Automation.PSCustomObject] PSObject collection.
+.NOTES
+ Author :: Roman Gelman.
+ Version 1.0 :: 07-Feb-2016 :: Release.
+ Version 1.1 :: 02-Aug-2016 :: -Cluster parameter data type changed to the portable type.
+.LINK
+ http://www.ps1code.com/single-post/2016/02/07/How-to-enabledisable-SSH-on-all-ESXi-hosts-in-a-cluster-using-PowerCLi
+#>
+
+Param (
+
+ [Parameter(Mandatory=$false,Position=0,ValueFromPipeline=$true)]
+ [ValidateNotNullorEmpty()]
+ [VMware.VimAutomation.ViCore.Types.V1.Inventory.Cluster[]]$Cluster = (Get-Cluster)
+ ,
+ [Parameter(Mandatory=$false,Position=1)]
+ [Switch]$BlockFirewall
+)
+
+Process {
+
+ Foreach ($container in $Cluster) {
+ Foreach ($esx in Get-VMHost -Location $container) {
+
+ If ('Connected','Maintenance' -contains $esx.ConnectionState -and $esx.PowerState -eq 'PoweredOn') {
+
+ $sshSvc = Get-VMHostService -VMHost $esx |? {$_.Key -eq 'TSM-SSH'} |Stop-VMHostService -Confirm:$false -ErrorAction Stop
+ If ($sshSvc.Running) {$sshStatus = 'Running'} Else {$sshStatus = 'NotRunning'}
+ $fwRule = Get-VMHostFirewallException -VMHost $esx -Name 'SSH Server'
+ If ($BlockFirewall) {
+ Try {$fwRule = Set-VMHostFirewallException -Exception $fwRule -Enabled:$false -Confirm:$false -ErrorAction Stop}
+ Catch {}
+ }
+
+ $Properties = [ordered]@{
+ Cluster = $container.Name
+ VMHost = $esx.Name
+ State = $esx.ConnectionState
+ PowerState = $esx.PowerState
+ SSHDaemon = $sshStatus
+ SSHEnabled = $fwRule.Enabled
+ }
+ }
+ Else {
+
+ $Properties = [ordered]@{
+ Cluster = $container.Name
+ VMHost = $esx.Name
+ State = $esx.ConnectionState
+ PowerState = $esx.PowerState
+ SSHDaemon = 'Unknown'
+ SSHEnabled = 'Unknown'
+ }
+ }
+ $Object = New-Object PSObject -Property $Properties
+ $Object
+ }
+ }
+
+}
+
+} #EndFunction Disable-VMHostSSH
+New-Alias -Name Disable-ViMVMHostSSH -Value Disable-VMHostSSH -Force:$true
+
+Function Set-VMHostNtpServer {
+
+<#
+.SYNOPSIS
+ Set NTP server settings on a group of ESXi hosts.
+.DESCRIPTION
+ This cmdlet sets NTP server settings on a group of ESXi hosts
+ and restarts the NTP daemon to apply these settings.
+.PARAMETER VMHost
+ ESXi hosts.
+.PARAMETER NewNtp
+ NTP servers (IP/Hostname).
+.EXAMPLE
+ PS C:\> Set-VMHostNtpServer -NewNtp 'ntp1','ntp2'
+ Set two NTP servers to all hosts in inventory.
+.EXAMPLE
+ PS C:\> Get-VMHost 'esx1.*','esx2.*' |Set-VMHostNtpServer -NewNtp 'ntp1','ntp2'
+.EXAMPLE
+ PS C:\> Get-Cluster DEV,TEST |Get-VMHost |sort Parent,Name |Set-VMHostNtpServer -NewNtp 'ntp1','10.1.2.200' |ft -au
+.EXAMPLE
+ PS C:\> Get-VMHost -Location Datacenter1 |sort Name |Set-VMHostNtpServer -NewNtp 'ntp1','ntp2' |epcsv -notype -Path '.\Ntp_report.csv'
+ Export the results to Excel.
+.INPUTS
+ [VMware.VimAutomation.ViCore.Types.V1.Inventory.VMHost[]] VMHost collection returned by Get-VMHost cmdlet.
+.OUTPUTS
+ [System.Management.Automation.PSCustomObject] PSObject collection.
+.NOTES
+ Author :: Roman Gelman.
+ Version 1.0 :: 10-Mar-2016 :: Release.
+.LINK
+ http://www.ps1code.com/single-post/2016/03/10/How-to-configure-NTP-servers-setting-on-ESXi-hosts-using-PowerCLi
+#>
+
+[CmdletBinding()]
+
+Param (
+
+ [Parameter(Mandatory=$false,Position=1,ValueFromPipeline=$true)]
+ [ValidateNotNullorEmpty()]
+ [VMware.VimAutomation.ViCore.Types.V1.Inventory.VMHost[]]$VMHost = (Get-VMHost)
+ ,
+ [Parameter(Mandatory,Position=2)]
+ [System.String[]]$NewNtp
+)
+
+Begin {
+ $ErrorActionPreference = 'Stop'
+}
+
+Process {
+
+ Foreach ($esx in $VMHost) {
+
+ If ('Connected','Maintenance' -contains $esx.ConnectionState -and $esx.PowerState -eq 'PoweredOn') {
+
+ ### Get current Ntp ###
+ $Ntps = Get-VMHostNtpServer -VMHost $esx
+
+ ### Remove previously configured Ntp ###
+ $removed = $false
+ Try
+ {
+ Remove-VMHostNtpServer -NtpServer $Ntps -VMHost $esx -Confirm:$false
+ $removed = $true
+ }
+ Catch { }
+
+ ### Add new Ntp ###
+ $added = $null
+ Try
+ {
+ $added = Add-VMHostNtpServer -NtpServer $NewNtp -VMHost $esx -Confirm:$false
+ }
+ Catch { }
+
+ ### Restart NTP Daemon ###
+ $restarted = $false
+ Try
+ {
+ If ($added) {Get-VMHostService -VMHost $esx |? {$_.Key -eq 'ntpd'} |Restart-VMHostService -Confirm:$false |Out-Null}
+ $restarted = $true
+ }
+ Catch {}
+
+ ### Return results ###
+ $Properties = [ordered]@{
+ VMHost = $esx
+ OldNtp = $Ntps
+ IsOldRemoved = $removed
+ NewNtp = $added
+ IsDaemonRestarted = $restarted
+ }
+ $Object = New-Object PSObject -Property $Properties
+ $Object
+ }
+ Else {Write-Warning "VMHost '$($esx.Name)' is in unsupported state"}
+ }
+
+}
+
+} #EndFunction Set-VMHostNtpServer
+New-Alias -Name Set-ViMVMHostNtpServer -Value Set-VMHostNtpServer -Force:$true
+
+Function Get-Version {
+
+<#
+.SYNOPSIS
+ Get VMware Virtual Infrastructure objects' version info.
+.DESCRIPTION
+ This cmdlet gets VMware Virtual Infrastructure objects' version info.
+.PARAMETER VIObject
+ Vitual Infrastructure objects (VM, VMHosts, DVSwitches, Datastores).
+.PARAMETER VCenter
+ Get versions for all connected VCenter servers/ESXi hosts and PowerCLi version on the localhost.
+.PARAMETER LicenseKey
+ Get versions of license keys.
+.EXAMPLE
+ PS C:\> Get-VMHost |Get-Version |? {$_.Version -ge 5.5 -and $_.Version.Revision -lt 2456374}
+ Get all ESXi v5.5 hosts that have Revision less than 2456374.
+.EXAMPLE
+ PS C:\> Get-View -ViewType HostSystem |Get-Version |select ProductName,Version |sort Version |group Version |sort Count |select Count,@{N='Version';E={$_.Name}},@{N='VMHost';E={($_.Group |select -expand ProductName) -join ','}} |epcsv -notype 'C:\reports\ESXi_Version.csv'
+ Group all ESXi hosts by Version and export the list to CSV.
+.EXAMPLE
+ PS C:\> Get-VM |Get-Version |? {$_.FullVersion -match 'v10' -and $_.Version -gt 9.1}
+ Get all VM with Virtual Hardware v10 and VMTools version above v9.1.0.
+.EXAMPLE
+ PS C:\> Get-Version -VCenter |Format-Table -AutoSize
+ Get all connected VCenter servers/ESXi hosts versions and PowerCLi version.
+.EXAMPLE
+ PS C:\> Get-VDSwitch |Get-Version |sort Version |? {$_.Version -lt 5.5}
+ Get all DVSwitches that have version below 5.5.
+.EXAMPLE
+ PS C:\> Get-Datastore |Get-Version |? {$_.Version.Major -eq 3}
+ Get all VMFS3 datastores.
+.EXAMPLE
+ PS C:\> Get-Version -LicenseKey
+ Get license keys version info.
+.INPUTS
+ Output objects from the following cmdlets:
+ Get-VMHost, Get-VM, Get-DistributedSwitch, Get-Datastore and Get-View -ViewType HostSystem.
+.OUTPUTS
+ [System.Management.Automation.PSCustomObject] PSObject collection.
+.NOTES
+ Author :: Roman Gelman.
+ Version 1.0 :: 23-May-2016 :: Release.
+ Version 1.1 :: 03-Aug-2016 :: Bugfix ::
+ [1] VDSwitch data type changed from [VMware.Vim.VmwareDistributedVirtualSwitch] to [VMware.VimAutomation.Vds.Types.V1.VmwareVDSwitch].
+ [2] Function Get-VersionVDSwitch edited to support data type change.
+.LINK
+ http://www.ps1code.com/single-post/2016/05/25/How-to-know-any-VMware-object%E2%80%99s-version-Use-GetVersion
+#>
+
+[CmdletBinding(DefaultParameterSetName='VIO')]
+
+Param (
+
+ [Parameter(Mandatory,Position=1,ValueFromPipeline=$true,ParameterSetName='VIO')]
+ $VIObject
+ ,
+ [Parameter(Mandatory,Position=1,ParameterSetName='VC')]
+ [switch]$VCenter
+ ,
+ [Parameter(Mandatory,Position=1,ParameterSetName='LIC')]
+ [switch]$LicenseKey
+)
+
+Begin {
+
+ $ErrorActionPreference = 'SilentlyContinue'
+
+ Function Get-VersionVMHostImpl {
+ Param ([Parameter(Mandatory,Position=1)]$InputObject)
+ $ErrorActionPreference = 'Stop'
+ Try
+ {
+ If ('Connected','Maintenance' -contains $InputObject.ConnectionState -and $InputObject.PowerState -eq 'PoweredOn') {
+ $ProductInfo = $InputObject.ExtensionData.Config.Product
+ $ProductVersion = [version]($ProductInfo.Version + '.' + $ProductInfo.Build)
+
+ $Properties = [ordered]@{
+ ProductName = $InputObject.Name
+ ProductType = $ProductInfo.Name
+ FullVersion = $ProductInfo.FullName
+ Version = $ProductVersion
+ }
+ }
+ Else {
+ $Properties = [ordered]@{
+ ProductName = $InputObject.Name
+ ProductType = 'VMware ESXi'
+ FullVersion = 'Unknown'
+ Version = [version]'0.0.0.0'
+ }
+ }
+ }
+ Catch
+ {
+ $Properties = [ordered]@{
+ ProductName = $InputObject.Name
+ ProductType = 'VMware ESXi'
+ FullVersion = 'Unknown'
+ Version = [version]'0.0.0.0'
+ }
+ }
+ Finally
+ {
+ $Object = New-Object PSObject -Property $Properties
+ $Object
+ }
+
+ } #EndFunction Get-VersionVMHostImpl
+
+ Function Get-VersionVMHostView {
+ Param ([Parameter(Mandatory,Position=1)]$InputObject)
+ $ErrorActionPreference = 'Stop'
+ Try
+ {
+ $ProductRuntime = $InputObject.Runtime
+ If ('connected','maintenance' -contains $ProductRuntime.ConnectionState -and $ProductRuntime.PowerState -eq 'poweredOn') {
+ $ProductInfo = $InputObject.Config.Product
+ $ProductVersion = [version]($ProductInfo.Version + '.' + $ProductInfo.Build)
+
+ $Properties = [ordered]@{
+ ProductName = $InputObject.Name
+ ProductType = $ProductInfo.Name
+ FullVersion = $ProductInfo.FullName
+ Version = $ProductVersion
+ }
+ }
+ Else {
+ $Properties = [ordered]@{
+ ProductName = $InputObject.Name
+ ProductType = 'VMware ESXi'
+ FullVersion = 'Unknown'
+ Version = [version]'0.0.0.0'
+ }
+ }
+ }
+ Catch
+ {
+ $Properties = [ordered]@{
+ ProductName = $InputObject.Name
+ ProductType = 'VMware ESXi'
+ FullVersion = 'Unknown'
+ Version = [version]'0.0.0.0'
+ }
+ }
+ Finally
+ {
+ $Object = New-Object PSObject -Property $Properties
+ $Object
+ }
+
+ } #EndFunction Get-VersionVMHostView
+
+ Function Get-VersionVM {
+ Param ([Parameter(Mandatory,Position=1)]$InputObject)
+ $ErrorActionPreference = 'Stop'
+ Try
+ {
+ $ProductInfo = $InputObject.Guest
+
+ If ($InputObject.ExtensionData.Guest.ToolsStatus -ne 'toolsNotInstalled' -and $ProductInfo) {
+ $ProductVersion = [version]$ProductInfo.ToolsVersion
+
+ $Properties = [ordered]@{
+ ProductName = $InputObject.Name
+ ProductType = $InputObject.ExtensionData.Config.GuestFullName #$ProductInfo.OSFullName
+ FullVersion = "VMware VM " + $InputObject.Version
+ Version = $ProductVersion
+ }
+ }
+ Else {
+
+ $Properties = [ordered]@{
+ ProductName = $InputObject.Name
+ ProductType = $InputObject.ExtensionData.Config.GuestFullName
+ FullVersion = "VMware VM " + $InputObject.Version
+ Version = [version]'0.0.0'
+ }
+ }
+ }
+ Catch
+ {
+ $Properties = [ordered]@{
+ ProductName = $InputObject.Name
+ ProductType = 'Unknown'
+ FullVersion = 'VMware VM'
+ Version = [version]'0.0.0'
+ }
+ }
+ Finally
+ {
+ $Object = New-Object PSObject -Property $Properties
+ $Object
+ }
+
+ } #EndFunction Get-VersionVM
+
+ Function Get-VersionPowerCLi {
+ $ErrorActionPreference = 'Stop'
+ Try
+ {
+ $PCLi = Get-PowerCLIVersion
+ $PCLiVer = [string]$PCLi.Major + '.' + [string]$PCLi.Minor + '.' + [string]$PCLi.Revision + '.' + [string]$PCLi.Build
+
+ $Properties = [ordered]@{
+ ProductName = $env:COMPUTERNAME
+ ProductType = 'VMware vSphere PowerCLi'
+ FullVersion = $PCLi.UserFriendlyVersion
+ Version = [version]$PCLiVer
+ }
+ $Object = New-Object PSObject -Property $Properties
+ $Object
+ }
+ Catch {}
+ } #EndFunction Get-VersionPowerCLi
+
+ Function Get-VersionVCenter {
+ Param ([Parameter(Mandatory,Position=1)]$InputObject)
+ $ErrorActionPreference = 'Stop'
+ Try
+ {
+ If ($obj.IsConnected) {
+ $ProductInfo = $InputObject.ExtensionData.Content.About
+ $ProductVersion = [version]($ProductInfo.Version + '.' + $ProductInfo.Build)
+ Switch -regex ($ProductInfo.OsType) {
+ '^win' {$ProductFullName = $ProductInfo.Name + ' Windows' ;Break}
+ '^linux' {$ProductFullName = $ProductInfo.Name + ' Appliance' ;Break}
+ Default {$ProductFullName = $ProductInfo.Name ;Break}
+ }
+
+ $Properties = [ordered]@{
+ ProductName = $InputObject.Name
+ ProductType = $ProductFullName
+ FullVersion = $ProductInfo.FullName
+ Version = $ProductVersion
+ }
+ }
+ Else {
+ $Properties = [ordered]@{
+ ProductName = $InputObject.Name
+ ProductType = 'VMware vCenter Server'
+ FullVersion = 'Unknown'
+ Version = [version]'0.0.0.0'
+ }
+ }
+ }
+ Catch
+ {
+ $Properties = [ordered]@{
+ ProductName = $InputObject.Name
+ ProductType = 'VMware vCenter Server'
+ FullVersion = 'Unknown'
+ Version = [version]'0.0.0.0'
+ }
+ }
+ Finally
+ {
+ $Object = New-Object PSObject -Property $Properties
+ $Object
+ }
+
+ } #EndFunction Get-VersionVCenter
+
+ Function Get-VersionVDSwitch {
+ Param ([Parameter(Mandatory,Position=1)]$InputObject)
+ $ErrorActionPreference = 'Stop'
+ $ProductTypeName = 'VMware DVSwitch'
+ Try
+ {
+ $ProductInfo = $InputObject.ExtensionData.Summary.ProductInfo
+ $ProductFullVersion = 'VMware Distributed Virtual Switch ' + $ProductInfo.Version + ' build-' + $ProductInfo.Build
+ $ProductVersion = [version]($ProductInfo.Version + '.' + $ProductInfo.Build)
+
+ $Properties = [ordered]@{
+ ProductName = $InputObject.Name
+ ProductType = $ProductTypeName
+ FullVersion = $ProductFullVersion
+ Version = $ProductVersion
+ }
+ }
+ Catch
+ {
+ $Properties = [ordered]@{
+ ProductName = $InputObject.Name
+ ProductType = $ProductTypeName
+ FullVersion = 'Unknown'
+ Version = [version]'0.0.0.0'
+ }
+ }
+ Finally
+ {
+ $Object = New-Object PSObject -Property $Properties
+ $Object
+ }
+
+ } #EndFunction Get-VersionVDSwitch
+
+ Function Get-VersionDatastore {
+ Param ([Parameter(Mandatory,Position=1)]$InputObject)
+ $ErrorActionPreference = 'Stop'
+ $ProductTypeName = 'VMware VMFS Datastore'
+ Try
+ {
+ $ProductVersionNumber = $InputObject.FileSystemVersion
+ $ProductFullVersion = 'VMware Datastore VMFS v' + $ProductVersionNumber
+ $ProductVersion = [version]$ProductVersionNumber
+
+ $Properties = [ordered]@{
+ ProductName = $InputObject.Name
+ ProductType = $ProductTypeName
+ FullVersion = $ProductFullVersion
+ Version = $ProductVersion
+ }
+ }
+ Catch
+ {
+ $Properties = [ordered]@{
+ ProductName = $InputObject.Name
+ ProductType = $ProductTypeName
+ FullVersion = 'Unknown'
+ Version = [version]'0.0'
+ }
+ }
+ Finally
+ {
+ $Object = New-Object PSObject -Property $Properties
+ $Object
+ }
+
+ } #EndFunction Get-VersionDatastore
+
+ Function Get-VersionLicenseKey {
+ Param ([Parameter(Mandatory,Position=1)]$InputObject)
+ $ErrorActionPreference = 'Stop'
+ $ProductTypeName = 'License Key'
+ Try
+ {
+ $InputObjectProp = $InputObject |select -ExpandProperty Properties
+ Foreach ($prop in $InputObjectProp) {
+ If ($prop.Key -eq 'ProductName') {$ProductType = $prop.Value + ' ' + $ProductTypeName}
+ ElseIf ($prop.Key -eq 'ProductVersion') {$ProductVersion = [version]$prop.Value}
+ }
+
+ Switch -regex ($InputObject.CostUnit) {
+ '^cpu' {$LicCostUnit = 'CPU'; Break}
+ '^vm' {$LicCostUnit = 'VM'; Break}
+ 'server' {$LicCostUnit = 'SRV'; Break}
+ Default {$LicCostUnit = $InputObject.CostUnit}
+
+ }
+
+ $ProductFullVersion = $InputObject.Name + ' [' + $InputObject.Used + '/' + $InputObject.Total + $LicCostUnit + ']'
+
+ $Properties = [ordered]@{
+ ProductName = $InputObject.LicenseKey
+ ProductType = $ProductType
+ FullVersion = $ProductFullVersion
+ Version = $ProductVersion
+ }
+ }
+ Catch
+ {
+ $Properties = [ordered]@{
+ ProductName = $InputObject.LicenseKey
+ ProductType = $ProductTypeName
+ FullVersion = 'Unknown'
+ Version = [version]'0.0'
+ }
+ }
+ Finally
+ {
+ $Object = New-Object PSObject -Property $Properties
+ If ($InputObject.EditionKey -ne 'eval') {$Object}
+ }
+
+ } #EndFunction Get-VersionLicenseKey
+
+}
+
+Process {
+
+ If ($PSCmdlet.ParameterSetName -eq 'VIO') {
+ Foreach ($obj in $VIObject) {
+ If ($obj -is [VMware.VimAutomation.ViCore.Types.V1.Inventory.VMHost]) {Get-VersionVMHostImpl -InputObject $obj}
+ ElseIf ($obj -is [VMware.Vim.HostSystem]) {Get-VersionVMHostView -InputObject $obj}
+ ElseIf ($obj -is [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine]) {Get-VersionVM -InputObject $obj}
+ ElseIf ($obj -is [VMware.VimAutomation.Vds.Types.V1.VmwareVDSwitch]) {Get-VersionVDSwitch -InputObject $obj}
+ ElseIf ($obj -is [VMware.VimAutomation.ViCore.Types.V1.DatastoreManagement.VmfsDatastore]) {Get-VersionDatastore -InputObject $obj}
+ Else {Write-Warning "Not supported object type"}
+ }
+ }
+ ElseIf ($PSCmdlet.ParameterSetName -eq 'VC') {
+ If ($global:DefaultVIServers.Length) {Foreach ($obj in $global:DefaultVIServers) {Get-VersionVCenter -InputObject $obj}}
+ Else {Write-Warning "Please use 'Connect-VIServer' cmdlet to connect to VCenter servers or ESXi hosts."}
+ Get-VersionPowerCLi
+ }
+ ElseIf ($PSCmdlet.ParameterSetName -eq 'LIC') {
+ If ($global:DefaultVIServers.Length) {Foreach ($obj in ((Get-View (Get-View ServiceInstance).Content.LicenseManager).Licenses)) {Get-VersionLicenseKey -InputObject $obj}}
+ Else {Write-Warning "Please use 'Connect-VIServer' cmdlet to connect to VCenter servers or ESXi hosts."}
+ }
+}
+
+End {}
+
+} #EndFunction Get-Version
+New-Alias -Name Get-ViMVersion -Value Get-Version -Force:$true
+
+Export-ModuleMember -Alias '*' -Function '*'
diff --git a/Pester/Get-DatastoreProvisioned.Tests.ps1 b/Pester/Get-DatastoreProvisioned.Tests.ps1
new file mode 100644
index 0000000..2e0dded
--- /dev/null
+++ b/Pester/Get-DatastoreProvisioned.Tests.ps1
@@ -0,0 +1,92 @@
+# To run: "Invoke-Pester \Get-DatastoreProvisioned.Tests.ps1"
+
+<#
+Script name: Get-DatastoreProvisioned.Tests.ps1
+Created on: 2016/07/27
+Author: Brian Bunke, @brianbunke
+Description: Help validate that any changes to Get-DatastoreProvisioned.ps1 do not break existing functionality
+Dependencies: Pester
+
+===Tested Against Environment====
+vSphere Version: 6.0 U1/U2
+PowerCLI Version: PowerCLI 6.3 R1
+PowerShell Version: 5.0
+OS Version: Windows 7/10
+#>
+
+# Tests file stored separately from actual script
+# Find where this file is running from, replace parent folder 'Pester' with 'Scripts'
+$Path = (Split-Path -Parent $MyInvocation.MyCommand.Path).Replace("Pester","Scripts")
+# Remove the '.Tests.' from the file name
+$File = (Split-Path -Leaf $MyInvocation.MyCommand.Path).Replace(".Tests.", ".")
+# With changes made to the path, dot-source the function for testing
+. "$Path\$File"
+
+Describe 'Get-DatastoreProvisioned' {
+ # Need to create a few example objects to proxy Get-Datastore pipeline input
+ $1 = [PSCustomObject]@{
+ Name = 'iSCSI-spin'
+ CapacityGB = 38.40
+ FreeSpaceGB = 15.55
+ ExtensionData = @{
+ Summary = @{
+ Capacity = 41234567890
+ FreeSpace = 16696685366
+ Uncommitted = 12345678999
+ }}}
+ $2 = [PSCustomObject]@{
+ Name = 'iSCSI-ssd'
+ CapacityGB = 51.74
+ FreeSpaceGB = 10.35
+ ExtensionData = @{
+ Summary = @{
+ Capacity = 55555555555
+ FreeSpace = 11111111111
+ Uncommitted = 23456765432
+ }}}
+ $3 = [PSCustomObject]@{
+ Name = 'FC-ssd'
+ CapacityGB = 10.35
+ FreeSpaceGB = 4.14
+ ExtensionData = @{
+ Summary = @{
+ Capacity = 11111111111
+ FreeSpace = 4444444444
+ Uncommitted = 2222222222
+ }}}
+
+ It "Doesn't change existing functionality" {
+ $StillWorks = $1,$2,$3 | Get-DatastoreProvisioned
+ $StillWorks | Should Not BeNullOrEmpty
+ ($StillWorks | Measure-Object).Count | Should Be 3
+ ($StillWorks | Get-Member -MemberType NoteProperty).Count | Should Be 6
+ 'Name','FreeSpaceGB','CapacityGB','ProvisionedGB','UsedPct','ProvisionedPct' | ForEach-Object {
+ ($StillWorks | Get-Member -MemberType NoteProperty).Name -contains $_ | Should Be $true
+ }
+ }
+
+ It 'Still calculates correctly' {
+ $calc = $1 | Get-DatastoreProvisioned
+ $calc | Should Not BeNullOrEmpty
+ $calc.ProvisionedGB | Should Be 34.35
+ $calc.UsedPct | Should Be 59.51
+ $calc.ProvisionedPct | Should Be 89.45
+ }
+
+ # Get-Datastore | Get-DatastoreProvisioned | Format-Table -AutoSize
+ It 'Follows Help Example 1' {
+ $Help1 = $1,$2,$3 | Get-DatastoreProvisioned
+ $Help1 | Should Not BeNullOrEmpty
+ ($Help1 | Measure-Object).Count | Should Be 3
+ # not testing Format-Table
+ }
+
+ # Get-Datastore -Name '*ssd' | Get-DatastoreProvisioned | Where-Object ProvisionedPct -ge 100
+ It 'Follows Help Example 2' {
+ $Help2 = $1,$2,$3 | Where Name -like '*ssd' | Get-DatastoreProvisioned | Where ProvisionedPct -ge 100
+ $Help2 | Should Not BeNullOrEmpty
+ ($Help2 | Measure-Object).Count | Should Be 1
+ $Help2.Name | Should BeExactly 'iSCSI-ssd'
+ $Help2.ProvisionedPct | Should BeGreaterThan 100
+ }
+}
diff --git a/Pester/Test Connection to VC.ps1 b/Pester/Test Connection to VC.ps1
new file mode 100644
index 0000000..006825a
--- /dev/null
+++ b/Pester/Test Connection to VC.ps1
@@ -0,0 +1,44 @@
+<#
+Script name: Test Connection to VC.ps1
+Created on: 07/15/2016
+Author: Alan Renouf, @alanrenouf
+Description: The purpose of this pester test is to ensure the PowerCLI modules are imported and a connection and disconnection can be made to a vCenter
+Dependencies: Pester Module
+Example run:
+
+Invoke-Pester -Script @{ Path = '.\Test Connection to VC.ps1'; Parameters = @{ VCNAME="VC01.local"; VCUSER="Administrator@vsphere.local"; VCPASS="Admin!23"} }
+
+#>
+
+$VCUSER = $Parameters.Get_Item("VCUSER")
+$VCPASS = $Parameters.Get_Item("VCPASS")
+$VCNAME = $Parameters.Get_Item("VCNAME")
+
+Describe "PowerCLI Tests" {
+ It "Importing PowerCLI Modules" {
+ Get-Module VMware* | Foreach {
+ Write-Host "Importing Module $($_.name) Version $($_.Version)"
+ $_ | Import-Module
+ Get-Module $_ | Should Be $true
+ }
+ }
+}
+
+Describe "Connect-VIServer Tests" {
+
+ $connection = Connect-VIServer $VCName -User $VCUser -password $VCPass
+ It "Connection is active" {
+ $Global:DefaultVIServer[0].isconnected | Should Be $true
+ }
+
+ It "Checking connected server name is $VCName" {
+ $Global:DefaultVIServer[0].name | Should Be $VCName
+ }
+}
+
+Describe "Disconnect-VIServer Tests" {
+ It "Disconnect from $VCName" {
+ Disconnect-VIServer $VCName -confirm:$false
+ $Global:DefaultVIServer | Should Be $null
+ }
+}
\ No newline at end of file
diff --git a/PowerActions/VM-CdDrive-Report.ps1 b/PowerActions/VM-CdDrive-Report.ps1
new file mode 100644
index 0000000..584484d
--- /dev/null
+++ b/PowerActions/VM-CdDrive-Report.ps1
@@ -0,0 +1,51 @@
+<#
+.MYNGC_REPORT
+KEY\(VM\)
+.LABEL
+VM CD-Drive Report
+.DESCRIPTION
+PowerActions Report Script that reports on VMs CD-Drive configuration, making it easy to find VMs holding onto ISOs that you
+need to update, or VMs that can't vMotion because they are tied into a physical resource from the ESXi host that is running it.
+VM object is key (as it's the first managed object in the output), enabling you the ability to right-click an entry in the
+report to edit the target VM. Script is able to report on VMs with multiple CD-Drives as well. Version 1.0, written by
+Aaron Smith (@awsmith99), published 07/29/2016.
+#>
+
+param
+(
+ [Parameter(Mandatory=$true)]
+ [VMware.VimAutomation.ViCore.Types.V1.Inventory.Cluster]
+ $vParam
+);
+
+[Array] $vmList = @( Get-VM -Location $vParam | Sort Name );
+
+foreach ( $vmItem in $vmList )
+{
+ [Array] $vmCdDriveList = @( Get-CDDrive -VM $vmItem );
+
+ foreach ( $vmCdDriveItem in $vmCdDriveList )
+ {
+ [String] $insertedElement = "";
+ [String] $connectionType = "";
+
+ switch ( $vmCdDriveItem )
+ {
+ { $_.IsoPath } { $insertedElement = $_.IsoPath; $connectionType = "ISO"; break; }
+ { $_.HostDevice } { $insertedElement = $_.HostDevice; $connectionType = "Host Device"; break; }
+ { $_.RemoteDevice } { $insertedElement = $_.RemoteDevice; $connectionType = "Remote Device"; break; }
+ default { $insertedElement = "None"; $connectionType = "Client Device"; break; }
+ }
+
+ $output = New-Object -TypeName PSObject;
+
+ $output | Add-Member -MemberType NoteProperty -Name "VM" -Value $vmItem
+ $output | Add-Member -MemberType NoteProperty -Name "CD-Drive" -Value $vmCdDriveItem.Name;
+ $output | Add-Member -MemberType NoteProperty -Name "Connection" -Value $connectionType;
+ $output | Add-Member -MemberType NoteProperty -Name "Inserted" -Value $insertedElement;
+ $output | Add-Member -MemberType NoteProperty -Name "Connected" -Value $vmCdDriveItem.ConnectionState.Connected;
+ $output | Add-Member -MemberType NoteProperty -Name "StartConnected" -Value $vmCdDriveItem.ConnectionState.StartConnected;
+ $output | Add-Member -MemberType NoteProperty -Name "AllowGuestControl" -Value $vmCdDriveItem.ConnectionState.AllowGuestControl;
+ $output;
+ }
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index 9a369fa..ae27a3d 100644
--- a/README.md
+++ b/README.md
@@ -178,11 +178,10 @@ The VMware Technnology Preview License Agreement:
+
+function Get-DatastoreProvisioned {
+<#
+.SYNOPSIS
+Retrieve the total thin provisioned space on each datastore.
+
+.DESCRIPTION
+Intended to reveal provisioned space alongside total/free space, to assist with svMotion decisions.
+-Name should be supplied from the pipeline via Get-Datastore.
+
+.EXAMPLE
+Get-Datastore | Get-DatastoreProvisioned | Format-Table -AutoSize
+View all datastores and view their capacity statistics in the current console.
+
+.EXAMPLE
+Get-Datastore -Name '*ssd' | Get-DatastoreProvisioned | Where-Object -Property ProvisionedPct -ge 100
+For all datastores ending in 'ssd', return the capacity stats of those at least 100% provisioned.
+
+.INPUTS
+[VMware.VimAutomation.ViCore.Impl.V1.DatastoreManagement.VmfsDatastoreImpl]
+Object type supplied by PowerCLI function Get-Datastore
+
+.LINK
+https://github.com/vmware/PowerCLI-Example-Scripts
+
+.LINK
+https://twitter.com/brianbunke
+#>
+ [CmdletBinding()]
+ param (
+ # Specifies the datastore names to check. Tested only with pipeline input (see examples).
+ [Parameter(ValueFromPipeline = $true)]
+ $Name
+ )
+
+ PROCESS {
+ ForEach ($DS in $Name) {
+ # Calculate total provisioned space from the exposed properties
+ $Provisioned = ($DS.ExtensionData.Summary.Capacity -
+ $DS.ExtensionData.Summary.FreeSpace +
+ $DS.ExtensionData.Summary.Uncommitted) / 1GB
+
+ # Return info, wrapping it in the Math.Round method to trim to two decimal places
+ [PSCustomObject]@{
+ Name = $DS.Name
+ FreeSpaceGB = [math]::Round($DS.FreeSpaceGB, 2)
+ CapacityGB = [math]::Round($DS.CapacityGB, 2)
+ ProvisionedGB = [math]::Round($Provisioned, 2)
+ UsedPct = [math]::Round((($DS.CapacityGB - $DS.FreeSpaceGB) / $DS.CapacityGB) * 100, 2)
+ ProvisionedPct = [math]::Round(($Provisioned / $DS.CapacityGB) * 100, 2)
+ } #pscustomobject
+ } #foreach
+ } #process
+} #function
diff --git a/Scripts/Get-VMID.ps1 b/Scripts/Get-VMID.ps1
new file mode 100644
index 0000000..a081bb3
--- /dev/null
+++ b/Scripts/Get-VMID.ps1
@@ -0,0 +1,41 @@
+function Get-VMID {
+<#
+ .NOTES
+ ===========================================================================
+ Created by: Markus Kraus
+ Organization: Private
+ Personal Blog: mycloudrevolution.com
+ Twitter: @vMarkus_K
+ ===========================================================================
+ .DESCRIPTION
+ This will quickly return all IDs of VMs
+ .Example
+ Get-VMID -myVMs (Get-VM) | ft
+ .Example
+ $SampleVMs = Get-VM "tst*"
+ Get-VMID -myVMs $SampleVMs
+#>
+ [CmdletBinding()]
+ param(
+ [Parameter(Mandatory=$true,
+ ValueFromPipeline=$True,
+ Position=0)]
+ [VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl[]]
+ $myVMs
+ )
+Process {
+
+ $MyView = @()
+ ForEach ($myVM in $myVMs){
+ $UUIDReport = [PSCustomObject] @{
+ Name = $myVM.name
+ UUID = $myVM.extensiondata.Config.UUID
+ InstanceUUID = $myVM.extensiondata.config.InstanceUUID
+ LocationID = $myVM.extensiondata.config.LocationId
+ MoRef = $myVM.extensiondata.Moref.Value
+ }
+ $MyView += $UUIDReport
+ }
+ $MyView
+ }
+}
\ No newline at end of file
diff --git a/Scripts/Report-LUNPath-ESXCLI.ps1 b/Scripts/Report-LUNPath-ESXCLI.ps1
new file mode 100644
index 0000000..ec3b8ee
--- /dev/null
+++ b/Scripts/Report-LUNPath-ESXCLI.ps1
@@ -0,0 +1,62 @@
+<#
+ .NOTES
+ ===========================================================================
+ Created by: Markus Kraus
+ Organization: Private
+ Personal Blog: mycloudrevolution.com
+ Twitter: @vMarkus_K
+ ===========================================================================
+ Tested Against Environment:
+ vSphere Version: 6.0 U1, 5.5 U2
+ PowerCLI Version: PowerCLI 6.3 R1
+ PowerShell Version: 5.0
+ OS Version: Windows 8.1, Server 2012 R2
+ Keyword: ESXi, LUN, Path, Storage
+
+ Dependencies:
+ PowerCLI Version: PowerCLI 6.3 R1
+
+ .DESCRIPTION
+ This script will create a Report of LUNs with Paths that have more than one unique LUN ID or have more than the defined Paths.
+ Information’s will be gathered via ESXCLI. This is necessary to report also hidden Paths!
+
+ .Example
+ ./Report-LUNPath-ESXCLI.ps1
+
+#>
+
+#Requires -Modules VMware.VimAutomation.Core, @{ModuleName="VMware.VimAutomation.Core";ModuleVersion="6.3.0.0"}
+
+#region 1: Global Definitions
+$MaxLUNPaths = 2
+#endregion
+
+#region 2: Get all Connected Hosts
+$myHosts = Get-VMHost | where {$_.ConnectionState -eq "Connected" -and $_.PowerState -eq "PoweredOn"}
+#endregion
+
+#region 3: Create Report
+$Report = @()
+foreach ($myHost in $myHosts) {
+ $esxcli2 = Get-ESXCLI -VMHost $myHost -V2
+ $devices = $esxcli2.storage.core.path.list.invoke() | select Device -Unique
+
+ foreach ($device in $devices) {
+ $arguments = $esxcli2.storage.core.path.list.CreateArgs()
+ $arguments.device = $device.Device
+ $LUNs = $esxcli2.storage.core.path.list.Invoke($arguments)
+
+ $LUNReport = [PSCustomObject] @{
+ HostName = $myHost.Name
+ Device = $device.Device
+ LUNPaths = $LUNs.Length
+ LUNIDs = $LUNs.LUN | Select-Object -Unique
+ }
+ $Report += $LUNReport
+ }
+ }
+#endregion
+
+#region 4: Output Report
+$Report | where {$_.LUNPaths -gt $MaxLUNPaths -or ($_.LUNIDs | measure).count -gt 1 } | ft -AutoSize
+#endregion
\ No newline at end of file
diff --git a/Scripts/vRealize Operations Maintenance Mode.ps1 b/Scripts/vRealize Operations Maintenance Mode.ps1
new file mode 100644
index 0000000..a6ff9e5
--- /dev/null
+++ b/Scripts/vRealize Operations Maintenance Mode.ps1
@@ -0,0 +1,116 @@
+Connect-VIServer vc-l-01a.corp.local -User administrator@vsphere.local -Password VMware1!
+Connect-OMServer vrops.corp1.local -User admin -Password VMware1!
+
+function Enable-OMMaintenance {
+ <#
+ .NOTES
+ Script name: vRealize Operations Maintenance Mode.ps1
+ Created on: 07/26/2016
+ Author: Alan Renouf, @alanrenouf
+ Dependencies: PowerCLI 6.0 R2 or later
+ .DESCRIPTION
+ Places a vSphere Inventory object into maintenance mode in vRealize Operations
+ .Example
+ Set All VMs with a name as backup as being in maintenance mode for 20 minutes:
+
+ Get-VM backup* | Enable-OMMaintenance -MaintenanceTime 20
+
+ Name Health ResourceKind Description
+ ---- ------ ------------ -----------
+ backup-089e13fd-7d7a-0 Grey VirtualMachine
+ backup-d90e0b39-2618-0 Grey VirtualMachine
+ backup-e48ca842-316a-0 Grey VirtualMachine
+ backup-77da3713-919a-0 Grey VirtualMachine
+ backup-c32f4da8-86c4-0 Grey VirtualMachine
+ backup-c3fcb95c-cfe2-0 Grey VirtualMachine
+ backup-4318bb1e-614a-0 Grey VirtualMachine
+
+ #>
+ [CmdletBinding()]
+ param(
+ [Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$true)]
+ [ValidateNotNullOrEmpty()]
+ [System.String]
+ $Resource,
+
+ [Parameter(Position=1, Mandatory=$true)]
+ [ValidateNotNullOrEmpty()]
+ [Int]
+ $MaintenanceTime
+ )
+ process {
+ Foreach ($Entry in $resource) {
+ $Item = Get-Inventory -Name $Entry | Get-OMResource
+ if (-not $Item) {
+ throw "$Entry not found"
+ } Else {
+ $Item.ExtensionData.MarkResourceAsBeingMaintained($MaintenanceTime)
+ Get-Inventory -Name $Entry | Get-OMResource
+ }
+ }
+ }
+}
+
+function Disable-OMMaintenance {
+ <#
+ .NOTES
+ Script name: vRealize Operations Maintenance Mode.ps1
+ Created on: 07/26/2016
+ Author: Alan Renouf, @alanrenouf
+ Dependencies: PowerCLI 6.0 R2 or later
+ .DESCRIPTION
+ Removes a vSphere Inventory object from maintenance mode in vRealize Operations
+ .Example
+ Disable maintenance mode for all VMs with a name of backup
+
+ Get-VM backup* | Disable-OMMaintenance
+
+ Name Health ResourceKind Description
+ ---- ------ ------------ -----------
+ backup-089e13fd-7d7a-0 Grey VirtualMachine
+ backup-d90e0b39-2618-0 Grey VirtualMachine
+ backup-e48ca842-316a-0 Grey VirtualMachine
+ backup-77da3713-919a-0 Grey VirtualMachine
+ backup-c32f4da8-86c4-0 Yellow VirtualMachine
+ backup-c3fcb95c-cfe2-0 Yellow VirtualMachine
+ backup-4318bb1e-614a-0 Yellow VirtualMachine
+
+ #>
+ [CmdletBinding()]
+ param(
+ [Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$true)]
+ [ValidateNotNullOrEmpty()]
+ [System.String]
+ $Resource
+ )
+ process {
+ Foreach ($Entry in $resource) {
+ $Item = Get-Inventory -Name $Entry | Get-OMResource
+ if (-not $Item) {
+ throw "$Entry not found"
+ } Else {
+ $Item.ExtensionData.UnmarkResourceAsBeingMaintained()
+ Get-Inventory -Name $Entry | Get-OMResource
+ }
+ }
+ }
+}
+
+Write-Host "Enable a single host as being in maintenance mode for 1 minute"
+Enable-OMMaintenance -Resource ESX-01a* -MaintenanceTime 1
+
+Write-Host "List All Host Resources and their state"
+Get-OMResource ESX-* | Select Name, State | FT
+
+Write-Host "Set All VMs with a name as backup as being in maintenance mode for 20 minutes"
+Get-VM backup* | Enable-OMMaintenance -MaintenanceTime 20
+
+Write-Host "List All Backup VM Resources and their state"
+Get-VM backup* | Get-OMResource | Select Name, State | FT
+
+Write-Host "Disable maintenance mode for all VMs with a name as backup as we have completed our scheduled work"
+Get-VM backup* | Disable-OMMaintenance
+
+Write-Host "List All VM Resources and their state"
+Get-VM backup* | Get-OMResource | Select Name, State | FT
+