Merge remote-tracking branch 'vmware/master'

This commit is contained in:
Kyle Ruddy
2018-01-18 08:31:53 -08:00
26 changed files with 6076 additions and 91 deletions

View File

@@ -25,12 +25,29 @@
$results = @()
foreach($libraryID in $libaryIDs) {
$library = $contentLibaryService.get($libraryId)
$library = $contentLibaryService.get($libraryID)
# Use vCenter REST API to retrieve name of Datastore that is backing the Content Library
$datastoreService = Get-CisService com.vmware.vcenter.datastore
$datastore = $datastoreService.get($library.storage_backings.datastore_id)
if($library.publish_info.published) {
$published = $library.publish_info.published
$publishedURL = $library.publish_info.publish_url
$externalReplication = $library.publish_info.persist_json_enabled
} else {
$published = $library.publish_info.published
$publishedURL = "N/A"
$externalReplication = "N/A"
}
if($library.subscription_info) {
$subscribeURL = $library.subscription_info.subscription_url
$published = "N/A"
} else {
$subscribeURL = "N/A"
}
if(!$LibraryName) {
$libraryResult = [pscustomobject] @{
Id = $library.Id;
@@ -38,6 +55,10 @@
Type = $library.Type;
Description = $library.Description;
Datastore = $datastore.name;
Published = $published;
PublishedURL = $publishedURL;
JSONPersistence = $externalReplication;
SubscribedURL = $subscribeURL;
CreationTime = $library.Creation_Time;
}
$results+=$libraryResult
@@ -49,6 +70,10 @@
Type = $library.Type;
Description = $library.Description;
Datastore = $datastore.name;
Published = $published;
PublishedURL = $publishedURL;
JSONPersistence = $externalReplication;
SubscribedURL = $subscribeURL;
CreationTime = $library.Creation_Time;
}
$results+=$libraryResult
@@ -194,4 +219,363 @@ Function Get-ContentLibraryItemFiles {
}
}
$results
}
Function Set-ContentLibrary {
<#
.NOTES
===========================================================================
Created by: William Lam
Organization: VMware
Blog: www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.DESCRIPTION
This function updates the JSON Persistence property for a given Content Library
.PARAMETER LibraryName
The name of a vSphere Content Library
.EXAMPLE
Set-ContentLibraryItems -LibraryName Test -JSONPersistenceEnabled
.EXAMPLE
Set-ContentLibraryItems -LibraryName Test -JSONPersistenceDisabled
#>
param(
[Parameter(Mandatory=$true)][String]$LibraryName,
[Parameter(Mandatory=$false)][Switch]$JSONPersistenceEnabled,
[Parameter(Mandatory=$false)][Switch]$JSONPersistenceDisabled
)
$contentLibaryService = Get-CisService com.vmware.content.library
$libaryIDs = $contentLibaryService.list()
$found = $false
foreach($libraryID in $libaryIDs) {
$library = $contentLibaryService.get($libraryId)
if($library.name -eq $LibraryName) {
$found = $true
break
}
}
if($found) {
$localLibraryService = Get-CisService -Name "com.vmware.content.local_library"
if($JSONPersistenceEnabled) {
$jsonPersist = $true
} else {
$jsonPersist = $false
}
$updateSpec = $localLibraryService.Help.update.update_spec.Create()
$updateSpec.type = $library.type
$updateSpec.publish_info.authentication_method = $library.publish_info.authentication_method
$updateSpec.publish_info.persist_json_enabled = $jsonPersist
Write-Host "Updating JSON Persistence configuration setting for $LibraryName ..."
$localLibraryService.update($library.id,$updateSpec)
} else {
Write-Host "Unable to find Content Library $Libraryname"
}
}
Function New-ExtReplicatedContentLibrary {
<#
.NOTES
===========================================================================
Created by: William Lam
Organization: VMware
Blog: www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.DESCRIPTION
This function creates a new Subscriber Content Library from a JSON Persisted
Content Library that has been externally replicated
.PARAMETER LibraryName
The name of the new vSphere Content Library
.PARAMETER DatastoreName
The name of the vSphere Datastore which contains JSON Persisted configuration file
.PARAMETER SubscribeLibraryName
The name fo the root directroy of the externally replicated Content Library residing on vSphere Datastore
.PARAMETER AutoSync
Whether or not to Automatically sync content
.PARAMETER OnDemand
Only sync content when requested
.EXAMPLE
New-ExtReplicatedContentLibrary -LibraryName Bar -DatastoreName iSCSI-02 -SubscribeLibraryName myExtReplicatedLibrary
.EXAMPLE
New-ExtReplicatedContentLibrary -LibraryName Bar -DatastoreName iSCSI-02 -SubscribeLibraryName myExtReplicatedLibrary -AutoSync $false -OnDemand $true
#>
param(
[Parameter(Mandatory=$true)][String]$LibraryName,
[Parameter(Mandatory=$true)][String]$DatastoreName,
[Parameter(Mandatory=$true)][String]$SubscribeLibraryName,
[Parameter(Mandatory=$false)][Boolean]$AutoSync=$false,
[Parameter(Mandatory=$false)][Boolean]$OnDemand=$true
)
$datastore = Get-Datastore -Name $DatastoreName
if($datastore) {
$datastoreId = $datastore.ExtensionData.MoRef.Value
$datastoreUrl = $datastore.ExtensionData.Info.Url
$subscribeUrl = $datastoreUrl + $SubscribeLibraryName + "/lib.json"
$subscribeLibraryService = Get-CisService -Name "com.vmware.content.subscribed_library"
$StorageSpec = [pscustomobject] @{
datastore_id = $datastoreId;
type = "DATASTORE";
}
$UniqueChangeId = [guid]::NewGuid().tostring()
$createSpec = $subscribeLibraryService.Help.create.create_spec.Create()
$createSpec.name = $LibraryName
$addResults = $createSpec.storage_backings.Add($StorageSpec)
$createSpec.subscription_info.automatic_sync_enabled = $false
$createSpec.subscription_info.on_demand = $true
$createSpec.subscription_info.subscription_url = $subscribeUrl
$createSpec.subscription_info.authentication_method = "NONE"
$createSpec.type = "SUBSCRIBED"
Write-Host "Creating new Externally Replicated Content Library called $LibraryName ..."
$library = $subscribeLibraryService.create($UniqueChangeId,$createSpec)
}
}
Function Remove-SubscribedContentLibrary {
<#
.NOTES
===========================================================================
Created by: William Lam
Organization: VMware
Blog: www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.DESCRIPTION
This function deletes a Subscriber Content Library
.PARAMETER LibraryName
The name of the new vSphere Content Library to delete
.EXAMPLE
Remove-SubscribedContentLibrary -LibraryName Bar
#>
param(
[Parameter(Mandatory=$true)][String]$LibraryName
)
$contentLibaryService = Get-CisService com.vmware.content.library
$libaryIDs = $contentLibaryService.list()
$found = $false
foreach($libraryID in $libaryIDs) {
$library = $contentLibaryService.get($libraryId)
if($library.name -eq $LibraryName) {
$found = $true
break
}
}
if($found) {
$subscribeLibraryService = Get-CisService -Name "com.vmware.content.subscribed_library"
Write-Host "Deleting Subscribed Content Library $LibraryName ..."
$subscribeLibraryService.delete($library.id)
} else {
Write-Host "Unable to find Content Library $LibraryName"
}
}
Function New-LocalContentLibrary {
<#
.NOTES
===========================================================================
Created by: William Lam
Organization: VMware
Blog: www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.DESCRIPTION
This function creates a new Subscriber Content Library from a JSON Persisted
Content Library that has been externally replicated
.PARAMETER LibraryName
The name of the new vSphere Content Library
.PARAMETER DatastoreName
The name of the vSphere Datastore to store the Content Library
.PARAMETER Publish
Whther or not to publish the Content Library, this is required for JSON Peristence
.PARAMETER JSONPersistence
Whether or not to enable JSON Persistence which enables external replication of Content Library
.EXAMPLE
New-LocalContentLibrary -LibraryName Foo -DatastoreName iSCSI-01 -Publish $true
.EXAMPLE
New-LocalContentLibrary -LibraryName Foo -DatastoreName iSCSI-01 -Publish $true -JSONPersistence $true
#>
param(
[Parameter(Mandatory=$true)][String]$LibraryName,
[Parameter(Mandatory=$true)][String]$DatastoreName,
[Parameter(Mandatory=$false)][Boolean]$Publish=$true,
[Parameter(Mandatory=$false)][Boolean]$JSONPersistence=$false
)
$datastore = Get-Datastore -Name $DatastoreName
if($datastore) {
$datastoreId = $datastore.ExtensionData.MoRef.Value
$localLibraryService = Get-CisService -Name "com.vmware.content.local_library"
$StorageSpec = [pscustomobject] @{
datastore_id = $datastoreId;
type = "DATASTORE";
}
$UniqueChangeId = [guid]::NewGuid().tostring()
$createSpec = $localLibraryService.Help.create.create_spec.Create()
$createSpec.name = $LibraryName
$addResults = $createSpec.storage_backings.Add($StorageSpec)
$createSpec.publish_info.authentication_method = "NONE"
$createSpec.publish_info.persist_json_enabled = $JSONPersistence
$createSpec.publish_info.published = $Publish
$createSpec.type = "LOCAL"
Write-Host "Creating new Local Content Library called $LibraryName ..."
$library = $localLibraryService.create($UniqueChangeId,$createSpec)
}
}
Function Remove-LocalContentLibrary {
<#
.NOTES
===========================================================================
Created by: William Lam
Organization: VMware
Blog: www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.DESCRIPTION
This function deletes a Local Content Library
.PARAMETER LibraryName
The name of the new vSphere Content Library to delete
.EXAMPLE
Remove-LocalContentLibrary -LibraryName Bar
#>
param(
[Parameter(Mandatory=$true)][String]$LibraryName
)
$contentLibaryService = Get-CisService com.vmware.content.library
$libaryIDs = $contentLibaryService.list()
$found = $false
foreach($libraryID in $libaryIDs) {
$library = $contentLibaryService.get($libraryId)
if($library.name -eq $LibraryName) {
$found = $true
break
}
}
if($found) {
$localLibraryService = Get-CisService -Name "com.vmware.content.local_library"
Write-Host "Deleting Local Content Library $LibraryName ..."
$localLibraryService.delete($library.id)
} else {
Write-Host "Unable to find Content Library $LibraryName"
}
}
Function Copy-ContentLibrary {
<#
.NOTES
===========================================================================
Created by: William Lam
Organization: VMware
Blog: www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.DESCRIPTION
This function copies all library items from one Content Library to another
.PARAMETER SourceLibaryName
The name of the source Content Library to copy from
.PARAMETER DestinationLibaryName
The name of the desintation Content Library to copy to
.PARAMETER DeleteSourceFile
Whther or not to delete library item from the source Content Library after copy
.EXAMPLE
Copy-ContentLibrary -SourceLibaryName Foo -DestinationLibaryName Bar
.EXAMPLE
Copy-ContentLibrary -SourceLibaryName Foo -DestinationLibaryName Bar -DeleteSourceFile $true
#>
param(
[Parameter(Mandatory=$true)][String]$SourceLibaryName,
[Parameter(Mandatory=$true)][String]$DestinationLibaryName,
[Parameter(Mandatory=$false)][Boolean]$DeleteSourceFile=$false
)
$sourceLibraryId = (Get-ContentLibrary -LibraryName $SourceLibaryName).Id
if($sourceLibraryId -eq $null) {
Write-Host -ForegroundColor red "Unable to find Source Content Library named $SourceLibaryName"
exit
}
$destinationLibraryId = (Get-ContentLibrary -LibraryName $DestinationLibaryName).Id
if($destinationLibraryId -eq $null) {
Write-Host -ForegroundColor Red "Unable to find Destination Content Library named $DestinationLibaryName"
break
}
$sourceItemFiles = Get-ContentLibraryItems -LibraryName $SourceLibaryName
if($sourceItemFiles -eq $null) {
Write-Host -ForegroundColor red "Unable to retrieve Content Library Items from $SourceLibaryName"
break
}
$contentLibaryItemService = Get-CisService com.vmware.content.library.item
foreach ($sourceItemFile in $sourceItemFiles) {
# Check to see if file already exists in destination Content Library
$result = Get-ContentLibraryItems -LibraryName $DestinationLibaryName -LibraryItemName $sourceItemFile.Name
if($result -eq $null) {
# Create CopySpec
$copySpec = $contentLibaryItemService.Help.copy.destination_create_spec.Create()
$copySpec.library_id = $destinationLibraryId
$copySpec.name = $sourceItemFile.Name
$copySpec.description = $sourceItemFile.Description
# Create random Unique Copy Id
$UniqueChangeId = [guid]::NewGuid().tostring()
# Perform Copy
try {
Write-Host -ForegroundColor Cyan "Copying" $sourceItemFile.Name "..."
$copyResult = $contentLibaryItemService.copy($UniqueChangeId, $sourceItemFile.Id, $copySpec)
} catch {
Write-Host -ForegroundColor Red "Failed to copy" $sourceItemFile.Name
$Error[0]
break
}
# Delete source file if set to true
if($DeleteSourceFile) {
try {
Write-Host -ForegroundColor Magenta "Deleteing" $sourceItemFile.Name "..."
$deleteResult = $contentLibaryItemService.delete($sourceItemFile.Id)
} catch {
Write-Host -ForegroundColor Red "Failed to delete" $sourceItemFile.Name
$Error[0]
break
}
}
} else {
Write-Host -ForegroundColor Yellow "Skipping" $sourceItemFile.Name "already exists"
# Delete source file if set to true
if($DeleteSourceFile) {
try {
Write-Host -ForegroundColor Magenta "Deleteing" $sourceItemFile.Name "..."
$deleteResult = $contentLibaryItemService.delete($sourceItemFile.Id)
} catch {
Write-Host -ForegroundColor Red "Failed to delete" $sourceItemFile.Name
break
}
}
}
}
}

View File

