Merge remote-tracking branch 'vmware/master'
Resnyc Fork
This commit is contained in:
0
.gitattributes
vendored
Normal file
0
.gitattributes
vendored
Normal file
51
.gitignore
vendored
Normal file
51
.gitignore
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
# PowerShell Studio Files
|
||||
*.temppoint.*
|
||||
*.psproj.psbuild
|
||||
*.psbuild
|
||||
|
||||
#VS Code Files
|
||||
*.vscode
|
||||
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
# =========================
|
||||
# Operating System Files
|
||||
# =========================
|
||||
|
||||
# OSX
|
||||
# =========================
|
||||
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear on external disk
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
184
Modules/DatastoreFunctions/DatastoreFunctions.psm1
Normal file
184
Modules/DatastoreFunctions/DatastoreFunctions.psm1
Normal file
@@ -0,0 +1,184 @@
|
||||
#Created by Alan Renouf, published at https://communities.vmware.com/docs/DOC-18008
|
||||
Function Get-DatastoreMountInfo {
|
||||
[CmdletBinding()]
|
||||
Param (
|
||||
[Parameter(ValueFromPipeline=$true)]
|
||||
$Datastore
|
||||
)
|
||||
Process {
|
||||
$AllInfo = @()
|
||||
if (-not $Datastore) {
|
||||
$Datastore = Get-Datastore
|
||||
}
|
||||
Foreach ($ds in $Datastore) {
|
||||
if ($ds.ExtensionData.info.Vmfs) {
|
||||
$hostviewDSDiskName = $ds.ExtensionData.Info.vmfs.extent[0].diskname
|
||||
if ($ds.ExtensionData.Host) {
|
||||
$attachedHosts = $ds.ExtensionData.Host
|
||||
Foreach ($VMHost in $attachedHosts) {
|
||||
$hostview = Get-View $VMHost.Key
|
||||
$hostviewDSState = $VMHost.MountInfo.Mounted
|
||||
$StorageSys = Get-View $HostView.ConfigManager.StorageSystem
|
||||
$devices = $StorageSys.StorageDeviceInfo.ScsiLun
|
||||
Foreach ($device in $devices) {
|
||||
$Info = "" | Select Datastore, VMHost, Lun, Mounted, State
|
||||
if ($device.canonicalName -eq $hostviewDSDiskName) {
|
||||
$hostviewDSAttachState = ""
|
||||
if ($device.operationalState[0] -eq "ok") {
|
||||
$hostviewDSAttachState = "Attached"
|
||||
} elseif ($device.operationalState[0] -eq "off") {
|
||||
$hostviewDSAttachState = "Detached"
|
||||
} else {
|
||||
$hostviewDSAttachState = $device.operationalstate[0]
|
||||
}
|
||||
$Info.Datastore = $ds.Name
|
||||
$Info.Lun = $hostviewDSDiskName
|
||||
$Info.VMHost = $hostview.Name
|
||||
$Info.Mounted = $HostViewDSState
|
||||
$Info.State = $hostviewDSAttachState
|
||||
$AllInfo += $Info
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$AllInfo
|
||||
}
|
||||
}
|
||||
|
||||
Function Detach-Datastore {
|
||||
[CmdletBinding()]
|
||||
Param (
|
||||
[Parameter(ValueFromPipeline=$true)]
|
||||
$Datastore
|
||||
)
|
||||
Process {
|
||||
if (-not $Datastore) {
|
||||
Write-Host "No Datastore defined as input"
|
||||
Exit
|
||||
}
|
||||
Foreach ($ds in $Datastore) {
|
||||
$hostviewDSDiskName = $ds.ExtensionData.Info.vmfs.extent[0].Diskname
|
||||
if ($ds.ExtensionData.Host) {
|
||||
$attachedHosts = $ds.ExtensionData.Host
|
||||
Foreach ($VMHost in $attachedHosts) {
|
||||
$hostview = Get-View $VMHost.Key
|
||||
$StorageSys = Get-View $HostView.ConfigManager.StorageSystem
|
||||
$devices = $StorageSys.StorageDeviceInfo.ScsiLun
|
||||
Foreach ($device in $devices) {
|
||||
if ($device.canonicalName -eq $hostviewDSDiskName) {
|
||||
$LunUUID = $Device.Uuid
|
||||
Write-Host "Detaching LUN $($Device.CanonicalName) from host $($hostview.Name)..."
|
||||
$StorageSys.DetachScsiLun($LunUUID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Function Unmount-Datastore {
|
||||
[CmdletBinding()]
|
||||
Param (
|
||||
[Parameter(ValueFromPipeline=$true)]
|
||||
$Datastore
|
||||
)
|
||||
Process {
|
||||
if (-not $Datastore) {
|
||||
Write-Host "No Datastore defined as input"
|
||||
Exit
|
||||
}
|
||||
Foreach ($ds in $Datastore) {
|
||||
$hostviewDSDiskName = $ds.ExtensionData.Info.vmfs.extent[0].Diskname
|
||||
if ($ds.ExtensionData.Host) {
|
||||
$attachedHosts = $ds.ExtensionData.Host
|
||||
Foreach ($VMHost in $attachedHosts) {
|
||||
$hostview = Get-View $VMHost.Key
|
||||
$StorageSys = Get-View $HostView.ConfigManager.StorageSystem
|
||||
Write-Host "Unmounting VMFS Datastore $($DS.Name) from host $($hostview.Name)..."
|
||||
$StorageSys.UnmountVmfsVolume($DS.ExtensionData.Info.vmfs.uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Function Mount-Datastore {
|
||||
[CmdletBinding()]
|
||||
Param (
|
||||
[Parameter(ValueFromPipeline=$true)]
|
||||
$Datastore
|
||||
)
|
||||
Process {
|
||||
if (-not $Datastore) {
|
||||
Write-Host "No Datastore defined as input"
|
||||
Exit
|
||||
}
|
||||
Foreach ($ds in $Datastore) {
|
||||
$hostviewDSDiskName = $ds.ExtensionData.Info.vmfs.extent[0].Diskname
|
||||
if ($ds.ExtensionData.Host) {
|
||||
$attachedHosts = $ds.ExtensionData.Host
|
||||
Foreach ($VMHost in $attachedHosts) {
|
||||
$hostview = Get-View $VMHost.Key
|
||||
$StorageSys = Get-View $HostView.ConfigManager.StorageSystem
|
||||
Write-Host "Mounting VMFS Datastore $($DS.Name) on host $($hostview.Name)..."
|
||||
$StorageSys.MountVmfsVolume($DS.ExtensionData.Info.vmfs.uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Function Attach-Datastore {
|
||||
[CmdletBinding()]
|
||||
Param (
|
||||
[Parameter(ValueFromPipeline=$true)]
|
||||
$Datastore
|
||||
)
|
||||
Process {
|
||||
if (-not $Datastore) {
|
||||
Write-Host "No Datastore defined as input"
|
||||
Exit
|
||||
}
|
||||
Foreach ($ds in $Datastore) {
|
||||
$hostviewDSDiskName = $ds.ExtensionData.Info.vmfs.extent[0].Diskname
|
||||
if ($ds.ExtensionData.Host) {
|
||||
$attachedHosts = $ds.ExtensionData.Host
|
||||
Foreach ($VMHost in $attachedHosts) {
|
||||
$hostview = Get-View $VMHost.Key
|
||||
$StorageSys = Get-View $HostView.ConfigManager.StorageSystem
|
||||
$devices = $StorageSys.StorageDeviceInfo.ScsiLun
|
||||
Foreach ($device in $devices) {
|
||||
if ($device.canonicalName -eq $hostviewDSDiskName) {
|
||||
$LunUUID = $Device.Uuid
|
||||
Write-Host "Attaching LUN $($Device.CanonicalName) to host $($hostview.Name)..."
|
||||
$StorageSys.AttachScsiLun($LunUUID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#
|
||||
#Get-Datastore | Get-DatastoreMountInfo | Sort Datastore, VMHost | FT -AutoSize
|
||||
#
|
||||
#Get-Datastore IX2ISCSI01 | Unmount-Datastore
|
||||
#
|
||||
#Get-Datastore IX2ISCSI01 | Get-DatastoreMountInfo | Sort Datastore, VMHost | FT -AutoSize
|
||||
#
|
||||
#Get-Datastore IX2iSCSI01 | Mount-Datastore
|
||||
#
|
||||
#Get-Datastore IX2iSCSI01 | Get-DatastoreMountInfo | Sort Datastore, VMHost | FT -AutoSize
|
||||
#
|
||||
#Get-Datastore IX2iSCSI01 | Detach-Datastore
|
||||
#
|
||||
#Get-Datastore IX2iSCSI01 | Get-DatastoreMountInfo | Sort Datastore, VMHost | FT -AutoSize
|
||||
#
|
||||
#Get-Datastore IX2iSCSI01 | Attach-datastore
|
||||
#
|
||||
#Get-Datastore IX2iSCSI01 | Get-DatastoreMountInfo | Sort Datastore, VMHost | FT -AutoSize
|
||||
#
|
||||
93
Modules/Get-NICDetails/Get-NICDetails.psm1
Normal file
93
Modules/Get-NICDetails/Get-NICDetails.psm1
Normal file
@@ -0,0 +1,93 @@
|
||||
function Get-NICDetails {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Markus Kraus
|
||||
Twitter: @VMarkus_K
|
||||
Private Blog: mycloudrevolution.com
|
||||
===========================================================================
|
||||
Changelog:
|
||||
2017.02 ver 1.0 Base Release
|
||||
===========================================================================
|
||||
External Code Sources:
|
||||
-
|
||||
===========================================================================
|
||||
Tested Against Environment:
|
||||
vSphere Version: ESXi 6.0 U2, ESXi 6.5
|
||||
PowerCLI Version: PowerCLI 6.3 R1, PowerCLI 6.5 R1
|
||||
PowerShell Version: 4.0, 5.0
|
||||
OS Version: Windows 8.1, Server 2008 R2, Server 2012 R2
|
||||
Keyword: ESXi, NIC, vmnic, Driver, Firmware
|
||||
===========================================================================
|
||||
|
||||
.DESCRIPTION
|
||||
Reports Firmware and Driver Details for your ESXi vmnics.
|
||||
|
||||
.Example
|
||||
Get-NICDetails -Clustername *
|
||||
|
||||
.PARAMETER Clustername
|
||||
Name or Wildcard of your vSphere Cluster Name to process.
|
||||
|
||||
|
||||
#Requires PS -Version 4.0
|
||||
#Requires -Modules VMware.VimAutomation.Core, @{ModuleName="VMware.VimAutomation.Core";ModuleVersion="6.3.0.0"}
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, Position=0)]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String] $Clustername
|
||||
|
||||
)
|
||||
|
||||
Begin {
|
||||
$Validate = $True
|
||||
|
||||
if (($myCluster = Get-Cluster -Name $Clustername).count -lt 1) {
|
||||
$Validate = $False
|
||||
thow "No Cluster '$myCluster' found!"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Process {
|
||||
|
||||
$MyView = @()
|
||||
if ($Validate -eq $True) {
|
||||
|
||||
foreach ($myVMhost in ($myCluster | Get-VMHost)) {
|
||||
|
||||
$esxcli2 = Get-ESXCLI -VMHost $myVMhost -V2
|
||||
$niclist = $esxcli2.network.nic.list.invoke()
|
||||
|
||||
$nicdetails = @()
|
||||
foreach ($nic in $niclist) {
|
||||
|
||||
$args = $esxcli2.network.nic.get.createargs()
|
||||
$args.nicname = $nic.name
|
||||
$nicdetail = $esxcli2.network.nic.get.Invoke($args)
|
||||
$nicdetails += $nicdetail
|
||||
|
||||
}
|
||||
ForEach ($nicdetail in $nicdetails){
|
||||
$NICReport = [PSCustomObject] @{
|
||||
Host = $myVMhost.Name
|
||||
vmnic = $nicdetail.Name
|
||||
LinkStatus = $nicdetail.LinkStatus
|
||||
BusInfo = $nicdetail.driverinfo.BusInfo
|
||||
Driver = $nicdetail.driverinfo.Driver
|
||||
FirmwareVersion = $nicdetail.driverinfo.FirmwareVersion
|
||||
DriverVersion = $nicdetail.driverinfo.Version
|
||||
}
|
||||
$MyView += $NICReport
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$MyView
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
131
Modules/Get-NewAndRemovedVMs/Get-NewAndRemovedVMs.psm1
Normal file
131
Modules/Get-NewAndRemovedVMs/Get-NewAndRemovedVMs.psm1
Normal file
@@ -0,0 +1,131 @@
|
||||
function Get-NewAndRemovedVMs {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Markus Kraus
|
||||
Twitter: @VMarkus_K
|
||||
Private Blog: mycloudrevolution.com
|
||||
===========================================================================
|
||||
Changelog:
|
||||
2016.12 ver 1.0 Base Release
|
||||
===========================================================================
|
||||
External Code Sources:
|
||||
https://github.com/alanrenouf/vCheck-vSphere
|
||||
===========================================================================
|
||||
Tested Against Environment:
|
||||
vSphere Version: 5.5 U2
|
||||
PowerCLI Version: PowerCLI 6.3 R1, PowerCLI 6.5 R1
|
||||
PowerShell Version: 4.0, 5.0
|
||||
OS Version: Windows 8.1, Server 2012 R2
|
||||
===========================================================================
|
||||
Keywords vSphere, VM
|
||||
===========================================================================
|
||||
|
||||
.DESCRIPTION
|
||||
This Function report newly created and deleted VMs by Cluster.
|
||||
|
||||
.Example
|
||||
Get-NewAndRemovedVMs -ClusterName Cluster* | ft -AutoSize
|
||||
|
||||
.Example
|
||||
Get-NewAndRemovedVMs -ClusterName Cluster01 -Days 90
|
||||
|
||||
.PARAMETER ClusterName
|
||||
Name or Wildcard of your vSphere Cluster Name(s) to report.
|
||||
|
||||
.PARAMETER Day
|
||||
Range in Days to report.
|
||||
|
||||
|
||||
#Requires PS -Version 4.0
|
||||
#Requires -Modules VMware.VimAutomation.Core, @{ModuleName="VMware.VimAutomation.Core";ModuleVersion="6.3.0.0"}
|
||||
#>
|
||||
|
||||
param(
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, Position=0, HelpMessage = "Name or Wildcard of your vSphere Cluster Name to report")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String]$ClusterName,
|
||||
[Parameter(Mandatory=$False, ValueFromPipeline=$False, Position=1, HelpMessage = "Range in Days to report")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String]$Days = "30"
|
||||
)
|
||||
Begin {
|
||||
function Get-VIEventPlus {
|
||||
|
||||
param(
|
||||
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl[]]$Entity,
|
||||
[string[]]$EventType,
|
||||
[DateTime]$Start,
|
||||
[DateTime]$Finish = (Get-Date),
|
||||
[switch]$Recurse,
|
||||
[string[]]$User,
|
||||
[Switch]$System,
|
||||
[string]$ScheduledTask,
|
||||
[switch]$FullMessage = $false,
|
||||
[switch]$UseUTC = $false
|
||||
)
|
||||
|
||||
process {
|
||||
$eventnumber = 100
|
||||
$events = @()
|
||||
$eventMgr = Get-View EventManager
|
||||
$eventFilter = New-Object VMware.Vim.EventFilterSpec
|
||||
$eventFilter.disableFullMessage = ! $FullMessage
|
||||
$eventFilter.entity = New-Object VMware.Vim.EventFilterSpecByEntity
|
||||
$eventFilter.entity.recursion = &{if($Recurse){"all"}else{"self"}}
|
||||
$eventFilter.eventTypeId = $EventType
|
||||
if($Start -or $Finish){
|
||||
$eventFilter.time = New-Object VMware.Vim.EventFilterSpecByTime
|
||||
if($Start){
|
||||
$eventFilter.time.beginTime = $Start
|
||||
}
|
||||
if($Finish){
|
||||
$eventFilter.time.endTime = $Finish
|
||||
}
|
||||
}
|
||||
if($User -or $System){
|
||||
$eventFilter.UserName = New-Object VMware.Vim.EventFilterSpecByUsername
|
||||
if($User){
|
||||
$eventFilter.UserName.userList = $User
|
||||
}
|
||||
if($System){
|
||||
$eventFilter.UserName.systemUser = $System
|
||||
}
|
||||
}
|
||||
if($ScheduledTask){
|
||||
$si = Get-View ServiceInstance
|
||||
$schTskMgr = Get-View $si.Content.ScheduledTaskManager
|
||||
$eventFilter.ScheduledTask = Get-View $schTskMgr.ScheduledTask |
|
||||
where {$_.Info.Name -match $ScheduledTask} |
|
||||
Select -First 1 |
|
||||
Select -ExpandProperty MoRef
|
||||
}
|
||||
if(!$Entity){
|
||||
$Entity = @(Get-Folder -NoRecursion)
|
||||
}
|
||||
$entity | %{
|
||||
$eventFilter.entity.entity = $_.ExtensionData.MoRef
|
||||
$eventCollector = Get-View ($eventMgr.CreateCollectorForEvents($eventFilter))
|
||||
$eventsBuffer = $eventCollector.ReadNextEvents($eventnumber)
|
||||
while($eventsBuffer){
|
||||
$events += $eventsBuffer
|
||||
$eventsBuffer = $eventCollector.ReadNextEvents($eventnumber)
|
||||
}
|
||||
$eventCollector.DestroyCollector()
|
||||
}
|
||||
if (-not $UseUTC)
|
||||
{
|
||||
$events | % { $_.createdTime = $_.createdTime.ToLocalTime() }
|
||||
}
|
||||
|
||||
$events
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
process {
|
||||
$result = Get-VIEventPlus -Start ((get-date).adddays(-$Days)) -EventType @("VmCreatedEvent", "VmBeingClonedEvent", "VmBeingDeployedEvent","VmRemovedEvent")
|
||||
$sortedResult = $result | Select CreatedTime, @{N='Cluster';E={$_.ComputeResource.Name}}, @{Name="VMName";Expression={$_.vm.name}}, UserName, @{N='Type';E={$_.GetType().Name}}, FullFormattedMessage | Sort CreatedTime
|
||||
$sortedResult | where {$_.Cluster -like $ClusterName}
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
function Get-VMmaxIOPS {
|
||||
<#
|
||||
|
||||
.SYNOPSIS
|
||||
Report VM Disk IOPS of VMs
|
||||
|
||||
.DESCRIPTION
|
||||
This Function will Create a VM Disk IOPS Report
|
||||
|
||||
.Example
|
||||
Get-VM TST* | Get-VMmaxIOPS -Minutes 60 | FT -Autosize
|
||||
|
||||
.Example
|
||||
$SampleVMs = Get-VM "TST*"
|
||||
Get-VMmaxIOPS -VMs $SampleVMs -Minutes 60
|
||||
|
||||
.PARAMETER VMs
|
||||
Specify the VMs
|
||||
|
||||
.PARAMETER Minutes
|
||||
Specify the Minutes to report (10080 is one Week)
|
||||
|
||||
.Notes
|
||||
NAME: Get-VMmaxIOPS.ps1
|
||||
LASTEDIT: 08/23/2016
|
||||
VERSION: 1.1
|
||||
KEYWORDS: VMware, vSphere, ESXi, IOPS
|
||||
|
||||
.Link
|
||||
http://mycloudrevolution.com/
|
||||
|
||||
#Requires PS -Version 4.0
|
||||
#Requires -Modules VMware.VimAutomation.Core, @{ModuleName="VMware.VimAutomation.Core";ModuleVersion="6.3.0.0"}
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory=$true, ValueFromPipeline=$True, Position=0)]
|
||||
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl[]]
|
||||
$VMs,
|
||||
[Parameter(Mandatory=$false, Position=1)]
|
||||
[int] $Minutes = 30
|
||||
)
|
||||
|
||||
Process {
|
||||
|
||||
#region: Global Definitions
|
||||
[int]$TimeRange = "-" + $Minutes
|
||||
#endregion
|
||||
|
||||
#region: Creating Metrics
|
||||
Write-Debug "Starting to Create Metrics..."
|
||||
$metrics = "virtualDisk.numberReadAveraged.average","virtualDisk.numberWriteAveraged.average"
|
||||
$start = (Get-Date).AddMinutes($TimeRange)
|
||||
$stats = Get-Stat -Stat $metrics -Entity $VMs -Start $start
|
||||
#endregion
|
||||
|
||||
#region: Creating HD-Tab
|
||||
Write-Debug "Starting to Create HD-Tab..."
|
||||
$hdTab = @{}
|
||||
foreach($hd in (Get-Harddisk -VM $VMs)){
|
||||
$controllerKey = $hd.Extensiondata.ControllerKey
|
||||
$controller = $hd.Parent.Extensiondata.Config.Hardware.Device | where{$_.Key -eq $controllerKey}
|
||||
$hdTab[$hd.Parent.Name + "/scsi" + $controller.BusNumber + ":" + $hd.Extensiondata.UnitNumber] = $hd.FileName.Split(']')[0].TrimStart('[')
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region: Creating Reports
|
||||
Write-Debug "Starting to Process IOPS Report..."
|
||||
$reportPerf = @()
|
||||
$reportPerf = $stats | Group-Object -Property {$_.Entity.Name},Instance | %{
|
||||
New-Object PSObject -Property @{
|
||||
VM = $_.Values[0]
|
||||
Disk = $_.Values[1]
|
||||
IOPSMax = ($_.Group | `
|
||||
Group-Object -Property Timestamp | `
|
||||
%{$_.Group[0].Value + $_.Group[1].Value} | `
|
||||
Measure-Object -Maximum).Maximum
|
||||
Datastore = $hdTab[$_.Values[0] + "/"+ $_.Values[1]]
|
||||
}
|
||||
}
|
||||
$reportPerf | Select-Object VM, Disk, Datastore, IOPSMax
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
114
Modules/Get-VMmaxIOPS/Get-VMmaxIOPS.psm1
Normal file
114
Modules/Get-VMmaxIOPS/Get-VMmaxIOPS.psm1
Normal file
@@ -0,0 +1,114 @@
|
||||
function Get-VMmaxIOPS {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Markus Kraus
|
||||
Twitter: @VMarkus_K
|
||||
Private Blog: mycloudrevolution.com
|
||||
===========================================================================
|
||||
Changelog:
|
||||
2016.10 ver 1.0 Base Release
|
||||
2016.11 ver 1.1 Added vSphere 6.5 Support, New Counters, More Error Handling
|
||||
===========================================================================
|
||||
External Code Sources:
|
||||
http://www.lucd.info/2011/04/22/get-the-maximum-iops/
|
||||
https://communities.vmware.com/thread/485386
|
||||
===========================================================================
|
||||
Tested Against Environment:
|
||||
vSphere Version: 5.5 U2, 6.5
|
||||
PowerCLI Version: PowerCLI 6.3 R1, 6.5 R1
|
||||
PowerShell Version: 4.0, 5.0
|
||||
OS Version: Windows 8.1, Windows Server 2012 R2
|
||||
===========================================================================
|
||||
Keywords vSphere, ESXi, VM, Storage
|
||||
===========================================================================
|
||||
|
||||
.DESCRIPTION
|
||||
This Function will Create a VM Disk IOPS Report
|
||||
|
||||
.Example
|
||||
Get-VM TST* | Get-VMmaxIOPS -Minutes 60 | FT -Autosize
|
||||
|
||||
.Example
|
||||
$SampleVMs = Get-VM "TST*"
|
||||
Get-VMmaxIOPS -VMs $SampleVMs -Minutes 60
|
||||
|
||||
.PARAMETER VMs
|
||||
Specify the VMs
|
||||
|
||||
.PARAMETER Minutes
|
||||
Specify the Minutes to report (10080 is one Week)
|
||||
|
||||
#Requires PS -Version 4.0
|
||||
#Requires -Modules VMware.VimAutomation.Core, @{ModuleName="VMware.VimAutomation.Core";ModuleVersion="6.3.0.0"}
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory=$true, ValueFromPipeline=$True, Position=0)]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl[]] $VMs,
|
||||
[Parameter(Mandatory=$false, Position=1, HelpMessage = "Specify the Minutes to report (10080 is one Week)")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[int] $Minutes = 30
|
||||
)
|
||||
Begin {
|
||||
# none
|
||||
}
|
||||
Process {
|
||||
if ($_.PowerState -eq "PoweredOn") {
|
||||
#region: Global Definitions
|
||||
[int]$TimeRange = "-" + $Minutes
|
||||
#endregion
|
||||
|
||||
#region: Creating VM Stats
|
||||
Write-Verbose "$(Get-Date -Format G) Create VM Stats..."
|
||||
$VMMetrics = "virtualdisk.numberwriteaveraged.average","virtualdisk.numberreadaveraged.average"
|
||||
$Start = (Get-Date).AddMinutes($TimeRange)
|
||||
$stats = Get-Stat -Realtime -Stat $VMMetrics -Entity $VMs -Start $Start -Verbose:$False
|
||||
Write-Verbose "$(Get-Date -Format G) Create VM Stats completed"
|
||||
#endregion
|
||||
|
||||
#region: Creating HD-Tab
|
||||
Write-Verbose "$(Get-Date -Format G) Create HD Tab..."
|
||||
$hdTab = @{}
|
||||
foreach($hd in (Get-Harddisk -VM $VMs)){
|
||||
$controllerKey = $hd.Extensiondata.ControllerKey
|
||||
$controller = $hd.Parent.Extensiondata.Config.Hardware.Device | where{$_.Key -eq $controllerKey}
|
||||
$hdTab[$hd.Parent.Name + "/scsi" + $controller.BusNumber + ":" + $hd.Extensiondata.UnitNumber] = $hd.FileName.Split(']')[0].TrimStart('[')
|
||||
}
|
||||
Write-Verbose "$(Get-Date -Format G) Create HD Tab completed"
|
||||
#endregion
|
||||
|
||||
#region: Creating Reports
|
||||
Write-Verbose "$(Get-Date -Format G) Create Report..."
|
||||
$reportPerf = @()
|
||||
$reportPerf = $stats | Group-Object -Property {$_.Entity.Name},Instance | %{
|
||||
New-Object PSObject -Property @{
|
||||
VM = $_.Values[0]
|
||||
Disk = $_.Values[1]
|
||||
IOPSWriteAvg = [math]::round( ($_.Group | `
|
||||
where{$_.MetricId -eq "virtualdisk.numberwriteaveraged.average"} | `
|
||||
Measure-Object -Property Value -Average).Average,2)
|
||||
IOPSReadAvg = [math]::round( ($_.Group | `
|
||||
where{$_.MetricId -eq "virtualdisk.numberreadaveraged.average"} | `
|
||||
Measure-Object -Property Value -Average).Average,2)
|
||||
Datastore = $hdTab[$_.Values[0] + "/"+ $_.Values[1]]
|
||||
}
|
||||
}
|
||||
Write-Verbose "$(Get-Date -Format G) Create Report completed"
|
||||
#endregion
|
||||
|
||||
|
||||
}
|
||||
Else {
|
||||
Write-Error "VM $($_.Name) is Powered Off! Processing Skipped"
|
||||
}
|
||||
$reportPerf | Select-Object VM, Disk, Datastore, IOPSWriteAvg, IOPSReadAvg
|
||||
}
|
||||
|
||||
End {
|
||||
# none
|
||||
}
|
||||
|
||||
}
|
||||
234
Modules/Konfig-ESXi/Konfig-ESXi.psm1
Normal file
234
Modules/Konfig-ESXi/Konfig-ESXi.psm1
Normal file
@@ -0,0 +1,234 @@
|
||||
function Konfig-ESXi {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Markus Kraus
|
||||
Twitter: @VMarkus_K
|
||||
Private Blog: mycloudrevolution.com
|
||||
===========================================================================
|
||||
Changelog:
|
||||
2016.12 ver 1.0 Base Release
|
||||
2016.12 ver 1.1 ESXi 6.5 Tests, Minor enhancements
|
||||
===========================================================================
|
||||
External Code Sources:
|
||||
Function My-Logger : http://www.virtuallyghetto.com/
|
||||
===========================================================================
|
||||
Tested Against Environment:
|
||||
vSphere Version: ESXi 5.5 U2, ESXi 6.5
|
||||
PowerCLI Version: PowerCLI 6.3 R1, PowerCLI 6.5 R1
|
||||
PowerShell Version: 4.0, 5.0
|
||||
OS Version: Windows 8.1, Server 2012 R2
|
||||
Keyword: ESXi, NTP, SSH, Syslog, SATP,
|
||||
===========================================================================
|
||||
|
||||
.DESCRIPTION
|
||||
This Function sets the Basic settings for a new ESXi.
|
||||
|
||||
* NTP
|
||||
* SSH
|
||||
* Syslog
|
||||
* Power Management
|
||||
* HP 3PAR SATP/PSP Rule
|
||||
* ...
|
||||
|
||||
.Example
|
||||
Konfig-ESXi -VMHost myesxi.lan.local -NTP 192.168.2.1, 192.168.2.2 -syslog "udp://loginsight.lan.local:514"
|
||||
|
||||
.PARAMETER VMHost
|
||||
Host to configure.
|
||||
|
||||
.PARAMETER NTP
|
||||
NTP Server(s) to set.
|
||||
|
||||
.PARAMETER Syslog
|
||||
Syslog Server to set, e.g. "udp://loginsight.lan.local:514"
|
||||
|
||||
DNS Name must be resolvable!
|
||||
|
||||
|
||||
#Requires PS -Version 4.0
|
||||
#Requires -Modules VMware.VimAutomation.Core, @{ModuleName="VMware.VimAutomation.Core";ModuleVersion="6.3.0.0"}
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, Position=0)]
|
||||
[String] $VMHost,
|
||||
[Parameter(Mandatory=$true, ValueFromPipeline=$False, Position=1)]
|
||||
[array]$NTP,
|
||||
[Parameter(Mandatory=$true, ValueFromPipeline=$False, Position=2)]
|
||||
[String] $syslog
|
||||
|
||||
)
|
||||
|
||||
Begin {
|
||||
Function My-Logger {
|
||||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[String]$message
|
||||
)
|
||||
|
||||
$timeStamp = Get-Date -Format "MM-dd-yyyy_hh-mm-ss"
|
||||
|
||||
Write-Host -NoNewline -ForegroundColor White "[$timestamp]"
|
||||
Write-Host -ForegroundColor Green " $message"
|
||||
}
|
||||
function Set-MyESXiOption {
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, Position=0)]
|
||||
[String] $Name,
|
||||
[Parameter(Mandatory=$False, ValueFromPipeline=$False, Position=1)]
|
||||
[String] $Value
|
||||
)
|
||||
process {
|
||||
$myESXiOption = Get-AdvancedSetting -Entity $ESXiHost -Name $Name
|
||||
if ($myESXiOption.Value -ne $Value) {
|
||||
My-Logger " Setting ESXi Option $Name to Value $Value"
|
||||
$myESXiOption | Set-AdvancedSetting -Value $Value -Confirm:$false | Out-Null
|
||||
}
|
||||
else {
|
||||
My-Logger " ESXi Option $Name already has Value $Value"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
$Validate = $True
|
||||
|
||||
#region: Start vCenter Connection
|
||||
My-Logger "Starting to Process ESXi Server Connection to $VMHost ..."
|
||||
if (($global:DefaultVIServers).count -gt 0) {
|
||||
Disconnect-VIServer -Force -Confirm:$False -ErrorAction SilentlyContinue
|
||||
}
|
||||
$VIConnection = Connect-VIServer -Server $VMHost
|
||||
if (-not $VIConnection.IsConnected) {
|
||||
Write-Error "ESXi Connection Failed."
|
||||
$Validate = $False
|
||||
}
|
||||
elseif ($VIConnection.ProductLine -ne "EmbeddedEsx") {
|
||||
Write-Error "Connencted System is not an ESXi."
|
||||
$Validate = $False
|
||||
}
|
||||
else {
|
||||
$ESXiHost = Get-VMHost
|
||||
My-Logger "Connected ESXi Version: $($ESXiHost.Version) $($ESXiHost.Build) "
|
||||
}
|
||||
#endregion
|
||||
|
||||
if ($Validate -eq $True) {
|
||||
|
||||
#region: Enable SSH and disable SSH Warning
|
||||
$SSHService = $ESXiHost | Get-VMHostService | where {$_.Key -eq 'TSM-SSH'}
|
||||
My-Logger "Starting SSH Service..."
|
||||
if($SSHService.Running -ne $True){
|
||||
Start-VMHostService -HostService $SSHService -Confirm:$false | Out-Null
|
||||
}
|
||||
else {
|
||||
My-Logger " SSH Service is already running"
|
||||
}
|
||||
My-Logger "Setting SSH Service to Automatic Start..."
|
||||
if($SSHService.Policy -ne "automatic"){
|
||||
Set-VMHostService -HostService $SSHService -Policy "Automatic" | Out-Null
|
||||
}
|
||||
else {
|
||||
My-Logger " SSH Service is already set to Automatic Start"
|
||||
}
|
||||
My-Logger "Disabling SSH Warning..."
|
||||
Set-MyESXiOption -Name "UserVars.SuppressShellWarning" -Value "1"
|
||||
#endregion
|
||||
|
||||
#region: Config NTP
|
||||
My-Logger "Removing existing NTP Server..."
|
||||
try {
|
||||
$ESXiHost | Remove-VMHostNtpServer -NtpServer (Get-VMHostNtpServer) -Confirm:$false
|
||||
}
|
||||
catch [System.Exception] {
|
||||
Write-Warning "Error during removing existing NTP Servers."
|
||||
}
|
||||
My-Logger "Setting new NTP Servers..."
|
||||
foreach ($myNTP in $NTP) {
|
||||
$ESXiHost | Add-VMHostNtpServer -ntpserver $myNTP -confirm:$False | Out-Null
|
||||
}
|
||||
|
||||
My-Logger "Configure NTP Service..."
|
||||
$NTPService = $ESXiHost | Get-VMHostService| Where-Object {$_.key -eq "ntpd"}
|
||||
if($NTPService.Running -eq $True){
|
||||
Stop-VMHostService -HostService $NTPService -Confirm:$false | Out-Null
|
||||
}
|
||||
if($NTPService.Policy -ne "on"){
|
||||
Set-VMHostService -HostService $NTPService -Policy "on" -confirm:$False | Out-Null
|
||||
}
|
||||
|
||||
My-Logger "Configure Local Time..."
|
||||
$HostTimeSystem = Get-View $ESXiHost.ExtensionData.ConfigManager.DateTimeSystem
|
||||
$HostTimeSystem.UpdateDateTime([DateTime]::UtcNow)
|
||||
|
||||
My-Logger "Start NTP Service..."
|
||||
Start-VMHostService -HostService $NTPService -confirm:$False | Out-Null
|
||||
#endregion
|
||||
|
||||
#region: Remove default PG
|
||||
My-Logger "Checking for Default Port Group ..."
|
||||
if ($defaultPG = $ESXiHost | Get-VirtualSwitch -Name vSwitch0 | Get-VirtualPortGroup -Name "VM Network" -ErrorAction SilentlyContinue ){
|
||||
Remove-VirtualPortGroup -VirtualPortGroup $defaultPG -confirm:$False | Out-Null
|
||||
My-Logger " Default PG Removed"
|
||||
}
|
||||
else {
|
||||
My-Logger " No Default PG found"
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region: Configure Static HighPower
|
||||
My-Logger "Setting PowerProfile to Static HighPower..."
|
||||
try {
|
||||
$HostView = ($ESXiHost | Get-View)
|
||||
(Get-View $HostView.ConfigManager.PowerSystem).ConfigurePowerPolicy(1)
|
||||
}
|
||||
catch [System.Exception] {
|
||||
Write-Warning "Error during Configure Static HighPower. See latest errors..."
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region: Conf Syslog
|
||||
My-Logger "Setting Syslog Firewall Rule ..."
|
||||
$SyslogFW = ($ESXiHost | Get-VMHostFirewallException | where {$_.Name -eq 'syslog'})
|
||||
if ($SyslogFW.Enabled -eq $False ){
|
||||
$SyslogFW | Set-VMHostFirewallException -Enabled:$true -Confirm:$false | Out-Null
|
||||
My-Logger " Syslog Firewall Rule enabled"
|
||||
}
|
||||
else {
|
||||
My-Logger " Syslog Firewall Rule already enabled"
|
||||
}
|
||||
My-Logger "Setting Syslog Server..."
|
||||
Set-MyESXiOption -Name "Syslog.global.logHost" -Value $syslog
|
||||
#endregion
|
||||
|
||||
#region: Change Disk Scheduler
|
||||
My-Logger "Changing Disk Scheduler..."
|
||||
Set-MyESXiOption -Name "Disk.SchedulerWithReservation" -Value "0"
|
||||
#endregion
|
||||
|
||||
#region: Configure HP 3PAR SATP/PSP Rule
|
||||
My-Logger "Configure HP 3PAR SATP/PSP Rule"
|
||||
$esxcli2 = Get-ESXCLI -VMHost $ESXiHost -V2
|
||||
$arguments = $esxcli2.storage.nmp.satp.rule.add.CreateArgs()
|
||||
$arguments.satp = "VMW_SATP_ALUA"
|
||||
$arguments.psp = "VMW_PSP_RR"
|
||||
$arguments.pspoption = "iops=100"
|
||||
$arguments.claimoption = "tpgs_on"
|
||||
$arguments.vendor = "3PARdata"
|
||||
$arguments.model = "VV"
|
||||
$arguments.description = "HP 3PAR custom SATP Claimrule"
|
||||
try {
|
||||
$esxcli2.storage.nmp.satp.rule.add.Invoke($arguments)
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Error during Configure HP 3PAR SATP/PSP Rule. See latest errors..."
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
468
Modules/ProactiveHA/ProactiveHA.psm1
Normal file
468
Modules/ProactiveHA/ProactiveHA.psm1
Normal file
@@ -0,0 +1,468 @@
|
||||
Function New-PHAProvider {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Function to register a new Proactive HA Provider with vCenter Server
|
||||
.PARAMETER ProviderName
|
||||
Name of ProactiveHA Provider
|
||||
.PARAMETER ComponentType
|
||||
Name of a supported ComponentType that ProactiveHA supports (Fan, Memory, Network, Power or Storage)
|
||||
.PARAMETER ComponentDescription
|
||||
Description of the health check for the given component
|
||||
.PARAMETER ComponentId
|
||||
Unique identifier for the given component within a ProactiveHA Provider
|
||||
.EXAMPLE
|
||||
New-PHAProvider -ProviderName "virtuallyGhetto" -ComponentType Power -ComponentDescription "Simulated ProactiveHA Provider" -ComponentId "Power"
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$ProviderName,
|
||||
[Parameter(Mandatory=$true)][ValidateSet("Fan","Memory","Network","Power","Storage")][String]$ComponentType,
|
||||
[Parameter(Mandatory=$true)][String]$ComponentDescription,
|
||||
[Parameter(Mandatory=$true)][String]$ComponentId
|
||||
)
|
||||
Write-Host -ForegroundColor Red "`n******************** DISCLAIMER ********************"
|
||||
Write-Host -ForegroundColor Red "**** THIS IS NOT INTENDED FOR PRODUCTION USE ****"
|
||||
Write-Host -ForegroundColor Red "**** LEARNING PURPOSES ONLY ****"
|
||||
Write-Host -ForegroundColor Red "******************** DISCLAIMER ********************`n"
|
||||
|
||||
$healthManager = Get-View $global:DefaultVIServer.ExtensionData.Content.HealthUpdateManager
|
||||
|
||||
$healthInfo = [VMware.Vim.HealthUpdateInfo] @{
|
||||
ComponentType = $ComponentType
|
||||
description = $ComponentDescription
|
||||
Id = $ComponentId
|
||||
}
|
||||
|
||||
try {
|
||||
Write-Host "`nRegistering new Proactive HA Provider $ProviderName ..."
|
||||
$providerId = $healthManager.RegisterHealthUpdateProvider($ProviderName,$healthInfo)
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red $Error[0].Exception
|
||||
}
|
||||
}
|
||||
|
||||
Function Get-PHAProvider {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Function to return list of all Proactive HA Providers registered with vCenter Server
|
||||
.EXAMPLE
|
||||
Get-PHAProvider
|
||||
#>
|
||||
$healthManager = Get-View $global:DefaultVIServer.ExtensionData.Content.HealthUpdateManager
|
||||
|
||||
$healthProviderResults = @()
|
||||
$hpIDs = $healthManager.QueryProviderList()
|
||||
|
||||
foreach ($hpID in $hpIDs) {
|
||||
$hpName = $healthManager.QueryProviderName($hpID)
|
||||
$hpConfig = $healthManager.QueryHealthUpdateInfos($hpID)
|
||||
|
||||
$hp = [pscustomobject] @{
|
||||
ProviderName = $hpName
|
||||
ProviderID = $hpID
|
||||
ComponentType = $hpConfig.componentType
|
||||
ComponentID = $hpConfig.id
|
||||
Description = $hpConfig.description
|
||||
}
|
||||
$healthProviderResults+=$hp
|
||||
}
|
||||
$healthProviderResults
|
||||
}
|
||||
|
||||
Function Remove-PHAProvider {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Function to remove a registered Proactive HA Provider from vCenter Server
|
||||
.PARAMETER ProviderId
|
||||
The ProactiveHA provider ID (retrieved from Get-PHAProvider) to unregister
|
||||
.EXAMPLE
|
||||
Remove-PHAProvider -ProviderID "52 85 22 c2 f2 6a e7 b9-fc ff 63 9e 10 81 00 79"
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$ProviderId
|
||||
)
|
||||
|
||||
Write-Host -ForegroundColor Red "`n******************** DISCLAIMER ********************"
|
||||
Write-Host -ForegroundColor Red "**** THIS IS NOT INTENDED FOR PRODUCTION USE ****"
|
||||
Write-Host -ForegroundColor Red "**** LEARNING PURPOSES ONLY ****"
|
||||
Write-Host -ForegroundColor Red "******************** DISCLAIMER ********************`n"
|
||||
|
||||
$healthManager = Get-View $global:DefaultVIServer.ExtensionData.Content.HealthUpdateManager
|
||||
|
||||
try {
|
||||
Write-Host "`nUnregistering Proactive HA Provider $ProviderId ... "
|
||||
$healthManager.UnregisterHealthUpdateProvider($providerId)
|
||||
} catch {
|
||||
if($Error[0].Exception.InnerException.MethodFault.getType().Name -eq "InvalidState") {
|
||||
Write-host -ForegroundColor Red "The Proactive HA Provider is still in use, please disable it before unregistering"
|
||||
} else {
|
||||
Write-host -ForegroundColor Red $Error[0].Exception
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Function Set-PHAConfig {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Function to enable/disable Proactive HA for vSphere Cluster
|
||||
.PARAMETER Cluster
|
||||
Name of the vSphere Cluster to enable Proactive HA
|
||||
.PARAMETER ProviderId
|
||||
Proactive HA Provider ID to enable in vSphere Cluster
|
||||
.PARAMETER ClusterMode
|
||||
Whether Proactive HA should be "Automated" or "Manual" for actions it will take
|
||||
.PARAMETER ModerateRemediation
|
||||
Type of operation (Maintenance Mode or Quaratine Mode) to perform when a Moderate issue is observed
|
||||
.PARAMETER SevereRemediation
|
||||
Type of operation (Maintenance Mode or Quaratine Mode) to perform when a Severe issue is observed
|
||||
.EXAMPLE
|
||||
Set-PHAConfig -Cluster VSAN-Cluster -Enabled -ClusterMode Automated -ModerateRemediation QuarantineMode -SevereRemediation QuarantineMode -ProviderID "52 85 22 c2 f2 6a e7 b9-fc ff 63 9e 10 81 00 79"
|
||||
.EXAMPLE
|
||||
Set-PHAConfig -Cluster VSAN-Cluster -Disabled -ProviderID "52 85 22 c2 f2 6a e7 b9-fc ff 63 9e 10 81 00 79"
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$ProviderId,
|
||||
[Parameter(Mandatory=$true)][String]$Cluster,
|
||||
[Parameter(Mandatory=$false)][ValidateSet("Automated","Manual")]$ClusterMode="Manual",
|
||||
[Parameter(Mandatory=$false)][ValidateSet("MaintenanceMode","QuarantineMode")]$ModerateRemediation="QuarantineMode",
|
||||
[Parameter(Mandatory=$false)][ValidateSet("MaintenanceMode","QuarantineMode")]$SevereRemediation="QuarantineMode",
|
||||
[Switch]$Enabled,
|
||||
[Switch]$Disabled
|
||||
)
|
||||
|
||||
$ClusterView = Get-View -ViewType ClusterComputeResource -Property Name,Host,ConfigurationEx -Filter @{"Name" = $Cluster}
|
||||
|
||||
if($ClusterView -eq $null) {
|
||||
Write-Host -ForegroundColor Red "Unable to find vSphere Cluster $cluster ..."
|
||||
break
|
||||
}
|
||||
|
||||
$vmhosts = $ClusterView.host
|
||||
|
||||
$healthManager = Get-View $global:DefaultVIServer.ExtensionData.Content.HealthUpdateManager
|
||||
|
||||
if($Enabled) {
|
||||
try {
|
||||
$entities = @()
|
||||
foreach ($vmhost in $vmhosts) {
|
||||
if(-not $healthManager.HasMonitoredEntity($ProviderId,$vmhost)) {
|
||||
$entities += $vmhost
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "Enabling Proactive HA monitoring for all ESXi hosts in cluster ..."
|
||||
$healthManager.AddMonitoredEntities($ProviderId,$entities)
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red $Error[0].Exception
|
||||
}
|
||||
|
||||
try {
|
||||
$healthProviders = @()
|
||||
|
||||
# Make sure not to remove existing ProactiveHA providers
|
||||
if($ClusterView.ConfigurationEx.InfraUpdateHaConfig.Providers -ne $null) {
|
||||
$currentHPs = $ClusterView.ConfigurationEx.infraUpdateHaConfig.providers
|
||||
foreach ($currentHP in $currentHPs) {
|
||||
$healthProviders+=$currentHP
|
||||
}
|
||||
if(-not ($healthProviders -contains $ProviderID)) {
|
||||
$healthProviders+=$ProviderId
|
||||
}
|
||||
} else {
|
||||
$healthProviders+=$ProviderId
|
||||
}
|
||||
|
||||
$PHASpec = [VMware.Vim.ClusterInfraUpdateHaConfigInfo] @{
|
||||
enabled = $true
|
||||
behavior = $ClusterMode
|
||||
moderateRemediation = $ModerateRemediation
|
||||
severeRemediation = $SevereRemediation
|
||||
providers = $healthProviders
|
||||
}
|
||||
|
||||
$spec = [VMware.Vim.ClusterConfigSpecEx] @{
|
||||
infraUpdateHaConfig = $PHASpec
|
||||
}
|
||||
|
||||
Write-Host "Enabling Proactive HA Provider $ProviderId on $Cluster ..."
|
||||
$task = $ClusterView.ReconfigureComputeResource_Task($spec,$True)
|
||||
$task1 = Get-Task -Id ("Task-$($task.value)")
|
||||
$task1 | Wait-Task | Out-Null
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red $Error[0].Exception
|
||||
}
|
||||
}
|
||||
|
||||
if($Disabled) {
|
||||
foreach ($vmhost in $vmhosts) {
|
||||
if($vmhost.runtime.inQuarantineMode) {
|
||||
Write-Host -ForegroundColor Red $vmhost.name " is currently still in Quaratine Mode, please remediate this before disabling Proactive HA"
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$healthProviders = @()
|
||||
|
||||
# Make sure not to remove existing ProactiveHA providers
|
||||
if($ClusterView.ConfigurationEx.InfraUpdateHaConfig.Providers -ne $null) {
|
||||
$currentHPs = $ClusterView.ConfigurationEx.infraUpdateHaConfig.providers
|
||||
foreach ($currentHP in $currentHPs) {
|
||||
if($currentHP -ne $ProviderId) {
|
||||
$healthProviders+=$currentHP
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$PHASpec = [VMware.Vim.ClusterInfraUpdateHaConfigInfo] @{
|
||||
enabled = $true
|
||||
behavior = $ClusterMode
|
||||
moderateRemediation = $ModerateRemediation
|
||||
severeRemediation = $SevereRemediation
|
||||
providers = $healthProviders
|
||||
}
|
||||
|
||||
$spec = [VMware.Vim.ClusterConfigSpecEx] @{
|
||||
infraUpdateHaConfig = $PHASpec
|
||||
}
|
||||
|
||||
Write-Host "Disabling Proactive HA Provider $ProviderId on $Cluster ..."
|
||||
$task = $ClusterView.ReconfigureComputeResource_Task($spec,$True)
|
||||
$task1 = Get-Task -Id ("Task-$($task.value)")
|
||||
$task1 | Wait-Task | Out-Null
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red $Error[0].Exception
|
||||
}
|
||||
|
||||
$ClusterView.UpdateViewData()
|
||||
|
||||
try {
|
||||
$entities = @()
|
||||
foreach ($vmhost in $vmhosts) {
|
||||
if($healthManager.HasMonitoredEntity($ProviderId,$vmhost)) {
|
||||
$entities += $vmhost
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "Disabling Proactive HA monitoring for all ESXi hosts in cluster ..."
|
||||
$healthManager.RemoveMonitoredEntities($ProviderId,$entities)
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red $Error[0].Exception
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Function Get-PHAConfig {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Function to retrieve Proactive HA configuration for a vSphere Cluster
|
||||
.PARAMETER Cluster
|
||||
Name of the vSphere Cluster to check Proactive HA configuration
|
||||
.EXAMPLE
|
||||
Get-PHAConfig -Cluster VSAN-Cluster
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$Cluster
|
||||
)
|
||||
|
||||
$ClusterView = Get-View -ViewType ClusterComputeResource -Property Name,ConfigurationEx -Filter @{"Name" = $Cluster}
|
||||
|
||||
if($ClusterView -eq $null) {
|
||||
Write-Host -ForegroundColor Red "Unable to find vSphere Cluster $cluster ..."
|
||||
break
|
||||
}
|
||||
|
||||
if($ClusterView.ConfigurationEx.InfraUpdateHaConfig.Providers -ne $null) {
|
||||
$healthManager = Get-View $global:DefaultVIServer.ExtensionData.Content.HealthUpdateManager
|
||||
|
||||
$phSettings = $ClusterView.ConfigurationEx.InfraUpdateHaConfig
|
||||
$providers = $ClusterView.ConfigurationEx.InfraUpdateHaConfig.Providers
|
||||
$healthProviders = @()
|
||||
foreach ($provider in $providers) {
|
||||
$providerName = $healthManager.QueryProviderName($provider)
|
||||
$healthProviders+=$providerName
|
||||
}
|
||||
|
||||
$pHAConfig = [pscustomobject] @{
|
||||
Enabled = $phSettings.Enabled
|
||||
ClusterMode = $phSettings.behavior
|
||||
ModerateRemediation = $phSettings.ModerateRemediation
|
||||
SevereRemediation = $phSettings.SevereRemediation
|
||||
HealthProviders = $healthProviders
|
||||
}
|
||||
$pHAConfig
|
||||
} else {
|
||||
Write-Host "Proactive HA has not been configured on this vSphere Cluster"
|
||||
}
|
||||
}
|
||||
|
||||
Function Get-PHAHealth {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Function to retrieve the Proactive HA health info for all ESXi hosts in vSphere Cluster
|
||||
.PARAMETER Cluster
|
||||
Name of the vSphere Cluster to check Proactive HA health information
|
||||
.EXAMPLE
|
||||
Get-PHAHealth -Cluster VSAN-Cluster
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$Cluster
|
||||
)
|
||||
|
||||
$ClusterView = Get-View -ViewType ClusterComputeResource -Property Name,ConfigurationEx -Filter @{"Name" = $Cluster}
|
||||
|
||||
if($ClusterView -eq $null) {
|
||||
Write-Host -ForegroundColor Red "Unable to find vSphere Cluster $cluster ..."
|
||||
break
|
||||
}
|
||||
|
||||
if($ClusterView.ConfigurationEx.InfraUpdateHaConfig.Providers -ne $null) {
|
||||
$healthManager = Get-View $global:DefaultVIServer.ExtensionData.Content.HealthUpdateManager
|
||||
|
||||
$providers = $ClusterView.ConfigurationEx.InfraUpdateHaConfig.Providers
|
||||
|
||||
foreach ($provider in $providers) {
|
||||
$providerName = $healthManager.QueryProviderName($provider)
|
||||
$healthUpdates = $healthManager.QueryHealthUpdates($provider)
|
||||
|
||||
$healthResults = @()
|
||||
Write-Host -NoNewline -ForegroundColor Magenta "Health summary for Proactive HA Provider $providerName`:`n"
|
||||
foreach ($healthUpdate in $healthUpdates) {
|
||||
$vmhost = Get-View $healthUpdate.Entity
|
||||
|
||||
$hr = [PSCustomObject] @{
|
||||
Entity = $vmhost.name
|
||||
Status = $healthUpdate.status
|
||||
HealthComponentId = $healthUpdate.HealthUpdateInfoId
|
||||
HealthUpdateId = $healthUpdate.Id
|
||||
Remediation = $healthUpdate.Remediation
|
||||
}
|
||||
$healthResults+=$hr
|
||||
}
|
||||
$healthResults
|
||||
}
|
||||
} else {
|
||||
Write-Host "Proactive HA has not been configured on this vSphere Cluster"
|
||||
}
|
||||
}
|
||||
|
||||
Function New-PHASimulation {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Function to return VCHA Configuration
|
||||
.PARAMETER ProviderId
|
||||
The Proactive HA Provider ID that you like to simulate a health update from
|
||||
.PARAMETER EsxiHost
|
||||
The name of ESXi host to update the health on
|
||||
.PARAMETER Component
|
||||
The name of the matching component ID from Proactive HA Provider to simulate a health update from
|
||||
.PARAMETER HealthStatus
|
||||
The health value (green, yellow or red) for the given simulated health Update
|
||||
.PARAMETER Remediation
|
||||
The remediation message associated with simulated health update
|
||||
.EXAMPLE
|
||||
New-PHASimulation -EsxiHost vesxi65-4.primp-industries.com -Component Power -HealthStatus green -Remediation "" -ProviderId "52 85 22 c2 f2 6a e7 b9-fc ff 63 9e 10 81 00 79"
|
||||
.EXAMPLE
|
||||
New-PHASimulation -EsxiHost vesxi65-4.primp-industries.com -Component Power -HealthStatus red -Remediation "Please replace my virtual PSU" -ProviderId "52 85 22 c2 f2 6a e7 b9-fc ff 63 9e 10 81 00 79"
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$ProviderId,
|
||||
[Parameter(Mandatory=$true)][String]$EsxiHost,
|
||||
[Parameter(Mandatory=$true)][String]$Component,
|
||||
[Parameter(Mandatory=$true)][ValidateSet("green","red","yellow")][String]$HealthStatus,
|
||||
[Parameter(Mandatory=$false)][String]$Remediation
|
||||
)
|
||||
|
||||
Write-Host -ForegroundColor Red "`n******************** DISCLAIMER ********************"
|
||||
Write-Host -ForegroundColor Red "**** THIS IS NOT INTENDED FOR PRODUCTION USE ****"
|
||||
Write-Host -ForegroundColor Red "**** LEARNING PURPOSES ONLY ****"
|
||||
Write-Host -ForegroundColor Red "******************** DISCLAIMER ********************`n"
|
||||
|
||||
$vmhost = Get-View -ViewType HostSystem -Property Name -Filter @{"name" = $EsxiHost}
|
||||
|
||||
if($vmhost -eq $null) {
|
||||
Write-Host -ForegroundColor Red "`nUnable to find ESXi host $EsxiHost ..."
|
||||
break
|
||||
}
|
||||
|
||||
$healthManager = Get-View $global:DefaultVIServer.ExtensionData.Content.HealthUpdateManager
|
||||
|
||||
# Randomly generating an ID for Health Update
|
||||
# In general, you would want to generate a specific ID
|
||||
# which can be referenced between ProactiveHA Provider
|
||||
# and VMware logs for troubleshooting purposes
|
||||
$HealthUpdateID = "vghetto-" + (Get-Random -Minimum 1 -Maximum 100000)
|
||||
|
||||
# All other Health Status can have a remediation message
|
||||
# but for green, it must be an empty string or API call will fail
|
||||
if($HealthStatus -eq "green") {
|
||||
$Remediation = ""
|
||||
}
|
||||
|
||||
$healthUpdate = [VMware.Vim.HealthUpdate] @{
|
||||
Entity = $vmhost.moref
|
||||
HealthUpdateInfoId = $Component
|
||||
Id = $HealthUpdateId
|
||||
Status = $HealthStatus
|
||||
Remediation = $Remediation
|
||||
}
|
||||
|
||||
try {
|
||||
Write-Host "`nSimulating Proactive HA Health Update to ..."
|
||||
Write-Host "`tHost: $EsxiHost "
|
||||
Write-Host -NoNewline "`tStatus: "
|
||||
Write-Host -ForegroundColor $HealthStatus "$HealthStatus"
|
||||
Write-Host "`tRemediation Messsage: $Remediation"
|
||||
$healthManager.PostHealthUpdates($providerId,$healthUpdate)
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red $Error[0].Exception
|
||||
}
|
||||
}
|
||||
716
Modules/VAMI/VAMI.psm1
Executable file
716
Modules/VAMI/VAMI.psm1
Executable file
@@ -0,0 +1,716 @@
|
||||
Function Get-VAMISummary {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves some basic information from VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return basic VAMI summary info
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMISummary
|
||||
#>
|
||||
$systemVersionAPI = Get-CisService -Name 'com.vmware.appliance.system.version'
|
||||
$results = $systemVersionAPI.get() | select product, type, version, build, install_time
|
||||
|
||||
$systemUptimeAPI = Get-CisService -Name 'com.vmware.appliance.system.uptime'
|
||||
$ts = [timespan]::fromseconds($systemUptimeAPI.get().toString())
|
||||
$uptime = $ts.ToString("hh\:mm\:ss\,fff")
|
||||
|
||||
$summaryResult = [pscustomobject] @{
|
||||
Product = $results.product;
|
||||
Type = $results.type;
|
||||
Version = $results.version;
|
||||
Build = $results.build;
|
||||
InstallTime = $results.install_time;
|
||||
Uptime = $uptime
|
||||
}
|
||||
$summaryResult
|
||||
}
|
||||
|
||||
Function Get-VAMIHealth {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves health information from VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return VAMI health
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMIHealth
|
||||
#>
|
||||
$healthOverall = (Get-CisService -Name 'com.vmware.appliance.health.system').get()
|
||||
$healthLastCheck = (Get-CisService -Name 'com.vmware.appliance.health.system').lastcheck()
|
||||
$healthCPU = (Get-CisService -Name 'com.vmware.appliance.health.load').get()
|
||||
$healthMem = (Get-CisService -Name 'com.vmware.appliance.health.mem').get()
|
||||
$healthSwap = (Get-CisService -Name 'com.vmware.appliance.health.swap').get()
|
||||
$healthStorage = (Get-CisService -Name 'com.vmware.appliance.health.storage').get()
|
||||
|
||||
# DB health only applicable for Embedded/External VCSA Node
|
||||
$vami = (Get-CisService -Name 'com.vmware.appliance.system.version').get()
|
||||
|
||||
if($vami.type -eq "vCenter Server with an embedded Platform Services Controller" -or $vami.type -eq "vCenter Server with an external Platform Services Controller") {
|
||||
$healthVCDB = (Get-CisService -Name 'com.vmware.appliance.health.databasestorage').get()
|
||||
} else {
|
||||
$healthVCDB = "N/A"
|
||||
}
|
||||
$healthSoftwareUpdates = (Get-CisService -Name 'com.vmware.appliance.health.softwarepackages').get()
|
||||
|
||||
$healthResult = [pscustomobject] @{
|
||||
HealthOverall = $healthOverall;
|
||||
HealthLastCheck = $healthLastCheck;
|
||||
HealthCPU = $healthCPU;
|
||||
HealthMem = $healthMem;
|
||||
HealthSwap = $healthSwap;
|
||||
HealthStorage = $healthStorage;
|
||||
HealthVCDB = $healthVCDB;
|
||||
HealthSoftware = $healthSoftwareUpdates
|
||||
}
|
||||
$healthResult
|
||||
}
|
||||
|
||||
Function Get-VAMIAccess {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves access information from VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return VAMI access interfaces (Console,DCUI,Bash Shell & SSH)
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMIAccess
|
||||
#>
|
||||
$consoleAccess = (Get-CisService -Name 'com.vmware.appliance.access.consolecli').get()
|
||||
$dcuiAccess = (Get-CisService -Name 'com.vmware.appliance.access.dcui').get()
|
||||
$shellAccess = (Get-CisService -Name 'com.vmware.appliance.access.shell').get()
|
||||
$sshAccess = (Get-CisService -Name 'com.vmware.appliance.access.ssh').get()
|
||||
|
||||
$accessResult = New-Object PSObject -Property @{
|
||||
Console = $consoleAccess;
|
||||
DCUI = $dcuiAccess;
|
||||
BashShell = $shellAccess.enabled;
|
||||
SSH = $sshAccess
|
||||
}
|
||||
$accessResult
|
||||
}
|
||||
|
||||
Function Get-VAMITime {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves the time and NTP info from VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return current Time and NTP information
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMITime
|
||||
#>
|
||||
$systemTimeAPI = Get-CisService -Name 'com.vmware.appliance.system.time'
|
||||
$timeResults = $systemTimeAPI.get()
|
||||
|
||||
$timeSync = (Get-CisService -Name 'com.vmware.appliance.techpreview.timesync').get()
|
||||
$timeSyncMode = $timeSync.mode
|
||||
|
||||
$timeResult = [pscustomobject] @{
|
||||
Timezone = $timeResults.timezone;
|
||||
Date = $timeResults.date;
|
||||
CurrentTime = $timeResults.time;
|
||||
Mode = $timeSyncMode;
|
||||
NTPServers = "N/A";
|
||||
NTPStatus = "N/A";
|
||||
}
|
||||
|
||||
if($timeSyncMode -eq "NTP") {
|
||||
$ntpServers = (Get-CisService -Name 'com.vmware.appliance.techpreview.ntp').get()
|
||||
$timeResult.NTPServers = $ntpServers.servers
|
||||
$timeResult.NTPStatus = $ntpServers.status
|
||||
}
|
||||
$timeResult
|
||||
}
|
||||
|
||||
Function Get-VAMINetwork {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves network information from VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return networking information including details for each interface
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMINetwork
|
||||
#>
|
||||
$netResults = @()
|
||||
|
||||
$Hostname = (Get-CisService -Name 'com.vmware.appliance.networking.dns.hostname').get()
|
||||
$dns = (Get-CisService -Name 'com.vmware.appliance.networking.dns.servers').get()
|
||||
|
||||
Write-Host "Hostname: " $hostname
|
||||
Write-Host "DNS Servers: " $dns.servers
|
||||
|
||||
$interfaces = (Get-CisService -Name 'com.vmware.appliance.networking.interfaces').list()
|
||||
foreach ($interface in $interfaces) {
|
||||
$ipv4API = (Get-CisService -Name 'com.vmware.appliance.techpreview.networking.ipv4')
|
||||
$spec = $ipv4API.Help.get.interfaces.CreateExample()
|
||||
$spec+= $interface.name
|
||||
$ipv4result = $ipv4API.get($spec)
|
||||
|
||||
$interfaceResult = [pscustomobject] @{
|
||||
Inteface = $interface.name;
|
||||
MAC = $interface.mac;
|
||||
Status = $interface.status;
|
||||
Mode = $ipv4result.mode;
|
||||
IP = $ipv4result.address;
|
||||
Prefix = $ipv4result.prefix;
|
||||
Gateway = $ipv4result.default_gateway;
|
||||
Updateable = $ipv4result.updateable
|
||||
}
|
||||
$netResults += $interfaceResult
|
||||
}
|
||||
$netResults
|
||||
}
|
||||
|
||||
Function Get-VAMIDisks {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves VMDK disk number to partition mapping VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return VMDK disk number to OS partition mapping
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMIDisks
|
||||
#>
|
||||
$storageAPI = Get-CisService -Name 'com.vmware.appliance.system.storage'
|
||||
$disks = $storageAPI.list()
|
||||
|
||||
foreach ($disk in $disks | sort {[int]$_.disk.toString()}) {
|
||||
$disk | Select Disk, Partition
|
||||
}
|
||||
}
|
||||
|
||||
Function Start-VAMIDiskResize {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function triggers an OS partition resize after adding additional disk capacity
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function triggers OS partition resize operation
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Start-VAMIDiskResize
|
||||
#>
|
||||
$storageAPI = Get-CisService -Name 'com.vmware.appliance.system.storage'
|
||||
Write-Host "Initiated OS partition resize operation ..."
|
||||
$storageAPI.resize()
|
||||
}
|
||||
|
||||
Function Get-VAMIStatsList {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves list avialable monitoring metrics in VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return list of available monitoring metrics that can be queried
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMIStatsList
|
||||
#>
|
||||
$monitoringAPI = Get-CisService -Name 'com.vmware.appliance.monitoring'
|
||||
$ids = $monitoringAPI.list() | Select id | Sort-Object -Property id
|
||||
|
||||
foreach ($id in $ids) {
|
||||
$id
|
||||
}
|
||||
}
|
||||
|
||||
Function Get-VAMIStorageUsed {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves the individaul OS partition storage utilization
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return individual OS partition storage utilization
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMIStorageUsed
|
||||
#>
|
||||
$monitoringAPI = Get-CisService 'com.vmware.appliance.monitoring'
|
||||
$querySpec = $monitoringAPI.help.query.item.CreateExample()
|
||||
|
||||
# List of IDs from Get-VAMIStatsList to query
|
||||
$querySpec.Names = @(
|
||||
"storage.used.filesystem.autodeploy",
|
||||
"storage.used.filesystem.boot",
|
||||
"storage.used.filesystem.coredump",
|
||||
"storage.used.filesystem.imagebuilder",
|
||||
"storage.used.filesystem.invsvc",
|
||||
"storage.used.filesystem.log",
|
||||
"storage.used.filesystem.netdump",
|
||||
"storage.used.filesystem.root",
|
||||
"storage.used.filesystem.updatemgr",
|
||||
"storage.used.filesystem.vcdb_core_inventory",
|
||||
"storage.used.filesystem.vcdb_seat",
|
||||
"storage.used.filesystem.vcdb_transaction_log",
|
||||
"storage.totalsize.filesystem.autodeploy",
|
||||
"storage.totalsize.filesystem.boot",
|
||||
"storage.totalsize.filesystem.coredump",
|
||||
"storage.totalsize.filesystem.imagebuilder",
|
||||
"storage.totalsize.filesystem.invsvc",
|
||||
"storage.totalsize.filesystem.log",
|
||||
"storage.totalsize.filesystem.netdump",
|
||||
"storage.totalsize.filesystem.root",
|
||||
"storage.totalsize.filesystem.updatemgr",
|
||||
"storage.totalsize.filesystem.vcdb_core_inventory",
|
||||
"storage.totalsize.filesystem.vcdb_seat",
|
||||
"storage.totalsize.filesystem.vcdb_transaction_log"
|
||||
)
|
||||
|
||||
# Tuple (Filesystem Name, Used, Total) to store results
|
||||
$storageStats = @{
|
||||
"autodeploy"=@{"name"="/storage/autodeploy";"used"=0;"total"=0};
|
||||
"boot"=@{"name"="/boot";"used"=0;"total"=0};
|
||||
"coredump"=@{"name"="/storage/core";"used"=0;"total"=0};
|
||||
"imagebuilder"=@{"name"="/storage/imagebuilder";"used"=0;"total"=0};
|
||||
"invsvc"=@{"name"="/storage/invsvc";"used"=0;"total"=0};
|
||||
"log"=@{"name"="/storage/log";"used"=0;"total"=0};
|
||||
"netdump"=@{"name"="/storage/netdump";"used"=0;"total"=0};
|
||||
"root"=@{"name"="/";"used"=0;"total"=0};
|
||||
"updatemgr"=@{"name"="/storage/updatemgr";"used"=0;"total"=0};
|
||||
"vcdb_core_inventory"=@{"name"="/storage/db";"used"=0;"total"=0};
|
||||
"vcdb_seat"=@{"name"="/storage/seat";"used"=0;"total"=0};
|
||||
"vcdb_transaction_log"=@{"name"="/storage/dblog";"used"=0;"total"=0}
|
||||
}
|
||||
|
||||
$querySpec.interval = "DAY1"
|
||||
$querySpec.function = "MAX"
|
||||
$querySpec.start_time = ((get-date).AddDays(-1))
|
||||
$querySpec.end_time = (Get-Date)
|
||||
$queryResults = $monitoringAPI.query($querySpec) | Select * -ExcludeProperty Help
|
||||
|
||||
foreach ($queryResult in $queryResults) {
|
||||
# Update hash if its used storage results
|
||||
if($queryResult.name -match "used") {
|
||||
$key = (($queryResult.name).toString()).split(".")[-1]
|
||||
$value = [Math]::Round([int]($queryResult.data[1]).toString()/1MB,2)
|
||||
$storageStats[$key]["used"] = $value
|
||||
# Update hash if its total storage results
|
||||
} else {
|
||||
$key = (($queryResult.name).toString()).split(".")[-1]
|
||||
$value = [Math]::Round([int]($queryResult.data[1]).toString()/1MB,2)
|
||||
$storageStats[$key]["total"] = $value
|
||||
}
|
||||
}
|
||||
|
||||
$storageResults = @()
|
||||
foreach ($key in $storageStats.keys | Sort-Object -Property name) {
|
||||
$statResult = [pscustomobject] @{
|
||||
Filesystem = $storageStats[$key].name;
|
||||
Used = $storageStats[$key].used;
|
||||
Total = $storageStats[$key].total
|
||||
}
|
||||
$storageResults += $statResult
|
||||
}
|
||||
$storageResults
|
||||
}
|
||||
|
||||
Function Get-VAMIService {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves list of services in VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return list of services and their description
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMIService
|
||||
.EXAMPLE
|
||||
Get-VAMIService -Name rbd
|
||||
#>
|
||||
param(
|
||||
[Parameter(
|
||||
Mandatory=$false,
|
||||
ValueFromPipeline=$true,
|
||||
ValueFromPipelineByPropertyName=$true)
|
||||
]
|
||||
[String]$Name
|
||||
)
|
||||
|
||||
if($Name -ne "") {
|
||||
$vMonAPI = Get-CisService 'com.vmware.appliance.vmon.service'
|
||||
|
||||
try {
|
||||
$serviceStatus = $vMonAPI.get($name,0)
|
||||
$serviceString = [pscustomobject] @{
|
||||
Name = $name;
|
||||
State = $serviceStatus.state;
|
||||
Health = "";
|
||||
Startup = $serviceStatus.startup_type
|
||||
}
|
||||
if($serviceStatus.health -eq $null) { $serviceString.Health = "N/A"} else { $serviceString.Health = $serviceStatus.health }
|
||||
$serviceString
|
||||
} catch {
|
||||
Write-Error $Error[0].exception.Message
|
||||
}
|
||||
} else {
|
||||
$vMonAPI = Get-CisService 'com.vmware.appliance.vmon.service'
|
||||
$services = $vMonAPI.list_details()
|
||||
|
||||
$serviceResult = @()
|
||||
foreach ($key in $services.keys | Sort-Object -Property Value) {
|
||||
$serviceString = [pscustomobject] @{
|
||||
Name = $key;
|
||||
State = $services[$key].state;
|
||||
Health = "N/A";
|
||||
Startup = $services[$key].Startup_type
|
||||
}
|
||||
if($services[$key].health -eq $null) { $serviceString.Health = "N/A"} else { $serviceString.Health = $services[$key].health }
|
||||
|
||||
$serviceResult += $serviceString
|
||||
}
|
||||
$serviceResult
|
||||
}
|
||||
}
|
||||
|
||||
Function Start-VAMIService {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves list of services in VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return list of services and their description
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Start-VAMIService -Name rbd
|
||||
#>
|
||||
param(
|
||||
[Parameter(
|
||||
Mandatory=$true,
|
||||
ValueFromPipeline=$true,
|
||||
ValueFromPipelineByPropertyName=$true)
|
||||
]
|
||||
[String]$Name
|
||||
)
|
||||
|
||||
$vMonAPI = Get-CisService 'com.vmware.appliance.vmon.service'
|
||||
|
||||
try {
|
||||
Write-Host "Starting $name service ..."
|
||||
$vMonAPI.start($name)
|
||||
} catch {
|
||||
Write-Error $Error[0].exception.Message
|
||||
}
|
||||
}
|
||||
|
||||
Function Stop-VAMIService {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves list of services in VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return list of services and their description
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Stop-VAMIService -Name rbd
|
||||
#>
|
||||
param(
|
||||
[Parameter(
|
||||
Mandatory=$true,
|
||||
ValueFromPipeline=$true,
|
||||
ValueFromPipelineByPropertyName=$true)
|
||||
]
|
||||
[String]$Name
|
||||
)
|
||||
|
||||
$vMonAPI = Get-CisService 'com.vmware.appliance.vmon.service'
|
||||
|
||||
try {
|
||||
Write-Host "Stopping $name service ..."
|
||||
$vMonAPI.stop($name)
|
||||
} catch {
|
||||
Write-Error $Error[0].exception.Message
|
||||
}
|
||||
}
|
||||
|
||||
Function Get-VAMIBackupSize {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves the backup size of the VCSA from VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return the current backup size of the VCSA (common and core data)
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMIBackupSize
|
||||
#>
|
||||
$recoveryAPI = Get-CisService 'com.vmware.appliance.recovery.backup.parts'
|
||||
$backupParts = $recoveryAPI.list() | select id
|
||||
|
||||
$estimateBackupSize = 0
|
||||
$backupPartSizes = ""
|
||||
foreach ($backupPart in $backupParts) {
|
||||
$partId = $backupPart.id.value
|
||||
$partSize = $recoveryAPI.get($partId)
|
||||
$estimateBackupSize += $partSize
|
||||
$backupPartSizes += $partId + " data is " + $partSize + " MB`n"
|
||||
}
|
||||
|
||||
Write-Host "Estimated Backup Size: $estimateBackupSize MB"
|
||||
Write-Host $backupPartSizes
|
||||
}
|
||||
|
||||
Function Get-VAMIUser {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves VAMI local users using VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to retrieve VAMI local users
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMIUser
|
||||
#>
|
||||
param(
|
||||
[Parameter(
|
||||
Mandatory=$false,
|
||||
ValueFromPipeline=$true,
|
||||
ValueFromPipelineByPropertyName=$true)
|
||||
]
|
||||
[String]$Name
|
||||
)
|
||||
|
||||
$userAPI = Get-CisService 'com.vmware.appliance.techpreview.localaccounts.user'
|
||||
|
||||
$userResults = @()
|
||||
|
||||
if($Name -ne "") {
|
||||
try {
|
||||
$user = $userAPI.get($name)
|
||||
|
||||
$userString = [pscustomobject] @{
|
||||
User = $user.username
|
||||
Name = $user.fullname
|
||||
Email = $user.email
|
||||
Status = $user.status
|
||||
PasswordStatus = $user.passwordstatus
|
||||
Role = $user.role
|
||||
}
|
||||
$userResults += $userString
|
||||
} catch {
|
||||
Write-Error $Error[0].exception.Message
|
||||
}
|
||||
} else {
|
||||
$users = $userAPI.list()
|
||||
|
||||
foreach ($user in $users) {
|
||||
$userString = [pscustomobject] @{
|
||||
User = $user.username
|
||||
Name = $user.fullname
|
||||
Email = $user.email
|
||||
Status = $user.status
|
||||
PasswordStatus = $user.passwordstatus
|
||||
Role = $user.role
|
||||
}
|
||||
$userResults += $userString
|
||||
}
|
||||
}
|
||||
$userResults
|
||||
}
|
||||
|
||||
Function New-VAMIUser {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function to create new VAMI local user using VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to create a new VAMI local user
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
New-VAMIUser -name lamw -fullname "William Lam" -role "operator" -email "lamw@virtuallyghetto.com" -password "VMware1!"
|
||||
#>
|
||||
param(
|
||||
[Parameter(
|
||||
Mandatory=$true)
|
||||
]
|
||||
[String]$name,
|
||||
[Parameter(
|
||||
Mandatory=$true)
|
||||
]
|
||||
[String]$fullname,
|
||||
[Parameter(
|
||||
Mandatory=$true)
|
||||
]
|
||||
[ValidateSet("admin","operator","superAdmin")][String]$role,
|
||||
[Parameter(
|
||||
Mandatory=$false)
|
||||
]
|
||||
[String]$email="",
|
||||
[Parameter(
|
||||
Mandatory=$true)
|
||||
]
|
||||
[String]$password
|
||||
)
|
||||
|
||||
$userAPI = Get-CisService 'com.vmware.appliance.techpreview.localaccounts.user'
|
||||
$createSpec = $userAPI.Help.add.config.CreateExample()
|
||||
|
||||
$createSpec.username = $name
|
||||
$createSpec.fullname = $fullname
|
||||
$createSpec.role = $role
|
||||
$createSpec.email = $email
|
||||
$createSpec.password = [VMware.VimAutomation.Cis.Core.Types.V1.Secret]$password
|
||||
|
||||
try {
|
||||
Write-Host "Creating new user $name ..."
|
||||
$userAPI.add($createSpec)
|
||||
} catch {
|
||||
Write-Error $Error[0].exception.Message
|
||||
}
|
||||
}
|
||||
|
||||
Function Remove-VAMIUser {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function to remove VAMI local user using VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to remove VAMI local user
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMIAccess
|
||||
#>
|
||||
param(
|
||||
[Parameter(
|
||||
Mandatory=$true)
|
||||
]
|
||||
[String]$name,
|
||||
[Parameter(
|
||||
Mandatory=$false)
|
||||
]
|
||||
[boolean]$confirm=$false
|
||||
)
|
||||
|
||||
if(!$confirm) {
|
||||
$answer = Read-Host -Prompt "Do you want to delete user $name (Y or N)"
|
||||
if($answer -eq "Y" -or $answer -eq "y") {
|
||||
$userAPI = Get-CisService 'com.vmware.appliance.techpreview.localaccounts.user'
|
||||
|
||||
try {
|
||||
Write-Host "Deleting user $name ..."
|
||||
$userAPI.delete($name)
|
||||
} catch {
|
||||
Write-Error $Error[0].exception.Message
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
413
Modules/VCHA/VCHA.psm1
Normal file
413
Modules/VCHA/VCHA.psm1
Normal file
@@ -0,0 +1,413 @@
|
||||
Function Get-VCHAConfig {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: Nov 20, 2016
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves the VCHA Configuration which provides you with
|
||||
the current state, mode as well as the IP Addresses of the Active,
|
||||
Passive & Witness Node. This is only available on VCSA 6.5 (vSphere 6.5 or greater)
|
||||
.DESCRIPTION
|
||||
Function to return VCHA Configuration
|
||||
.EXAMPLE
|
||||
Get-VCHAConfig
|
||||
#>
|
||||
$vcHAClusterConfig = Get-View failoverClusterConfigurator
|
||||
$vcHAConfig = $vcHAClusterConfig.getVchaConfig()
|
||||
|
||||
$vcHAState = $vcHAConfig.State
|
||||
switch($vcHAState) {
|
||||
configured {
|
||||
$activeIp = $vcHAConfig.FailoverNodeInfo1.ClusterIpSettings.Ip.IpAddress
|
||||
$passiveIp = $vcHAConfig.FailoverNodeInfo2.ClusterIpSettings.Ip.IpAddress
|
||||
$witnessIp = $vcHAConfig.WitnessNodeInfo.IpSettings.Ip.IpAddress
|
||||
|
||||
$vcHAClusterManager = Get-View failoverClusterManager
|
||||
$vcHAMode = $vcHAClusterManager.getClusterMode()
|
||||
|
||||
Write-Host ""
|
||||
Write-Host -NoNewline -ForegroundColor Green "VCHA State: "
|
||||
Write-Host -ForegroundColor White "$vcHAState"
|
||||
Write-Host -NoNewline -ForegroundColor Green " VCHA Mode: "
|
||||
Write-Host -ForegroundColor White "$vcHAMode"
|
||||
Write-Host -NoNewline -ForegroundColor Green " ActiveIP: "
|
||||
Write-Host -ForegroundColor White "$activeIp"
|
||||
Write-Host -NoNewline -ForegroundColor Green " PassiveIP: "
|
||||
Write-Host -ForegroundColor White "$passiveIp"
|
||||
Write-Host -NoNewline -ForegroundColor Green " WitnessIP: "
|
||||
Write-Host -ForegroundColor White "$witnessIp`n"
|
||||
;break
|
||||
}
|
||||
invalid { Write-Host -ForegroundColor Red "VCHA State is in invalid state ...";break}
|
||||
notConfigured { Write-Host "VCHA is not configured";break}
|
||||
prepared { Write-Host "VCHA is being prepared, please try again in a little bit ...";break}
|
||||
}
|
||||
}
|
||||
|
||||
Function Get-VCHAClusterHealth {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: Nov 20, 2016
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves the VCHA Cluster Health which provides more info
|
||||
on each of the individual. This is only available on VCSA 6.5 (vSphere 6.5 or greater)
|
||||
.DESCRIPTION
|
||||
Function to return VCHA Cluster Health
|
||||
.EXAMPLE
|
||||
Get-VCHAClusterHealth
|
||||
#>
|
||||
$vcHAClusterConfig = Get-View failoverClusterConfigurator
|
||||
$vcHAConfig = $vcHAClusterConfig.getVchaConfig()
|
||||
$vcHAState = $vcHAConfig.State
|
||||
|
||||
switch($vcHAState) {
|
||||
invalid { Write-Host -ForegroundColor Red "VCHA State is in invalid state ...";break}
|
||||
notConfigured { Write-Host "VCHA is not configured";break}
|
||||
prepared { Write-Host "VCHA is being prepared ...";break}
|
||||
configured {
|
||||
$vcHAClusterManager = Get-View failoverClusterManager
|
||||
$healthInfo = $vcHAClusterManager.GetVchaClusterHealth()
|
||||
|
||||
$vcClusterState = $healthInfo.RuntimeInfo.ClusterState
|
||||
$nodeState = $healthInfo.RuntimeInfo.NodeInfo
|
||||
|
||||
Write-Host ""
|
||||
Write-Host -NoNewline -ForegroundColor Green "VCHA Cluster State: "
|
||||
Write-Host -ForegroundColor White "$vcClusterState"
|
||||
Write-Host -NoNewline -ForegroundColor Green "VCHA Node Information: "
|
||||
$nodeState | Select NodeIp, NodeRole, NodeState
|
||||
;break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Function Set-VCHAClusterMode {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: Nov 20, 2016
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function allows you to set the mode of the VCHA Cluster whether
|
||||
that is Enabled, Disabled or in Maintenance Mode. This is only available on VCSA 6.5 (vSphere 6.5 or greater)
|
||||
.DESCRIPTION
|
||||
Function to set VCHA Cluster Mode
|
||||
.EXAMPLE
|
||||
Set-VCHAClusterMode -Enabled $true
|
||||
.EXAMPLE
|
||||
Set-VCHAClusterMode -Disabled $true
|
||||
.EXAMPLE
|
||||
Set-VCHAClusterMode -Maintenance $true
|
||||
#>
|
||||
param(
|
||||
[Switch]$Enabled,
|
||||
[Switch]$Disabled,
|
||||
[Switch]$Maintenance
|
||||
)
|
||||
|
||||
$vcHAClusterManager = Get-View failoverClusterManager
|
||||
|
||||
if($Enabled) {
|
||||
Write-Host "Setting VCHA Cluster to Enabled ..."
|
||||
$task = $vcHAClusterManager.setClusterMode_Task("enabled")
|
||||
$task1 = Get-Task -Id ("Task-$($task.value)")
|
||||
$task1 | Wait-Task
|
||||
} elseIf($Maintenance) {
|
||||
Write-Host "Setting VCHA Cluster to Maintenance ..."
|
||||
$task = $vcHAClusterManager.setClusterMode_Task("maintenance")
|
||||
$task1 = Get-Task -Id ("Task-$($task.value)")
|
||||
$task1 | Wait-Task
|
||||
} elseIf($Disabled) {
|
||||
Write-Host "`nSetting VCHA Cluster to Disabled ...`n"
|
||||
$task = $vcHAClusterManager.setClusterMode_Task("disabled")
|
||||
$task1 = Get-Task -Id ("Task-$($task.value)")
|
||||
$task1 | Wait-Task
|
||||
}
|
||||
}
|
||||
|
||||
Function New-VCHABasicConfig {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: Nov 20, 2016
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function allows you create a new "Basic" VCHA Cluster, it does not
|
||||
cover the "Advanced" use case. You will need to ensure that you have a
|
||||
"Self Managed" vCenter Server before attempting this workflow.
|
||||
This is only available on VCSA 6.5 (vSphere 6.5 or greater)
|
||||
.DESCRIPTION
|
||||
Function to create "Basic" VCHA Cluster
|
||||
.PARAMETER VCSAVM
|
||||
The name of the vCenter Server Appliance (VCSA) in which you wish to enable VCHA on (must be self-managed)
|
||||
.PARAMETER HANetwork
|
||||
The name of the Virtual Portgroup or Distributed Portgroup used for the HA Network
|
||||
.PARAMETER ActiveHAIp
|
||||
The IP Address for the Active VCSA node
|
||||
.PARAMETER ActiveNetmask
|
||||
The Netmask for the Active VCSA node
|
||||
.PARAMETER PassiveHAIp
|
||||
The IP Address for the Passive VCSA node
|
||||
.PARAMETER PassiveNetmask
|
||||
The Netmask for the Passive VCSA node
|
||||
.PARAMETER WitnessHAIp
|
||||
The IP Address for the Witness VCSA node
|
||||
.PARAMETER WitnessNetmask
|
||||
The Netmask for the Witness VCSA node
|
||||
.PARAMETER PassiveDatastore
|
||||
The name of the datastore to deploy the Passive node to
|
||||
.PARAMETER WitnessDatastore
|
||||
The name of the datastore to deploy the Witness node to
|
||||
.PARAMETER VCUsername
|
||||
The VCSA username (e.g. administrator@vghetto.local)
|
||||
.PARAMETER VCPassword
|
||||
The VCSA password
|
||||
.EXAMPLE
|
||||
New-VCHABasicConfig -VCSAVM "vcenter65-1" -HANetwork "DVPG-VCHA-Network" `
|
||||
-ActiveHAIp 192.168.1.70 `
|
||||
-ActiveNetmask 255.255.255.0 `
|
||||
-PassiveHAIp 192.168.1.71 `
|
||||
-PassiveNetmask 255.255.255.0 `
|
||||
-WitnessHAIp 192.168.1.72 `
|
||||
-WitnessNetmask 255.255.255.0 `
|
||||
-PassiveDatastore "vsanDatastore" `
|
||||
-WitnessDatastore "vsanDatastore" `
|
||||
-VCUsername "administrator@vghetto.local" `
|
||||
-VCPassword "VMware1!"
|
||||
#>
|
||||
param(
|
||||
[Parameter(
|
||||
Mandatory=$true,
|
||||
ValueFromPipeline=$true,
|
||||
ValueFromPipelineByPropertyName=$true)
|
||||
]
|
||||
[String]$VCSAVM,
|
||||
[String]$HANetwork,
|
||||
[String]$ActiveHAIp,
|
||||
[String]$ActiveNetmask,
|
||||
[String]$PassiveHAIp,
|
||||
[String]$PassiveNetmask,
|
||||
[String]$PassiveDatastore,
|
||||
[String]$WitnessHAIp,
|
||||
[String]$WitnessNetmask,
|
||||
[String]$WitnessDatastore,
|
||||
# Crappy Implementation but need to research more into using PSH Credential
|
||||
[String]$VCUsername,
|
||||
[String]$VCPassword
|
||||
)
|
||||
|
||||
$VCSAVMView = Get-View -ViewType VirtualMachine -Filter @{"name"=$VCSAVM}
|
||||
if($VCSAVMView -eq $null) {
|
||||
Write-Host -ForegroundColor Red "Error: Unable to find Virtual Machine $VCSAVM"
|
||||
return
|
||||
}
|
||||
|
||||
$HANetworkView = Get-View -ViewType Network -Filter @{"name"=$HANetwork}
|
||||
if($HANetworkView -eq $null) {
|
||||
Write-Host -ForegroundColor Red "Error: Unable to find Network $HANetwork"
|
||||
return
|
||||
}
|
||||
|
||||
$PassiveDatastoreView = Get-View -ViewType Datastore -Filter @{"name"=$PassiveDatastore}
|
||||
if($PassiveDatastoreView -eq $null) {
|
||||
Write-Host -ForegroundColor Red "Error: Unable to find Passive Datastore $PassiveDatastore"
|
||||
return
|
||||
}
|
||||
|
||||
$WitnessDatastoreView = Get-View -ViewType Datastore -Filter @{"name"=$WitnessDatastore}
|
||||
if($WitnessDatastoreView -eq $null) {
|
||||
Write-Host -ForegroundColor Red "Error: Unable to find Witness Datastore $WitnessDatastore"
|
||||
return
|
||||
}
|
||||
|
||||
$vcIP = $VCSAVMView.Guest.IpAddress
|
||||
if($vcIP -eq $null) {
|
||||
Write-Host -ForegroundColor Red "Error: Unable to automatically retrieve the IP Address of $VCSAVM which is needed to use this function"
|
||||
return
|
||||
}
|
||||
|
||||
# Retrieve Source VC SSL Thumbprint
|
||||
$vcurl = "https://$vcIP"
|
||||
add-type @"
|
||||
using System.Net;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
public class IDontCarePolicy : ICertificatePolicy {
|
||||
public IDontCarePolicy() {}
|
||||
public bool CheckValidationResult(
|
||||
ServicePoint sPoint, X509Certificate cert,
|
||||
WebRequest wRequest, int certProb) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
"@
|
||||
[System.Net.ServicePointManager]::CertificatePolicy = new-object IDontCarePolicy
|
||||
# Need to do simple GET connection for this method to work
|
||||
Invoke-RestMethod -Uri $VCURL -Method Get | Out-Null
|
||||
|
||||
$endpoint_request = [System.Net.Webrequest]::Create("$vcurl")
|
||||
# Get Thumbprint + add colons for a valid Thumbprint
|
||||
$vcSSLThumbprint = ($endpoint_request.ServicePoint.Certificate.GetCertHashString()) -replace '(..(?!$))','$1:'
|
||||
|
||||
$vcHAClusterConfig = Get-View failoverClusterConfigurator
|
||||
$spec = New-Object VMware.Vim.VchaClusterDeploymentSpec
|
||||
|
||||
$activeNetworkConfig = New-Object VMware.Vim.ClusterNetworkConfigSpec
|
||||
$activeNetworkConfig.NetworkPortGroup = $HANetworkView.MoRef
|
||||
$ipSettings = New-Object Vmware.Vim.CustomizationIPSettings
|
||||
$ipSettings.SubnetMask = $ActiveNetmask
|
||||
$activeIpSpec = New-Object VMware.Vim.CustomizationFixedIp
|
||||
$activeIpSpec.IpAddress = $ActiveHAIp
|
||||
$ipSettings.Ip = $activeIpSpec
|
||||
$activeNetworkConfig.IpSettings = $ipSettings
|
||||
$spec.ActiveVcNetworkConfig = $activeNetworkConfig
|
||||
|
||||
$activeVCConfig = New-Object Vmware.Vim.SourceNodeSpec
|
||||
$activeVCConfig.ActiveVc = $VCSAVMView.MoRef
|
||||
$serviceLocator = New-Object Vmware.Vim.ServiceLocator
|
||||
$credential = New-Object VMware.Vim.ServiceLocatorNamePassword
|
||||
$credential.username = $VCUsername
|
||||
$credential.password = $VCPassword
|
||||
$serviceLocator.Credential = $credential
|
||||
$serviceLocator.InstanceUuid = $global:DefaultVIServer.InstanceUuid
|
||||
$serviceLocator.Url = $vcurl
|
||||
$serviceLocator.SslThumbprint = $vcSSLThumbprint
|
||||
$activeVCConfig.ManagementVc = $serviceLocator
|
||||
$spec.ActiveVcSpec = $activeVCConfig
|
||||
|
||||
$passiveSpec = New-Object VMware.Vim.PassiveNodeDeploymentSpec
|
||||
$passiveSpec.Folder = (Get-View (Get-Folder vm)).MoRef
|
||||
$passiveIpSettings = New-object Vmware.Vim.CustomizationIPSettings
|
||||
$passiveIpSettings.SubnetMask = $passiveNetmask
|
||||
$passiveIpSpec = New-Object VMware.Vim.CustomizationFixedIp
|
||||
$passiveIpSpec.IpAddress = $passiveHAIp
|
||||
$passiveIpSettings.Ip = $passiveIpSpec
|
||||
$passiveSpec.IpSettings = $passiveIpSettings
|
||||
$passiveSpec.NodeName = $VCSAVMView.Name + "-Passive"
|
||||
$passiveSpec.datastore = $PassiveDatastoreView.MoRef
|
||||
$spec.PassiveDeploymentSpec = $passiveSpec
|
||||
|
||||
$witnessSpec = New-Object VMware.Vim.NodeDeploymentSpec
|
||||
$witnessSpec.Folder = (Get-View (Get-Folder vm)).MoRef
|
||||
$witnessSpec.NodeName = $VCSAVMView.Name + "-Witness"
|
||||
$witnessIpSettings = New-object Vmware.Vim.CustomizationIPSettings
|
||||
$witnessIpSettings.SubnetMask = $witnessNetmask
|
||||
$witnessIpSpec = New-Object VMware.Vim.CustomizationFixedIp
|
||||
$witnessIpSpec.IpAddress = $witnessHAIp
|
||||
$witnessIpSettings.Ip = $witnessIpSpec
|
||||
$witnessSpec.IpSettings = $witnessIpSettings
|
||||
$witnessSpec.datastore = $WitnessDatastoreView.MoRef
|
||||
$spec.WitnessDeploymentSpec = $witnessSpec
|
||||
|
||||
Write-Host "`nDeploying VCHA Cluster ...`n"
|
||||
$task = $vcHAClusterConfig.deployVcha_Task($spec)
|
||||
$task1 = Get-Task -Id ("Task-$($task.value)")
|
||||
$task1 | Wait-Task -Verbose
|
||||
}
|
||||
|
||||
Function Remove-VCHAConfig {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: Nov 20, 2016
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function allows you destroy a VCHA Cluster. In addition, you have
|
||||
the option to specify whether you would like both the Passive & Witness
|
||||
Virtual Machines be deleted after the VCHA Cluster has been destroyed.
|
||||
This is only available on VCSA 6.5 (vSphere 6.5 or greater)
|
||||
.DESCRIPTION
|
||||
Function to destroy a VCHA Cluster Mode
|
||||
.EXAMPLE
|
||||
Remove-VCHAConfig
|
||||
.EXAMPLE
|
||||
Remove-VCHAConfig -Confirm:$false
|
||||
.EXAMPLE
|
||||
Remove-VCHAConfig -DeleteVM $true -Confirm:$false
|
||||
.NOTES
|
||||
Before you can destroy a VCHA Cluster, you must make sure it is first
|
||||
disabled. Run the Set-VCHAClusterMode -Disabled $true to do so
|
||||
#>
|
||||
param(
|
||||
[Boolean]$Confirm=$true,
|
||||
[Switch]$DeleteVM=$false
|
||||
)
|
||||
|
||||
$Verified = $false
|
||||
if($Confirm -eq $true) {
|
||||
Write-Host -ForegroundColor Yellow "`nDo you want to destroy VCHA Cluster?"
|
||||
$answer = Read-Host -Prompt "Do you accept (Y or N)"
|
||||
if($answer -eq "Y" -or $answer -eq "y") {
|
||||
$Verified = $true
|
||||
}
|
||||
} else {
|
||||
$Verified = $true
|
||||
}
|
||||
|
||||
if($Verified) {
|
||||
$vcHAClusterManager = Get-View failoverClusterManager
|
||||
$vcHAMode = $vcHAClusterManager.getClusterMode()
|
||||
|
||||
if($vcHAMode -ne "disabled") {
|
||||
Write-Host -ForegroundColor Yellow "To destroy VCHA Cluster, you must first set the VCHA Cluster Mode to `"Disabled`""
|
||||
Exit
|
||||
}
|
||||
|
||||
# Query BIOS UUID of the Passive/Witness to be able to delete
|
||||
if($DeleteVM) {
|
||||
$vcHAClusterConfig = Get-View failoverClusterConfigurator
|
||||
$vcHAConfig = $vcHAClusterConfig.getVchaConfig()
|
||||
$passiveBiosUUID = $vcHAConfig.FailoverNodeInfo2.biosUuid
|
||||
$witnessBiosUUID = $vcHAConfig.WitnessNodeInfo.biosUuid
|
||||
}
|
||||
|
||||
$vcHAClusterConfig = Get-View failoverClusterConfigurator
|
||||
|
||||
Write-Host "Destroying VCHA Cluster ..."
|
||||
$task = $vcHAClusterConfig.destroyVcha_Task()
|
||||
$task1 = Get-Task -Id ("Task-$($task.value)")
|
||||
$task1 | Wait-Task
|
||||
|
||||
# After VCHA Cluster has been destroyed, we can now delete the VMs we had queried earlier
|
||||
if($DeleteVM) {
|
||||
if($passiveBiosUUID -ne $null -and $witnessBiosUUID -ne $null) {
|
||||
$searchIndex = Get-View searchIndex
|
||||
|
||||
$passiveVM = $searchIndex.FindByUuid($null,$passiveBiosUUID,$true,$null)
|
||||
$witnessVM = $searchIndex.FindByUuid($null,$witnessBiosUUID,$true,$null)
|
||||
|
||||
if($passiveVM -ne $null -and $witnessVM -ne $null) {
|
||||
Write-Host "Powering off & deleting Passive VM ..."
|
||||
Stop-VM -VM (Get-View $passiveVM).Name -Confirm:$false | Out-Null
|
||||
Remove-VM (Get-View $passiveVM).Name -DeletePermanently -Confirm:$false
|
||||
Write-Host "Powering off & deleting Witness VM ..."
|
||||
Stop-VM -VM (Get-View $witnessVM).Name -Confirm:$false | Out-Null
|
||||
Remove-VM (Get-View $witnessVM).Name -DeletePermanently -Confirm:$false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
{
|
||||
"Type": "AUTOMATED",
|
||||
"Data": {
|
||||
"Name": "ICFarmJson",
|
||||
"DisplayName": "FarmJsonTest",
|
||||
"AccessGroup": "Root",
|
||||
"Description": "created IC Farm from PS via JSON",
|
||||
"Enabled": null,
|
||||
"Deleting": false,
|
||||
"Settings": {
|
||||
"DisconnectedSessionTimeoutPolicy" : "NEVER",
|
||||
"DisconnectedSessionTimeoutMinutes" : 1,
|
||||
"EmptySessionTimeoutPolicy" : "AFTER",
|
||||
"EmptySessionTimeoutMinutes" : 1,
|
||||
"LogoffAfterTimeout" : false
|
||||
},
|
||||
"Desktop": null,
|
||||
"DisplayProtocolSettings": {
|
||||
"DefaultDisplayProtocol" : "PCOIP",
|
||||
"AllowDisplayProtocolOverride" : false,
|
||||
"EnableHTMLAccess" : false
|
||||
},
|
||||
"ServerErrorThreshold": null,
|
||||
"MirageConfigurationOverrides": {
|
||||
"OverrideGlobalSetting" : false,
|
||||
"Enabled" : false,
|
||||
"Url" : null
|
||||
}
|
||||
},
|
||||
"AutomatedFarmSpec": {
|
||||
"ProvisioningType": "INSTANT_CLONE_ENGINE",
|
||||
"VirtualCenter": null,
|
||||
"RdsServerNamingSpec": {
|
||||
"NamingMethod": "PATTERN",
|
||||
"PatternNamingSettings": {
|
||||
"NamingPattern": "ICFarmVMPS",
|
||||
"MaxNumberOfRDSServers": 1
|
||||
}
|
||||
},
|
||||
"VirtualCenterProvisioningSettings": {
|
||||
"EnableProvisioning": true,
|
||||
"StopProvisioningOnError": true,
|
||||
"MinReadyVMsOnVComposerMaintenance": 0,
|
||||
"VirtualCenterProvisioningData": {
|
||||
"ParentVm": "vm-rdsh-ic",
|
||||
"Snapshot": "snap_5",
|
||||
"Datacenter": null,
|
||||
"VmFolder": "Instant_Clone_VMs",
|
||||
"HostOrCluster": "vimal-cluster",
|
||||
"ResourcePool": "vimal-cluster"
|
||||
},
|
||||
"VirtualCenterStorageSettings": {
|
||||
"Datastores": [
|
||||
{
|
||||
"Datastore": "Datastore1",
|
||||
"StorageOvercommit": "UNBOUNDED"
|
||||
}
|
||||
],
|
||||
"UseVSan": false,
|
||||
"ViewComposerStorageSettings": {
|
||||
"UseSeparateDatastoresReplicaAndOSDisks": false,
|
||||
"ReplicaDiskDatastore": null,
|
||||
"UseNativeSnapshots": false,
|
||||
"SpaceReclamationSettings": {
|
||||
"ReclaimVmDiskSpace": false,
|
||||
"ReclamationThresholdGB": null,
|
||||
"BlackoutTimes": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"VirtualCenterNetworkingSettings": {
|
||||
"Nics": null
|
||||
}
|
||||
},
|
||||
"VirtualCenterManagedCommonSettings": {
|
||||
"TransparentPageSharingScope": "VM"
|
||||
},
|
||||
"CustomizationSettings": {
|
||||
"CustomizationType": "CLONE_PREP",
|
||||
"DomainAdministrator": null,
|
||||
"AdContainer": "CN=Computers",
|
||||
"ReusePreExistingAccounts": false,
|
||||
"ClonePrepCustomizationSettings": {
|
||||
"InstantCloneEngineDomainAdministrator": null,
|
||||
"PowerOffScriptName": null,
|
||||
"PowerOffScriptParameters": null,
|
||||
"PostSynchronizationScriptName": null,
|
||||
"PostSynchronizationScriptParameters": null
|
||||
}
|
||||
},
|
||||
"RdsServerMaxSessionsData": {
|
||||
"MaxSessionsType": "UNLIMITED",
|
||||
"MaxSessions": null
|
||||
}
|
||||
},
|
||||
"ManualFarmSpec": null,
|
||||
"NetBiosName" : "ad-vimalg"
|
||||
}
|
||||
@@ -1,17 +1,31 @@
|
||||
{
|
||||
"Type": "AUTOMATED",
|
||||
"Data": {
|
||||
"Name": "LCFarmTest",
|
||||
"DisplayName": "Ankit LC Farm Test",
|
||||
"Name": "LCFarmJson",
|
||||
"DisplayName": "FarmJsonTest",
|
||||
"AccessGroup": "Root",
|
||||
"Description": "created LC Farm from PS",
|
||||
"Description": "created LC Farm from PS via JSON",
|
||||
"Enabled": null,
|
||||
"Deleting": false,
|
||||
"Settings": null,
|
||||
"Settings": {
|
||||
"DisconnectedSessionTimeoutPolicy" : "NEVER",
|
||||
"DisconnectedSessionTimeoutMinutes" : 1,
|
||||
"EmptySessionTimeoutPolicy" : "AFTER",
|
||||
"EmptySessionTimeoutMinutes" : 1,
|
||||
"LogoffAfterTimeout" : false
|
||||
},
|
||||
"Desktop": null,
|
||||
"DisplayProtocolSettings": null,
|
||||
"DisplayProtocolSettings": {
|
||||
"DefaultDisplayProtocol" : "PCOIP",
|
||||
"AllowDisplayProtocolOverride" : false,
|
||||
"EnableHTMLAccess" : false
|
||||
},
|
||||
"ServerErrorThreshold": null,
|
||||
"MirageConfigurationOverrides": null
|
||||
"MirageConfigurationOverrides": {
|
||||
"OverrideGlobalSetting" : false,
|
||||
"Enabled" : false,
|
||||
"Url" : null
|
||||
}
|
||||
},
|
||||
"AutomatedFarmSpec": {
|
||||
"ProvisioningType": "VIEW_COMPOSER",
|
||||
@@ -19,7 +33,7 @@
|
||||
"RdsServerNamingSpec": {
|
||||
"NamingMethod": "PATTERN",
|
||||
"PatternNamingSettings": {
|
||||
"NamingPattern": "LCFarmVM_PS",
|
||||
"NamingPattern": "LCFarmVMPS",
|
||||
"MaxNumberOfRDSServers": 1
|
||||
}
|
||||
},
|
||||
@@ -28,17 +42,17 @@
|
||||
"StopProvisioningOnError": true,
|
||||
"MinReadyVMsOnVComposerMaintenance": 0,
|
||||
"VirtualCenterProvisioningData": {
|
||||
"ParentVm": "Win_Server_2012_R2",
|
||||
"Snapshot": "Snap_RDS",
|
||||
"ParentVm": "RDSServer",
|
||||
"Snapshot": "RDS_SNAP1",
|
||||
"Datacenter": null,
|
||||
"VmFolder": "AnkitPoolVM",
|
||||
"HostOrCluster": "cls",
|
||||
"ResourcePool": "cls"
|
||||
"VmFolder": "Praveen",
|
||||
"HostOrCluster": "CS-1",
|
||||
"ResourcePool": "CS-1"
|
||||
},
|
||||
"VirtualCenterStorageSettings": {
|
||||
"Datastores": [
|
||||
{
|
||||
"Datastore": "datastore1 (5)",
|
||||
"Datastore": "Datastore1",
|
||||
"StorageOvercommit": "UNBOUNDED"
|
||||
}
|
||||
],
|
||||
@@ -67,7 +81,7 @@
|
||||
"AdContainer": "CN=Computers",
|
||||
"ReusePreExistingAccounts": false,
|
||||
"SysprepCustomizationSettings": {
|
||||
"CustomizationSpec": "RDSH_Cust2"
|
||||
"CustomizationSpec": "PraveenCust"
|
||||
}
|
||||
},
|
||||
"RdsServerMaxSessionsData": {
|
||||
@@ -76,5 +90,5 @@
|
||||
}
|
||||
},
|
||||
"ManualFarmSpec": null,
|
||||
"NetBiosName" : "adankit"
|
||||
"NetBiosName" : "adviewdev"
|
||||
}
|
||||
@@ -7,17 +7,31 @@
|
||||
"Description": "Manual PS Test",
|
||||
"Enabled": null,
|
||||
"Deleting": false,
|
||||
"Settings": null,
|
||||
"Settings": {
|
||||
"DisconnectedSessionTimeoutPolicy" : "NEVER",
|
||||
"DisconnectedSessionTimeoutMinutes" : 1,
|
||||
"EmptySessionTimeoutPolicy" : "AFTER",
|
||||
"EmptySessionTimeoutMinutes" : 1,
|
||||
"LogoffAfterTimeout" : false
|
||||
},
|
||||
"Desktop": null,
|
||||
"DisplayProtocolSettings": null,
|
||||
"DisplayProtocolSettings": {
|
||||
"DefaultDisplayProtocol" : "PCOIP",
|
||||
"AllowDisplayProtocolOverride" : false,
|
||||
"EnableHTMLAccess" : false
|
||||
},
|
||||
"ServerErrorThreshold": null,
|
||||
"MirageConfigurationOverrides": null
|
||||
"MirageConfigurationOverrides": {
|
||||
"OverrideGlobalSetting" : false,
|
||||
"Enabled" : false,
|
||||
"Url" : null
|
||||
}
|
||||
},
|
||||
"AutomatedFarmSpec": null,
|
||||
"ManualFarmSpec": {
|
||||
"RdsServers": [
|
||||
{
|
||||
"rdsServer": "WIN-ORKA1Q8B0P7"
|
||||
"rdsServer": "RDSServer.adviewdev.eng.vmware.com"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -5,7 +5,44 @@
|
||||
"AccessGroup": "Root",
|
||||
"Description": "create full clone via JSON"
|
||||
},
|
||||
"DesktopSettings": null,
|
||||
"DesktopSettings": {
|
||||
"enabled": true,
|
||||
"deleting": false,
|
||||
"connectionServerRestrictions": null,
|
||||
"logoffSettings": {
|
||||
"powerPolicy": "TAKE_NO_POWER_ACTION",
|
||||
"automaticLogoffPolicy": "NEVER",
|
||||
"automaticLogoffMinutes": 120,
|
||||
"allowUsersToResetMachines": false,
|
||||
"allowMultipleSessionsPerUser": false,
|
||||
"deleteOrRefreshMachineAfterLogoff": "NEVER",
|
||||
"refreshOsDiskAfterLogoff": "NEVER",
|
||||
"refreshPeriodDaysForReplicaOsDisk": 5,
|
||||
"refreshThresholdPercentageForReplicaOsDisk": 10
|
||||
},
|
||||
"displayProtocolSettings": {
|
||||
"supportedDisplayProtocols": ["PCOIP", "BLAST" ],
|
||||
"defaultDisplayProtocol": "BLAST",
|
||||
"allowUsersToChooseProtocol": true,
|
||||
"pcoipDisplaySettings": {
|
||||
"renderer3D": "DISABLED",
|
||||
"enableGRIDvGPUs": false,
|
||||
"vRamSizeMB": 96,
|
||||
"maxNumberOfMonitors": 3,
|
||||
"maxResolutionOfAnyOneMonitor": "WSXGA_PLUS"
|
||||
},
|
||||
"enableHTMLAccess": true
|
||||
},
|
||||
"flashSettings": {
|
||||
"quality": "NO_CONTROL",
|
||||
"throttling": "DISABLED"
|
||||
},
|
||||
"mirageConfigurationOverrides": {
|
||||
"overrideGlobalSetting": false,
|
||||
"enabled": false,
|
||||
"url": false
|
||||
}
|
||||
},
|
||||
"Type": "AUTOMATED",
|
||||
"AutomatedDesktopSpec": {
|
||||
"ProvisioningType": "VIRTUAL_CENTER",
|
||||
@@ -69,7 +106,7 @@
|
||||
"NoCustomizationSettings": {
|
||||
"DoNotPowerOnVMsAfterCreation": false
|
||||
},
|
||||
"SysprepCustomizationSettings": null,
|
||||
"SysprepCustomizationSettings": {"customizationSpec" : "praveencust"},
|
||||
"QuickprepCustomizationSettings": null,
|
||||
"CloneprepCustomizationSettings": null
|
||||
}
|
||||
@@ -77,6 +114,5 @@
|
||||
"ManualDesktopSpec": null,
|
||||
"RdsDesktopSpec": null,
|
||||
"GlobalEntitlementData": null,
|
||||
"NetBiosName" : "adviewdev",
|
||||
"SysPrepName" : "praveencust"
|
||||
"NetBiosName" : "adviewdev"
|
||||
}
|
||||
@@ -5,7 +5,44 @@
|
||||
"AccessGroup": "ROOT",
|
||||
"Description": "create instant pool"
|
||||
},
|
||||
"DesktopSettings": null,
|
||||
"DesktopSettings": {
|
||||
"enabled": true,
|
||||
"deleting": false,
|
||||
"connectionServerRestrictions": null,
|
||||
"logoffSettings": {
|
||||
"powerPolicy": "ALWAYS_POWERED_ON",
|
||||
"automaticLogoffPolicy": "NEVER",
|
||||
"automaticLogoffMinutes": 120,
|
||||
"allowUsersToResetMachines": false,
|
||||
"allowMultipleSessionsPerUser": false,
|
||||
"deleteOrRefreshMachineAfterLogoff": "DELETE",
|
||||
"refreshOsDiskAfterLogoff": "NEVER",
|
||||
"refreshPeriodDaysForReplicaOsDisk": 5,
|
||||
"refreshThresholdPercentageForReplicaOsDisk": 10
|
||||
},
|
||||
"displayProtocolSettings": {
|
||||
"supportedDisplayProtocols": ["PCOIP", "BLAST" ],
|
||||
"defaultDisplayProtocol": "BLAST",
|
||||
"allowUsersToChooseProtocol": true,
|
||||
"pcoipDisplaySettings": {
|
||||
"renderer3D": "DISABLED",
|
||||
"enableGRIDvGPUs": false,
|
||||
"vRamSizeMB": 96,
|
||||
"maxNumberOfMonitors": 3,
|
||||
"maxResolutionOfAnyOneMonitor": "WSXGA_PLUS"
|
||||
},
|
||||
"enableHTMLAccess": true
|
||||
},
|
||||
"flashSettings": {
|
||||
"quality": "NO_CONTROL",
|
||||
"throttling": "DISABLED"
|
||||
},
|
||||
"mirageConfigurationOverrides": {
|
||||
"overrideGlobalSetting": false,
|
||||
"enabled": false,
|
||||
"url": false
|
||||
}
|
||||
},
|
||||
"Type": "AUTOMATED",
|
||||
"AutomatedDesktopSpec": {
|
||||
"ProvisioningType": "INSTANT_CLONE_ENGINE",
|
||||
@@ -5,7 +5,44 @@
|
||||
"AccessGroup": "Root",
|
||||
"Description": "created linkedclone pool from ps"
|
||||
},
|
||||
"DesktopSettings": null,
|
||||
"DesktopSettings": {
|
||||
"enabled": true,
|
||||
"deleting": false,
|
||||
"connectionServerRestrictions": null,
|
||||
"logoffSettings": {
|
||||
"powerPolicy": "TAKE_NO_POWER_ACTION",
|
||||
"automaticLogoffPolicy": "NEVER",
|
||||
"automaticLogoffMinutes": 120,
|
||||
"allowUsersToResetMachines": false,
|
||||
"allowMultipleSessionsPerUser": false,
|
||||
"deleteOrRefreshMachineAfterLogoff": "NEVER",
|
||||
"refreshOsDiskAfterLogoff": "NEVER",
|
||||
"refreshPeriodDaysForReplicaOsDisk": 5,
|
||||
"refreshThresholdPercentageForReplicaOsDisk": 10
|
||||
},
|
||||
"displayProtocolSettings": {
|
||||
"supportedDisplayProtocols": ["RDP","PCOIP", "BLAST" ],
|
||||
"defaultDisplayProtocol": "PCOIP",
|
||||
"allowUsersToChooseProtocol": true,
|
||||
"pcoipDisplaySettings": {
|
||||
"renderer3D": "DISABLED",
|
||||
"enableGRIDvGPUs": false,
|
||||
"vRamSizeMB": 96,
|
||||
"maxNumberOfMonitors": 3,
|
||||
"maxResolutionOfAnyOneMonitor": "WSXGA_PLUS"
|
||||
},
|
||||
"enableHTMLAccess": true
|
||||
},
|
||||
"flashSettings": {
|
||||
"quality": "NO_CONTROL",
|
||||
"throttling": "DISABLED"
|
||||
},
|
||||
"mirageConfigurationOverrides": {
|
||||
"overrideGlobalSetting": false,
|
||||
"enabled": false,
|
||||
"url": null
|
||||
}
|
||||
},
|
||||
"Type": "AUTOMATED",
|
||||
"AutomatedDesktopSpec": {
|
||||
"ProvisioningType": "VIEW_COMPOSER",
|
||||
@@ -33,7 +70,7 @@
|
||||
"Template": null,
|
||||
"ParentVm": "Agent_pra",
|
||||
"Snapshot": "kb-hotfix",
|
||||
"Datacenter": null,
|
||||
"Datacenter": "Dev-Dc",
|
||||
"VmFolder": "Praveen",
|
||||
"HostOrCluster": "CS-1",
|
||||
"ResourcePool": "CS-1"
|
||||
@@ -52,7 +89,8 @@
|
||||
"UseNativeSnapshots": false,
|
||||
"SpaceReclamationSettings": {
|
||||
"ReclaimVmDiskSpace": false,
|
||||
"ReclamationThresholdGB": null
|
||||
"ReclamationThresholdGB": null,
|
||||
"BlackoutTimes" : null
|
||||
},
|
||||
"PersistentDiskSettings": {
|
||||
"RedirectWindowsProfile": false,
|
||||
@@ -75,19 +113,31 @@
|
||||
}
|
||||
},
|
||||
"VirtualCenterNetworkingSettings": {
|
||||
"Nics": null
|
||||
"Nics": [
|
||||
{
|
||||
"Nic": "nicName",
|
||||
"NetworkLabelAssignmentSpecs": [
|
||||
{
|
||||
"Enabled" : false,
|
||||
"networkLabel" : null,
|
||||
"maxLabelType" : null,
|
||||
"maxLabel" : null
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"VirtualCenterManagedCommonSettings": {
|
||||
"TransparentPageSharingScope": "VM"
|
||||
},
|
||||
"CustomizationSettings": {
|
||||
"CustomizationType": "QUICK_PREP",
|
||||
"DomainAdministrator": null,
|
||||
"CustomizationType": "SYS_PREP",
|
||||
"DomainAdministrator": "administrator",
|
||||
"AdContainer": "CN=Computers",
|
||||
"ReusePreExistingAccounts": false,
|
||||
"NoCustomizationSettings": null,
|
||||
"SysprepCustomizationSettings": null,
|
||||
"SysprepCustomizationSettings": {"customizationSpec" : "praveencust"},
|
||||
"QuickprepCustomizationSettings": {
|
||||
"PowerOffScriptName": null,
|
||||
"PowerOffScriptParameters": null,
|
||||
@@ -99,7 +149,6 @@
|
||||
},
|
||||
"ManualDesktopSpec": null,
|
||||
"RdsDesktopSpec": null,
|
||||
"GlobalEntitlementData": null,
|
||||
"NetBiosName" : "adviewdev",
|
||||
"SysPrepName" : "praveencust"
|
||||
"GlobalEntitlementData": null,
|
||||
"NetBiosName" : "adviewdev"
|
||||
}
|
||||
@@ -5,7 +5,44 @@
|
||||
"AccessGroup": "ROOT",
|
||||
"Description": "Manual pool creation"
|
||||
},
|
||||
"DesktopSettings": null,
|
||||
"DesktopSettings": {
|
||||
"enabled": true,
|
||||
"deleting": false,
|
||||
"connectionServerRestrictions": null,
|
||||
"logoffSettings": {
|
||||
"powerPolicy": "TAKE_NO_POWER_ACTION",
|
||||
"automaticLogoffPolicy": "NEVER",
|
||||
"automaticLogoffMinutes": 120,
|
||||
"allowUsersToResetMachines": false,
|
||||
"allowMultipleSessionsPerUser": false,
|
||||
"deleteOrRefreshMachineAfterLogoff": "NEVER",
|
||||
"refreshOsDiskAfterLogoff": "NEVER",
|
||||
"refreshPeriodDaysForReplicaOsDisk": 5,
|
||||
"refreshThresholdPercentageForReplicaOsDisk": 10
|
||||
},
|
||||
"displayProtocolSettings": {
|
||||
"supportedDisplayProtocols": ["PCOIP", "BLAST" ],
|
||||
"defaultDisplayProtocol": "BLAST",
|
||||
"allowUsersToChooseProtocol": true,
|
||||
"pcoipDisplaySettings": {
|
||||
"renderer3D": "DISABLED",
|
||||
"enableGRIDvGPUs": false,
|
||||
"vRamSizeMB": 96,
|
||||
"maxNumberOfMonitors": 3,
|
||||
"maxResolutionOfAnyOneMonitor": "WSXGA_PLUS"
|
||||
},
|
||||
"enableHTMLAccess": true
|
||||
},
|
||||
"flashSettings": {
|
||||
"quality": "NO_CONTROL",
|
||||
"throttling": "DISABLED"
|
||||
},
|
||||
"mirageConfigurationOverrides": {
|
||||
"overrideGlobalSetting": false,
|
||||
"enabled": false,
|
||||
"url": false
|
||||
}
|
||||
},
|
||||
"Type": "MANUAL",
|
||||
"AutomatedDesktopSpec": null,
|
||||
"ManualDesktopSpec": {
|
||||
@@ -16,7 +53,7 @@
|
||||
"Source": "VIRTUAL_CENTER",
|
||||
"Machines": [
|
||||
{
|
||||
"Machine" : "PowerCLI-VM"
|
||||
"Machine" : "Praveen_Agent"
|
||||
}
|
||||
],
|
||||
"VirtualCenter": null,
|
||||
@@ -32,4 +69,5 @@
|
||||
},
|
||||
"RdsDesktopSpec": null,
|
||||
"GlobalEntitlementData": null
|
||||
|
||||
}
|
||||
27
Modules/VMware.Hv.Helper/Json/Pool/RdsSpec.json
Normal file
27
Modules/VMware.Hv.Helper/Json/Pool/RdsSpec.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"Base": {
|
||||
"Name" : "RdsJson",
|
||||
"DisplayName": "TestRDSPS",
|
||||
"AccessGroup": "Root",
|
||||
"Description": "Testing PS"
|
||||
},
|
||||
"DesktopSettings": {
|
||||
"enabled": true,
|
||||
"deleting": false,
|
||||
"connectionServerRestrictions": null,
|
||||
"logoffSettings": null,
|
||||
"displayProtocolSettings": null,
|
||||
"flashSettings": {
|
||||
"quality": "NO_CONTROL",
|
||||
"throttling": "DISABLED"
|
||||
},
|
||||
"mirageConfigurationOverrides": null
|
||||
},
|
||||
"Type": "RDS",
|
||||
"AutomatedDesktopSpec": null,
|
||||
"ManualDesktopSpec": null,
|
||||
"RdsDesktopSpec": {
|
||||
"Farm": "test1"
|
||||
},
|
||||
"GlobalEntitlementData": null
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"Base": {
|
||||
"Name" : "RdsJson",
|
||||
"DisplayName": "TestRDSPS",
|
||||
"AccessGroup": "Root",
|
||||
"Description": "Testing PS"
|
||||
},
|
||||
"DesktopSettings": null,
|
||||
"Type": "RDS",
|
||||
"AutomatedDesktopSpec": null,
|
||||
"ManualDesktopSpec": null,
|
||||
"RdsDesktopSpec": {
|
||||
"Farm": "Farm2"
|
||||
},
|
||||
"GlobalEntitlementData": null
|
||||
}
|
||||
20
Modules/VMware.Hv.Helper/README.md
Normal file
20
Modules/VMware.Hv.Helper/README.md
Normal file
@@ -0,0 +1,20 @@
|
||||
Prerequisites/Steps to use this module:
|
||||
|
||||
1. This module only works for Horizon product E.g. Horizon 7.0.2 and later.
|
||||
2. Install the latest version of Powershell, PowerCLI(6.5) or (later version via psgallery).
|
||||
3. Import HorizonView module by running: Import-Module VMware.VimAutomation.HorizonView.
|
||||
4. Import "VMware.Hv.Helper" module by running: Import-Module -Name "location of this module" or Get-Module -ListAvailable 'VMware.Hv.Helper' | Import-Module.
|
||||
5. Get-Command -Module "This module Name" to list all available functions or Get-Command -Module 'VMware.Hv.Helper'.
|
||||
|
||||
# Example script to connect view API service of Connection Server:
|
||||
|
||||
Import-Module VMware.VimAutomation.HorizonView
|
||||
# Connection to view API service
|
||||
$hvServer = Connect-HVServer -server <connection server IP/FQDN>
|
||||
$hvServices = $hvserver.ExtensionData
|
||||
$csList = $hvServices.ConnectionServer.ConnectionServer_List()
|
||||
# Load this module
|
||||
Get-Module -ListAvailable 'VMware.Hv.Helper' | Import-Module
|
||||
Get-Command -Module 'VMware.Hv.Helper'
|
||||
# Use advanced functions of this module
|
||||
New-HVPool -spec 'path to InstantClone.json file'
|
||||
@@ -30,6 +30,10 @@
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader>
|
||||
<Width>8</Width>
|
||||
<Label>Entitled</Label>
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader>
|
||||
<Width>7</Width>
|
||||
<Label>Enabled</Label>
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader>
|
||||
@@ -56,10 +60,23 @@
|
||||
<TableColumnItem>
|
||||
<ScriptBlock>$_.desktopSummaryData.userAssignment</ScriptBlock>
|
||||
</TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<ScriptBlock>
|
||||
$filterContains = Get-HVQueryFilter localData.desktops -contains ([VMware.Hv.DesktopId[]]$_.id)
|
||||
$GlobalfilterContains = Get-HVQueryFilter localData.desktops -contains ([VMware.Hv.DesktopId[]]$_.id)
|
||||
Try {
|
||||
$results += Get-HVQueryResult -EntityType EntitledUserOrGroupLocalSummaryView -Filter $filterContains
|
||||
$results += Get-HVQueryResult -EntityType EntitledUserOrGroupGlobalSummaryView -Filter $GlobalfilterContains
|
||||
} Catch {
|
||||
#Do nothing
|
||||
}
|
||||
$results.length
|
||||
</ScriptBlock>
|
||||
</TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<ScriptBlock>$_.desktopSummaryData.enabled</ScriptBlock>
|
||||
</TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<ScriptBlock>$_.desktopSummaryData.numSessions</ScriptBlock>
|
||||
</TableColumnItem>
|
||||
</TableColumnItems>
|
||||
@@ -97,6 +114,20 @@
|
||||
<ScriptBlock>$_.desktopSummaryData.userAssignment</ScriptBlock>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Label>Entitled</Label>
|
||||
<ScriptBlock>
|
||||
$filterContains = Get-HVQueryFilter localData.desktops -contains ([VMware.Hv.DesktopId[]]$_.id)
|
||||
$GlobalfilterContains = Get-HVQueryFilter localData.desktops -contains ([VMware.Hv.DesktopId[]]$_.id)
|
||||
Try {
|
||||
$results += Get-HVQueryResult -EntityType EntitledUserOrGroupLocalSummaryView -Filter $filterContains
|
||||
$results += Get-HVQueryResult -EntityType EntitledUserOrGroupGlobalSummaryView -Filter $GlobalfilterContains
|
||||
} Catch {
|
||||
#Do nothing
|
||||
}
|
||||
$results.length
|
||||
</ScriptBlock>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Label>Enabled</Label>
|
||||
<ScriptBlock>$_.desktopSummaryData.enabled</ScriptBlock>
|
||||
</ListItem>
|
||||
@@ -117,27 +148,27 @@
|
||||
<TableControl>
|
||||
<TableHeaders>
|
||||
<TableColumnHeader>
|
||||
<Width>16</Width>
|
||||
<Width>15</Width>
|
||||
<Label>Machine</Label>
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader>
|
||||
<Width>16</Width>
|
||||
<Width>12</Width>
|
||||
<Label>DesktopPool</Label>
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader>
|
||||
<Width>16</Width>
|
||||
<Width>12</Width>
|
||||
<Label>DNS Name</Label>
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader>
|
||||
<Width>16</Width>
|
||||
<Width>8</Width>
|
||||
<Label>User</Label>
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader>
|
||||
<Width>16</Width>
|
||||
<Width>15</Width>
|
||||
<Label>Host</Label>
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader>
|
||||
<Width>8</Width>
|
||||
<Width>5</Width>
|
||||
<Label>Agent</Label>
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader>
|
||||
@@ -145,9 +176,8 @@
|
||||
<Label>Datastore</Label>
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader>
|
||||
<Width>10</Width>
|
||||
<Width>15</Width>
|
||||
<Label>Status</Label>
|
||||
<Alignment>Right</Alignment>
|
||||
</TableColumnHeader>
|
||||
</TableHeaders>
|
||||
<TableRowEntries>
|
||||
@@ -169,13 +199,13 @@
|
||||
<ScriptBlock>$_.ManagedMachineNamesData.HostName</ScriptBlock>
|
||||
</TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<ScriptBlock>$_.Data.AgentVersion</ScriptBlock>
|
||||
<ScriptBlock>$_.Base.AgentVersion</ScriptBlock>
|
||||
</TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<ScriptBlock>$_.ManagedMachineNamesData.DatastorePaths</ScriptBlock>
|
||||
</TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<ScriptBlock>$_.Data.BasicState</ScriptBlock>
|
||||
<ScriptBlock>$_.Base.BasicState</ScriptBlock>
|
||||
</TableColumnItem>
|
||||
</TableColumnItems>
|
||||
</TableRowEntry>
|
||||
@@ -212,12 +242,16 @@
|
||||
<ScriptBlock>$_.ManagedMachineNamesData.HostName</ScriptBlock>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Label>Enabled</Label>
|
||||
<Label>Agent</Label>
|
||||
<ScriptBlock>$_.Base.AgentVersion</ScriptBlock>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Label>Datastore</Label>
|
||||
<ScriptBlock>$_.ManagedMachineNamesData.DatastorePaths</ScriptBlock>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Label>Sessions</Label>
|
||||
<ScriptBlock>$_.Data.BasicState</ScriptBlock>
|
||||
<Label>Status</Label>
|
||||
<ScriptBlock>$_.Base.BasicState</ScriptBlock>
|
||||
</ListItem>
|
||||
</ListItems>
|
||||
</ListEntry>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
# RootModule = ''
|
||||
|
||||
# Version number of this module.
|
||||
ModuleVersion = '1.0'
|
||||
ModuleVersion = '1.1'
|
||||
|
||||
# ID used to uniquely identify this module
|
||||
GUID = '6d3f7fb5-4e52-43d8-91e1-f65f72532a1d'
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
7
Modules/VMware.VMEncryption/README.md
Normal file
7
Modules/VMware.VMEncryption/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
Prerequisites/Steps to use this module:
|
||||
|
||||
1. This module only works for vSphere products that support VM Encryption. E.g. vSphere 6.5 and later.
|
||||
2. All the functions in this module only work for KMIP Servers.
|
||||
3. Install the latest version of Powershell and PowerCLI(6.5).
|
||||
4. Import this module by running: Import-Module -Name "location of this module"
|
||||
5. Get-Command -Module "This module Name" to list all available functions.
|
||||
BIN
Modules/VMware.VMEncryption/VMware.VMEncryption.psd1
Normal file
BIN
Modules/VMware.VMEncryption/VMware.VMEncryption.psd1
Normal file
Binary file not shown.
2107
Modules/VMware.VMEncryption/VMware.VMEncryption.psm1
Normal file
2107
Modules/VMware.VMEncryption/VMware.VMEncryption.psm1
Normal file
File diff suppressed because it is too large
Load Diff
37
Pester/00 Test Connect-CISServer Connection to VC.Tests.ps1
Normal file
37
Pester/00 Test Connect-CISServer Connection to VC.Tests.ps1
Normal file
@@ -0,0 +1,37 @@
|
||||
<#
|
||||
Script name: Test Connect-CISServer to VC.Tests.ps1
|
||||
Created on: 04/20/2017
|
||||
Author: Alan Renouf, @alanrenouf
|
||||
Description: The purpose of this pester test is to ensure the PowerCLI modules are imported and a connection can be made to a vCenter for the CIS Service
|
||||
Dependencies: Pester Module
|
||||
Example run:
|
||||
|
||||
Invoke-Pester -Script @{ Path = '.\Test Connect-CISServer to VC.Tests.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 "Checking PowerCLI Cmdlets available" {
|
||||
$cmdletname = "Connect-CISServer"
|
||||
It "Checking $cmdletname is available" {
|
||||
$command = Get-Command $cmdletname
|
||||
$command | Select Name, Version
|
||||
$command.Name| Should Be $cmdletname
|
||||
}
|
||||
}
|
||||
|
||||
Describe "Connect-CISServer Tests" {
|
||||
|
||||
$connection = Connect-CISServer $VCName -User $VCUser -password $VCPass
|
||||
It "Connection is active" {
|
||||
$Global:DefaultCISServers[0].isconnected | Should Be $true
|
||||
}
|
||||
|
||||
It "Checking connected server name is $VCName" {
|
||||
$Global:DefaultCISServers[0] | Select *
|
||||
$Global:DefaultCISServers[0].name | Should Be $VCName
|
||||
}
|
||||
}
|
||||
36
Pester/00 Test Connect-VIServer Connection to VC.Tests.ps1
Normal file
36
Pester/00 Test Connect-VIServer Connection to VC.Tests.ps1
Normal file
@@ -0,0 +1,36 @@
|
||||
<#
|
||||
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 can be made to a vCenter
|
||||
Dependencies: Pester Module
|
||||
Example run:
|
||||
|
||||
Invoke-Pester -Script @{ Path = '.\Test Connection to VC.Tests.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 "Checking PowerCLI Cmdlets available" {
|
||||
$cmdletname = "Connect-VIServer"
|
||||
It "Checking $cmdletname is available" {
|
||||
$command = Get-Command $cmdletname
|
||||
$command | Select Name, Version
|
||||
$command.Name| Should Be $cmdletname
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
<#
|
||||
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
|
||||
}
|
||||
}
|
||||
49
Pester/Test Get-CISService.Tests.ps1
Normal file
49
Pester/Test Get-CISService.Tests.ps1
Normal file
@@ -0,0 +1,49 @@
|
||||
<#
|
||||
Script name: Test Connect-CISService.Tests.ps1
|
||||
Created on: 04/20/2017
|
||||
Author: Alan Renouf, @alanrenouf
|
||||
Description: The purpose of this pester test is to ensure the CIS Service cmdlet works correctly
|
||||
Dependencies: Pester Module
|
||||
Example run:
|
||||
|
||||
Invoke-Pester -Script @{ Path = '.\Test Get-CISService.ps1' }
|
||||
|
||||
#>
|
||||
|
||||
Describe "Checking PowerCLI Cmdlets available" {
|
||||
$cmdletname = "Get-CISService"
|
||||
It "Checking $cmdletname is available" {
|
||||
$command = Get-Command $cmdletname
|
||||
$command | Select Name, Version
|
||||
$command.Name| Should Be $cmdletname
|
||||
}
|
||||
}
|
||||
|
||||
Describe "Get-CISService Tests for services" {
|
||||
|
||||
It "Checking CIS connection is active" {
|
||||
$Global:DefaultCISServers[0].isconnected | Should Be $true
|
||||
}
|
||||
|
||||
It "Checking Get-CISService returns services" {
|
||||
Get-CISService | Should Be $true
|
||||
}
|
||||
|
||||
# Checking some known services which have a Get Method
|
||||
$servicestocheck = "com.vmware.appliance.system.version", "com.vmware.appliance.health.system"
|
||||
Foreach ($service in $servicestocheck) {
|
||||
It "Checking $service get method returns data" {
|
||||
Get-CisService -Name $service | Should Be $true
|
||||
(Get-CisService -Name $service).get() | Should Be $true
|
||||
}
|
||||
}
|
||||
|
||||
# Checking some known services which have a List Method
|
||||
$servicestocheck = "com.vmware.vcenter.folder", "com.vmware.vcenter.vm"
|
||||
Foreach ($service in $servicestocheck) {
|
||||
It "Checking $service list method returns data" {
|
||||
Get-CisService -Name $service | Should Be $true
|
||||
(Get-CisService -Name $service).list() | Should Be $true
|
||||
}
|
||||
}
|
||||
}
|
||||
20
Pester/ZZ Test Disconnect-CISServer to VC.Tests.ps1
Normal file
20
Pester/ZZ Test Disconnect-CISServer to VC.Tests.ps1
Normal file
@@ -0,0 +1,20 @@
|
||||
<#
|
||||
Script name: Test Disconnect-CISServer to VC.Tests.ps1
|
||||
Created on: 04/20/2017
|
||||
Author: Alan Renouf, @alanrenouf
|
||||
Description: The purpose of this pester test is to ensure the Disconnect-CISServer cmdlet disconnects
|
||||
Dependencies: Pester Module
|
||||
Example run:
|
||||
|
||||
Invoke-Pester -Script @{ Path = '.\Test Disconnect-CISServer to VC.Tests.ps1'; Parameters = @{ VCNAME="VC01.local" } }
|
||||
|
||||
#>
|
||||
|
||||
$VCNAME = $Parameters.Get_Item("VCNAME")
|
||||
|
||||
Describe "Disconnect-CISServer Tests" {
|
||||
It "Disconnect from $VCName" {
|
||||
Disconnect-CISServer $VCName -confirm:$false
|
||||
$Global:DefaultCISServers | Should Be $null
|
||||
}
|
||||
}
|
||||
20
Pester/ZZ Test Disconnect-VIServer to VC.Tests.ps1
Normal file
20
Pester/ZZ Test Disconnect-VIServer to VC.Tests.ps1
Normal file
@@ -0,0 +1,20 @@
|
||||
<#
|
||||
Script name: Test Disconnect-VIServer to VC.ps1
|
||||
Created on: 04/20/2017
|
||||
Author: Alan Renouf, @alanrenouf
|
||||
Description: The purpose of this pester test is to ensure the Disconnect-VIServer cmdlet disconnects
|
||||
Dependencies: Pester Module
|
||||
Example run:
|
||||
|
||||
Invoke-Pester -Script @{ Path = '.\Test Disconnect-VISServer to VC.ps1'; Parameters = @{ VCNAME="VC01.local" } }
|
||||
|
||||
#>
|
||||
|
||||
$VCNAME = $Parameters.Get_Item("VCNAME")
|
||||
|
||||
Describe "Disconnect-VIServer Tests" {
|
||||
It "Disconnect from $VCName" {
|
||||
Disconnect-VIServer $VCName -confirm:$false
|
||||
$Global:DefaultVIServer | Should Be $null
|
||||
}
|
||||
}
|
||||
108
Scripts/DatastoreSIOCStatistics.ps1
Normal file
108
Scripts/DatastoreSIOCStatistics.ps1
Normal file
@@ -0,0 +1,108 @@
|
||||
function Get-DatastoreSIOCStatCollection {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Gathers information on the status of SIOC statistics collection for a datastore
|
||||
.DESCRIPTION
|
||||
Will provide the status on a datastore's SIOC statistics collection
|
||||
.NOTES
|
||||
Author: Kyle Ruddy, @kmruddy, thatcouldbeaproblem.com
|
||||
.PARAMETER Datastore
|
||||
Datastore to be ran against
|
||||
.EXAMPLE
|
||||
Get-DatastoreSIOCStatCollection -Datastore ExampleDatastore
|
||||
Retreives the status of SIOC statistics collection for the provided datastore
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory=$true,Position=0,ValueFromPipelineByPropertyName=$true)]
|
||||
$Datastore
|
||||
)
|
||||
|
||||
Process {
|
||||
|
||||
#Collect information about the desired datastore/s and verify existance
|
||||
$ds = Get-Datastore $datastore -warningaction silentlycontinue -erroraction silentlycontinue
|
||||
if (!$ds) {Write-Warning -Message "No Datastore found"}
|
||||
else {
|
||||
|
||||
$report = @()
|
||||
|
||||
#Loops through each datastore provided and feeds back information about the SIOC Statistics Collection status
|
||||
foreach ($item in $ds) {
|
||||
|
||||
$tempitem = "" | select Name,SIOCStatCollection
|
||||
$tempitem.Name = $item.Name
|
||||
$tempitem.SIOCStatCollection = $item.ExtensionData.IormConfiguration.statsCollectionEnabled
|
||||
$report += $tempitem
|
||||
|
||||
}
|
||||
|
||||
#Returns the output to the user
|
||||
return $report
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function Set-DatastoreSIOCStatCollection {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Configures the status of SIOC statistics collection for a datastore
|
||||
.DESCRIPTION
|
||||
Will modify the status on a datastore's SIOC statistics collection
|
||||
.NOTES
|
||||
Author: Kyle Ruddy, @kmruddy, thatcouldbeaproblem.com
|
||||
.PARAMETER Datastore
|
||||
Datastore to be ran against
|
||||
.EXAMPLE
|
||||
Set-DatastoreSIOCStatCollection -Datastore ExampleDatastore -Enable
|
||||
Enables SIOC statistics collection for the provided datastore
|
||||
#>
|
||||
[CmdletBinding(SupportsShouldProcess)]
|
||||
param(
|
||||
[Parameter(Mandatory=$true,Position=0,ValueFromPipelineByPropertyName=$true)]
|
||||
$Datastore,
|
||||
[Switch]$Enable,
|
||||
[Switch]$Disable
|
||||
)
|
||||
|
||||
Process {
|
||||
|
||||
#Collect information about the desired datastore/s and verify existance
|
||||
$ds = Get-Datastore $datastore -warningaction silentlycontinue -erroraction silentlycontinue
|
||||
if (!$ds) {Write-Warning -Message "No Datastore found"}
|
||||
else {
|
||||
|
||||
$report = @()
|
||||
|
||||
#Loops through each datastore provided and modifies the SIOC Statistics Collection status
|
||||
foreach ($dsobj in $ds) {
|
||||
|
||||
$_this = Get-View -id 'StorageResourceManager-StorageResourceManager'
|
||||
$spec = New-Object vmware.vim.storageiormconfigspec
|
||||
|
||||
if ($Enable) {
|
||||
|
||||
$spec.statsCollectionEnabled = $true
|
||||
|
||||
} elseif ($Disable) {
|
||||
|
||||
$spec.statsCollectionEnabled = $false
|
||||
|
||||
}
|
||||
|
||||
$_this.ConfigureDatastoreIORM_Task($dsobj.ExtensionData.MoRef,$spec) | out-null
|
||||
start-sleep -s 1
|
||||
$report += Get-View -Id $dsobj.ExtensionData.MoRef -Property Name,Iormconfiguration.statsCollectionEnabled | select Name,@{N='SIOCStatCollection';E={$_.Iormconfiguration.statsCollectionEnabled}}
|
||||
|
||||
}
|
||||
|
||||
#Returns the output to the user
|
||||
return $report
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
29
Scripts/Get-VsanHclDatabase.ps1
Normal file
29
Scripts/Get-VsanHclDatabase.ps1
Normal file
@@ -0,0 +1,29 @@
|
||||
Function Get-VsanHclDatabase {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Alan Renouf
|
||||
Organization: VMware
|
||||
Blog: http://virtu-al.net
|
||||
Twitter: @alanrenouf
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function will allow you to view and download the VSAN Hardware Compatability List (HCL) Database
|
||||
|
||||
.DESCRIPTION
|
||||
Use this function to view or download the VSAN HCL
|
||||
.EXAMPLE
|
||||
View the latest online HCL Database from online source
|
||||
PS C:\> Get-VsanHclDatabase | Format-Table
|
||||
.EXAMPLE
|
||||
Download the latest HCL Database from online source and store locally
|
||||
PS C:\> Get-VsanHclDatabase -filepath ~/hcl.json
|
||||
#>
|
||||
param ($filepath)
|
||||
$uri = "https://partnerweb.vmware.com/service/vsan/all.json"
|
||||
If ($filepath) {
|
||||
Invoke-WebRequest -Uri $uri -OutFile $filepath
|
||||
} Else {
|
||||
Invoke-WebRequest -Uri $uri | ConvertFrom-Json | Select-Object -ExpandProperty Data | Select-object -ExpandProperty Controller
|
||||
}
|
||||
}
|
||||
28
Scripts/Home Lab/Home Lab Delete settings.ps1
Normal file
28
Scripts/Home Lab/Home Lab Delete settings.ps1
Normal file
@@ -0,0 +1,28 @@
|
||||
$ESXIP = "192.168.1.201"
|
||||
$ESXUser = "root"
|
||||
$ESXPWD = "VMware1!"
|
||||
|
||||
Connect-viserver $esxip -user $ESXUser -pass $ESXPWD
|
||||
|
||||
#Leaving confirm off just in case someone happens to be connected to more than one vCenter/Host!
|
||||
Get-VM | Stop-VM
|
||||
Get-VM | Remove-VM
|
||||
|
||||
$ESXCLI = Get-EsxCli -v2 -VMHost (get-VMHost)
|
||||
$esxcli.vsan.cluster.leave.invoke()
|
||||
|
||||
$VSANDisks = $esxcli.storage.core.device.list.invoke() | Where {$_.isremovable -eq "false"} | Sort size
|
||||
$Performance = $VSANDisks[0]
|
||||
$Capacity = $VSANDisks[1]
|
||||
|
||||
$removal = $esxcli.vsan.storage.remove.CreateArgs()
|
||||
$removal.ssd = $performance.Device
|
||||
$esxcli.vsan.storage.remove.Invoke($removal)
|
||||
|
||||
$capacitytag = $esxcli.vsan.storage.tag.remove.CreateArgs()
|
||||
$capacitytag.disk = $Capacity.Device
|
||||
$capacitytag.tag = "capacityFlash"
|
||||
$esxcli.vsan.storage.tag.remove.Invoke($capacitytag)
|
||||
|
||||
Set-VMHostSysLogServer $null
|
||||
Remove-VMHostNtpServer (Get-VMHostNtpServer) -Confirm:$false
|
||||
215
Scripts/Home Lab/Home Lab Deployment.ps1
Normal file
215
Scripts/Home Lab/Home Lab Deployment.ps1
Normal file
@@ -0,0 +1,215 @@
|
||||
# ESX Start Host deployment Settings
|
||||
$ESXIP = "192.168.1.201"
|
||||
$ESXUser = "root"
|
||||
$ESXPWD = "VMware1!"
|
||||
|
||||
# VCSA Configuration
|
||||
$VCSACDDrive = "D:\"
|
||||
$SSODomainName = "corp.local"
|
||||
$VCNAME = "VC01"
|
||||
$VCUser = "Administrator@$SSODomainName"
|
||||
$VCPass = "VMware1!"
|
||||
$VCIP = "192.168.1.200"
|
||||
$VCDNS = "192.168.1.1"
|
||||
$VCGW = "192.168.1.1"
|
||||
$VCNetPrefix = "24"
|
||||
$VCSADeploymentSize = "tiny"
|
||||
|
||||
# vCenter Configuration
|
||||
$SSOSiteName = "Site01"
|
||||
$datacenter = "DC01"
|
||||
$cluster = "Cluster01"
|
||||
$ntpserver = "pool.ntp.org"
|
||||
|
||||
# VSAN Configuration
|
||||
$VSANPolicy = '(("hostFailuresToTolerate" i1) ("forceProvisioning" i1))'
|
||||
$VMKNetforVSAN = "Management Network"
|
||||
|
||||
# General Settings
|
||||
$verboseLogFile = "$ENV:Temp\vsphere65-NUC-lab-deployment.log"
|
||||
|
||||
# End of configuration
|
||||
Function My-Logger {
|
||||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[String]$message
|
||||
)
|
||||
|
||||
$timeStamp = Get-Date -Format "MM-dd-yyyy_hh:mm:ss"
|
||||
|
||||
Write-Host -NoNewline -ForegroundColor White "[$timestamp]"
|
||||
Write-Host -ForegroundColor Green " $message"
|
||||
$logMessage = "[$timeStamp] $message"
|
||||
$logMessage | Out-File -Append -LiteralPath $verboseLogFile
|
||||
}
|
||||
|
||||
$StartTime = Get-Date
|
||||
|
||||
Write-Host "Writing Log files to $verboselogfile" -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
|
||||
If (-not (Test-Path "$($VCSACDDrive)vcsa-cli-installer\win32\vcsa-deploy.exe")){
|
||||
Write-Host "VCSA media not found at $($VCSACDDrive) please mount it and try again"
|
||||
return
|
||||
}
|
||||
My-Logger "Connecting to ESXi Host: $ESXIP ..."
|
||||
$connection = Connect-viserver $ESXIP -user $ESXUser -Password $ESXPWD -WarningAction SilentlyContinue
|
||||
|
||||
My-Logger "Enabling SSH Service for future troubleshooting ..."
|
||||
Start-VMHostService -HostService (Get-VMHost | Get-VMHostService | Where { $_.Key -eq "TSM-SSH"} ) | Out-File -Append -LiteralPath $verboseLogFile
|
||||
|
||||
My-Logger "Configuring NTP server to $ntpserver and retarting service ..."
|
||||
Get-VMHost | Add-VMHostNtpServer $ntpserver | Out-File -Append -LiteralPath $verboseLogFile
|
||||
Get-VMHost | Get-VMHostFirewallException | where {$_.Name -eq "NTP client"} | Set-VMHostFirewallException -Enabled:$true | Out-File -Append -LiteralPath $verboseLogFile
|
||||
Get-VMHost | Get-VmHostService | Where-Object {$_.key -eq "ntpd"} | Start-VMHostService | Out-File -Append -LiteralPath $verboseLogFile
|
||||
Get-VMhost | Get-VmHostService | Where-Object {$_.key -eq "ntpd"} | Set-VMHostService -policy "automatic" | Out-File -Append -LiteralPath $verboseLogFile
|
||||
|
||||
#Configure VSAN Bootstrap (http://www.virtuallyghetto.com/2013/09/how-to-bootstrap-vcenter-server-onto_9.html)
|
||||
My-Logger "Setting the VSAN Policy for ForceProvisiong ..."
|
||||
$esxcli = get-esxcli -V2
|
||||
$VSANPolicyDefaults = $esxcli.vsan.policy.setdefault.CreateArgs()
|
||||
$VSANPolicyDefaults.policy = $VSANPolicy
|
||||
$VSANPolicyDefaults.policyclass = "vdisk"
|
||||
$esxcli.vsan.policy.setdefault.Invoke($VSANPolicyDefaults) | Out-File -Append -LiteralPath $verboseLogFile
|
||||
$VSANPolicyDefaults.policyclass = "vmnamespace"
|
||||
$esxcli.vsan.policy.setdefault.Invoke($VSANPolicyDefaults) | Out-File -Append -LiteralPath $verboseLogFile
|
||||
|
||||
# Create new VSAN Cluster
|
||||
My-Logger "Creating a new VSAN Cluster ..."
|
||||
$esxcli.vsan.cluster.new.Invoke() | Out-File -Append -LiteralPath $verboseLogFile
|
||||
$VSANDisks = $esxcli.storage.core.device.list.invoke() | Where {$_.isremovable -eq "false"} | Sort size
|
||||
"Found the following disks to use for VSAN:" | Out-File -Append -LiteralPath $verboseLogFile
|
||||
$VSANDisks | FT | Out-File -Append -LiteralPath $verboseLogFile
|
||||
$Performance = $VSANDisks[0]
|
||||
"Using $($Performance.Model) for Performance disk" | Out-File -Append -LiteralPath $verboseLogFile
|
||||
$Capacity = $VSANDisks[1]
|
||||
"Using $($Capacity.Model) for Capacity disk" | Out-File -Append -LiteralPath $verboseLogFile
|
||||
|
||||
My-Logger "Tagging $($Capacity.Model) as Capacity ..."
|
||||
$capacitytag = $esxcli.vsan.storage.tag.add.CreateArgs()
|
||||
$capacitytag.disk = $Capacity.Device
|
||||
$capacitytag.tag = "capacityFlash"
|
||||
$esxcli.vsan.storage.tag.add.Invoke($capacitytag) | Out-File -Append -LiteralPath $verboseLogFile
|
||||
|
||||
My-Logger "Create VSAN Diskgroup to back VSAN Cluster ..."
|
||||
$addvsanstorage = $esxcli.vsan.storage.add.CreateArgs()
|
||||
$addvsanstorage.ssd = $Performance.Device
|
||||
$addvsanstorage.disks = $Capacity.device
|
||||
$esxcli.vsan.storage.add.Invoke($addvsanstorage) | Out-File -Append -LiteralPath $verboseLogFile
|
||||
|
||||
My-Logger "Deploying VCSA using Script CLI + JSON ..."
|
||||
$config = (get-content –raw “$($VCSACDDrive)vcsa-cli-installer\templates\install\embedded_vCSA_on_ESXi.json” ) | convertfrom-json
|
||||
$config.'new.vcsa'.esxi.hostname = $ESXIP
|
||||
$config.'new.vcsa'.esxi.username = $ESXUser
|
||||
$config.'new.vcsa'.esxi.password = $ESXPWD
|
||||
$config.'new.vcsa'.esxi.datastore = "vsanDatastore"
|
||||
$config.'new.vcsa'.network.ip = $VCIP
|
||||
$config.'new.vcsa'.network.'dns.servers'[0] = $VCDNS
|
||||
$config.'new.vcsa'.network.gateway = $VCGW
|
||||
$config.'new.vcsa'.network.'system.name' = $VCIP #Change to $VCName if you have DNS setup
|
||||
$config.'new.vcsa'.network.prefix = $VCNetPrefix
|
||||
$config.'new.vcsa'.os.password = $VCPass
|
||||
$config.'new.vcsa'.appliance.'deployment.option' = $VCSADeploymentSize
|
||||
$config.'new.vcsa'.sso.password = $VCPass
|
||||
$config.'new.vcsa'.sso.'site-name' = $SSOSiteName
|
||||
$config.'new.vcsa'.sso.'domain-name' = $SSODomainName
|
||||
$config | convertto-json | set-content –path “$($ENV:Temp)\jsontemplate.json”
|
||||
invoke-expression “$($VCSACDDrive)vcsa-cli-installer\win32\vcsa-deploy.exe install --no-esx-ssl-verify --accept-eula --acknowledge-ceip $($ENV:Temp)\jsontemplate.json” | Out-File -Append -LiteralPath $verboseLogFile
|
||||
|
||||
My-Logger "Enable VSAN Traffic on VMKernel Network ..."
|
||||
$VMKernel = Get-VMHost $ESXIP | Get-VMHostNetworkAdapter -VMKernel | Where {$_.PortGroupName -eq $VMKNetforVSAN }
|
||||
$IsVSANEnabled = $VMKernel | Where { $_.VsanTrafficEnabled}
|
||||
If (-not $IsVSANEnabled) {
|
||||
My-Logger "Enabling VSAN Kernel on $VMKernel ..."
|
||||
$VMKernel | Set-VMHostNetworkAdapter -VsanTrafficEnabled $true -Confirm:$false | Out-File -Append -LiteralPath $verboseLogFile
|
||||
} Else {
|
||||
My-Logger "VSAN Kernel already enabled on $VmKernel ..."
|
||||
}
|
||||
|
||||
My-Logger "Disconnecting from ESXi Host: $ESXIP ..."
|
||||
Disconnect-VIServer $ESXIP -Force -Confirm:$false -WarningAction SilentlyContinue
|
||||
|
||||
My-Logger "Connecting to vCenter: $VCIP ..."
|
||||
$connection = Connect-VIServer -Server $VCIP -User $VCUser -Password $vcpass -WarningAction SilentlyContinue
|
||||
|
||||
My-Logger "Creating Datacenter: $datacenter ..."
|
||||
New-Datacenter -Name $datacenter -Location (Get-Folder -Type Datacenter) | Out-File -Append -LiteralPath $verboseLogFile
|
||||
My-Logger "Creating Cluster: $cluster ..."
|
||||
New-Cluster -Name $cluster -Location (Get-Datacenter -Name $datacenter) -DrsEnabled -VsanEnabled | Out-File -Append -LiteralPath $verboseLogFile
|
||||
My-Logger "Adding ESXi Host $ESXIP to vCenter ..."
|
||||
Add-VMHost -Location (Get-Cluster -Name $cluster) -User $ESXUser -Password $ESXPWD -Name $ESXIP -Force | Out-File -Append -LiteralPath $verboseLogFile
|
||||
|
||||
My-Logger "Setting the VCSA NTP server to: $NTPServer ..."
|
||||
Connect-CISServer -Server $VCIP -User $VCUser -Password $VCPass
|
||||
(Get-CISService com.vmware.appliance.techpreview.ntp.server).set(@($NTPServer)) | Out-File -Append -LiteralPath $verboseLogFile
|
||||
|
||||
My-Logger "Configuring Host syslog to VC ..."
|
||||
Get-VMHost | Set-VMHostSysLogServer -SysLogServer $VCIP | Out-File -Append -LiteralPath $verboseLogFile
|
||||
|
||||
My-Logger "Acknowledging Alarms on the cluster ..."
|
||||
$alarmMgr = Get-View AlarmManager
|
||||
Get-Cluster | where {$_.ExtensionData.TriggeredAlarmState} | %{
|
||||
$cluster = $_
|
||||
$Cluster.ExtensionData.TriggeredAlarmState | %{
|
||||
$alarmMgr.AcknowledgeAlarm($_.Alarm,$vm.ExtensionData.MoRef) | Out-File -Append -LiteralPath $verboseLogFile
|
||||
}
|
||||
}
|
||||
|
||||
My-Logger "Creating @lamw Content Library with Nested ESXi Images ..."
|
||||
|
||||
# Get a Datastore to create the content library on
|
||||
$datastoreID = (Get-Datastore "vsanDatastore").extensiondata.moref.value
|
||||
|
||||
# Get the Service that works with Subscribed content libraries
|
||||
$ContentCatalog = Get-CisService com.vmware.content.subscribed_library
|
||||
|
||||
# Create a Subscribed content library on an existing datastore
|
||||
$createSpec = $ContentCatalog.help.create.create_spec.CreateExample()
|
||||
$createSpec.subscription_info.authentication_method = "NONE"
|
||||
$createSpec.subscription_info.ssl_thumbprint = "69:d9:9e:e9:0b:4b:68:24:09:2b:ce:14:d7:4a:f9:8c:bd:c6:5a:e9"
|
||||
$createSpec.subscription_info.automatic_sync_enabled = $true
|
||||
$createSpec.subscription_info.subscription_url = "https://s3-us-west-1.amazonaws.com/vghetto-content-library/lib.json"
|
||||
$createSpec.subscription_info.on_demand = $false
|
||||
$createSpec.subscription_info.password = $null
|
||||
$createSpec.server_guid = $null
|
||||
$createspec.name = "virtuallyGhetto CL"
|
||||
$createSpec.description = "@lamw CL: http://www.virtuallyghetto.com/2015/04/subscribe-to-vghetto-nested-esxi-template-content-library-in-vsphere-6-0.html"
|
||||
$createSpec.type = "SUBSCRIBED"
|
||||
$createSpec.publish_info = $null
|
||||
$datastoreID = [VMware.VimAutomation.Cis.Core.Types.V1.ID]$datastoreID
|
||||
$StorageSpec = New-Object PSObject -Property @{
|
||||
datastore_id = $datastoreID
|
||||
type = "DATASTORE"
|
||||
}
|
||||
$CreateSpec.storage_backings.Add($StorageSpec)
|
||||
$UniqueID = [guid]::NewGuid().tostring()
|
||||
$ContentCatalog.create($UniqueID, $createspec) | Out-File -Append -LiteralPath $verboseLogFile
|
||||
|
||||
My-Logger "Changing the default VSAN VM Storage Policy to FTT=0 & Force Provisioning to Yes ..."
|
||||
$VSANPolicy = Get-SpbmStoragePolicy "Virtual SAN Default Storage Policy"
|
||||
$Ruleset = New-SpbmRuleSet -Name “Rule-set 1” -AllOfRules @((New-SpbmRule -Capability VSAN.forceProvisioning $True), (New-SpbmRule -Capability VSAN.hostFailuresToTolerate 0))
|
||||
$VSANPolicy | Set-SpbmStoragePolicy -RuleSet $Ruleset | Out-File -Append -LiteralPath $verboseLogFile
|
||||
|
||||
My-Logger "Enabling VM Autostart for the VCSA VM ..."
|
||||
$VCVM = Get-VM
|
||||
$vmstartpolicy = Get-VMStartPolicy -VM $VCVM
|
||||
Set-VMHostStartPolicy (Get-VMHost $ESXIP | Get-VMHostStartPolicy) -Enabled:$true | Out-File -Append -LiteralPath $verboseLogFile
|
||||
Set-VMStartPolicy -StartPolicy $vmstartpolicy -StartAction PowerOn -StartDelay 0 | Out-File -Append -LiteralPath $verboseLogFile
|
||||
|
||||
My-Logger "Enabling SSH on VCSA for easier troubleshooting ..."
|
||||
$vcsassh = Get-CIsService com.vmware.appliance.access.ssh
|
||||
$vcsassh.set($true)
|
||||
|
||||
$EndTime = Get-Date
|
||||
$duration = [math]::Round((New-TimeSpan -Start $StartTime -End $EndTime).TotalMinutes,2)
|
||||
|
||||
My-Logger "================================"
|
||||
My-Logger "vSphere Lab Deployment Complete!"
|
||||
My-Logger "StartTime: $StartTime"
|
||||
My-Logger " EndTime: $EndTime"
|
||||
My-Logger " Duration: $duration minutes"
|
||||
Write-Host ""
|
||||
My-Logger "Access the vSphere Web Client at https://$VCIP/vsphere-client/"
|
||||
My-Logger "Access the HTML5 vSphere Web Client at https://$VCIP/ui/"
|
||||
My-Logger "Browse the vSphere REST APIs using the API Explorer here: https://$VCIP/apiexplorer/"
|
||||
My-Logger "================================"
|
||||
38
Scripts/Horizon-GetUsageStats.ps1
Normal file
38
Scripts/Horizon-GetUsageStats.ps1
Normal file
@@ -0,0 +1,38 @@
|
||||
<#
|
||||
.NOTES
|
||||
Script name: Horizon-UsageStats.ps1
|
||||
Author: Ray Heffer, @rayheffer
|
||||
Last Edited on: 04/18/2017
|
||||
Dependencies: PowerCLI 6.5 R1 or later, Horizon 7.0.2 or later
|
||||
.DESCRIPTION
|
||||
This is a sample script that retrieves the Horizon usage statistics. This produces the same metrics as listed under View Configuration > Product Licensing and Usage. Service providers can use this script or incorporate it with their existing scripts to automate the reporting of Horizon usage.
|
||||
|
||||
Example Output:
|
||||
NumConnections : 180
|
||||
NumConnectionsHigh : 250
|
||||
NumViewComposerConnections : 0
|
||||
NumViewComposerConnectionsHigh : 0
|
||||
NumTunneledSessions : 0
|
||||
NumPSGSessions : 180
|
||||
#>
|
||||
|
||||
# User Configuration
|
||||
$hzUser = "Administrator"
|
||||
$hzPass = "VMware1!"
|
||||
$hzDomain = "vmw.lab"
|
||||
$hzConn = "connect01.vmw.lab"
|
||||
|
||||
# Import the Horizon module
|
||||
Import-Module VMware.VimAutomation.HorizonView
|
||||
|
||||
# Establish connection to Connection Server
|
||||
$hvServer = Connect-HVServer -server $hzConn -User $hzUser -Password $hzPass -Domain $hzDomain
|
||||
|
||||
# Assign a variable to obtain the API Extension Data
|
||||
$hvServices = $Global:DefaultHVServers.ExtensionData
|
||||
|
||||
# Retrieve Connection Server Health metrics
|
||||
$hvHealth =$hvServices.ConnectionServerHealth.ConnectionServerHealth_List()
|
||||
|
||||
# Display ConnectionData (Usage stats)
|
||||
$hvHealth.ConnectionData
|
||||
27
Scripts/NVME Info.ps1
Normal file
27
Scripts/NVME Info.ps1
Normal file
@@ -0,0 +1,27 @@
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Alan Renouf
|
||||
Organization: VMware
|
||||
Blog: http://virtu-al.net
|
||||
Twitter: @alanrenouf
|
||||
===========================================================================
|
||||
#>
|
||||
|
||||
Foreach ($vmhost in Get-VMHost) {
|
||||
$esxcli = get-esxcli -V2 -vmhost $vmhost
|
||||
Write-Host "Host: $($vmhost.name)" -ForegroundColor Green
|
||||
$devices = $esxcli.nvme.device.list.Invoke()
|
||||
Foreach ($device in $devices) {
|
||||
$nvmedevice = $esxcli.nvme.device.get.CreateArgs()
|
||||
$nvmedevice.adapter = $device.HBAName
|
||||
$esxcli.nvme.device.get.invoke($nvmedevice) | Select-Object ModelNumber, FirmwareRevision
|
||||
$features = $esxcli.nvme.device.feature.ChildElements | Select-object -ExpandProperty name
|
||||
ForEach ($feature in $features){
|
||||
Write-Host "Feature: $feature" -ForegroundColor Yellow
|
||||
$currentfeature = $esxcli.nvme.device.feature.$feature.get.CreateArgs()
|
||||
$currentfeature.adapter = $device.HBAName
|
||||
$esxcli.nvme.device.feature.$feature.get.Invoke($currentfeature)
|
||||
}
|
||||
}
|
||||
}
|
||||
43
Scripts/New-ClusterHostGroup.ps1
Normal file
43
Scripts/New-ClusterHostGroup.ps1
Normal file
@@ -0,0 +1,43 @@
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Script name: New-ClusterHostGroup.ps1
|
||||
Created on: 2016-10-25
|
||||
Author: Peter D. Jorgensen (@pjorg, pjorg.com)
|
||||
Dependencies: None known
|
||||
===Tested Against Environment====
|
||||
vSphere Version: 5.5, 6.0
|
||||
PowerCLI Version: PowerCLI 6.5R1
|
||||
PowerShell Version: 5.0
|
||||
OS Version: Windows 10, Windows 7
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Creates a DRS Host Group in a vSphere cluster.
|
||||
.Example
|
||||
$ProdCluster = Get-Cluster *prod*
|
||||
$OddHosts = $ProdCluster | Get-VMHost | ?{ $_.Name -match 'esxi-\d*[13579]+.\lab\.local' }
|
||||
.\New-ClusterHostGroup.ps1 -Name 'OddProdHosts' -Cluster $ProdCluster -VMHost $OddHosts
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory=$True,Position=1)]
|
||||
[String]$Name,
|
||||
[Parameter(Mandatory=$True,ValueFromPipeline=$True,Position=2)]
|
||||
[VMware.VimAutomation.ViCore.Types.V1.Inventory.Cluster]$Cluster,
|
||||
[Parameter(Mandatory=$False,Position=3)]
|
||||
[VMware.VimAutomation.ViCore.Types.V1.Inventory.VMHost[]]$VMHost
|
||||
)
|
||||
|
||||
$NewGroup = New-Object VMware.Vim.ClusterHostGroup -Property @{
|
||||
'Name'=$Name
|
||||
'Host'=$VMHost.Id
|
||||
}
|
||||
|
||||
$spec = New-Object VMware.Vim.ClusterConfigSpecEx -Property @{
|
||||
'GroupSpec'=(New-Object VMware.Vim.ClusterGroupSpec -Property @{
|
||||
'Info'=$NewGroup
|
||||
})
|
||||
}
|
||||
|
||||
$ClusterToReconfig = Get-View -VIObject $Cluster -Property Name
|
||||
$ClusterToReconfig.ReconfigureComputeResource($spec, $true)
|
||||
43
Scripts/New-ClusterVmGroup.ps1
Normal file
43
Scripts/New-ClusterVmGroup.ps1
Normal file
@@ -0,0 +1,43 @@
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Script name: New-ClusterVmGroup.ps1
|
||||
Created on: 2016-10-25
|
||||
Author: Peter D. Jorgensen (@pjorg, pjorg.com)
|
||||
Dependencies: None known
|
||||
===Tested Against Environment====
|
||||
vSphere Version: 5.5, 6.0
|
||||
PowerCLI Version: PowerCLI 6.5R1
|
||||
PowerShell Version: 5.0
|
||||
OS Version: Windows 10, Windows 7
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Creates a DRS VM Group in a vSphere cluster.
|
||||
.Example
|
||||
$ProdCluster = Get-Cluster *prod*
|
||||
$EvenVMs = $ProdCluster | Get-VM | ?{ $_.Name -match 'MyVM-\d*[02468]+' }
|
||||
.\New-ClusterVmGroup.ps1 -Name 'EvenVMs' -Cluster $ProdCluster -VM $EvenVMs
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory=$True,Position=1)]
|
||||
[String]$Name,
|
||||
[Parameter(Mandatory=$True,ValueFromPipeline=$True,Position=2)]
|
||||
[VMware.VimAutomation.ViCore.Types.V1.Inventory.Cluster]$Cluster,
|
||||
[Parameter(Mandatory=$False,Position=3)]
|
||||
[VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine[]]$VM
|
||||
)
|
||||
|
||||
$NewGroup = New-Object VMware.Vim.ClusterVmGroup -Property @{
|
||||
'Name'=$Name
|
||||
'VM'=$VM.Id
|
||||
}
|
||||
|
||||
$spec = New-Object VMware.Vim.ClusterConfigSpecEx -Property @{
|
||||
'GroupSpec'=(New-Object VMware.Vim.ClusterGroupSpec -Property @{
|
||||
'Info'=$NewGroup
|
||||
})
|
||||
}
|
||||
|
||||
$ClusterToReconfig = Get-View -VIObject $Cluster -Property Name
|
||||
$ClusterToReconfig.ReconfigureComputeResource($spec, $true)
|
||||
48
Scripts/New-ClusterVmHostRule.ps1
Normal file
48
Scripts/New-ClusterVmHostRule.ps1
Normal file
@@ -0,0 +1,48 @@
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Script name: New-ClusterVmHostRule.ps1
|
||||
Created on: 2016-10-25
|
||||
Author: Peter D. Jorgensen (@pjorg, pjorg.com)
|
||||
Dependencies: None known
|
||||
===Tested Against Environment====
|
||||
vSphere Version: 5.5, 6.0
|
||||
PowerCLI Version: PowerCLI 6.5R1
|
||||
PowerShell Version: 5.0
|
||||
OS Version: Windows 10, Windows 7
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Creates a VM to Host affinity rule in a vSphere cluster.
|
||||
.Example
|
||||
$ProdCluster = Get-Cluster *prod*
|
||||
.\New-ClusterVmHostRule.ps1 -Name 'Even VMs to Odd Hosts' -AffineHostGroupName 'OddHosts' -VMGroupName 'EvenVMs' -Enabled:$true -Cluster $ProdCluster
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory=$True,Position=1)]
|
||||
[String]$Name,
|
||||
[Parameter(Mandatory=$True,Position=2)]
|
||||
[String]$AffineHostGroupName,
|
||||
[Parameter(Mandatory=$True,Position=3)]
|
||||
[String]$VMGroupName,
|
||||
[Parameter(Mandatory=$False,Position=4)]
|
||||
[Switch]$Enabled=$True,
|
||||
[Parameter(Mandatory=$True,ValueFromPipeline=$True,Position=5)]
|
||||
[VMware.VimAutomation.ViCore.Types.V1.Inventory.Cluster]$Cluster
|
||||
)
|
||||
|
||||
$NewRule = New-Object VMware.Vim.ClusterVmHostRuleInfo -Property @{
|
||||
'AffineHostGroupName'=$AffineHostGroupName
|
||||
'VmGroupName'=$VMGroupName
|
||||
'Enabled'=$Enabled
|
||||
'Name'=$Name
|
||||
}
|
||||
|
||||
$spec = New-Object VMware.Vim.ClusterConfigSpecEx -Property @{
|
||||
'RulesSpec'=(New-Object VMware.Vim.ClusterRuleSpec -Property @{
|
||||
'Info'=$NewRule
|
||||
})
|
||||
}
|
||||
|
||||
$ClusterToReconfig = Get-View -VIObject $Cluster -Property Name
|
||||
$ClusterToReconfig.ReconfigureComputeResource($spec, $true)
|
||||
103
Scripts/SetLunReservation.ps1
Normal file
103
Scripts/SetLunReservation.ps1
Normal file
@@ -0,0 +1,103 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Set a given LUN ID to Perennially Reserved.
|
||||
|
||||
.DESCRIPTION
|
||||
A description of the file.
|
||||
|
||||
.PARAMETER vCenter
|
||||
Set vCenter server to connect to
|
||||
|
||||
.PARAMETER Username
|
||||
Set username to use
|
||||
|
||||
.PARAMETER Password
|
||||
Set password to be used
|
||||
|
||||
.PARAMETER VirtualMachine
|
||||
Name of the virtual machine which has the RDM
|
||||
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created on: 20/03/2017 15:05
|
||||
Created by: Alessio Rocchi <arocchi@vmware.com>
|
||||
Organization: VMware
|
||||
Filename: SetLunReservation.ps1
|
||||
===========================================================================
|
||||
#>
|
||||
param
|
||||
(
|
||||
[Parameter(Mandatory = $true,
|
||||
ValueFromPipeline = $true,
|
||||
Position = 0)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]$vCenter,
|
||||
[Parameter(Mandatory = $false,
|
||||
ValueFromPipeline = $true,
|
||||
HelpMessage = 'Set vCenter Username')]
|
||||
[AllowNull()]
|
||||
[String]$Username,
|
||||
[Parameter(Mandatory = $false,
|
||||
ValueFromPipeline = $true,
|
||||
HelpMessage = 'Set vCenterPassword')]
|
||||
[AllowNull()]
|
||||
[String]$Password,
|
||||
[Parameter(Mandatory = $true,
|
||||
ValueFromPipeline = $true)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]$VirtualMachine
|
||||
)
|
||||
|
||||
Import-Module -Name VMware.VimAutomation.Core -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null
|
||||
|
||||
try
|
||||
{
|
||||
if ([String]::IsNullOrEmpty($Username) -or [String]::IsNullOrEmpty($Password))
|
||||
{
|
||||
$vcCredential = Get-Credential
|
||||
Connect-VIServer -Server $vCenter -Credential $vcCredential -WarningAction SilentlyContinue -ErrorAction Stop | Out-Null
|
||||
}
|
||||
else
|
||||
{
|
||||
Connect-VIServer -Server $vCenter -User $Username -Password $Password -WarningAction SilentlyContinue -ErrorAction Stop | Out-Null
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Error("Error connecting to vCenter: {0}" -f $vCenter)
|
||||
exit
|
||||
}
|
||||
|
||||
|
||||
$rDms = Get-HardDisk -DiskType rawPhysical -Vm (Get-VM -Name $VirtualMachine)
|
||||
$clusterHosts = Get-Cluster -VM $VirtualMachine | Get-VMHost
|
||||
|
||||
$menu = @{ }
|
||||
|
||||
for ($i = 1; $i -le $rDms.count; $i++)
|
||||
{
|
||||
Write-Host("{0}) {1}[{2}]: {3}" -f ($i, $rDms[$i - 1].Name, $rDms[$i - 1].CapacityGB, $rDms[$i - 1].ScsiCanonicalName))
|
||||
$menu.Add($i, ($rDms[$i - 1].ScsiCanonicalName))
|
||||
}
|
||||
|
||||
[int]$ans = Read-Host 'Which Disk you want to configure?'
|
||||
$selection = $menu.Item($ans)
|
||||
write-host("Choosed Disk: {0}" -f $selection)
|
||||
|
||||
$current = 0
|
||||
foreach ($vmHost in $clusterHosts)
|
||||
{
|
||||
Write-Progress -Activity "Processing Cluster." -CurrentOperation $vmHost.Name -PercentComplete (($counter / $clusterHosts.count) * 100)
|
||||
$esxcli = Get-EsxCli -V2 -VMHost $vmHost
|
||||
$deviceListArgs = $esxcli.storage.core.device.list.CreateArgs()
|
||||
$deviceListArgs.device = $selection
|
||||
$esxcli.storage.core.device.list.Invoke($deviceListArgs) | Select-Object Device, IsPerenniallyReserved
|
||||
$deviceSetArgs = $esxcli.storage.core.device.setconfig.CreateArgs()
|
||||
$deviceSetArgs.device = $selection
|
||||
$deviceSetArgs.perenniallyreserved = $true
|
||||
$esxcli.storage.core.device.setconfig.Invoke($deviceSetArgs)
|
||||
$counter++
|
||||
}
|
||||
|
||||
Disconnect-VIServer -WarningAction SilentlyContinue -Server $vCenter -Force -Confirm:$false
|
||||
|
||||
59
Scripts/VSANSmartsData.ps1
Normal file
59
Scripts/VSANSmartsData.ps1
Normal file
@@ -0,0 +1,59 @@
|
||||
Function Get-VSANSmartsData {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function retreives SMART drive data using new vSAN
|
||||
Management 6.6 API. This can also be used outside of vSAN
|
||||
to query existing SSD devices not being used for vSAN.
|
||||
.PARAMETER Cluster
|
||||
The name of a vSAN Cluster
|
||||
.EXAMPLE
|
||||
Get-VSANSmartsData -Cluster VSAN-Cluster
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$false)][String]$Cluster
|
||||
)
|
||||
|
||||
if($global:DefaultVIServer.ExtensionData.Content.About.ApiType -eq "VirtualCenter") {
|
||||
if(!$cluster) {
|
||||
Write-Host "Cluster property is required when connecting to vCenter Server"
|
||||
break
|
||||
}
|
||||
|
||||
$vchs = Get-VSANView -Id "VsanVcClusterHealthSystem-vsan-cluster-health-system"
|
||||
$cluster_view = (Get-Cluster -Name $Cluster).ExtensionData.MoRef
|
||||
$result = $vchs.VsanQueryVcClusterSmartStatsSummary($cluster_view)
|
||||
} else {
|
||||
$vhs = Get-VSANView -Id "HostVsanHealthSystem-ha-vsan-health-system"
|
||||
$result = $vhs.VsanHostQuerySmartStats($null,$true)
|
||||
}
|
||||
|
||||
$vmhost = $result.Hostname
|
||||
$smartsData = $result.SmartStats
|
||||
|
||||
Write-Host "`nESXi Host: $vmhost`n"
|
||||
foreach ($data in $smartsData) {
|
||||
if($data.stats) {
|
||||
$stats = $data.stats
|
||||
Write-Host $data.disk
|
||||
|
||||
$smartsResults = @()
|
||||
foreach ($stat in $stats) {
|
||||
$statResult = [pscustomobject] @{
|
||||
Parameter = $stat.Parameter;
|
||||
Value =$stat.Value;
|
||||
Threshold = $stat.Threshold;
|
||||
Worst = $stat.Worst
|
||||
}
|
||||
$smartsResults+=$statResult
|
||||
}
|
||||
$smartsResults | Format-Table
|
||||
}
|
||||
}
|
||||
}
|
||||
26
Scripts/VSANVersion.ps1
Normal file
26
Scripts/VSANVersion.ps1
Normal file
@@ -0,0 +1,26 @@
|
||||
Function Get-VSANVersion {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function retreives the vSAN software version for both VC/ESXi
|
||||
.PARAMETER Cluster
|
||||
The name of a vSAN Cluster
|
||||
.EXAMPLE
|
||||
Get-VSANVersion -Cluster VSAN-Cluster
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$Cluster
|
||||
)
|
||||
$vchs = Get-VSANView -Id "VsanVcClusterHealthSystem-vsan-cluster-health-system"
|
||||
$cluster_view = (Get-Cluster -Name $Cluster).ExtensionData.MoRef
|
||||
$results = $vchs.VsanVcClusterQueryVerifyHealthSystemVersions($cluster_view)
|
||||
|
||||
Write-Host "`nVC Version:"$results.VcVersion
|
||||
$results.HostResults | Select Hostname, Version
|
||||
}
|
||||
97
Scripts/esxi-image-comparator.ps1
Normal file
97
Scripts/esxi-image-comparator.ps1
Normal file
@@ -0,0 +1,97 @@
|
||||
<#
|
||||
Script name: esxi-image-comparator.ps1
|
||||
Last update: 24 May 2017
|
||||
Author: Eric Gray, @eric_gray
|
||||
Description: Compare contents (VIBs) of multiple VMware ESXi image profiles.
|
||||
Dependencies: PowerCLI Image Builder (VMware.ImageBuilder,VMware.VimAutomation.Core)
|
||||
#>
|
||||
|
||||
param(
|
||||
[switch]$ShowAllVIBs=$false,
|
||||
[switch]$HideDates=$false,
|
||||
[switch]$Interactive=$false,
|
||||
[switch]$Grid=$false,
|
||||
[string]$ProfileInclude,
|
||||
[string]$ProfileExclude
|
||||
)
|
||||
|
||||
$profileList = Get-EsxImageProfile | sort -Property Name
|
||||
|
||||
if ($ProfileInclude) {
|
||||
$profileList = $profileList | ? Name -Match $ProfileInclude
|
||||
}
|
||||
|
||||
if ($ProfileExclude) {
|
||||
$profileList = $profileList | ? Name -NotMatch $ProfileExclude
|
||||
}
|
||||
|
||||
if ($profileList.Count -eq 0) {
|
||||
Write-Host "No ESXi image profiles available in current session."
|
||||
Write-Host "Use Add-EsxSoftwareDepot for each depot zip bundle you would like to compare."
|
||||
exit 1
|
||||
}
|
||||
|
||||
if ($Interactive) {
|
||||
$keep = @()
|
||||
Write-Host "Found the following profiles:" -ForegroundColor Yellow
|
||||
$profileList | % { write-host $_.Name }
|
||||
|
||||
if ($profileList.Count -gt 7) {
|
||||
Write-Host "Found $($profileList.Count) profiles!" -ForegroundColor Yellow
|
||||
Write-Host "Note: List filtering is possible through -ProfileInclude / -ProfileExclude" -ForegroundColor DarkGreen
|
||||
}
|
||||
|
||||
write-host "`nType 'y' next to each profile to compare..." -ForegroundColor Yellow
|
||||
|
||||
foreach ($profile in $profileList) {
|
||||
$want = Read-Host -Prompt $profile.Name
|
||||
if ($want.StartsWith("y") ) {
|
||||
$keep += $profile
|
||||
}
|
||||
|
||||
}
|
||||
$profileList = $keep
|
||||
|
||||
}
|
||||
|
||||
# go thru each profile and build a hash of the vib name and hash of profile name + version
|
||||
$diffResults = @{}
|
||||
foreach ($profile in $profileList ) {
|
||||
foreach ($vib in $profile.VibList) {
|
||||
$vibValue = $vib.Version
|
||||
if (! $HideDates) {
|
||||
$vibValue += " "+ $vib.CreationDate.ToShortDateString()
|
||||
}
|
||||
$diffResults.($vib.name) += @{$profile.name = $vibValue}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# create an object that will neatly output as CSV or table
|
||||
$outputTable=@()
|
||||
foreach ($row in $diffResults.keys | sort) {
|
||||
$vibRow = new-object PSObject
|
||||
$vibRow | add-member -membertype NoteProperty -name "VIB" -Value $row
|
||||
$valueCounter = @{}
|
||||
|
||||
foreach ($profileName in $profileList.name) {
|
||||
#populate this hash to decide if all profiles have same version of VIB
|
||||
$valueCounter.($diffResults.$row.$profileName) = 1
|
||||
$vibRow | add-member -membertype NoteProperty -name $profileName -Value $diffResults.$row.$profileName
|
||||
}
|
||||
|
||||
if ($valueCounter.Count -gt 1 -or $ShowAllVIBs) {
|
||||
$outputTable += $vibRow
|
||||
}
|
||||
}
|
||||
|
||||
# useful for debugging
|
||||
#$diffResults | ConvertTo-Json
|
||||
#$outputTable|Export-Csv -Path .\image-diff-results.csv -NoTypeInformation
|
||||
|
||||
if ($Grid) {
|
||||
$outputTable | Out-GridView -Title "VMware ESXi Image Profile Comparator"
|
||||
} else {
|
||||
$outputTable
|
||||
}
|
||||
108
Scripts/esxi-image-creator.ps1
Normal file
108
Scripts/esxi-image-creator.ps1
Normal file
@@ -0,0 +1,108 @@
|
||||
<#
|
||||
Script name: esxi-image-creator.ps1
|
||||
Last update: 24 May 2017
|
||||
Author: Eric Gray, @eric_gray
|
||||
Description: Create a VMware ESXi image profile based on
|
||||
one or more depots and offline driver bundles.
|
||||
Dependencies: PowerCLI Image Builder (VMware.ImageBuilder,VMware.VimAutomation.Core)
|
||||
#>
|
||||
|
||||
param(
|
||||
[switch]$NewestDate = $false,
|
||||
[switch]$WriteZip = $false,
|
||||
[switch]$WriteISO = $false,
|
||||
[switch]$LeaveCurrentDepotsMounted = $false,
|
||||
[string]$NewProfileName = "Custom Image $(Get-Date -Format "yyyyMMddhhmm")",
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[ValidateSet('VMwareCertified','VMwareAccepted','PartnerSupported','CommunitySupported')]
|
||||
[string]$Acceptance = "VMwareCertified",
|
||||
[string[]]$Files = "*.zip"
|
||||
)
|
||||
|
||||
#### Specify optional image fine-tuning here ####
|
||||
# comma-separated list (array) of VIBs to exclude
|
||||
$removeVibs = @("tools-light")
|
||||
|
||||
# force specific VIB version to be included, when more than one version is present
|
||||
# e.g. "net-enic"="2.1.2.71-1OEM.550.0.0.1331820"
|
||||
$overrideVibs = @{
|
||||
# "net-enic"="2.1.2.71-1OEM.550.0.0.1331820",
|
||||
}
|
||||
|
||||
#### end of optional fine-tuning ####
|
||||
|
||||
# may be desirable to manually mount an online depot in advance, such as for HPE
|
||||
# e.g. Add-EsxSoftwareDepot http://vibsdepot.hpe.com/index-ecli-650.xml
|
||||
if (! $LeaveCurrentDepotsMounted) {
|
||||
Get-EsxSoftwareDepot | Remove-EsxSoftwareDepot
|
||||
}
|
||||
|
||||
foreach ($depot in Get-ChildItem $Files) {
|
||||
if ($depot.Name.EndsWith(".zip") ) {
|
||||
Add-EsxSoftwareDepot $depot.FullName
|
||||
} else {
|
||||
Write-Host "Not a zip depot:" $depot.Name
|
||||
}
|
||||
}
|
||||
|
||||
if ((Get-EsxImageProfile).count -eq 0) {
|
||||
write-host "No image profiles found in the selected files"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# either use the native -Newest switch, or try to find latest VIBs by date (NewestDate)
|
||||
if ($NewestDate) {
|
||||
$pkgsAll = Get-EsxSoftwarePackage | sort -Property Name,CreationDate -Descending
|
||||
$pkgsNewestDate=@()
|
||||
|
||||
foreach ($pkg in $pkgsAll) {
|
||||
if ($pkgsNewestDate.GetEnumerator().name -notcontains $pkg.Name ) {
|
||||
$pkgsNewestDate += $pkg
|
||||
}
|
||||
}
|
||||
$pkgs = $pkgsNewestDate
|
||||
|
||||
} else {
|
||||
$pkgs = Get-ESXSoftwarePackage -Newest
|
||||
}
|
||||
|
||||
# rebuild the package array according to manual fine-tuning
|
||||
if ($removeVibs) {
|
||||
Write-Host "`nThe following VIBs will not be included in ${NewProfileName}:" -ForegroundColor Yellow
|
||||
$removeVibs
|
||||
$pkgs = $pkgs | ? name -NotIn $removeVibs
|
||||
}
|
||||
|
||||
foreach ($override in $overrideVibs.keys) {
|
||||
# check that the override exists, then remove existing and add override
|
||||
$tmpOver = Get-EsxSoftwarePackage -Name $override -Version $overrideVibs.$override
|
||||
if ($tmpOver) {
|
||||
$pkgs = $pkgs | ? name -NotIn $tmpOver.name
|
||||
$pkgs += $tmpOver
|
||||
} else {
|
||||
Write-host "Did not find:" $override $overrideVibs.$override -ForegroundColor Yellow
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
New-EsxImageProfile -NewProfile $NewProfileName -SoftwarePackage $pkgs `
|
||||
-Vendor Custom -AcceptanceLevel $Acceptance -Description "Made with esxi-image-creator.ps1" `
|
||||
-ErrorAction Stop -ErrorVariable CreationError | Out-Null
|
||||
}
|
||||
catch {
|
||||
Write-Host "Custom image profile $NewProfileName not created." -ForegroundColor Yellow
|
||||
$CreationError
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "`nFinished creating $NewProfileName" -ForegroundColor Yellow
|
||||
|
||||
if ($WriteZip) {
|
||||
Write-Host "Creating zip bundle..." -ForegroundColor Green
|
||||
Export-EsxImageProfile -ImageProfile $NewProfileName -ExportToBundle -FilePath .\${NewProfileName}.zip -Force
|
||||
}
|
||||
|
||||
if ($WriteISO) {
|
||||
Write-Host "Creating ISO image..." -ForegroundColor Green
|
||||
Export-EsxImageProfile -ImageProfile $NewProfileName -ExportToIso -FilePath .\${NewProfileName}.iso -Force
|
||||
}
|
||||
6
Scripts/modules.sh
Normal file
6
Scripts/modules.sh
Normal file
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
for file in $( ls /powershell/PowerCLI-Example-Scripts/Modules/ )
|
||||
do
|
||||
mkdir "/root/.local/share/powershell/Modules/${file%.*}/"
|
||||
mv "/powershell/PowerCLI-Example-Scripts/Modules/$file" "/root/.local/share/powershell/Modules/${file%.*}/$file"
|
||||
done
|
||||
198
SetDatastoreTag.ps1
Executable file
198
SetDatastoreTag.ps1
Executable file
@@ -0,0 +1,198 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
A brief description of the file.
|
||||
|
||||
.DESCRIPTION
|
||||
Given a list of Datastore Names, this script will assign a Tag to them
|
||||
|
||||
.PARAMETER csvFile
|
||||
String representing the full path of the file
|
||||
The file must be structured like this:
|
||||
-----------------------------
|
||||
Tag1,Tag2,Tag3,Tag4
|
||||
IPv4-iSCSI-SiteA,Tag1,Tag3
|
||||
IPv4-NFS-SiteA,Tag2,Tag4
|
||||
...
|
||||
-----------------------------
|
||||
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created on: 31/03/2017 11:16
|
||||
Created by: Alessio Rocchi <arocchi@vmware.com>
|
||||
Organization: VMware
|
||||
Filename: SetDatastoreTag.ps1
|
||||
===========================================================================
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param
|
||||
(
|
||||
[Parameter(Mandatory = $true,
|
||||
ValueFromPipeline = $true)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[System.String]$csvFile,
|
||||
[Parameter(Mandatory = $true,
|
||||
ValueFromPipeline = $true)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]$vCenter,
|
||||
[Parameter(ValueFromPipeline = $true,
|
||||
Position = 2)]
|
||||
[AllowNull()]
|
||||
[String]$Username,
|
||||
[Parameter(Position = 3)]
|
||||
[AllowNull()]
|
||||
[String]$Password
|
||||
)
|
||||
|
||||
Import-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue | Out-Null
|
||||
|
||||
class vcConnector : System.IDisposable
|
||||
{
|
||||
[String]$Username
|
||||
[String]$Password
|
||||
[String]$vCenter
|
||||
[PSObject]$server
|
||||
|
||||
static [vcConnector]$instance
|
||||
|
||||
vcConnector($Username, $Password, $vCenter)
|
||||
{
|
||||
Import-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue | Out-Null
|
||||
|
||||
$this.Username = $Username
|
||||
$this.Password = $Password
|
||||
$this.vCenter = $vCenter
|
||||
$this.connect()
|
||||
}
|
||||
|
||||
vcConnector($vcCredential, $vCenter)
|
||||
{
|
||||
Import-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue | Out-Null
|
||||
|
||||
$this.vcCredential = $vcCredential
|
||||
$this.vCenter = $vCenter
|
||||
$this.connect()
|
||||
}
|
||||
|
||||
[void] hidden connect()
|
||||
{
|
||||
try
|
||||
{
|
||||
if ([String]::IsNullOrEmpty($this.Username) -or [String]::IsNullOrEmpty($this.Password))
|
||||
{
|
||||
$vcCredential = Get-Credential
|
||||
Connect-VIServer -Server $this.vCenter -Credential $this.vcCredential -WarningAction SilentlyContinue -ErrorAction Stop | Out-Null
|
||||
}
|
||||
else
|
||||
{
|
||||
Connect-VIServer -Server $this.vCenter -User $this.Username -Password $this.Password -WarningAction SilentlyContinue -ErrorAction Stop
|
||||
}
|
||||
Write-Debug("Connected to vCenter: {0}" -f $this.vCenter)
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Error($Error[0].Exception.Message)
|
||||
exit
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[void] Dispose()
|
||||
{
|
||||
Write-Debug("Called Dispose Method of Instance: {0}" -f ($this))
|
||||
Disconnect-VIServer -WarningAction SilentlyContinue -Server $this.vCenter -Force -Confirm:$false | Out-Null
|
||||
}
|
||||
|
||||
static [vcConnector] GetInstance()
|
||||
{
|
||||
if ([vcConnector]::instance -eq $null)
|
||||
{
|
||||
[vcConnector]::instance = [vcConnector]::new()
|
||||
}
|
||||
|
||||
return [vcConnector]::instance
|
||||
}
|
||||
}
|
||||
|
||||
class Content{
|
||||
[System.Collections.Generic.List[System.String]]$availableTags
|
||||
[System.Collections.Generic.List[System.String]]$elements
|
||||
|
||||
Content()
|
||||
{
|
||||
}
|
||||
|
||||
Content([String]$filePath)
|
||||
{
|
||||
if ((Test-Path -Path $filePath) -eq $false)
|
||||
{
|
||||
throw ("Cannot find file: {0}" -f ($filePath))
|
||||
}
|
||||
try
|
||||
{
|
||||
# Cast the Get-Content return type to Generic List of Strings in order to avoid fixed-size array
|
||||
$this.elements = [System.Collections.Generic.List[System.String]](Get-Content -Path $filePath -ea SilentlyContinue -wa SilentlyContinue)
|
||||
$this.availableTags = $this.elements[0].split(',')
|
||||
# Delete the first element aka availableTags
|
||||
$this.elements.RemoveAt(0)
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw ("Error reading the file: {0}" -f ($filePath))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$vc = [vcConnector]::new($Username, $Password, $vCenter)
|
||||
$csvContent = [Content]::new($csvFile)
|
||||
|
||||
Write-Host("Available Tags: {0}" -f ($csvContent.availableTags))
|
||||
|
||||
foreach ($element in $csvContent.elements)
|
||||
{
|
||||
[System.Collections.Generic.List[System.String]]$splittedList = $element.split(',')
|
||||
# Get the Datastore Name
|
||||
[System.String]$datastoreName = $splittedList[0]
|
||||
# Removing Datastore Name
|
||||
$splittedList.RemoveAt(0)
|
||||
# Create a List of Tags which will be assigned to the Datastore
|
||||
[System.Collections.Generic.List[PSObject]]$tagsToAssign = $splittedList | ForEach-Object { Get-Tag -Name $_ }
|
||||
Write-Host("Tags to assign to Datastore: {0} are: {1}" -f ($datastoreName, $tagsToAssign))
|
||||
# Get Datastore object by the given Datastore Name, first field of the the line
|
||||
$datastore = Get-Datastore -Name $datastoreName -ea Stop
|
||||
# Iterate the assigned Datastore Tags
|
||||
foreach ($tag in ($datastore | Get-TagAssignment))
|
||||
{
|
||||
# Check if the current tag is one of the available ones.
|
||||
if ($tag.Tag.Name -in $csvContent.availableTags)
|
||||
{
|
||||
# Remove the current assigned Tag
|
||||
Write-Host("Removing Tag: {0}" -f ($tag))
|
||||
Remove-TagAssignment -TagAssignment $tag -Confirm:$false
|
||||
}
|
||||
}
|
||||
# Finally add the new set of tags to the Datastore
|
||||
foreach ($tag in $tagsToAssign)
|
||||
{
|
||||
Write-Host("Trying to assign Tag: {0} to Datastore: {1}" -f ($tag.Name, $datastoreName))
|
||||
# Assign the Tag
|
||||
New-TagAssignment -Entity $datastore -Tag $tag
|
||||
}
|
||||
}
|
||||
}
|
||||
catch [VMware.VimAutomation.Sdk.Types.V1.ErrorHandling.VimException.VimException]
|
||||
{
|
||||
Write-Error("VIException: {0}" -f ($Error[0].Exception.Message))
|
||||
exit
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Error $Error[0].Exception.Message
|
||||
exit
|
||||
}
|
||||
finally
|
||||
{
|
||||
# Let be assured that the vc connection will be disposed.
|
||||
$vc.Dispose()
|
||||
}
|
||||
Reference in New Issue
Block a user