Merge remote-tracking branch 'vmware/master'
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
290
Modules/CrossvCentervmotion/XVM.psm1
Normal file
290
Modules/CrossvCentervmotion/XVM.psm1
Normal 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
18
Modules/NSXT/NSXT.psd1
Normal 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
260
Modules/NSXT/NSXT.psm1
Normal 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
|
||||
}
|
||||
1238
Modules/VMToolsManagement/VMToolsManagement.psm1
Normal file
1238
Modules/VMToolsManagement/VMToolsManagement.psm1
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
BIN
Modules/VMware.VMC/VMware.VMC.psd1
Executable file
BIN
Modules/VMware.VMC/VMware.VMC.psd1
Executable file
Binary file not shown.
323
Modules/VMware.VMC/VMware.VMC.psm1
Normal file
323
Modules/VMware.VMC/VMware.VMC.psm1
Normal 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'
|
||||
@@ -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.
|
||||
|
||||
17
Modules/rCisTag/Examples/01-Get.ps1
Normal file
17
Modules/rCisTag/Examples/01-Get.ps1
Normal 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
|
||||
|
||||
14
Modules/rCisTag/Examples/02-New.ps1
Normal file
14
Modules/rCisTag/Examples/02-New.ps1
Normal 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
|
||||
|
||||
11
Modules/rCisTag/Examples/03-Set.ps1
Normal file
11
Modules/rCisTag/Examples/03-Set.ps1
Normal 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
|
||||
|
||||
13
Modules/rCisTag/Examples/04-Remove.ps1
Normal file
13
Modules/rCisTag/Examples/04-Remove.ps1
Normal 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
|
||||
|
||||
20
Modules/rCisTag/Examples/05-Tag-Datastore.ps1
Normal file
20
Modules/rCisTag/Examples/05-Tag-Datastore.ps1
Normal 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
|
||||
|
||||
3
Modules/rCisTag/Examples/CisConfig.ps1
Normal file
3
Modules/rCisTag/Examples/CisConfig.ps1
Normal file
@@ -0,0 +1,3 @@
|
||||
$cisServer = 'vcsa.my.domain'
|
||||
$cisUser = 'administrator@vsphere.local'
|
||||
$cisPswd = 'VMware1!'
|
||||
21
Modules/rCisTag/MITLicense.txt
Normal file
21
Modules/rCisTag/MITLicense.txt
Normal 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
15
Modules/rCisTag/README.md
Normal 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
|
||||
|
||||
26
Modules/rCisTag/en-US/about_rCISTag.Help.txt
Normal file
26
Modules/rCisTag/en-US/about_rCISTag.Help.txt
Normal 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.
|
||||
1793
Modules/rCisTag/en-US/rCISTag-help.xml
Normal file
1793
Modules/rCisTag/en-US/rCISTag-help.xml
Normal file
File diff suppressed because it is too large
Load Diff
BIN
Modules/rCisTag/rCISTag.psd1
Normal file
BIN
Modules/rCisTag/rCISTag.psd1
Normal file
Binary file not shown.
821
Modules/rCisTag/rCISTag.psm1
Normal file
821
Modules/rCisTag/rCISTag.psm1
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
475
Modules/vCenterManualMigration/vCenterManualMigration.psm1
Normal file
475
Modules/vCenterManualMigration/vCenterManualMigration.psm1
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
32
README.md
32
README.md
@@ -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 resource’s 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: Microsoft’s 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 PowerShell’s strict mode is preferred, but not required.
|
||||
* Usage of PowerShell’s strict mode is preferred, but not required.
|
||||
* Remove any information related to one’s 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 repository’s 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 repository’s 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.
|
||||
|
||||
19
Scripts/CreateVLANonStandardSwitch
Normal file
19
Scripts/CreateVLANonStandardSwitch
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user