@@ -0,0 +1,290 @@
Function Get-XVCMStatus {
<#
.NOTES
===========================================================================
Created by: William Lam
Organization: VMware
Blog: www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.DESCRIPTION
This function returns whether Cross vCenter Workload Migration Utility is running or not
.EXAMPLE
Get-XVCMStatus
#>
$Uri = "http://localhost:8080/api/ping"
$results = Invoke-WebRequest -Uri $Uri -Method GET -TimeoutSec 5
if($results.StatusCode -eq 200) {
Write-Host -ForegroundColor Green $results.Content
} else { Write-Host -ForegroundColor Red "Cross vCenter Workload Migration Utility is probably not running" }
}
Function Get-XVCMSite {
<#
.NOTES
===========================================================================
Created by: William Lam
Organization: VMware
Blog: www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.DESCRIPTION
This function returns all registered vCenter Servers
.EXAMPLE
Get-XVCMSite
#>
$Uri = "http://localhost:8080/api/sites"
$results = Invoke-WebRequest -Uri $Uri -Method GET
if($results.StatusCode -eq 200) {
($results.Content | ConvertFrom-Json)|select sitename,hostname,username
} else { Write-Host -ForegroundColor Red "Failed to retrieve VC Site Registration details" }
}
Function New-XVCMSite {
<#
.NOTES
===========================================================================
Created by: William Lam
Organization: VMware
Blog: www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.DESCRIPTION
This function registers a new vCenter Server endpoint
.PARAMETER SiteName
The display name for the particular vCenter Server to be registered
.PARAMETER VCHostname
The Hostname/IP Address of vCenter Server
.PARAMETER VCUsername
The VC Username of vCenter Server
.PARAMETER VCPassword
The VC Password of vCenter Server
.PARAMETER Insecure
Flag to disable SSL Verification checking, useful for lab environments
.EXAMPLE
New-XVCMSite -SiteName "SiteA" -VCHostname "vcenter65-1.primp-industries.com" -VCUsername "administrator@vsphere.local" -VCPassword "VMware1!" -Insecure
#>
param(
[Parameter(Mandatory=$true)][String]$SiteName,
[Parameter(Mandatory=$true)][String]$VCHostname,
[Parameter(Mandatory=$true)][String]$VCUsername,
[Parameter(Mandatory=$true)][String]$VCPassword,
[Parameter(Mandatory=$false)][Switch]$Insecure
)
$Uri = "http://localhost:8080/api/sites"
$insecureFlag = $false
if($Insecure) {
$insecureFlag = $true
}
$body = @{
"sitename"=$SiteName;
"hostname"=$VCHostname;
"username"=$VCUsername;
"password"=$VCPassword;
"insecure"=$insecureFlag;
}
$body = $body | ConvertTo-Json
Write-Host -ForegroundColor Cyan "Registering vCenter Server $VCHostname as $SiteName ..."
$results = Invoke-WebRequest -Uri $Uri -Method POST -Body $body -ContentType "application/json"
if($results.StatusCode -eq 200) {
Write-Host -ForegroundColor Green "Successfully registered $SiteName"
} else { Write-Host -ForegroundColor Red "Failed to register $SiteName" }
}
Function Remove-XVCMSite {
<#
.NOTES
===========================================================================
Created by: William Lam
Organization: VMware
Blog: www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.DESCRIPTION
This function removes vCenter Server endpoint
.PARAMETER SiteName
The name of the registered vCenter Server to remove
.EXAMPLE
Remove-XVCMSite -SiteName "SiteA"
#>
param(
[Parameter(Mandatory=$true)][String]$SiteName
)
$Uri = "http://localhost:8080/api/sites/$SiteName"
Write-Host -ForegroundColor Cyan "Deleting vCenter Server Site Registerion $SiteName ..."
$results = Invoke-WebRequest -Uri $Uri -Method DELETE
if($results.StatusCode -eq 200) {
Write-Host -ForegroundColor Green "Successfully deleted $SiteName"
} else { Write-Host -ForegroundColor Red "Failed to deleted $SiteName" }
}
Function New-XVCMRequest {
<#
.NOTES
===========================================================================
Created by: William Lam
Organization: VMware
Blog: www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.DESCRIPTION
This function initiates a migration request
.PARAMETER SrcSite
The name of the source vCenter Server
.PARAMETER DstSite
The name of the destination vCenter Server
.PARAMETER SrcDatacenter
The name of the source vSphere Datacenter
.PARAMETER DstDatacenter
The name of the destination vSphere Datacenter
.PARAMETER SrcCluster
The name of the source vSphere Cluster
.PARAMETER DstCluster
The name of the destination vSphere Cluster
.PARAMETER DstDatastore
The name of the destination Datastore
.PARAMETER srcVMs
List of VMs to migrate
.PARAMETER NetworkMapping
Hash table of the VM network mappings between your source and destination vCenter Server
.EXAMPLE
New-XVCMRequest -SrcSite SiteA -DstSite SiteB `
-SrcDatacenter Datacenter-SiteA -DstDatacenter Datacenter-SiteB `
-SrcCluster Palo-Alto -DstCluster Santa-Barbara `
-DstDatastore vsanDatastore `
-srcVMs @("PhotonOS-01","PhotonOS-02","PhotonOS-03","PhotonOS-04") `
-NetworkMapping @{"DVPG-VM Network 1"="DVPG-Internal Network";"DVPG-VM Network 2"="DVPG-External Network"}
#>
param(
[Parameter(Mandatory=$true)][String]$SrcSite,
[Parameter(Mandatory=$true)][String]$DstSite,
[Parameter(Mandatory=$true)][String]$SrcDatacenter,
[Parameter(Mandatory=$true)][String]$DstDatacenter,
[Parameter(Mandatory=$true)][String]$SrcCluster,
[Parameter(Mandatory=$true)][String]$DstCluster,
[Parameter(Mandatory=$true)][String]$DstDatastore,
[Parameter(Mandatory=$true)][String[]]$srcVMs,
[Parameter(Mandatory=$true)][Hashtable]$NetworkMapping
)
$Uri = "http://localhost:8080/api/tasks"
$body = @{
"sourceSite"=$SrcSite;
"targetSite"=$DstSite;
"sourceDatacenter"=$SrcDatacenter;
"targetDatacenter"=$dstDatacenter;
"sourceCluster"=$SrcCluster;
"targetCluster"=$DstCluster;
"targetDatastore"=$DstDatastore;
"networkMap"=$NetworkMapping;
"vmList"=$srcVMs;
}
$body = $body | ConvertTo-Json
Write-Host -ForegroundColor Cyan "Initiating migration request ..."
$results = Invoke-WebRequest -Uri $Uri -Method POST -Body $body -ContentType "application/json"
if($results.StatusCode -eq 200) {
$taskId = ($results.Content | ConvertFrom-Json).requestId
Write-Host -ForegroundColor Green "Successfully issued migration with TaskID: $taskId"
} else { Write-Host -ForegroundColor Red "Failed to initiate migration request" }
}
Function Get-XVCMTask {
<#
.NOTES
===========================================================================
Created by: William Lam
Organization: VMware
Blog: www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.DESCRIPTION
This function retrieves either all migration tasks and/or a specific migration task
.PARAMETER Id
The task ID returned from initiating a migration
.EXAMPLE
Get-XVCMTask -Id <Task ID>
#>
param(
[Parameter(Mandatory=$false)][String]$Id
)
$Uri = "http://localhost:8080/api/tasks"
if($Id) {
$body = @{"requestId"=$Id}
$results = Invoke-WebRequest -Uri $Uri -Method GET -Body $body -ContentType "application/json"
} else {
$results = Invoke-WebRequest -Uri $Uri -Method GET
}
if($results.StatusCode -eq 200) {
$results.Content | ConvertFrom-Json
} else { Write-Host -ForegroundColor Red "Failed to retrieve tasks" }
}
Function Get-VMNetwork {
<#
.NOTES
===========================================================================
Created by: William Lam
Organization: VMware
Blog: www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.DESCRIPTION
This function returns the list of all VM Networks attached to
given VMs to help with initiating migration
.PARAMETER srcVMs
List of VMs to query their current VM Networks
.EXAMPLE
Get-VMNetwork -srcVMs @("PhotonOS-01","PhotonOS-02","PhotonOS-03","PhotonOS-04")
#>
param(
[Parameter(Mandatory=$false)][String[]]$srcVMs
)
if (-not $global:DefaultVIServers) { Write-Host -ForegroundColor red "No vCenter Server Connection found, please connect to your source vCenter Server using Connect-VIServer"; break }
$results = @()
if($srcVMs) {
foreach ($srcVM in $srcVMs) {
$vm = Get-VM -Name $srcVM
$networkDetails = $vm | Get-NetworkAdapter
$tmp = [pscustomobject] @{
Name = $srcVM;
Adapter = $networkDetails.name;
Network = $networkDetails.NetworkName;
}
$results+=$tmp
}
} else {
foreach ($vm in Get-VM) {
$networkDetails = $vm | Get-NetworkAdapter
$tmp = [pscustomobject] @{
Name = $vm.Name;
Adapter = $networkDetails.name;
Network = $networkDetails.NetworkName;
}
$results+=$tmp
}
}
$results
}

18
Modules/NSXT/NSXT.psd1 Normal file
View File

@@ -0,0 +1,18 @@
@{
ModuleToProcess = 'NSXT.psm1'
ModuleVersion = '1.0.0.0'
GUID = 'c72f4e3d-5d1d-498f-ba86-6fa03e4ae6dd'
Author = 'William Lam'
CompanyName = 'primp-industries.com'
Copyright = '(c) 2017. All rights reserved.'
Description = 'Powershell Module for NSX-T REST API Functions'
PowerShellVersion = '5.0'
FunctionsToExport = 'Get-NSXTComputeManager','Get-NSXTFabricNode','Get-NSXTFirewallRule','Get-NSXTIPPool','Get-NSXTLogicalSwitch','Get-NSXTManager','Get-NSXTTransportZone','Get-NSXTController'
PrivateData = @{
PSData = @{
Tags = @('NSX-T','REST')
LicenseUri = 'https://www.tldrlegal.com/l/mit'
ProjectUri = 'https://github.com/lamw/PowerCLI-Example-Scripts/tree/master/Modules/NSXT'
}
}
}

260
Modules/NSXT/NSXT.psm1 Normal file
View File

@@ -0,0 +1,260 @@
Function Get-NSXTController {
Param (
[parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id
)
$clusterNodeService = Get-NsxtService -Name "com.vmware.nsx.cluster.nodes"
$clusterNodeStatusService = Get-NsxtService -Name "com.vmware.nsx.cluster.nodes.status"
if($Id) {
$nodes = $clusterNodeService.get($Id)
} else {
$nodes = $clusterNodeService.list().results | where { $_.manager_role -eq $null }
}
$results = @()
foreach ($node in $nodes) {
$nodeId = $node.id
$nodeName = $node.controller_role.control_plane_listen_addr.ip_address
$nodeStatusResults = $clusterNodeStatusService.get($nodeId)
$tmp = [pscustomobject] @{
Id = $nodeId;
Name = $nodeName;
ClusterStatus = $nodeStatusResults.control_cluster_status.control_cluster_status;
Version = $nodeStatusResults.version;
}
$results+=$tmp
}
$results
}
Function Get-NSXTFabricNode {
Param (
[parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id,
[Switch]$ESXi,
[Switch]$Edge
)
$fabricNodeService = Get-NsxtService -Name "com.vmware.nsx.fabric.nodes"
$fabricNodeStatusService = Get-NsxtService -Name "com.vmware.nsx.fabric.nodes.status"
if($Id) {
$nodes = $fabricNodeService.get($Id)
} else {
if($ESXi) {
$nodes = $fabricNodeService.list().results | where { $_.resource_type -eq "HostNode" }
} elseif ($Edge) {
$nodes = $fabricNodeService.list().results | where { $_.resource_type -eq "EdgeNode" }
} else {
$nodes = $fabricNodeService.list().results
}
}
$results = @()
foreach ($node in $nodes) {
$nodeStatusResult = $fabricNodeStatusService.get($node.id)
$tmp = [pscustomobject] @{
Id = $node.id;
Name = $node.display_name;
Type = $node.resource_type;
Address = $node.ip_addresses;
NSXVersion = $nodeStatusResult.software_version
OS = $node.os_type;
Version = $node.os_version;
Status = $nodeStatusResult.host_node_deployment_status
ManagerStatus = $nodeStatusResult.mpa_connectivity_status
ControllerStatus = $nodeStatusResult.lcp_connectivity_status
}
$results+=$tmp
}
$results
}
Function Get-NSXTIPPool {
Param (
[parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id
)
$ipPoolService = Get-NsxtService -Name "com.vmware.nsx.pools.ip_pools"
if($Id) {
$ipPools = $ipPoolService.get($Id)
} else {
$ipPools = $ipPoolService.list().results
}
$results = @()
foreach ($ipPool in $ipPools) {
$tmp = [pscustomobject] @{
Id = $ipPool.Id;
Name = $ipPool.Display_Name;
Total = $ipPool.pool_usage.total_ids;
Free = $ipPool.pool_usage.free_ids;
Network = $ipPool.subnets.cidr;
Gateway = $ipPool.subnets.gateway_ip;
DNS = $ipPool.subnets.dns_nameservers;
RangeStart = $ipPool.subnets.allocation_ranges.start;
RangeEnd = $ipPool.subnets.allocation_ranges.end
}
$results+=$tmp
}
$results
}
Function Get-NSXTTransportZone {
Param (
[parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id
)
$transportZoneService = Get-NsxtService -Name "com.vmware.nsx.transport_zones"
if($Id) {
$transportZones = $transportZoneService.get($Id)
} else {
$transportZones = $transportZoneService.list().results
}
$results = @()
foreach ($transportZone in $transportZones) {
$tmp = [pscustomobject] @{
Id = $transportZone.Id;
Name = $transportZone.display_name;
Type = $transportZone.transport_type;
HostSwitchName = $transportZone.host_switch_name;
}
$results+=$tmp
}
$results
}
Function Get-NSXTComputeManager {
Param (
[parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id
)
$computeManagerSerivce = Get-NsxtService -Name "com.vmware.nsx.fabric.compute_managers"
$computeManagerStatusService = Get-NsxtService -Name "com.vmware.nsx.fabric.compute_managers.status"
if($Id) {
$computeManagers = $computeManagerSerivce.get($id)
} else {
$computeManagers = $computeManagerSerivce.list().results
}
$results = @()
foreach ($computeManager in $computeManagers) {
$computeManagerStatus = $computeManagerStatusService.get($computeManager.Id)
$tmp = [pscustomobject] @{
Id = $computeManager.Id;
Name = $computeManager.display_name;
Server = $computeManager.server
Type = $computeManager.origin_type;
Version = $computeManagerStatus.Version;
Registration = $computeManagerStatus.registration_status;
Connection = $computeManagerStatus.connection_status;
}
$results+=$tmp
}
$results
}
Function Get-NSXTLogicalSwitch {
Param (
[parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id
)
$logicalSwitchService = Get-NsxtService -Name "com.vmware.nsx.logical_switches"
$logicalSwitchSummaryService = Get-NsxtService -Name "com.vmware.nsx.logical_switches.summary"
if($Id) {
$logicalSwitches = $logicalSwitchService.get($Id)
} else {
$logicalSwitches = $logicalSwitchService.list().results
}
$results = @()
foreach ($logicalSwitch in $logicalSwitches) {
$transportZone = (Get-NSXTTransportZone -Id $logicalSwitch.transport_zone_id | Select Name | ft -HideTableHeaders | Out-String).trim()
$ports = $logicalSwitchSummaryService.get($logicalSwitch.id).num_logical_ports
$tmp = [pscustomobject] @{
Id = $logicalSwitch.Id;
Name = $logicalSwitch.display_name;
VLAN = $logicalSwitch.vlan;
AdminStatus = $logicalSwitch.admin_state;
Ports = $ports;
TransportZone = $transportZone;
}
$results+=$tmp
}
$results
}
Function Get-NSXTFirewallRule {
Param (
[parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id
)
$firewallService = Get-NsxtService -Name "com.vmware.nsx.firewall.sections"
$firewallRuleService = Get-NsxtService -Name "com.vmware.nsx.firewall.sections.rules"
if($Id) {
$firewallRuleSections = $firewallService.get($Id)
} else {
$firewallRuleSections = $firewallService.list().results
}
$sectionResults = @()
foreach ($firewallRuleSection in $firewallRuleSections) {
$tmp = [pscustomobject] @{
Id = $firewallRuleSection.Id;
Name = $firewallRuleSection.display_name;
Type = $firewallRuleSection.section_type;
Stateful = $firewallRuleSection.stateful;
RuleCount = $firewallRuleSection.rule_count;
}
$sectionResults+=$tmp
}
$sectionResults
$firewallResults = @()
if($id) {
$firewallRules = $firewallRuleService.list($id).results
foreach ($firewallRule in $firewallRules) {
$tmp = [pscustomobject] @{
Id = $firewallRule.id;
Name = $firewallRule.display_name;
Sources = if($firewallRule.sources -eq $null) { "ANY" } else { $firewallRule.sources};
Destination = if($firewallRule.destinations -eq $null) { "ANY" } else { $firewallRule.destinations };
Services = if($firewallRule.services -eq $null) { "ANY" } else { $firewallRule.services } ;
Action = $firewallRule.action;
AppliedTo = if($firewallRule.applied_tos -eq $null) { "ANY" } else { $firewallRule.applied_tos };
Log = $firewallRule.logged;
}
$firewallResults+=$tmp
}
}
$firewallResults
}
Function Get-NSXTManager {
$clusterNodeService = Get-NsxtService -Name "com.vmware.nsx.cluster.nodes"
$nodes = $clusterNodeService.list().results
$results = @()
foreach ($node in $nodes) {
if($node.manager_role -ne $null) {
$tmp = [pscustomobject] @{
Id = $node.id;
Name = $node.display_name;
Address = $node.appliance_mgmt_listen_addr;
SHA256Thumbprint = $node.manager_role.api_listen_addr.certificate_sha256_thumbprint;
}
$results+=$tmp
}
}
$results
}

File diff suppressed because it is too large Load Diff

View File

@@ -2646,8 +2646,7 @@ function New-HVFarm {
$farmData = $farmSpecObj.data
$AccessGroup_service_helper = New-Object VMware.Hv.AccessGroupService
$ag = $AccessGroup_service_helper.AccessGroup_List($services) | Where-Object { $_.base.name -eq $accessGroup }
$farmData.AccessGroup = $ag.id
$farmData.AccessGroup = Get-HVAccessGroupID $AccessGroup_service_helper.AccessGroup_List($services)
$farmData.name = $farmName
$farmData.DisplayName = $farmDisplayName
@@ -2851,21 +2850,17 @@ function Get-HVFarmProvisioningData {
}
if ($hostOrCluster) {
$HostOrCluster_service_helper = New-Object VMware.Hv.HostOrClusterService
$hostClusterList = ($HostOrCluster_service_helper.HostOrCluster_GetHostOrClusterTree($services, $vmobject.datacenter)).treeContainer.children.info
$HostClusterObj = $hostClusterList | Where-Object { $_.name -eq $hostOrCluster }
if ($null -eq $HostClusterObj) {
throw "No host or cluster found with name: [$hostOrCluster]"
$vmObject.HostOrCluster = Get-HVHostOrClusterID $HostOrCluster_service_helper.HostOrCluster_GetHostOrClusterTree($services,$vmobject.datacenter)
if ($null -eq $vmObject.HostOrCluster) {
throw "No hostOrCluster found with Name: [$hostOrCluster]"
}
$vmObject.HostOrCluster = $HostClusterObj.id
}
if ($resourcePool) {
$ResourcePool_service_helper = New-Object VMware.Hv.ResourcePoolService
$resourcePoolList = $ResourcePool_service_helper.ResourcePool_GetResourcePoolTree($services, $vmobject.HostOrCluster)
$resourcePoolObj = $resourcePoolList | Where-Object { $_.resourcepooldata.name -eq $resourcePool }
if ($null -eq $resourcePoolObj) {
throw "No resource pool found with name: [$resourcePool]"
$vmObject.ResourcePool = Get-HVResourcePoolID $ResourcePool_service_helper.ResourcePool_GetResourcePoolTree($services,$vmobject.HostOrCluster)
if ($null -eq $vmObject.ResourcePool) {
throw "No Resource Pool found with Name: [$resourcePool]"
}
$vmObject.ResourcePool = $resourcePoolObj.id
}
return $vmObject
}
@@ -3244,6 +3239,10 @@ function New-HVPool {
Datastore names to store the VM
Applicable to Full, Linked, Instant Clone Pools.
.PARAMETER StorageOvercommit
Storage overcommit determines how View places new VMs on the selected datastores.
Supported values are 'UNBOUNDED','AGGRESSIVE','MODERATE','CONSERVATIVE','NONE' and are case sensitive.
.PARAMETER UseVSAN
Whether to use vSphere VSAN. This is applicable for vSphere 5.5 or later.
Applicable to Full, Linked, Instant Clone Pools.
@@ -3274,6 +3273,7 @@ function New-HVPool {
.PARAMETER PersistentDiskStorageOvercommit
Storage overcommit determines how view places new VMs on the selected datastores.
Supported values are 'UNBOUNDED','AGGRESSIVE','MODERATE','CONSERVATIVE','NONE' and are case sensitive.
.PARAMETER DiskSizeMB
Size of the persistent disk in MB.
@@ -3568,10 +3568,6 @@ function New-HVPool {
[string[]]
$ConnectionServerRestrictions,
#desktopSpec.desktopSettings.deleting
[Parameter(Mandatory = $false,ParameterSetName = "LINKED_CLONE")]
[boolean]$Deleting = $false,
#desktopSpec.desktopSettings.logoffSettings.powerPloicy
[Parameter(Mandatory = $false,ParameterSetName = "LINKED_CLONE")]
[ValidateSet('TAKE_NO_POWER_ACTION', 'ALWAYS_POWERED_ON', 'SUSPEND', 'POWER_OFF')]
@@ -3584,7 +3580,7 @@ function New-HVPool {
#desktopSpec.desktopSettings.logoffSettings.automaticLogoffMinutes
[Parameter(Mandatory = $false,ParameterSetName = "LINKED_CLONE")]
[ValidateRange(1,120)]
[ValidateRange(1,[int]::MaxValue)]
[int]$AutomaticLogoffMinutes = 120,
#desktopSpec.desktopSettings.logoffSettings.allowUsersToResetMachines
@@ -3597,7 +3593,7 @@ function New-HVPool {
#desktopSpec.desktopSettings.logoffSettings.deleteOrRefreshMachineAfterLogoff
[Parameter(Mandatory = $false,ParameterSetName = "LINKED_CLONE")]
[ValidateSet('NEVER', 'DELETE', 'AFTER')]
[ValidateSet('NEVER', 'DELETE', 'REFRESH')]
[string]$deleteOrRefreshMachineAfterLogoff = 'NEVER',
#desktopSpec.desktopSettings.logoffSettings.refreshOsDiskAfterLogoff
@@ -3961,8 +3957,9 @@ function New-HVPool {
[int]
$NumUnassignedMachinesKeptPoweredOn = 1,
#desktopSpec.automatedDesktopSpec.customizationSettings.cloneprepCustomizationSettings.instantCloneEngineDomainAdministrator if INSTANT_CLONE
#desktopSpec.automatedDesktopSpec.customizationSettings.AdContainer
[Parameter(Mandatory = $false,ParameterSetName = 'INSTANT_CLONE')]
[Parameter(Mandatory = $false,ParameterSetName = 'LINKED_CLONE')]
$AdContainer = 'CN=Computers',
[Parameter(Mandatory = $true,ParameterSetName = 'INSTANT_CLONE')]
@@ -4623,8 +4620,7 @@ function New-HVPool {
}
if (!$desktopBase) {
$accessGroup_client = New-Object VMware.Hv.AccessGroupService
$ag = $accessGroup_client.AccessGroup_List($services) | Where-Object { $_.base.name -eq $accessGroup }
$desktopSpecObj.base.AccessGroup = $ag.id
$desktopSpecObj.base.AccessGroup = Get-HVAccessGroupID $accessGroup_client.AccessGroup_List($services)
} else {
$desktopSpecObj.base = $desktopBase
}
@@ -4744,6 +4740,92 @@ function New-HVPool {
}
}
function Get-HVResourceStructure {
<#
.Synopsis
Output the structure of the resource pools available to a HV. Primarily this is for debugging
PS> Get-HVResourceStructure
vCenter vc.domain.local
Container DC path /DC/host
HostOrCluster Servers path /DC/host/Servers
HostOrCluster VDI path /DC/host/VDI
ResourcePool Servers path /DC/host/Servers/Resources
ResourcePool VDI path /DC/host/VDI/Resources
ResourcePool RP1 path /DC/host/VDI/Resources/RP1
ResourcePool RP2 path /DC/host/VDI/Resources/RP1/RP2
Author : Mark Elvers <mark.elvers@tunbury.org>
#>
param(
[Parameter(Mandatory = $false)]
$HvServer = $null
)
begin {
$services = Get-ViewAPIService -hvServer $HvServer
if ($null -eq $services) {
Write-Error "Could not retrieve ViewApi services from connection object"
break
}
}
process {
$vc_service_helper = New-Object VMware.Hv.VirtualCenterService
$vcList = $vc_service_helper.VirtualCenter_List($services)
foreach ($vc in $vcList) {
Write-Host vCenter $vc.ServerSpec.ServerName
$datacenterList = @{}
$BaseImage_service_helper = New-Object VMware.Hv.BaseImageVmService
$parentList = $BaseImage_service_helper.BaseImageVm_List($services, $vc.id)
foreach ($possibleParent in $parentList) {
if (-not $datacenterList.ContainsKey($possibleParent.datacenter.id)) {
$datacenterList.Add($possibleParent.datacenter.id, $possibleParent.datacenter)
}
if (0) {
Write-Host "$($possibleParent.name): " -NoNewLine
if ($possibleParent.incompatibleReasons.inUseByDesktop) { Write-Host "inUseByDesktop, " -NoNewLine }
if ($possibleParent.incompatibleReasons.viewComposerReplica) { Write-Host "viewComposerReplica, " -NoNewLine }
if ($possibleParent.incompatibleReasons.inUseByLinkedCloneDesktop) { Write-Host "inUseByLinkedCloneDesktop, " -NoNewLine }
if ($possibleParent.incompatibleReasons.unsupportedOSForLinkedCloneFarm) { Write-Host "unsupportedOSForLinkedCloneFarm, " -NoNewLine }
if ($possibleParent.incompatibleReasons.unsupportedOS) { Write-Host "unsupportedOS, " -NoNewLine }
if ($possibleParent.incompatibleReasons.noSnapshots) { Write-Host "noSnapshots, " -NoNewLine }
Write-Host
}
}
$hcNodes = @()
$index = 0
foreach ($datacenter in $datacenterList.keys) {
$HostOrCluster_service_helper = New-Object VMware.Hv.HostOrClusterService
$hcNodes += $HostOrCluster_service_helper.HostOrCluster_GetHostOrClusterTree($services, $datacenterList.$datacenter)
while ($index -lt $hcNodes.length) {
if ($hcNodes[$index].container) {
Write-Host "Container" $hcNodes[$index].treecontainer.name "path" $hcNodes[$index].treecontainer.path
if ($hcNodes[$index].treecontainer.children.Length) { $hcNodes += $hcNodes[$index].treecontainer.children }
} else {
Write-Host "HostOrCluster" $hcNodes[$index].info.name "path" $hcNodes[$index].info.path
}
$index++
}
}
$rpNodes = @()
$index = 0
foreach ($hostOrCluster in $hcNodes) {
if (-not $hostOrCluster.container) {
$ResourcePool_service_helper = New-Object VMware.Hv.ResourcePoolService
$rpNodes += $ResourcePool_service_helper.ResourcePool_GetResourcePoolTree($services, $hostOrCluster.info.id)
while ($index -lt $rpNodes.length) {
Write-Host "ResourcePool" $rpNodes[$index].resourcePoolData.name "path" $rpNodes[$index].resourcePoolData.path
if ($rpNodes[$index].children.Length) { $rpNodes += $rpNodes[$index].children }
$index++
}
}
}
}
}
end {
[System.gc]::collect()
}
}
function Get-HVPoolProvisioningData {
param(
[Parameter(Mandatory = $false)]
@@ -4814,25 +4896,146 @@ function Get-HVPoolProvisioningData {
}
if ($hostOrCluster) {
$vmFolder_helper = New-Object VMware.Hv.HostOrClusterService
$hostClusterList = ($vmFolder_helper.HostOrCluster_GetHostOrClusterTree($services,$vmobject.datacenter)).treeContainer.children.info
$hostClusterObj = $hostClusterList | Where-Object { ($_.path -eq $hostOrCluster) -or ($_.name -eq $hostOrCluster) }
if ($null -eq $hostClusterObj) {
$vmObject.HostOrCluster = Get-HVHostOrClusterID $vmFolder_helper.HostOrCluster_GetHostOrClusterTree($services,$vmobject.datacenter)
if ($null -eq $vmObject.HostOrCluster) {
throw "No hostOrCluster found with Name: [$hostOrCluster]"
}
$vmObject.HostOrCluster = $hostClusterObj.id
}
if ($resourcePool) {
$resourcePool_helper = New-Object VMware.Hv.ResourcePoolService
$resourcePoolList = $resourcePool_helper.ResourcePool_GetResourcePoolTree($services,$vmobject.HostOrCluster)
$resourcePoolObj = $resourcePoolList | Where-Object { ($_.resourcepooldata.path -eq $resourcePool) -or ($_.resourcepooldata.name -eq $resourcePool) }
if ($null -eq $resourcePoolObj) {
throw "No hostOrCluster found with Name: [$resourcePool]"
$vmObject.ResourcePool = Get-HVResourcePoolID $resourcePool_helper.ResourcePool_GetResourcePoolTree($services,$vmobject.HostOrCluster)
if ($null -eq $vmObject.ResourcePool) {
throw "No Resource Pool found with Name: [$resourcePool]"
}
$vmObject.ResourcePool = $resourcePoolObj.id
}
return $vmObject
}
function Get-HVHostOrClusterID {
<#
.Synopsis
Recursive search for a Host or Cluster name within the results tree from HostOrCluster_GetHostOrClusterTree() and returns the ID
.NOTES
HostOrCluster_GetHostOrClusterTree() returns a HostOrClusterTreeNode as below
HostOrClusterTreeNode.container $true if this is a container
HostOrClusterTreeNode.treecontainer HostOrClusterTreeContainer
HostOrClusterTreeNode.treecontainer.name Container name
HostOrClusterTreeNode.treecontainer.path Path to this container
HostOrClusterTreeNode.treecontainer.type DATACENTER, FOLDER or OTHER
HostOrClusterTreeNode.treecontainer.children HostOrClusterTreeNode[] list of child nodes with potentially more child nodes
HostOrClusterTreeNode.info HostOrClusterInfo
HostOrClusterTreeNode.info.id Host or cluster ID
HostOrClusterTreeNode.info.cluster Is this a cluster
HostOrClusterTreeNode.info.name Host or cluster name
HostOrClusterTreeNode.info.path Path to host or cluster name
HostOrClusterTreeNode.info.virtualCenter
HostOrClusterTreeNode.info.datacenter
HostOrClusterTreeNode.info.vGPUTypes
HostOrClusterTreeNode.info.incompatibileReasons
Author : Mark Elvers <mark.elvers@tunbury.org>
#>
param(
[Parameter(Mandatory = $true)]
[VMware.Hv.HostOrClusterTreeNode]$hoctn
)
if ($hoctn.container) {
foreach ($node in $hoctn.treeContainer.children) {
$id = Get-HVHostOrClusterID $node
if ($id -ne $null) {
return $id
}
}
} else {
if ($hoctn.info.path -eq $hostOrCluster -or $hoctn.info.name -eq $hostOrCluster) {
return $hoctn.info.id
}
}
return $null
}
function Get-HVResourcePoolID {
<#
.Synopsis
Recursive search for a Resource Pool within the results tree from ResourcePool_GetResourcePoolTree() and returns the ID
.NOTES
ResourcePool_GetResourcePoolTree() returns ResourcePoolInfo as below
ResourcePoolInfo.id Resource pool ID
ResourcePoolInfo.resourcePoolData
ResourcePoolInfo.resourcePoolData.name Resource pool name
ResourcePoolInfo.resourcePoolData.path Resource pool path
ResourcePoolInfo.resourcePoolData.type HOST_OR_CLUSTER, RESOURCE_POOL or OTHER
ResourcePoolInfo.children ResourcePoolInfo[] list of child nodes with potentially further child nodes
Author : Mark Elvers <mark.elvers@tunbury.org>
#>
param(
[Parameter(Mandatory = $true)]
[VMware.Hv.ResourcePoolInfo]$rpi
)
if ($rpi.resourcePoolData.path -eq $resourcePool -or $rpi.resourcePoolData.name -eq $resourcePool) {
return $rpi.id
}
foreach ($child in $rpi.children) {
$id = Get-HVResourcePoolID $child
if ($id -ne $null) {
return $id
}
}
return $null
}
function Get-HVAccessGroupID {
<#
.Synopsis
Recursive search for an Acess Group within the results tree from AccessGroup_List() and returns the ID
.NOTES
AccessGroup_List() returns AccessGroupInfo[] (a list of structures)
Iterate through the list of structures
AccessGroupInfo.id Access Group ID
AccessGroupInfo.base
AccessGroupInfo.base.name Access Group name
AccessGroupInfo.base.description Access Group description
AccessGroupInfo.base.parent Access Group parent ID
AccessGroupInfo.data
AccessGroupInfo.data.permissions PermissionID[]
AccessGroupInfo.children AccessGroupInfo[] list of child nodes with potentially further child nodes
I couldn't create a child node of a child node via the Horizon View Administrator GUI, but the this code allows that if it occurs
Furthermore, unless you are using the Root access group you must iterate over the children
Root -\
+- Access Group 1
+- Access Group 2
\- Access Group 3
Author : Mark Elvers <mark.elvers@tunbury.org>
#>
param(
[Parameter(Mandatory = $true)]
[VMware.Hv.AccessGroupInfo[]]$agi
)
foreach ($element in $agi) {
if ($element.base.name -eq $accessGroup) {
return $element.id
}
foreach ($child in $element.children) {
$id = Get-HVAccessGroupID $child
if ($id -ne $null) {
return $id
}
}
}
return $null
}
function Get-HVPoolStorageObject {
param(
[Parameter(Mandatory = $true)]
@@ -4874,7 +5077,7 @@ function Get-HVPoolStorageObject {
if ($persistentDiskStorageOvercommit -and ($persistentDiskDatastores.Length -ne $persistentDiskStorageOvercommit.Length) ) {
throw "Parameters persistentDiskDatastores length: [$persistentDiskDatastores.Length] and persistentDiskStorageOvercommit length: [$persistentDiskStorageOvercommit.Length] should be of same size"
}
$desktopPersistentDiskSettings.PersistentDiskDatastores = Get_Datastore -DatastoreInfoList $datastoreList -DatastoreNames $PersistentDiskDatastores -DsStorageOvercommit $persistentDiskStorageOvercommit
$desktopPersistentDiskSettings.PersistentDiskDatastores = Get-HVDatastore -DatastoreInfoList $datastoreList -DatastoreNames $PersistentDiskDatastores -DsStorageOvercommit $persistentDiskStorageOvercommit
}
$desktopNonPersistentDiskSettings.RedirectDisposableFiles = $redirectDisposableFiles
$desktopNonPersistentDiskSettings.DiskSizeMB = $nonPersistentDiskSizeMB
@@ -4927,15 +5130,16 @@ function Get-HVDatastore {
foreach ($ds in $datastoreNames) {
$datastoresSelected += ($datastoreInfoList | Where-Object { ($_.DatastoreData.Path -eq $ds) -or ($_.datastoredata.name -eq $ds) }).id
}
$Datastores = $null
if (! $DsStorageOvercommit) {
$DsStorageOvercommit += 'UNBOUNDED'
}
$Datastores = @()
$StorageOvercommitCnt = 0
foreach ($ds in $datastoresSelected) {
$myDatastores = New-Object VMware.Hv.DesktopVirtualCenterDatastoreSettings
$myDatastores.Datastore = $ds
$mydatastores.StorageOvercommit = $DsStorageOvercommit[$StorageOvercommitCnt]
if (! $DsStorageOvercommit) {
$mydatastores.StorageOvercommit = 'UNBOUNDED'
} else {
$mydatastores.StorageOvercommit = $DsStorageOvercommit[$StorageOvercommitCnt]
}
$Datastores += $myDatastores
$StorageOvercommitCnt++
}
@@ -5823,6 +6027,10 @@ function Set-HVPool {
[string]
$globalEntitlement,
[Parameter(Mandatory = $false)]
[string]
$ResourcePool,
[Parameter(Mandatory = $false)]
[boolean]$allowUsersToChooseProtocol,
@@ -5853,8 +6061,8 @@ function Set-HVPool {
}
if ($desktopPools) {
foreach ($desktopObj in $desktopPools) {
if (($Start -or $Stop) -and ("AUTOMATED" -ne $item.DesktopSummaryData.Type)) {
Write-Error "Start/Stop operation is not supported for Poll with name : [$item.DesktopSummaryData.Name]"
if (($Start -or $Stop) -and ("AUTOMATED" -ne $desktopObj.DesktopSummaryData.Type)) {
Write-Error "Start/Stop operation is not supported for Pool with name : [$desktopObj.DesktopSummaryData.Name]"
return
}
$poolList.add($desktopObj.id, $desktopObj.DesktopSummaryData.Name)
@@ -5887,9 +6095,9 @@ function Set-HVPool {
}
}
$updates = @()
if ($key -and $value) {
if ($PSBoundParameters.ContainsKey("key") -and $PSBoundParameters.ContainsKey("value")) {
$updates += Get-MapEntry -key $key -value $value
} elseif ($key -or $value) {
} elseif ($PSBoundParameters.ContainsKey("key") -or $PSBoundParameters.ContainsKey("value")) {
Write-Error "Both key:[$key] and value:[$value] needs to be specified"
}
if ($spec) {
@@ -5926,6 +6134,15 @@ function Set-HVPool {
$updates += Get-MapEntry -key 'desktopSettings.displayProtocolSettings.enableHTMLAccess' -value $enableHTMLAccess
}
if ($PSBoundParameters.ContainsKey("ResourcePool")) {
foreach ($item in $poolList.Keys) {
$pool = Get-HVPool -PoolName $poolList.$item
$ResourcePool_service_helper = New-Object VMware.Hv.ResourcePoolService
$ResourcePoolID = Get-HVResourcePoolID $ResourcePool_service_helper.ResourcePool_GetResourcePoolTree($services, $pool.AutomatedDesktopData.VirtualCenterProvisioningSettings.VirtualCenterProvisioningData.HostOrCluster)
$updates += Get-MapEntry -key 'automatedDesktopData.virtualCenterProvisioningSettings.virtualCenterProvisioningData.resourcePool' -value $ResourcePoolID
}
}
$info = $services.PodFederation.PodFederation_get()
if ($globalEntitlement -and ("ENABLED" -eq $info.localPodStatus.status)) {
$QueryFilterEquals = New-Object VMware.Hv.QueryFilterEquals
@@ -6797,25 +7014,39 @@ function Find-HVMachine {
$andFilter.Filters = $filterset
$query.Filter = $andFilter
}
$queryResults = $query_service_helper.QueryService_Query($services,$query)
$machineList = $queryResults.results
$machineList = @()
$GetNext = $false
$queryResults = $query_service_helper.QueryService_Create($services, $query)
do {
if ($GetNext) { $queryResults = $query_service_helper.QueryService_GetNext($services, $queryResults.id) }
$machineList += $queryResults.results
$GetNext = $true
} while ($queryResults.remainingCount -gt 0)
$query_service_helper.QueryService_Delete($services, $queryResults.id)
}
if ($wildcard -or [string]::IsNullOrEmpty($machineList)) {
$query.Filter = $null
$queryResults = $query_service_helper.QueryService_Query($services,$query)
$strFilterSet = @()
foreach ($setting in $machineSelectors.Keys) {
if ($null -ne $params[$setting]) {
if ($wildcard -and (($setting -eq 'MachineName') -or ($setting -eq 'DnsName')) ) {
$strFilterSet += '($_.' + $machineSelectors[$setting] + ' -like "' + $params[$setting] + '")'
} else {
$strFilterSet += '($_.' + $machineSelectors[$setting] + ' -eq "' + $params[$setting] + '")'
$machineList = @()
$GetNext = $false
$queryResults = $query_service_helper.QueryService_Create($services,$query)
do {
if ($GetNext) { $queryResults = $query_service_helper.QueryService_GetNext($services, $queryResults.id) }
$strFilterSet = @()
foreach ($setting in $machineSelectors.Keys) {
if ($null -ne $params[$setting]) {
if ($wildcard -and (($setting -eq 'MachineName') -or ($setting -eq 'DnsName')) ) {
$strFilterSet += '($_.' + $machineSelectors[$setting] + ' -like "' + $params[$setting] + '")'
} else {
$strFilterSet += '($_.' + $machineSelectors[$setting] + ' -eq "' + $params[$setting] + '")'
}
}
}
}
$whereClause = [string]::Join(' -and ', $strFilterSet)
$scriptBlock = [Scriptblock]::Create($whereClause)
$machineList = $queryResults.results | where $scriptBlock
$whereClause = [string]::Join(' -and ', $strFilterSet)
$scriptBlock = [Scriptblock]::Create($whereClause)
$machineList += $queryResults.results | where $scriptBlock
$GetNext = $true
} while ($queryResults.remainingCount -gt 0)
$query_service_helper.QueryService_Delete($services, $queryResults.id)
}
return $machineList
}
@@ -9591,5 +9822,4 @@ function Set-HVGlobalSettings {
}
}
Export-ModuleMember Add-HVDesktop,Add-HVRDSServer,Connect-HVEvent,Disconnect-HVEvent,Get-HVPoolSpec,Get-HVInternalName, Get-HVEvent,Get-HVFarm,Get-HVFarmSummary,Get-HVPool,Get-HVPoolSummary,Get-HVMachine,Get-HVMachineSummary,Get-HVQueryResult,Get-HVQueryFilter,New-HVFarm,New-HVPool,Remove-HVFarm,Remove-HVPool,Set-HVFarm,Set-HVPool,Start-HVFarm,Start-HVPool,New-HVEntitlement,Get-HVEntitlement,Remove-HVEntitlement, Set-HVMachine, New-HVGlobalEntitlement, Remove-HVGlobalEntitlement, Get-HVGlobalEntitlement, Get-HVPodSession, Set-HVApplicationIcon, Remove-HVApplicationIcon, Get-HVGlobalSettings, Set-HVGlobalSettings, Set-HVGlobalEntitlement
Export-ModuleMember Add-HVDesktop,Add-HVRDSServer,Connect-HVEvent,Disconnect-HVEvent,Get-HVPoolSpec,Get-HVInternalName, Get-HVEvent,Get-HVFarm,Get-HVFarmSummary,Get-HVPool,Get-HVPoolSummary,Get-HVMachine,Get-HVMachineSummary,Get-HVQueryResult,Get-HVQueryFilter,New-HVFarm,New-HVPool,Remove-HVFarm,Remove-HVPool,Set-HVFarm,Set-HVPool,Start-HVFarm,Start-HVPool,New-HVEntitlement,Get-HVEntitlement,Remove-HVEntitlement, Set-HVMachine, New-HVGlobalEntitlement, Remove-HVGlobalEntitlement, Get-HVGlobalEntitlement, Get-HVPodSession, Set-HVApplicationIcon, Remove-HVApplicationIcon, Get-HVGlobalSettings, Set-HVGlobalSettings, Set-HVGlobalEntitlement, Get-HVResourceStructure

Binary file not shown.

View File

@@ -0,0 +1,323 @@
Function Get-VMCCommand {
<#
.NOTES
===========================================================================
Created by: VMware
Date: 11/17/2017
Organization: VMware
Blog: http://vmware.com/go/powercli
Twitter: @powercli
===========================================================================
.SYNOPSIS
Returns all cmdlets for VMware Cloud on AWS
.DESCRIPTION
This cmdlet will allow you to return all cmdlets included in the VMC module
.EXAMPLE
Get-VMCCommand
.EXAMPLE
Get-Command -Module VMware.VMC
.NOTES
You can either use this cmdlet or the Get-Command cmdlet as seen in Example 2
#>
Get-command -Module VMware.VimAutomation.Vmc
Get-Command -Module VMware.VMC
}
Function Connect-VMCVIServer {
<#
.NOTES
===========================================================================
Created by: VMware
Date: 11/17/2017
Organization: VMware
Blog: http://vmware.com/go/powercli
Twitter: @powercli
===========================================================================
.SYNOPSIS
Cmdlet to connect to your VMC vCenter Server
.DESCRIPTION
This will connect you to both the VMC ViServer as well as the CiSServer at the same time.
.EXAMPLE
Connect-VMCVIServer -Server <VMC vCenter address> -User <Username> -Password <Password>
.NOTES
Easiest way is to pipe through your credentials from Get-VMCSDDCDefaultCredential
#>
Param (
[Parameter(Mandatory=$true)]$Org,
[Parameter(Mandatory=$true)]$Sddc,
[switch]$Autologin
)
If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect" } Else {
$creds = Get-VMCSDDCDefaultCredential -Org $Org -Sddc $Sddc
Write-Host "Connecting to VMC vCenter Server" $creds.vc_public_ip
Connect-VIServer -Server $creds.vc_public_ip -User $creds.cloud_username -Password $creds.cloud_password | Add-Member -MemberType Noteproperty -Name Location -Value "VMC"
Write-Host "Connecting to VMC CIS Endpoint" $creds.vc_public_ip
Connect-CisServer -Server $creds.vc_public_ip -User $creds.cloud_username -Password $creds.cloud_password | Add-Member -MemberType Noteproperty -Name Location -Value "VMC"
}
}
Function Get-VMCOrg {
<#
.NOTES
===========================================================================
Created by: VMware
Date: 11/17/2017
Organization: VMware
Blog: http://vmware.com/go/powercli
Twitter: @powercli
===========================================================================
.SYNOPSIS
Return the Orgs that you are a part of
.DESCRIPTION
Depending on what you've purchased, you may be a part of one or more VMC Orgs. This will return your orgs
.EXAMPLE
Get-VMCOrg
.EXAMPLE
Get-VMCOrg -Name <Org Name>
.NOTES
Return all the info about the orgs you are a part of
#>
Param (
[Parameter(Mandatory=$false)]$Name
)
If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use Connect-VMC to connect" } Else {
$orgService = Get-VMCService com.vmware.vmc.orgs
if ($PSBoundParameters.ContainsKey("Name")){
$orgs = $orgService.list() | Where {$_.display_name -match $Name}
} Else {
$orgs = $orgService.list()
}
$Orgs | Select display_name, name, user_name, created, id
}
}
Function Get-VMCSDDC {
<#
.NOTES
===========================================================================
Created by: VMware
Date: 11/17/2017
Organization: VMware
Blog: http://vmware.com/go/powercli
Twitter: @powercli
===========================================================================
.SYNOPSIS
Returns all of the SDDCs you are associated to
.DESCRIPTION
Returns all of the SDDCs ayou are associated to
.EXAMPLE
Get-VMCSDDC -Org <Org Name>
.EXAMPLE
Get-VMCSDDC -Name <SDDC Name> -Org <Org Name>
#>
Param (
[Parameter(Mandatory=$True)]$Org,
[Parameter(Mandatory=$false)]$Name
)
If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect" } Else {
if ($PSBoundParameters.ContainsKey("Org")){
$orgs = Get-VMCOrg -Name $Org
} else {
$orgs = Get-VMCOrg
}
foreach ($org in $orgs) {
$orgID = $org.ID
$sddcService = Get-VMCService com.vmware.vmc.orgs.sddcs
if ($PSBoundParameters.ContainsKey("Name")){
$sddcService.list($OrgID) | Where {$_.name -match $Name}
} Else {
$sddcService.list($OrgID)
}
}
}
}
Function Get-VMCTask {
<#
.NOTES
===========================================================================
Created by: VMware
Date: 11/17/2017
Organization: VMware
Blog: http://vmware.com/go/powercli
Twitter: @powercli
===========================================================================
.SYNOPSIS
Returns all of the VMC Tasks
.DESCRIPTION
Returns all of the VMC Tasks that have either occurred or are in process
.EXAMPLE
Get-VMCTask
#>
Param (
[Parameter(Mandatory=$True)]$Org
)
If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect" } Else {
if ($PSBoundParameters.ContainsKey("Org")){
$orgs = Get-VMCOrg -Name $Org
} else {
$orgs = Get-VMCOrg
}
foreach ($org in $orgs) {
$orgID = $org.ID
$taskService = Get-VMCService com.vmware.vmc.orgs.tasks
$taskService.list($OrgID) | Select * -ExcludeProperty Help
}
}
}
Function Get-VMCSDDCDefaultCredential {
<#
.NOTES
===========================================================================
Created by: VMware
Date: 11/17/2017
Organization: VMware
Blog: http://vmware.com/go/powercli
Twitter: @powercli
===========================================================================
.SYNOPSIS
Returns the default credential for the SDDC
.DESCRIPTION
Returns the default credential for the sddc
.EXAMPLE
Get-VMCSDDCDefaultCredential -Org <Org Name>
.EXAMPLE
Get-VMCSDDCDefaultCredential -Sddc <SDDC Name> -Org <Org Name>
#>
Param (
[Parameter(Mandatory=$true)]$Org,
[Parameter(Mandatory=$false)]$Sddc
)
If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect" } Else {
if ($PSBoundParameters.ContainsKey("Sddc")){
$sddcs = Get-VMCSDDC -Name $Sddc -Org $Org
} else {
$sddcs = Get-VMCSDDC -Org $Org
}
foreach ($sddc in $sddcs) {
$sddc.resource_config | Select-object vc_url, vc_management_ip, vc_public_ip, cloud_username, cloud_password
}
}
}
Function Get-VMCSDDCPublicIP {
<#
.NOTES
===========================================================================
Created by: VMware
Date: 11/17/2017
Organization: VMware
Blog: http://vmware.com/go/powercli
Twitter: @powercli
===========================================================================
.SYNOPSIS
Returns your Public IPs
.DESCRIPTION
Returns your Public IPs
.EXAMPLE
Get-VMCSDDCPublicIP -Org <Org Name>
.EXAMPLE
Get-VMCSDDCPublicIP -Sddc <SDDC Name> -Org <Org Name>
.NOTES
Return your Public IPs that you have assigned to your account
#>
Param (
[Parameter(Mandatory=$true)]$Org,
[Parameter(Mandatory=$false)]$Sddc
)
If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect" } Else {
if ($PSBoundParameters.ContainsKey("Sddc")){
$sddcs = Get-VMCSDDC -Name $Sddc -Org $Org
} else {
$sddcs = Get-VMCSDDC -Org $Org
}
foreach ($sddc in $sddcs) {
$sddc.resource_config.Public_ip_pool
}
}
}
Function Get-VMCVMHost {
Param (
[Parameter(Mandatory=$false)]$Sddc,
[Parameter(Mandatory=$true)]$Org
)
If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect" } Else {
if ($PSBoundParameters.ContainsKey("Sddc")){
$sddcs = Get-VMCSDDC -Name $Sddc -Org $Org
} else {
$sddcs = Get-VMCSDDC -Org $Org
}
$results = @()
foreach ($sddc in $sddcs) {
foreach ($vmhost in $sddc.resource_config.esx_hosts) {
$tmp = [pscustomobject] @{
esx_id = $vmhost.esx_id;
name = $vmhost.name;
hostname = $vmhost.hostname;
esx_state = $vmhost.esx_state;
sddc_id = $sddc.id;
org_id = $sddc.org_id;
}
$results += $tmp
}
$results
}
}
}
Function Get-VMCSDDCVersion {
<#
.NOTES
===========================================================================
Created by: VMware
Date: 11/17/2017
Organization: VMware
Blog: http://vmware.com/go/powercli
Twitter: @powercli
===========================================================================
.SYNOPSIS
Returns SDDC Version
.DESCRIPTION
Returns Version of the SDDC
.EXAMPLE
Get-VMCSDDCVersion -Name <SDDC Name> -Org <Org Name>
#>
Param (
[Parameter(Mandatory=$True)]$Org,
[Parameter(Mandatory=$false)]$Name
)
If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect" } Else {
if ($PSBoundParameters.ContainsKey("Org")){
$orgs = Get-VMCOrg -Name $Org
} else {
$orgs = Get-VMCOrg
}
foreach ($org in $orgs) {
$orgID = $org.ID
$sddcService = Get-VMCService com.vmware.vmc.orgs.sddcs
if ($PSBoundParameters.ContainsKey("Name")){
($sddcService.list($OrgID) | Where {$_.name -match $Name}).resource_config.sddc_manifest | Select *version
} Else {
($sddcService.list($OrgID)).resource_config.sddc_manifest | Select *version
}
}
}
}
Export-ModuleMember -Function 'Get-VMCCommand', 'Connect-VMCVIServer', 'Get-VMCOrg', 'Get-VMCSDDC', 'Get-VMCTask', 'Get-VMCSDDCDefaultCredential', 'Get-VMCSDDCPublicIP', 'Get-VMCVMHost', 'Get-VMCSDDCVersion'

View File

@@ -882,7 +882,7 @@ Function Set-VMEncryptionKey {
C:\PS>$VM|Set-VMEncryptionKey -KMSClusterId $KMSCluster.Id -Deep
Deep rekeys the VM Home and all its disks using a new key.
The key is generted from the KMS whose clusterId is $KMSCluster.Id.
The key is generated from the KMS whose clusterId is $KMSCluster.Id.
.NOTES
This cmdlet assumes there is already a KMS in vCenter Server. If VM is not encrypted, the cmdlet quits.
@@ -1037,7 +1037,7 @@ Function Set-VMDiskEncryptionKey {
C:\PS>$HardDisk| Set-VMDiskEncryptionKey -VM $VM -KMSClusterId $KMSCluster.Id -Deep
Deep rekeys all the disks of the $VM using a new key.
The key is generted from the KMS whose clusterId is $KMSCluster.Id.
The key is generated from the KMS whose clusterId is $KMSCluster.Id.
.NOTES
This cmdlet assumes there is already a KMS in vCenter Server.

View File

@@ -0,0 +1,17 @@
# Fetch Cis Server hostname and credentials
.\CisConfig.ps1
Connect-rCisServer -Server $cisServer -User $cisUser -Password $cisPswd
# Get Tag information
Get-rCisTag
# Get Tag Category information
Get-rCisTagCategory
# Get Tag Assignment information
Get-rCisTagAssignment
Disconnect-rCisServer -Server $cisServer -Confirm:$false

View File

@@ -0,0 +1,14 @@
# Fetch Cis Server hostname and credentials
.\CisConfig.ps1
Connect-rCisServer -Server $cisServer -User $cisUser -Password $cisPswd
New-rCisTagCategory -Name MyCat1 -Cardinality Single -Description 'Test Tag Category' -EntityType 'VirtualMachine'
New-rCisTag -Name MyTag1 -Category MyCat1 -Description 'Test Tag'
$vm = Get-VM | Get-Random
New-rCisTagAssignment -Entity $vm -Tag MyTag1
Get-rCisTagAssignment -Tag MyTag1
Disconnect-rCisServer -Server $cisServer -Confirm:$false

View File

@@ -0,0 +1,11 @@
# Fetch Cis Server hostname and credentials
.\CisConfig.ps1
Connect-rCisServer -Server $cisServer -User $cisUser -Password $cisPswd
Get-rCisTag -Name MyTag1 | Set-rCisTag -Name MyNewTag1 -Description 'Name changed'
Get-rCisTagCategory -Name MyCat1 | Set-rCisTagCategory -Cardinality Multiple -Name MyNewCat1 -Description 'Name changed'
Disconnect-rCisServer -Server $cisServer -Confirm:$false

View File

@@ -0,0 +1,13 @@
# Fetch Cis Server hostname and credentials
.\CisConfig.ps1
Connect-rCisServer -Server $cisServer -User $cisUser -Password $cisPswd
Get-rCisTagAssignment -Tag MyNewTag1 | Remove-rCisTagAssignment -Confirm:$false
Get-rCisTag -Name MyNewTag1 | Remove-rCisTag -Confirm:$false
Get-rCisTagCategory -Name MyNewCat1 | Remove-rCisTagCategory -Confirm:$false
Disconnect-rCisServer -Server $cisServer -Confirm:$false

View File

@@ -0,0 +1,20 @@
# Fetch Cis Server hostname and credentials
.\CisConfig.ps1
Connect-rCisServer -Server $cisServer -User $cisUser -Password $cisPswd
$catName = 'Homelab'
# Clean up
Get-rCisTagCategory -Name $catName | Remove-rCisTagCategory -Confirm:$false
# Tag all datastores with their type
New-rCisTagCategory -Name HomeLab -Description 'Homelab datastores' -Cardinality Single -EntityType 'Datastore' |
New-rCisTag -Name 'VMFS','NFS' -Description 'Datastore type'
Get-Cluster -Name Cluster1 | Get-Datastore | %{
New-rCisTagAssignment -Entity $_ -Tag "$($_.Type)"
}
Disconnect-rCisServer -Server $cisServer -Confirm:$false

View File

@@ -0,0 +1,3 @@
$cisServer = 'vcsa.my.domain'
$cisUser = 'administrator@vsphere.local'
$cisPswd = 'VMware1!'

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) since 2015 Luc Dekens, Matt Boren
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

15
Modules/rCisTag/README.md Normal file
View File

@@ -0,0 +1,15 @@
# rCisTag
A module with cmdlets to provide CRUD functions to
* Tags
* Tag Categories
* Tag Assignments
The cmdlets use the Cis REST API
## History
* Author : **Luc Dekens**
* Release :
* **0.9.0** First draft

View File

@@ -0,0 +1,26 @@
TOPIC
about_rCISTag
SHORT DESCRIPTION
The rCisTag module provides CRUD functions to work with vSphere Tags
LONG DESCRIPTION
The CisTag module provides CRUD functions to work with vSphere Tags.
The functions in the module are based on the REST API
NOTE
The module requires PowerShell 5.0
TROUBLESHOOTING NOTE
EXAMPLES
Get-rCisTag
KEYWORDS
SEE ALSO
Place related topics here.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -0,0 +1,821 @@
function Disable-SSLValidation{
<#
.SYNOPSIS
Disables SSL certificate validation
.DESCRIPTION
Disable-SSLValidation disables SSL certificate validation by using reflection to implement the System.Net.ICertificatePolicy class.
Author: Matthew Graeber (@mattifestation)
License: BSD 3-Clause
.NOTES
Reflection is ideal in situations when a script executes in an environment in which you cannot call csc.ese to compile source code. If compiling code is an option, then implementing System.Net.ICertificatePolicy in C# and Add-Type is trivial.
.LINK
http://www.exploit-monday.com
#>
Set-StrictMode -Version 2
# You have already run this function
if ([System.Net.ServicePointManager]::CertificatePolicy.ToString() -eq 'IgnoreCerts') { Return }
$Domain = [AppDomain]::CurrentDomain
$DynAssembly = New-Object System.Reflection.AssemblyName('IgnoreCerts')
$AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, [System.Reflection.Emit.AssemblyBuilderAccess]::Run)
$ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('IgnoreCerts', $false)
$TypeBuilder = $ModuleBuilder.DefineType('IgnoreCerts', 'AutoLayout, AnsiClass, Class, Public, BeforeFieldInit', [System.Object], [System.Net.ICertificatePolicy])
$TypeBuilder.DefineDefaultConstructor('PrivateScope, Public, HideBySig, SpecialName, RTSpecialName') | Out-Null
$MethodInfo = [System.Net.ICertificatePolicy].GetMethod('CheckValidationResult')
$MethodBuilder = $TypeBuilder.DefineMethod($MethodInfo.Name, 'PrivateScope, Public, Virtual, HideBySig, VtableLayoutMask', $MethodInfo.CallingConvention, $MethodInfo.ReturnType, ([Type[]] ($MethodInfo.GetParameters() | % {$_.ParameterType})))
$ILGen = $MethodBuilder.GetILGenerator()
$ILGen.Emit([Reflection.Emit.Opcodes]::Ldc_I4_1)
$ILGen.Emit([Reflection.Emit.Opcodes]::Ret)
$TypeBuilder.CreateType() | Out-Null
# Disable SSL certificate validation
[System.Net.ServicePointManager]::CertificatePolicy = New-Object IgnoreCerts
}
function Invoke-vCisRest{
param (
[String]$Method,
[String]$Request,
[PSObject]$Body
)
Process
{
Write-Verbose -Message "$($MyInvocation.MyCommand.Name)"
Write-Verbose -Message "`t$($PSCmdlet.ParameterSetName)"
Write-Verbose -Message "`tCalled from $($stack = Get-PSCallStack; $stack[1].Command) at $($stack[1].Location)"
Disable-SSLValidation
$sRest = @{
Uri = "https:/",$Script:CisServer.Server,'rest',$Request -join '/'
Method = $Method
# Body = &{if($Body){$Body}}
Body = &{if($Body){$Body | ConvertTo-Json -Depth 32}}
ContentType = 'application/json'
Headers = &{
if($Script:CisServer.ContainsKey('vmware-api-session-id')){
@{
'vmware-api-session-id' = "$($Script:CisServer.'vmware-api-session-id')"
}
}
else{
@{
Authorization = "$($Script:CisServer.AuthHeader)"
}
}
}
}
Try
{
# $result = Invoke-WebRequest @sRest
$result = Invoke-RestMethod @sRest
}
Catch
{
}
$result
}
}
function Connect-rCisServer{
[CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Low')]
param (
[Parameter(Mandatory, Position = 1)]
[String]$Server,
[Parameter(Mandatory = $True,ValueFromPipeline = $True, Position = 2, ParameterSetName = 'Credential')]
[System.Management.Automation.PSCredential]$Credential,
[Parameter(Mandatory = $True, Position = 2, ParameterSetName = 'PlainText')]
[String]$User,
[Parameter(Mandatory = $True, Position = 3, ParameterSetName = 'PlainText')]
[String]$Password,
[string]$Proxy,
[Parameter(DontShow)]
[switch]$Fiddler = $false
)
Process
{
if ($Proxy)
{
if ($PSDefaultParameterValues.ContainsKey('*:Proxy'))
{
$PSDefaultParameterValues['*:Proxy'] = $Proxy
}
else
{
$PSDefaultParameterValues.Add('*:Proxy', $Proxy)
}
if ($PSDefaultParameterValues.ContainsKey('*:ProxyUseDefaultCredentials'))
{
$PSDefaultParameterValues['*:ProxyUseDefaultCredentials'] = $True
}
else
{
$PSDefaultParameterValues.Add('*:ProxyUseDefaultCredentials', $True)
}
}
if ($PSCmdlet.ParameterSetName -eq 'PlainText')
{
$sPswd = ConvertTo-SecureString -String $Password -AsPlainText -Force
$CisCredential = New-Object System.Management.Automation.PSCredential -ArgumentList ($User, $sPswd)
}
if ($PSCmdlet.ParameterSetName -eq 'Credential')
{
$CisCredential = $Credential
}
if ($Fiddler)
{
if (Get-Process -Name fiddler -ErrorAction SilentlyContinue)
{
if ($PSDefaultParameterValues.ContainsKey('Invoke-RestMethod:Proxy'))
{
$PSDefaultParameterValues['Invoke-RestMethod:Proxy'] = 'http://127.0.0.1:8888'
}
else
{
$PSDefaultParameterValues.Add('Invoke-RestMethod:Proxy', 'http://127.0.0.1:8888')
}
}
}
$Script:CisServer = @{
Server = $Server
AuthHeader = &{
$User = $CisCredential.UserName
$Password = $CisCredential.GetNetworkCredential().password
$Encoded = [System.Text.Encoding]::UTF8.GetBytes(($User, $Password -Join ':'))
$EncodedPassword = [System.Convert]::ToBase64String($Encoded)
"Basic $($EncodedPassword)"
}
}
$sRest = @{
Method = 'Post'
Request = 'com/vmware/cis/session'
}
If($PSCmdlet.ShouldProcess("CisServer $($Server)"))
{
$result = Invoke-vCisRest @sRest
$Script:CisServer.Add('vmware-api-session-id',$result.value)
$Script:CisServer.Remove('AuthHeader')
}
}
}
function Disconnect-rCisServer{
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'High')]
param (
[Parameter(Mandatory = $True, Position = 1)]
[String]$Server
)
Process
{
if($Server -ne $Script:CisServer.Server){
Write-Warning "You are not connected to server $($Server)"
}
$sRest = @{
Method = 'Delete'
Request = 'com/vmware/cis/session'
}
If($PSCmdlet.ShouldProcess("CisServer $($Server)"))
{
$result = Invoke-vCisRest @sRest
$Script:CisServer.Remove('vmware-api-session-id')
}
}
}
function Get-rCisTag{`
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'Low', DefaultParameterSetName='Name')]
param (
[Parameter(Position = 1, ParameterSetName='Name')]
[String[]]$Name,
[Parameter(Position = 2, ParameterSetName='Name',ValueFromPipeline = $true)]
[PSObject[]]$Category,
[Parameter(Mandatory = $True, Position = 1, ParameterSetName='Id')]
[String[]]$Id
)
Process
{
if($PSCmdlet.ParameterSetName -eq 'Name'){
if($Category){
$tagIds = $Category | %{
$categoryIds = &{if($_ -is [string]){
(Get-rCisTagCategory -Name $_).Id
}
else{
$_.Id
}}
$categoryIds | %{
# Get all tags in categories
$sRest = @{
Method = 'Post'
Request = "com/vmware/cis/tagging/tag/id:$([uri]::EscapeDataString($_))?~action=list-tags-for-category"
}
(Invoke-vCisRest @sRest).value
}
}
}
else{
$sRest = @{
Method = 'Get'
Request = 'com/vmware/cis/tagging/tag'
}
$tagIds = (Invoke-vCisRest @sRest).value
}
}
else{
$tagIds = $Id
}
# Get category details
$out = @()
$tagIds | where{($PSCmdlet.ParameterSetName -eq 'Id' -and $Id -contains $_) -or $PSCmdlet.ParameterSetName -eq 'Name'} | %{
$sRest = @{
Method = 'Get'
Request = "com/vmware/cis/tagging/tag/id:$([uri]::EscapeDataString($_))"
}
$result = Invoke-vCisRest @sRest
if($PSCmdlet.ParameterSetName -eq 'Id' -or ($PSCmdlet.ParameterSetName -eq 'Name' -and ($Name -eq $null -or $Name -contains $result.value.name))){
$out += New-Object PSObject -Property @{
Description = $result.value.description
Id = $result.value.id
Name = $result.value.name
Category = (Get-rCisTagCategory -Id $result.value.category_id).Name
Uid = "$($global:defaultviserver.Id)Tag=$($result.value.id)/"
Client = $global:defaultviserver.Client
}
}
}
$out | Select-Object Category,Description,Id,Name,Uid,Client
}
}
function Get-rCisTagCategory{
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'Low', DefaultParameterSetName='Name')]
param (
[Parameter(Position = 1, ParameterSetName='Name')]
[String[]]$Name,
[Parameter(Mandatory = $True, Position = 1, ParameterSetName='Id')]
[String[]]$Id
)
Begin
{
$txtInfo = (Get-Culture).TextInfo
$entityTab = @{
'ClusterComputeResource' = 'Cluster'
'DistributedVirtualSwitch' = 'DistributedSwitch'
'VmwareDistributedVirtualSwitch' = 'DistributedSwitch'
'HostSystem' = 'VMHost'
'DistributedVirtualPortGroup' = 'DistributedPortGroup'
'VirtualApp' = 'VApp'
'StoragePod' = 'DatastoreCluster'
'Network' = 'VirtualPortGroup'
}
}
Process
{
if($PSCmdlet.ParameterSetName -eq 'Name'){
# Get all categories
$sRest = @{
Method = 'Get'
Request = 'com/vmware/cis/tagging/category'
}
$tagCategoryIds = (Invoke-vCisRest @sRest).value
}
else{
$tagCategoryIds = $Id
}
# Get category details
$out = @()
$tagCategoryids | where{($PSCmdlet.ParameterSetName -eq 'Id' -and $Id -contains $_) -or $PSCmdlet.ParameterSetName -eq 'Name'} | %{
$sRest = @{
Method = 'Get'
Request = "com/vmware/cis/tagging/category/id:$([uri]::EscapeDataString($_))"
}
$result = Invoke-vCisRest @sRest
if($PSCmdlet.ParameterSetName -eq 'Id' -or ($PSCmdlet.ParameterSetName -eq 'Name' -and ($Name -eq $null -or $Name -contains $result.value.name))){
$out += New-Object PSObject -Property @{
Description = $result.value.description
Cardinality = $txtInfo.ToTitleCase($result.value.cardinality.ToLower())
EntityType = @(&{
if($result.value.associable_types.Count -eq 0){'All'}
else{
$result.value.associable_types | %{
if($entityTab.ContainsKey($_)){
$entityTab.Item($_)
}
else{$_}
}
}} | Sort-Object -Unique)
Id = $result.value.id
Name = $result.value.name
Uid = "$($global:defaultviserver.Id)TagCategory=$($result.value.id)/"
Client = $global:defaultviserver.Client
}
}
}
$out | Select-Object Description,Cardinality,EntityType,Id,Name,Uid,Client
}
}
function Get-rCisTagAssignment{
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'Low')]
param (
[parameter(Position = 1, ValueFromPipeline = $true)]
[PSObject[]]$Entity,
[parameter(Position = 2)]
[PSObject[]]$Tag,
[parameter(Position = 3)]
[PSObject[]]$Category
)
Begin
{
if($Category.Count -ne 0 -or $Tag.Count -ne 0){
$tagIds = @((Get-rCisTag -Name $Tag -Category $Category).Id)
}
else{
$tagIds = @((Get-rCisTag).Id)
}
$out = @()
}
Process
{
foreach($ent in $Entity){
if($ent -is [string]){
$ent = Get-Inventory -Name $ent -ErrorAction SilentlyContinue
}
$entMoRef = New-Object PSObject -Property @{
type = $ent.ExtensionData.MoRef.Type
id = $ent.ExtensionData.MoRef.Value
}
$sRest = @{
Method = 'Post'
Request = 'com/vmware/cis/tagging/tag-association?~action=list-attached-tags-on-objects'
Body = @{
object_ids = @($entMoRef)
}
}
$tagObj = (Invoke-vCisRest @sRest).value
foreach($obj in @($tagObj)){
foreach($tag in ($obj.tag_ids | where{$tagIds -contains $_})){
$sMoRef = "$($obj.object_id.type)-$($obj.object_id.id)"
$out += New-Object PSObject -Property @{
Entity = (Get-View -id $sMoRef -Property Name).Name
Tag = (Get-rCisTag -Id $tag).Name
Id = 'com.vmware.cis.tagging.TagAssociationModel'
Name = 'com.vmware.cis.tagging.TagAssociationModel'
Uid = "$($global:defaultviserver.Id)VirtualMachine=$($sMoRef)/TagAssignment=/Tag=$($tag.tag_id)/"
Client = $global:defaultviserver.Client
}
}
}
}
}
End
{
if($out.Count -eq 0)
{
$sRest = @{
Method = 'Post'
Request = 'com/vmware/cis/tagging/tag-association?~action=list-attached-objects-on-tags'
Body = @{
tag_ids = $tagIds
}
}
$tagObj = (Invoke-vCisRest @sRest).value
$out = foreach($tag in @(($tagObj | where{$tagIds -contains $_.tag_id}))){
foreach($obj in $tag.object_ids){
$sMoRef = "$($obj.type)-$($obj.id)"
New-Object PSObject -Property @{
Entity = (Get-View -id $sMoRef -Property Name).Name
Tag = (Get-rCisTag -Id $tag.tag_id).Name
Id = 'com.vmware.cis.tagging.TagAssociationModel'
Name = 'com.vmware.cis.tagging.TagAssociationModel'
Uid = "$($global:defaultviserver.Id)VirtualMachine=$($sMoRef)/TagAssignment=/Tag=$($tag.tag_id)/"
Client = $global:defaultviserver.Client
}
}
}
}
$out | Select-Object Uid,Tag,Entity,Id,Name,Client
}
}
function New-rCisTag{
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'High')]
param (
[Parameter(Mandatory=$true, Position = 1)]
[String[]]$Name,
[Parameter(Mandatory=$true, Position = 2,ValueFromPipeline = $true)]
[PSObject]$Category,
[Parameter(Position = 3)]
[string]$Description
)
Process
{
$out = @()
if($Category -is [String]){
$Category = Get-rCisTagCategory -Name $Category
}
$Name | %{
$sRest = @{
Method = 'Post'
Request = 'com/vmware/cis/tagging/tag'
Body = @{
create_spec = @{
category_id = $Category.Id
name = $_
description = $Description
}
}
}
$tagId = (Invoke-vCisRest @sRest).value
$out += New-Object PSObject -Property @{
Category = $Category.Name
Description = $Description
Id = $tagId
Name = $_
Uid = "$($global:defaultviserver.Id)Tag=$($tagId)/"
Client = $global:defaultviserver.Client
}
}
$out | Select-Object Category,Description,Id,Name,Uid,Client
}
}
function New-rCisTagCategory{
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'High')]
param (
[Parameter(Mandatory=$true, Position = 1)]
[String[]]$Name,
[Parameter(Position = 2)]
[ValidateSet('Single','Multiple')]
[string]$Cardinality = 'Single',
[Parameter(Position = 3)]
[string]$Description,
[Parameter(Position = 4)]
[string[]]$EntityType
)
Process
{
$out = @()
$Name | %{
$sRest = @{
Method = 'Post'
Request = 'com/vmware/cis/tagging/category'
Body = @{
create_spec = @{
cardinality = $Cardinality.ToUpper()
associable_types = @($EntityType)
name = $_
description = $Description
}
}
}
$categoryId = (Invoke-vCisRest @sRest).value
$out += New-Object PSObject -Property @{
Description = $Description
Cardinality = $Cardinality
EntityType = @($EntityType)
Id = $categoryId
Name = $_
Uid = "$($global:defaultviserver.Id)TagCategory=$($categoryId)/"
Client = $global:defaultviserver.Client
}
}
$out | Select-Object Description,Cardinality,EntityType,Id,Name,Uid,Client
}
}
function New-rCisTagAssignment{
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'High')]
param (
[Parameter(Mandatory=$true, Position = 1)]
[String[]]$Tag,
[Parameter(Mandatory=$true,ValueFromPipeline = $true, Position = 2)]
[PSObject[]]$Entity
)
Process
{
$tagIds = @((Get-rCisTag -Name $Tag).Id)
$Entity = foreach($ent in $Entity){
if($ent -is [string]){
$ent = Get-Inventory -Name $ent -ErrorAction SilentlyContinue
}
$entMoRef = New-Object PSObject -Property @{
type = $ent.ExtensionData.MoRef.Type
id = $ent.ExtensionData.MoRef.Value
}
foreach($tagId in $tagIds){
$sRest = @{
Method = 'Post'
Request = "com/vmware/cis/tagging/tag-association/id:$($tagId)?~action=attach"
Body = @{
object_id = $entMoRef
}
}
Invoke-vCisRest @sRest
}
}
}
# foreach($ent in
# if($Tag.Count -eq 1)
# {
# $tagId = (Get-rCisTag -Name $Tag).Id
# }
# elseif($Tag.Count -gt 1)
# {
# $tagIds = (Get-rCisTag -Name $Tag).Id
# }
# $Entity = foreach($ent in $Entity){
# if($ent -is [string]){
# Get-Inventory -Name $ent -ErrorAction SilentlyContinue
# }
# else{$ent}
# }
#
# if($Entity.Count -eq 1)
# {
# $entMoRef = New-Object PSObject -Property @{
# type = $Entity[0].ExtensionData.MoRef.Type
# id = $Entity[0].ExtensionData.MoRef.Value
# }
# if($tag.Count -eq 1){
# $sRest = @{
# Method = 'Post'
# Request = "com/vmware/cis/tagging/tag-association/id:$($tagId)?~action=attach"
# Body = @{
# object_id = $entMoRef
# }
# }
# Invoke-vCisRest @sRest
# }
# elseif($Tag.Count -gt 1){
# $sRest = @{
# Method = 'Post'
# Request = 'com/vmware/cis/tagging/tagassociation?~action=attach-multiple-tags-to-object'
# Body = @{
# object_id = $entMoRef
# tag_ids = @($tagIds)
# }
# }
# Invoke-vCisRest @sRest
# }
# }
# elseif($Entity.Count -gt 1)
# {
# $entMorefs = $Entity | %{
# New-Object PSObject -Property @{
# type = $_.ExtensionData.MoRef.Type
# id = $_.ExtensionData.MoRef.Value
# }
# }
# if($tag.Count -eq 1){
# $sRest = @{
# Method = 'Post'
# Request = 'com/vmware/cis/tagging/tagassociation/id:$($tagId)?~action=attach-tag-to-multiple-objects'
# Body = @{
# objects_ids = @($entMoRefs)
# tag_id = $tagId
# }
# }
# Invoke-vCisRest @sRest
# }
# elseif($Tag.Count -gt 1){
# $tagIds | %{
# $sRest = @{
# Method = 'Post'
# Request = 'com/vmware/cis/tagging/tagassociation/id:$($tagId)?~action=attach-tag-to-multiple-objects'
# Body = @{
# objects_ids = @($entMoRefs)
# tag_id = $_
# }
# }
# Invoke-vCisRest @sRest
# }
# }
# }
# }
}
function Remove-rCisTag{
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'High', DefaultParameterSetName='Name')]
param (
[Parameter(Mandatory=$true, Position = 1, ValueFromPipeline = $true,ParameterSetName='Name')]
[PSObject[]]$Tag,
[Parameter(Mandatory=$true, Position = 1, ValueFromPipelineByPropertyName = $true,ParameterSetName='Id')]
[String[]]$Id
)
Process
{
if($PSCmdlet.ParameterSetName -eq 'Name'){
foreach($tagObj in $Tag){
if($tagObj -is [string]){
$tagObj = Get-rCisTag -Name $tagObj
}
$sRest = @{
Method = 'Delete'
Request = "com/vmware/cis/tagging/tag/id:$($tagObj.Id)"
}
Invoke-vCisRest @sRest
}
}
else{
foreach($tagId in $Id){
$sRest = @{
Method = 'Delete'
Request = "com/vmware/cis/tagging/tag/id:$($tagId)"
}
Invoke-vCisRest @sRest
}
}
}
}
function Remove-rCisTagCategory{
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'High', DefaultParameterSetName='Name')]
param (
[Parameter(Mandatory=$true,Position = 1, ValueFromPipeline = $true,ParameterSetName='Name')]
[PSObject[]]$Category,
[Parameter(Mandatory=$true,Position = 1, ValueFromPipelineByPropertyName = $true,ParameterSetName='Id')]
[String[]]$Id
)
Process
{
if($PSCmdlet.ParameterSetName -eq 'Name'){
foreach($catObj in $Category){
if($catObj -is [string]){
$catObj = Get-rCisTagCategory -Name $catObj
}
$sRest = @{
Method = 'Delete'
Request = "com/vmware/cis/tagging/category/id:$($catObj.Id)"
}
Invoke-vCisRest @sRest
}
}
else{
foreach($catId in $Id){
$sRest = @{
Method = 'Delete'
Request = "com/vmware/cis/tagging/category/id:$($catId)"
}
Invoke-vCisRest @sRest
}
}
}
}
function Remove-rCisTagAssignment{
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'High',DefaultParameterSetName='Assignment')]
param (
[Parameter(Mandatory=$true, Position = 1, ValueFromPipeline = $true,ParameterSetName='Assignment')]
[PSObject[]]$TagAssignment,
[Parameter(Mandatory=$true,Position = 1, ValueFromPipeline = $true,ParameterSetName='Name')]
[string[]]$Tag,
[Parameter(Position = 2, ParameterSetName='Name')]
[string[]]$Category,
[Parameter(Mandatory=$true, ValueFromPipelineByPropertyName = $true,ParameterSetName='Id')]
[string[]]$TagId,
[Parameter(ParameterSetName='Name')]
[Parameter(ParameterSetName='Id')]
[PSObject[]]$Entity
)
Process
{
switch ($PSCmdlet.ParameterSetName){
'Name' {
$TagAssignment = Get-rCisTagAssignment -Entity $Entity -Tag $Tag -Category $Category
}
'Id' {
$tags = Get-rCisTag -Id $TagId
$TagAssignment = Get-rCisTagAssignment -Tag $tags.Name -Entity $Entity
}
}
if($TagAssignment){
$entMoRefs = @(Get-Inventory -Name $TagAssignment.Entity -ErrorAction SilentlyContinue | %{
New-Object PSObject -Property @{
type = $_.ExtensionData.MoRef.Type
id = $_.ExtensionData.MoRef.Value
}
})
$tagIds = @((Get-rCisTag -Name $TagAssignment.Tag).Id)
}
foreach($entMoRef in $entMoRefs){
foreach($tId in $tagIds){
$sRest = @{
Method = 'Post'
Request = "com/vmware/cis/tagging/tag-association/id:$($tId)?~action=detach"
Body = @{
object_id = $entMoRef
}
}
Invoke-vCisRest @sRest
}
}
}
}
function Set-rCisTag{
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'High')]
param (
[Parameter(Mandatory=$true, Position = 1, ValueFromPipeline = $true)]
[PSObject[]]$Tag,
[Parameter(Position = 2)]
[string]$Name,
[Parameter(Position = 3)]
[string]$Description
)
Process
{
foreach($tagObj in $Tag){
if($tagObj -is [string]){
$tagObj = Get-rCisTag -Name $tagObj
}
$sRest = @{
Method = 'Patch'
Request = "com/vmware/cis/tagging/tag/id:$($tagObj.Id)"
Body = @{
update_spec = @{
name = $Name
description = $Description
}
}
}
Invoke-vCisRest @sRest
}
}
}
function Set-rCisTagCategory{
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'High')]
param (
[Parameter(Mandatory=$true, Position = 1, ValueFromPipeline = $true)]
[PSObject[]]$Category,
[Parameter(Position = 2)]
[string]$Name,
[Parameter(Position = 3)]
[ValidateSet('Single','Multiple')]
[string]$Cardinality, # Only SINGLE to MULTIPLE
# [string[]]$AddEntityType, # Does not work
[string]$Description
)
Process
{
foreach($catObj in $Category){
if($catObj -is [string]){
$catObj = Get-rCisTagCategory -Name $catObj
}
$sRest = @{
Method = 'Patch'
Request = "com/vmware/cis/tagging/category/id:$($catObj.Id)"
Body = @{
update_spec = @{
}
}
}
if($Name){
$sRest.Body.update_spec.Add('name',$Name)
}
if($Description){
$sRest.Body.update_spec.Add('description',$Description)
}
if($Cardinality -and $catObj.Cardinality -eq 'SINGLE'){
$sRest.Body.update_spec.Add('cardinality',$Cardinality.ToUpper())
}
if($Name -or $Description -or $Cardinality){
Invoke-vCisRest @sRest
}
}
}
}

View File

@@ -0,0 +1,475 @@
Function Export-DRSRules {
<#
.NOTES
===========================================================================
Created by: William Lam
Date: 11/21/2017
Blog: https://www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.SYNOPSIS
Export DRS Rules to JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
.DESCRIPTION
Export DRS Rules to JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
.EXAMPLE
Export-DRSRules -Path C:\Users\primp\Desktop\VMworld2017 -Cluster Windows-Cluster
#>
param(
[Parameter(Mandatory=$false)][String]$Path,
[Parameter(Mandatory=$true)][String]$Cluster
)
$rules = Get-Cluster -Name $Cluster | Get-DrsRule
$results = @()
foreach ($rule in $rules) {
$vmNames = @()
$vmIds = $rule.VMIds
# Reconstruct MoRef ID to VM Object to get Name
foreach ($vmId in $vmIds) {
$vm = New-Object VMware.Vim.ManagedObjectReference
$vm.Type = "VirtualMachine"
$vm.Value = ($vmId -replace "VirtualMachine-","")
$vmView = Get-View $vm
$vmNames += $vmView.name
}
$rulesObject = [pscustomobject] @{
Name = $rule.ExtensionData.Name;
Type = $rule.Type; #VMAffinity = 1, VMAntiAffinity = 0
Enabled = $rule.Enabled;
Mandatory = $rule.ExtensionData.Mandatory
VM = $vmNames
}
$results+=$rulesObject
}
if($Path) {
$fullPath = $Path + "\DRSRules.json"
Write-Host -ForegroundColor Green "Exporting DRS Rules to $fullpath ..."
$results | ConvertTo-Json | Out-File $fullPath
} else {
$results | ConvertTo-Json
}
}
Function Import-DRSRules {
<#
.NOTES
===========================================================================
Created by: William Lam
Date: 11/21/2017
Blog: https://www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.SYNOPSIS
Import DRS Rules from JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
.DESCRIPTION
Import DRS Rules from JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
.EXAMPLE
Import-DRSRules -Path C:\Users\primp\Desktop\VMworld2017 -Cluster Windows-Cluster
#>
param(
[Parameter(Mandatory=$true)][String]$Path,
[Parameter(Mandatory=$true)][String]$Cluster
)
Get-DrsRule -Cluster $cluster | Remove-DrsRule -Confirm:$false | Out-Null
$DRSRulesFilename = "/DRSRules.json"
$fullPath = $Path + $DRSRulesFilename
$json = Get-Content -Raw $fullPath | ConvertFrom-Json
foreach ($line in $json) {
$vmArr = @()
$vmNames = $line.vm
foreach ($vmName in $vmNames) {
$vmView = Get-VM -Name $vmName
$vmArr+=$vmView
}
New-DrsRule -Name $line.name -Enabled $line.Enabled -Cluster (Get-Cluster -Name $Cluster) -KeepTogether $line.Type -VM $vmArr
}
}
Function Export-DRSClusterGroup {
<#
.NOTES
===========================================================================
Created by: William Lam
Date: 11/21/2017
Blog: https://www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.SYNOPSIS
Export DRS Cluster Group Rules to JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
.DESCRIPTION
Export DRS Cluster Group Rules to JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
.EXAMPLE
Export-DRSClusterGroup -Path C:\Users\primp\Desktop\VMworld2017 -Cluster Windows-Cluster
#>
param(
[Parameter(Mandatory=$false)][String]$Path,
[Parameter(Mandatory=$true)][String]$Cluster
)
$rules = Get-Cluster -Name $Cluster | Get-DrsClusterGroup
$results = @()
foreach ($rule in $rules) {
$rulesObject = [pscustomobject] @{
Name = $rule.ExtensionData.Name;
Type = $rule.GroupType; #VMType = 1, HostType = 0
Member = $rule.Member
}
$results+=$rulesObject
}
if($Path) {
$fullPath = $Path + "\DRSClusterGroupRules.json"
Write-Host -ForegroundColor Green "Exporting DRS Cluster Group Rules to $fullpath ..."
$results | ConvertTo-Json | Out-File $fullPath
} else {
$results | ConvertTo-Json
}
}
Function Import-DRSClusterClusterGroup {
<#
.NOTES
===========================================================================
Created by: William Lam
Date: 11/21/2017
Blog: https://www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.SYNOPSIS
Import DRS Cluster Group Rules from JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
.DESCRIPTION
Import DRS Cluster Group Rules from JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
.EXAMPLE
Import-DRSClusterClusterGroup -Path C:\Users\primp\Desktop\VMworld2017 -Cluster Windows-Cluster
#>
param(
[Parameter(Mandatory=$true)][String]$Path,
[Parameter(Mandatory=$true)][String]$Cluster
)
$DRSClusterGroupRulesFilename = "\DRSClusterGroupRules.json"
$fullPath = $Path + $DRSClusterGroupRulesFilename
$json = Get-Content -Raw $fullPath | ConvertFrom-Json
foreach ($line in $json) {
$memberArr = @()
$members = $line.member
# VMHost Group
if($line.Type -eq 0) {
foreach ($member in $members) {
$memberView = Get-VMhost -Name $member
$memberArr+=$memberView
}
New-DrsClusterGroup -Name $line.name -Cluster (Get-Cluster -Name $Cluster) -VMhost $memberArr
# VM Group
} else {
foreach ($member in $members) {
$memberView = Get-VM -Name $member
$memberArr+=$memberView
}
New-DrsClusterGroup -Name $line.name -Cluster (Get-Cluster -Name $Cluster) -VM $memberArr
}
}
}
Function Export-Tag {
<#
.NOTES
===========================================================================
Created by: William Lam
Date: 11/21/2017
Blog: https://www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.SYNOPSIS
Export vSphere Tags and VM Assocations to JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
.DESCRIPTION
Export vSphere Tags and VM Assocations to JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
.EXAMPLE
Export-Tag -Path C:\Users\primp\Desktop\VMworld2017
#>
param(
[Parameter(Mandatory=$false)][String]$Path
)
# Export Tag Categories
$tagCatagorys = Get-TagCategory
$tagCatresults = @()
foreach ($tagCategory in $tagCatagorys) {
$tagCatObj = [pscustomobject] @{
Name = $tagCategory.Name;
Cardinality = $tagCategory.Cardinality;
Description = $tagCategory.Description;
Type = $tagCategory.EntityType
}
$tagCatresults+=$tagCatObj
}
if($Path) {
$fullPath = $Path + "\AllTagCategory.json"
Write-Host -ForegroundColor Green "Exporting vSphere Tag Category to $fullpath ..."
$tagCatresults | ConvertTo-Json | Out-File $fullPath
} else {
$tagCatresults | ConvertTo-Json
}
# Export Tags
$tags = Get-Tag
$tagResults = @()
foreach ($tag in $tags) {
$tagObj = [pscustomobject] @{
Name = $tag.Name;
Description = $tag.Description;
Category = $tag.Category.Name
}
$tagResults+=$tagObj
}
if($Path) {
$fullPath = $Path + "\AllTag.json"
Write-Host -ForegroundColor Green "Exporting vSphere Tag to $fullpath ..."
$tagResults | ConvertTo-Json | Out-File $fullPath
} else {
$tagResults | ConvertTo-Json
}
# Export VM to Tag Mappings
$vms = Get-VM
$vmResults = @()
foreach ($vm in $vms) {
$tagAssignments = $vm | Get-TagAssignment
$tags = @()
foreach ($tagAssignment in $tagAssignments) {
$tag = $tagAssignment.Tag
$tagName = $tag -split "/"
$tags+=$tagName
}
$vmObj = [pscustomobject] @{
Name = $vm.name;
Tag = $tags
}
$vmResults+=$vmObj
}
if($Path) {
$fullPath = $Path + "\AllTagAssocations.json"
Write-Host -ForegroundColor Green "Exporting VM to vSphere Tag Assignment to $fullpath ..."
$vmResults | ConvertTo-Json | Out-File $fullPath
} else {
$vmResults | ConvertTo-Json
}
}
Function Import-Tag {
<#
.NOTES
===========================================================================
Created by: William Lam
Date: 11/21/2017
Blog: https://www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.SYNOPSIS
Import vSphere Tags and VM Assocations from JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
.DESCRIPTION
Import vSphere Tags and VM Assocations from JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
.EXAMPLE
Import-Tag -Path C:\Users\primp\Desktop\VMworld2017
#>
param(
[Parameter(Mandatory=$true)][String]$Path
)
$tagCatFilename = "\AllTagCategory.json"
$fullPath = $Path + $tagCatFilename
$tagCategoryJson = Get-Content -Raw $fullPath | ConvertFrom-Json
$tagFilename = "\AllTag.json"
$fullPath = $Path + $tagFilename
$tagJson = Get-Content -Raw $fullPath | ConvertFrom-Json
$vmTagFilename = "\AllTagAssocations.json"
$fullPath = $Path + $vmTagFilename
$vmTagJson = Get-Content -Raw $fullPath | ConvertFrom-Json
# Re-Create Tag Category
foreach ($category in $tagCategoryJson) {
if($category.Cardinality -eq 0) {
$cardinality = "Single"
} else {
$cardinality = "Multiple"
}
New-TagCategory -Name $category.Name -Cardinality $cardinality -Description $category.Description -EntityType $category.Type
}
# Re-Create Tags
foreach ($tag in $tagJson) {
New-Tag -Name $tag.Name -Description $tag.Description -Category (Get-TagCategory -Name $tag.Category)
}
# Re-Create VM to Tag Mappings
foreach ($vmTag in $vmTagJson) {
$vm = Get-VM -Name $vmTag.name
$tags = $vmTag.Tag
foreach ($tag in $tags) {
New-TagAssignment -Entity $vm -Tag (Get-Tag -Name $tag)
}
}
}
Function Export-VMFolder {
<#
.NOTES
===========================================================================
Created by: William Lam
Date: 11/21/2017
Blog: https://www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.SYNOPSIS
Export vSphere Folder to JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
.DESCRIPTION
Export vSphere Folder to JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
.EXAMPLE
Export-VMFolder -Path C:\Users\primp\Desktop\VMworld2017
#>
param(
[Parameter(Mandatory=$false)][String]$Path
)
$vms = Get-VM
$vmFolderResults = @()
foreach ($vm in $vms) {
$vmFolderObj = [pscustomobject] @{
Name = $vm.name;
Folder = $vm.Folder.Name;
}
$vmFolderResults+=$vmFolderObj
}
if($Path) {
$fullPath = $Path + "\AllVMFolder.json"
Write-Host -ForegroundColor Green "Exporting VM Folders to $fullpath ..."
$vmFolderResults | ConvertTo-Json | Out-File $fullPath
} else {
$vmFolderResults | ConvertTo-Json
}
}
Function Import-VMFolder {
<#
.NOTES
===========================================================================
Created by: William Lam
Date: 11/21/2017
Blog: https://www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.SYNOPSIS
Import vSphere Folder from JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
.DESCRIPTION
Import vSphere Folder from JSON file based on VMworld Demo https://youtu.be/MagjfbIL4kg
.EXAMPLE
Import-VMFolder -Path C:\Users\primp\Desktop\VMworld2017
#>
param(
[Parameter(Mandatory=$true)][String]$Path
)
$vmFolderFilename = "\AllVMFolder.json"
$fullPath = $Path + $vmFolderFilename
$vmFolderJson = Get-Content -Raw $fullPath | ConvertFrom-Json
# Root vm Folder
$rootVMFolder = Get-Folder -Type VM -Name vm
$folders = $vmFolderJson | Select Folder | Sort-Object -Property Folder -Unique
foreach ($folder in $folders) {
$rootVMFolder | New-Folder -Name $folder.folder
}
foreach ($vmFolder in $vmFolderJson) {
$vm = Get-VM -Name $vmFolder.Name
$folder = Get-Folder -Name $vmFolder.Folder
Move-VM -VM $vm -Destination $folder
}
}
Function Export-VMStoragePolicy {
<#
.NOTES
===========================================================================
Created by: William Lam
Date: 11/21/2017
Blog: https://www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.SYNOPSIS
Export VM Storage Policies to JSON file
.DESCRIPTION
Export VM Storage Policies to JSON file
.EXAMPLE
Export-VMStoragePolicy -Path C:\Users\primp\Desktop\VMworld2017
#>
param(
[Parameter(Mandatory=$false)][String]$Path
)
foreach ($policy in Get-SpbmStoragePolicy) {
$policyName = $policy.Name
if($Path) {
Write-Host -ForegroundColor Green "Exporting Policy $policyName to $Path\$policyName.xml ..."
$policy | Export-SpbmStoragePolicy -FilePath $Path\$policyName.xml -Force | Out-Null
} else {
$policy
}
}
}
Function Import-VMStoragePolicy {
<#
.NOTES
===========================================================================
Created by: William Lam
Date: 11/21/2017
Blog: https://www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.SYNOPSIS
Import VM Storage Policies from JSON file
.DESCRIPTION
Import VM Storage Policies from JSON file
.EXAMPLE
Import-VMStoragePolicy -Path C:\Users\primp\Desktop\VMworld2017
#>
param(
[Parameter(Mandatory=$false)][String]$Path
)
foreach ($file in Get-ChildItem -Path $Path -Filter *.xml) {
$policyName = $file.name
$policyName = $policyName.replace(".xml","")
if(Get-SpbmStoragePolicy -Name $policyName -ErrorAction SilentlyContinue) {
Continue
} else {
Write-Host "Importing Policy $policyname ..."
Import-SpbmStoragePolicy -FilePath $Path\$file -Name $policyName
}
}
}

View File

@@ -59,15 +59,15 @@ The repository has been provided to allow the community to share resources that
1. Browse to the appropriate section (example: Scripts)
2. Select the “Create new file” button
3. On the new page, enter a file name, enter the resources information
4. Within the “Commit new file” area, enter the title and description, then select “Create a new branch for this commit…” and enter a sensical branch name
4. Within the “Commit new file” area, enter the title and description, then select “Create a new branch for this commit…” and enter a sensible branch name
5. Click “Propose new file”
6. On the “Open a pull request” page, click “Create pull request”
#### GitHub - Upload files Option
1. Browse to the appropriate section (example: Modules)
2. Select the “Upload files” button
3. On the new page, drag or choose the files to add
4. Within the “Commit changes” area, enter the title and description, then select “Create a new branch for this commit…” and enter a sensical branch name
3. On the new page, drag or choose the files to add
4. Within the “Commit changes” area, enter the title and description, then select “Create a new branch for this commit…” and enter a sensible branch name
5. Click “Propose new file”
6. On the “Open a pull request” page, click “Create pull request”
@@ -88,7 +88,7 @@ The following information must be included with each submitted scripting resourc
#### Note Placement Examples:
Script: Top few lines
Module: Module manifest
#### Required Script Note Example:
`<#`
`Script name: script_name.ps1`
@@ -126,7 +126,7 @@ The following information should be included when possible. Inclusion of informa
This section describes guidelines put in place to maintain a standard of quality while also promoting broader contribution.
### General Best Practices
### Resource Naming
* Give the resource a name that is indicitive of the actions and/or results of its running
* Give the resource a name that is indicative of the actions and/or results of its running
### Fault Handling
* Read and apply the following basic fault handling where applicable: Microsofts Hey, Scripting Guy! Blog: https://blogs.technet.microsoft.com/heyscriptingguy/2014/07/09/handling-errors-the-powershell-way/
@@ -138,7 +138,7 @@ This section describes guidelines put in place to maintain a standard of quality
* Avoid changing any global variables
### Help Information
* All resources should have inline documentation.
* All resources should have inline documentation.
### Scripts
* The script should be easy to read and understand
@@ -149,27 +149,27 @@ This section describes guidelines put in place to maintain a standard of quality
* Use only standard verbs
### Security
* Usage of PowerShells strict mode is preferred, but not required.
* Usage of PowerShells strict mode is preferred, but not required.
* Remove any information related to ones own environment (examples: Passwords, DNS/IP Addresses, custom user credentials, etc)
## Resource Maintenance
### Maintenance Ownership
Ownership of any and all submitted resources are maintained by the submitter. This ownership also includes maintenance of any and all submitted resources.
Ownership of any and all submitted resources are maintained by the submitter. This ownership also includes maintenance of any and all submitted resources.
### Filing Issues
Any bugs or other issues should be filed within GitHub by way of the repositorys Issue Tracker.
### Resolving Issues
Any community member can resolve issues within the repository, however only the owner or a board member can approve the update. Once approved, assuming the resolution involves a pull request, only a board member will be able to merge and close the request.
Any bugs or other issues should be filed within GitHub by way of the repositorys Issue Tracker.
### Resolving Issues
Any community member can resolve issues within the repository, however only the owner or a board member can approve the update. Once approved, assuming the resolution involves a pull request, only a board member will be able to merge and close the request.
## Additional Resources
### Discussions
Join in on the discussion within the VMware Code Slack team's PowerCLI channel: <https://code.vmware.com/slack/>
### VMware Sample Exchange
It is highly recommened to add any and all submitted resources to the VMware Sample Exchange: <https://developercenter.vmware.com/samples>
It is highly recommended to add any and all submitted resources to the VMware Sample Exchange: <https://developercenter.vmware.com/samples>
Sample Exchange can be allowed to access your GitHub resources, by way of a linking process, where they can be indexed and searched by the community. There are VMware social media accounts which will advertise resources posted to the site and there's no additional accounts needed, as the VMware Sample Exchange uses MyVMware credentials.
## VMWARE TECHNOLOGY PREVIEW LICENSE AGREEMENT
The VMware Technnology Preview License Agreement: <https://github.com/vmware/PowerCLI-Example-Scripts/blob/master/LICENSE.md>
The VMware Technology Preview License Agreement: <https://github.com/vmware/PowerCLI-Example-Scripts/blob/master/LICENSE.md>
# Repository Administrator Resources
## Table of Contents
@@ -180,7 +180,7 @@ The VMware Technnology Preview License Agreement: <https://github.com/vmware/Pow
Board members are volunteers from the PowerCLI community and VMware staff members, board members are not held responsible for any issues which may occur from running of scripts inside this repository.
Members:
Members:
* Josh Atwell (Community Member)
* Luc Dekens (Community Member)
* Jonathan Medd (Community Member)
@@ -189,4 +189,4 @@ Members:
* Rynardt Spies (Community Member)
## Approval of Additions
Items added to the repository, including items from the Board members, require a review and approval from at least one board member before being added to the repository. The approving member/s will have verified for a lack of malicious code. Once an “Approved for Merge” comment has been added from a board member, the pull can then be committed to the repository.
Items added to the repository, including items from the Board members, require a review and approval from at least one board member before being added to the repository. The approving member/s will have verified for a lack of malicious code. Once an “Approved for Merge” comment has been added from a board member, the pull can then be committed to the repository.

View File

@@ -0,0 +1,19 @@
<#
Script name: CreateVLANonStandardSwitch.ps1
Created on: 10/26/2017
Author: Alan Comstock, @Mr_Uptime
Description: Adds VLANs to an existing standard switch
Dependencies: None known
PowerCLI Version: VMware PowerCLI 6.5 Release 1 build 4624819
PowerShell Version: 5.1.14393.1532
OS Version: Windows 10
#>
$esxhost="HOSTNAME"
$vswitch="vSwitch0"
$vlanlist=10,20,30,40,50
Foreach ($vlan in $vlanlist) {
$portgroupname="VLAN " + $vlan
Get-VMHost $esxhost | Get-VirtualSwitch -name $vswitch | New-VirtualPortGroup -Name $portgroupname -VLanId $vlan
}
#The End

View File

@@ -30,7 +30,7 @@
foreach ($v in $vm) {
#Validate the input is a valid VM
$vmobj = Get-VM -Name $v -erroraction silentlycontinue
if (!$vmobj) {Write-Verbose "No VM found by the name $vm."}
if (!$vmobj) {Write-Verbose "No VM found by the name $v."}
else {
#Create a temporary object to store individual ouput
$tempout = "" | select VM,PortId

View File

@@ -2,28 +2,22 @@
Script name: SetClusterMultiPathToRoundRobin.ps1
Created on: 09/14/2017
Author: Alan Comstock, @Mr_Uptime
Description: Set the MultiPath policy for FC devices to RoundRobin for all hosts in a cluster.
Description: Set the MultiPath policy for FC devices to RoundRobin and IOPS to 1 for all hosts in a cluster based upon the vendor tag.
Dependencies: None known
PowerCLI Version: VMware PowerCLI 6.5 Release 1 build 4624819
PowerShell Version: 5.1.14393.1532
OS Version: Windows 10
#>
#Check for any Fibre Channel devices that are not set to Round Robin in a cluster.
#Get-Cluster -Name CLUSTERNAME | Get-VMhost | Get-VMHostHba -Type "FibreChannel" | Get-ScsiLun -LunType disk | Where { $_.MultipathPolicy -notlike "RoundRobin" } | Select CanonicalName,MultipathPolicy
#Set the Multipathing Policy to Round Robin for any Fibre Channel devices that are not Round Robin in a cluster
$cluster = Get-Cluster CLUSTERNAME
$hostlist = Get-VMHost -Location $cluster | Sort Name
$TotalHostCount = $hostlist.count
$hostincrement = 0
while ($hostincrement -lt $TotalHostCount){ #Host Loop
$currenthost = $hostlist[$hostincrement].Name
Write-Host "Working on" $currenthost
$scsilun = Get-VMhost $currenthost | Get-VMHostHba -Type "FibreChannel" | Get-ScsiLun -LunType disk | Where { $_.MultipathPolicy -notlike "RoundRobin" }
$pathpolicy="RoundRobin"
$iops="1"
$vendor="3PARdata"
$AllESXHosts = Get-VMHost -Location CLUSTERNAME | Sort Name
Foreach ($esxhost in $AllESXHosts) {
Write-Host "Working on" $esxhost
$scsilun = Get-VMhost $esxhost | Get-VMHostHba -Type "FibreChannel" | Get-ScsiLun -LunType disk | Where-Object {$_.Vendor -like $vendor -and ($_.MultipathPolicy -notlike $pathpolicy -or $_.CommandsToSwitchPath -ne $iops)}
if ($scsilun -ne $null){
Set-ScsiLun -ScsiLun $scsilun -MultipathPolicy RoundRobin
Set-ScsiLun -ScsiLun $scsilun -MultipathPolicy $pathpolicy -CommandsToSwitchPath $iops
}
$hostincrement++ #bump the host increment
}
#The End