Merge pull request #1 from vmware/master

updating fork
This commit is contained in:
jpgrall
2020-01-10 13:52:20 -06:00
committed by GitHub
50 changed files with 13385 additions and 1604 deletions

View File

@@ -190,7 +190,7 @@ Function Get-ContentLibraryItemFiles {
$itemIds = $contentLibraryItemService.list($libraryID)
$DatastoreID = $library.storage_backings.datastore_id.Value
$Datastore = get-datastore -id "Datastore-$DatastoreID"
foreach($itemId in $itemIds) {
$itemName = ($contentLibraryItemService.get($itemId)).name
$contentLibraryItemFileSerice = Get-CisService com.vmware.content.library.item.file
@@ -205,7 +205,7 @@ Function Get-ContentLibraryItemFiles {
else{
$fullfilepath = "UNKNOWN"
}
if(!$LibraryItemName) {
$fileResult = [pscustomobject] @{
Name = $file.name;
@@ -344,8 +344,8 @@ Function New-ExtReplicatedContentLibrary {
$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.automatic_sync_enabled = $AutoSync
$createSpec.subscription_info.on_demand = $OnDemand
$createSpec.subscription_info.subscription_url = $subscribeUrl
$createSpec.subscription_info.authentication_method = "NONE"
$createSpec.type = "SUBSCRIBED"
@@ -709,4 +709,72 @@ Function New-VMFromVMTX {
Write-Host "`nDeploying new VM $NewVMName from VMTX Template $VMTXName ..."
$results = $vmtxService.deploy($vmtxId,$vmtxDeploySpec)
}
}
Function New-SubscribedContentLibrary {
<#
.NOTES
===========================================================================
Created by: William Lam
Organization: VMware
Blog: www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.DESCRIPTION
This function creates a new Subscriber Content Library from Subscription URL
.PARAMETER LibraryName
The name of the new vSphere Content Library
.PARAMETER DatastoreName
The name of the vSphere Datastore to store the Content Library
.PARAMETER SubscriptionURL
The URL of the published Content Library
.PARAMETER SubscriptionThumbprint
The SSL Thumbprint for the published Content Library
.PARAMETER OnDemand
Specifies whether content is downloaded on-demand (e.g. no immediately)
.PARAMETER AutomaticSync
Specifies whether automatic synchronization with the external content library is enabled
.EXAMPLE
New-SubscribedContentLibrary -LibraryName NestedESXi -DatastoreName vsanDatastore -SubscriptionURL https://download3.vmware.com/software/vmw-tools/lib.json -SubscriptionThumbprint "7a:c4:08:2d:d3:55:56:af:9f:26:43:65:d0:31:99:0b:d2:f3:d8:69" -AutomaticSync
.EXAMPLE
New-SubscribedContentLibrary -LibraryName NestedESXi -DatastoreName vsanDatastore -SubscriptionURL https://download3.vmware.com/software/vmw-tools/lib.json -SubscriptionThumbprint "7a:c4:08:2d:d3:55:56:af:9f:26:43:65:d0:31:99:0b:d2:f3:d8:69" -OnDemand
#>
param(
[Parameter(Mandatory=$true)][String]$LibraryName,
[Parameter(Mandatory=$true)][String]$DatastoreName,
[Parameter(Mandatory=$true)][String]$SubscriptionURL,
[Parameter(Mandatory=$true)][String]$SubscriptionThumbprint,
[Parameter(Mandatory=$false)][Switch]$OnDemand,
[Parameter(Mandatory=$false)][Switch]$AutomaticSync
)
$datastore = Get-Datastore -Name $DatastoreName
if($datastore) {
$datastoreId = $datastore.ExtensionData.MoRef.Value
$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
$createSpec.type = "SUBSCRIBED"
$addResults = $createSpec.storage_backings.Add($StorageSpec)
if($OnDemand) { $OnDemandFlag = $true } else { $OnDemandFlag = $false }
if($AutomaticSync) { $AutomaticSyncFlag = $true } else { $AutomaticSyncFlag = $false }
$createSpec.subscription_info.on_demand = $OnDemandFlag
$createSpec.subscription_info.automatic_sync_enabled = $AutomaticSyncFlag
$createSpec.subscription_info.subscription_url = $SubscriptionURL
$createSpec.subscription_info.authentication_method = "NONE"
$createSpec.subscription_info.ssl_thumbprint = $SubscriptionThumbprint
Write-Host "Creating new Subscribed Content Library called $LibraryName ..."
$library = $subscribeLibraryService.create($UniqueChangeId, $createSpec)
}
}

View File

@@ -152,10 +152,12 @@ Function New-XVCMRequest {
The name of the source vSphere Datacenter
.PARAMETER DstDatacenter
The name of the destination vSphere Datacenter
.PARAMETER SrcCluster
<Not needed for v2.0,removed from code>
.PARAMETER DstCluster
The name of the destination vSphere Cluster, set to null if DstHost is defined
.PARAMETER DstPool
The name of the destination vSphere Resource Pool
.PARAMETER DstFolder
The name of the destination vSphere Folder
.PARAMETER DstDatastore
The name of the destination Datastore
.PARAMETER DstHost
@@ -171,6 +173,15 @@ Function New-XVCMRequest {
-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"}
.EXAMPLE
New-XVCMRequest -opType Clone -SrcSite OREGON -DstSite CALIF `
-SrcDatacenter SDDC-Datacenter -srcVMs @(“DUDE-ubuntu”) `
-DstDatacenter SDDC-Datacenter `
-DstCluster "Cluster-1" -DstHost $null `
-DstPool Compute-ResourcePool `
-DstFolder Workloads `
-DstDatastore WorkloadDatastore `
-NetworkMapping @{"OREGON-VMs-sddc"="CALIF-sddc-VMs"}
#>
param(
[Parameter(Mandatory=$true)][String]$opType, #Added by CPM for 2.0
@@ -178,8 +189,9 @@ Function New-XVCMRequest {
[Parameter(Mandatory=$true)][String]$DstSite,
[Parameter(Mandatory=$true)][String]$SrcDatacenter,
[Parameter(Mandatory=$true)][String]$DstDatacenter,
#[Parameter(Mandatory=$true)][String]$SrcCluster, #Removed by CPM for 2.0
[Parameter(Mandatory=$true)][AllowNull()] $DstCluster, #Added [AllowNull()], removed [String] by CPM for 2.0
[Parameter(Mandatory=$true)][String]$DstPool,
[Parameter(Mandatory=$true)][String]$DstFolder,
[Parameter(Mandatory=$true)][String]$DstDatastore,
[Parameter(Mandatory=$true)][AllowNull()] $DstHost, #Added by CPM for 2.0
[Parameter(Mandatory=$true)][String[]]$srcVMs,
@@ -193,7 +205,8 @@ Function New-XVCMRequest {
"targetSite"=$DstSite;
"sourceDatacenter"=$SrcDatacenter;
"targetDatacenter"=$dstDatacenter;
#"sourceCluster"=$SrcCluster; #Removed by CPM for 2.0
"targetPool"=$DstPool;
"targetFolder"=$DstFolder;
"targetCluster"=$DstCluster;
"targetDatastore"=$DstDatastore;
"targetHost"=$DstHost; #Added by CPM for 2.0

View File

@@ -7,7 +7,35 @@
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'
FunctionsToExport = 'Get-NSXTBGPNeighbors',
'Get-NSXTComputeManager',
'Get-NSXTController',
'Get-NSXTEdgeCluster',
'Get-NSXTFabricNode',
'Get-NSXTFabricVM',
'Get-NSXTFirewallRule',
'Get-NSXTForwardingTable',
'Get-NSXTIPPool',
'Get-NSXTLogicalRouter',
'Get-NSXTLogicalRouterPorts',
'Get-NSXTLogicalSwitch',
'Get-NSXTManager',
'Get-NSXTNetworkRoutes',
'Get-NSXTRoutingTable',
'Get-NSXTTraceFlow',
'Get-NSXTTraceFlowObservations',
'Get-NSXTTransportNode',
'Get-NSXTTransportZone',
'Get-NSXTClusterNode',
'Set-NSXTIPPool',
'Set-NSXTLogicalRouter',
'Set-NSXTLogicalSwitch',
'Set-NSXTTraceFlow',
'Get-NSXTIPAMIPBlock',
'Set-NSXTIPAMIPBlock',
'Remove-NSXTIPAMIPBlock'
PrivateData = @{
PSData = @{
Tags = @('NSX-T','REST')

File diff suppressed because it is too large Load Diff

View File

@@ -21,7 +21,8 @@
[Parameter(Mandatory=$true)][String]$RefreshToken
)
$results = Invoke-WebRequest -Uri "https://console.cloud.vmware.com/csp/gateway/am/api/auth/api-tokens/authorize?refresh_token=$RefreshToken" -Method POST -ContentType "application/json" -UseBasicParsing -Headers @{"csp-auth-token"="$RefreshToken"}
$body = "refresh_token=$RefreshToken"
$results = Invoke-WebRequest -Uri "https://console.cloud.vmware.com/csp/gateway/am/api/auth/api-tokens/authorize" -Method POST -ContentType "application/x-www-form-urlencoded" -UseBasicParsing -Body $body
if($results.StatusCode -ne 200) {
Write-Host -ForegroundColor Red "Failed to retrieve Access Token, please ensure your VMC Refresh Token is valid and try again"
break
@@ -51,4 +52,43 @@ Function Get-CSPServices {
$results = Invoke-WebRequest -Uri "https://console.cloud.vmware.com/csp/gateway/slc/api/definitions?expand=1" -Method GET -ContentType "application/json" -UseBasicParsing -Headers @{"csp-auth-token"="$env:cspAuthToken"}
((($results.Content) | ConvertFrom-Json).results | where {$_.visible -eq $true}).displayName
}
}
}
Function Get-CSPRefreshTokenExpiry {
<#
.NOTES
===========================================================================
Created by: William Lam
Date: 01/10/2019
Organization: VMware
Blog: https://www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.DESCRIPTION
Retrieve the expiry for a given CSP Refresh Token
.PARAMETER RefreshToken
Retrieve the expiry for a given CSP Refresh Token
.EXAMPLE
Get-CSPRefreshTokenExpiry -RefreshToken $RefreshToken
#>
Param (
[Parameter(Mandatory=$true)][String]$RefreshToken
)
$body = @{"tokenValue"="$RefreshToken"}
$json = $body | ConvertTo-Json
$results = Invoke-WebRequest -Uri "https://console.cloud.vmware.com/csp/gateway/am/api/auth/api-tokens/details" -Method POST -ContentType "application/json" -UseBasicParsing -Body $json
$tokenDetails = (($results.Content) | ConvertFrom-Json)
$createDate = (Get-Date -Date "01/01/1970").AddMilliseconds($tokenDetails.createdAt).ToLocalTime()
$usedDate = (Get-Date -Date "01/01/1970").AddMilliseconds($tokenDetails.lastUsedAt).ToLocalTime()
$expiryDate = (Get-Date -Date "01/01/1970").AddMilliseconds($tokenDetails.expiresAt).ToLocalTime()
$tmp = [pscustomobject] @{
LastUsedDate = $usedDate;
CreatedDate = $createDate;
ExpiryDate = $expiryDate;
}
$tmp | Format-List
}

View File

@@ -0,0 +1,123 @@
#
# Module manifest for module 'VMware.Community.CISTag'
#
# Generated by: Kyle Ruddy
#
# Generated on: 12/14/18
#
@{
# Script module or binary module file associated with this manifest.
RootModule = 'VMware.Community.CISTag.psm1'
# Version number of this module.
ModuleVersion = '1.0.0'
# Supported PSEditions
# CompatiblePSEditions = @()
# ID used to uniquely identify this module
GUID = 'a0803efd-6017-4049-bfc9-5983a5a0c348'
# Author of this module
Author = 'Kyle Ruddy'
# Company or vendor of this module
CompanyName = 'VMware'
# Copyright statement for this module
Copyright = '(c) VMware. All rights reserved.'
# Description of the functionality provided by this module
Description = 'Community sourced PowerShell Module for managing vSphere Tags via the CIS Endpoint'
# Minimum version of the PowerShell engine required by this module
PowerShellVersion = '4.0'
# Name of the PowerShell host required by this module
# PowerShellHostName = ''
# Minimum version of the PowerShell host required by this module
# PowerShellHostVersion = ''
# Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
# DotNetFrameworkVersion = ''
# Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
# CLRVersion = ''
# Processor architecture (None, X86, Amd64) required by this module
# ProcessorArchitecture = ''
# Modules that must be imported into the global environment prior to importing this module
# RequiredModules = @()
# Assemblies that must be loaded prior to importing this module
# RequiredAssemblies = @()
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
# ScriptsToProcess = @()
# Type files (.ps1xml) to be loaded when importing this module
# TypesToProcess = @()
# Format files (.ps1xml) to be loaded when importing this module
# FormatsToProcess = @()
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
# NestedModules = @()
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
FunctionsToExport = 'Get-CISTag', 'Get-CISTagCategory', 'Get-CISTagAssignment', 'New-CISTag', 'New-CISTagCategory', 'New-CISTagAssignment', 'Remove-CISTag', 'Remove-CISTagCategory', 'Remove-CISTagAssignment'
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
# CmdletsToExport = '*'
# Variables to export from this module
# VariablesToExport = '*'
# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
# AliasesToExport = '*'
# DSC resources to export from this module
# DscResourcesToExport = @()
# List of all modules packaged with this module
# ModuleList = @()
# List of all files packaged with this module
# FileList = @()
# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
PrivateData = @{
PSData = @{
# Tags applied to this module. These help with module discovery in online galleries.
# Tags = @()
# A URL to the license for this module.
# LicenseUri = ''
# A URL to the main website for this project.
# ProjectUri = ''
# A URL to an icon representing this module.
# IconUri = ''
# ReleaseNotes of this module
# ReleaseNotes = ''
} # End of PSData hashtable
} # End of PrivateData hashtable
# HelpInfo URI of this module
# HelpInfoURI = ''
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
# DefaultCommandPrefix = ''
}

View File

@@ -0,0 +1,770 @@
function Get-CISTag {
<#
.SYNOPSIS
Gathers tag information from the CIS REST API endpoint
.DESCRIPTION
Will provide a list of tags
.NOTES
Author: Kyle Ruddy, @kmruddy
.PARAMETER Name
Tag name which should be retreived
.PARAMETER Category
Tag category name which should be retreived
.PARAMETER Id
Tag ID which should be retreived
.EXAMPLE
Get-CISTag
Retreives all tag information
.EXAMPLE
Get-CISTag -Name tagName
Retreives the tag information based on the specified name
#>
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'Low')]
param(
[Parameter(Mandatory=$false,Position=0,ValueFromPipelineByPropertyName=$true)]
[String]$Name,
[Parameter(Mandatory=$false,Position=1,ValueFromPipelineByPropertyName=$true)]
[String]$Category,
[Parameter(Mandatory=$false,Position=2,ValueFromPipelineByPropertyName=$true)]
[String]$Id
)
If (-Not $global:DefaultCisServers) { Write-error "No CIS Connection found, please use the Connect-CisServer to connect" } Else {
$tagSvc = Get-CisService -Name com.vmware.cis.tagging.tag
if ($PSBoundParameters.ContainsKey("Id")) {
$tagOutput = $tagSvc.get($Id)
} else {
if ($global:DefaultVIServer -and $global:DefaultVIServer.Name -eq $global:DefaultCisServers.Name) {
[Boolean]$vCenterConn = $true
$vCTagList = Get-Tag
} else {
$tagArray = @()
$tagIdList = $tagSvc.list() | Select-Object -ExpandProperty Value
[int]$counter = 1
foreach ($t in $tagIdList) {
$tagArray += $tagSvc.get($t)
$counter++
if ($counter -gt 200) {Start-Sleep -Milliseconds 1; $counter = 1}
}
}
if ($PSBoundParameters.ContainsKey("Name")) {
if ($vCenterConn){
$tagOutput = $vCTagList | Where-Object {$_.Name -eq $Name}
} else {$tagOutput = $tagArray | Where-Object {$_.Name -eq $Name}}
} elseif ($PSBoundParameters.ContainsKey("Category")) {
if ($vCenterConn){
$tagOutput = $vCTagList | Where-Object {$_.Category -eq $Category}
} else {
$tagCatid = Get-CISTagCategory -Name $Category | Select-Object -ExpandProperty Id
$tagIdList = $tagSvc.list_tags_for_category($tagCatid)
$tagArray2 = @()
foreach ($t in $tagIdList) {
$tagArray2 += $tagSvc.get($t)
}
$tagOutput = $tagArray2
}
} else {
if ($vCenterConn){$tagOutput = $vCTagList}
else {$tagOutput = $tagArray}
}
}
$tagOutput | Select-Object Id, Name, Description
}
}
function New-CISTag {
<#
.SYNOPSIS
Creates a new tag from the CIS REST API endpoint
.DESCRIPTION
Will create a new tag
.NOTES
Author: Kyle Ruddy, @kmruddy
.PARAMETER Name
Tag name which should be created
.PARAMETER Category
Category name where the new tag should be associated
.PARAMETER Description
Description for the new tag
.PARAMETER CategoryID
Category ID where the new tag should be associated
.EXAMPLE
New-CISTag -Name tagName -Category categoryName -Description "Tag Descrition"
Creates a new tag based on the specified name
#>
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'Medium')]
param(
[Parameter(Mandatory=$true,Position=0)]
[String]$Name,
[Parameter(Mandatory=$false,Position=1)]
[String]$Category,
[Parameter(Mandatory=$false,Position=2)]
[String]$Description,
[Parameter(Mandatory=$false,Position=3)]
[String]$CategoryID
)
If (-Not $global:DefaultCisServers) { Write-error "No CIS Connection found, please use the Connect-CisServer to connect" } Else {
$tagSvc = Get-CisService -Name com.vmware.cis.tagging.tag
$tagCreateHelper = $tagSvc.Help.create.create_spec.Create()
$tagCreateHelper.name = $Name
if ($PSBoundParameters.ContainsKey("Category")) {
$tagCreateHelper.category_id = Get-CISTagCategory -Name $Category | Select-Object -ExpandProperty Id
} elseif ($PSBoundParameters.ContainsKey("CategoryId")) {
$tagCreateHelper.category_id = $CategoryID
} else {Write-Warning "No Category input found. Add a Category name or ID."; break}
if ($PSBoundParameters.ContainsKey("Description")) {
$tagCreateHelper.description = $Description
} else {
$tagCreateHelper.description = ""
}
$tagNewId = $tagSvc.create($tagCreateHelper)
Get-CISTag -Id $tagNewId
}
}
function Remove-CISTag {
<#
.SYNOPSIS
Removes a tag from the CIS REST API endpoint
.DESCRIPTION
Will delete a new tag
.NOTES
Author: Kyle Ruddy, @kmruddy
.PARAMETER Name
Tag name which should be removed
.PARAMETER ID
Tag ID which should be removed
.EXAMPLE
Remove-CISTag -Name tagName
Removes a new tag based on the specified name
#>
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'High')]
param(
[Parameter(Mandatory=$false,Position=0,ValueFromPipelineByPropertyName=$true)]
[String]$Name,
[Parameter(Mandatory=$false,Position=1,ValueFromPipelineByPropertyName=$true)]
[String]$ID
)
If (-Not $global:DefaultCisServers) { Write-error "No CIS Connection found, please use the Connect-CisServer to connect" } Else {
$tagSvc = Get-CisService -Name com.vmware.cis.tagging.tag
if ($ID) {
$tagSvc.delete($ID)
} else {
$tagId = Get-CISTag -Name $Name | select -ExpandProperty Id
if ($tagId) {$tagSvc.delete($tagId)}
else {Write-Warning "No valid tag found."}
}
}
}
function Get-CISTagCategory {
<#
.SYNOPSIS
Gathers tag category information from the CIS REST API endpoint
.DESCRIPTION
Will provide a list of tag categories
.NOTES
Author: Kyle Ruddy, @kmruddy
.PARAMETER Name
Tag category name which should be retreived
.PARAMETER Id
Tag category ID which should be retreived
.EXAMPLE
Get-CISTagCategory
Retreives all tag category information
.EXAMPLE
Get-CISTagCategory -Name tagCategoryName
Retreives the tag category information based on the specified name
#>
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'Low')]
param(
[Parameter(Mandatory=$false,Position=0,ValueFromPipelineByPropertyName=$true)]
[String]$Name,
[Parameter(Mandatory=$false,Position=2,ValueFromPipelineByPropertyName=$true)]
[String]$Id
)
If (-Not $global:DefaultCisServers) { Write-error "No CIS Connection found, please use the Connect-CisServer to connect" } Else {
$tagCatSvc = Get-CisService -Name com.vmware.cis.tagging.category
if ($PSBoundParameters.ContainsKey("Id")) {
$tagCatOutput = $tagCatSvc.get($Id)
} else {
$tagCatArray = @()
$tagCatIdList = $tagCatSvc.list() | Select-Object -ExpandProperty Value
foreach ($tc in $tagCatIdList) {
$tagCatArray += $tagCatSvc.get($tc)
}
if ($PSBoundParameters.ContainsKey("Name")) {
$tagCatOutput = $tagCatArray | Where-Object {$_.Name -eq $Name}
} else {
$tagCatOutput = $tagCatArray
}
}
$tagCatOutput | Select-Object Id, Name, Description, Cardinality
}
}
function New-CISTagCategory {
<#
.SYNOPSIS
Creates a new tag category from the CIS REST API endpoint
.DESCRIPTION
Will create a new tag category
.NOTES
Author: Kyle Ruddy, @kmruddy
.PARAMETER Name
Tag category name which should be created
.PARAMETER Description
Tag category ID which should be retreived
.PARAMETER Cardinality
Tag category ID which should be retreived
.PARAMETER AssociableTypes
Tag category ID which should be retreived
.EXAMPLE
New-CISTagCategory -Name NewTagCategoryName -Description "New Tag Category Description" -Cardinality "Single" -AssociableTypes
Creates a new tag category with the specified information
#>
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'Medium')]
param(
[Parameter(Mandatory=$true,Position=0)]
[String]$Name,
[Parameter(Mandatory=$false,Position=1)]
[String]$Description,
[Parameter(Mandatory=$false,Position=2)]
[ValidateSet("SINGLE","MULTIPLE")]
[String]$Cardinality = "SINGLE",
[Parameter(Mandatory=$false,Position=3)]
[ValidateSet("All", "Cluster", "Datacenter", "Datastore", "DatastoreCluster", "DistributedPortGroup", "DistributedSwitch", "Folder", "ResourcePool", "VApp", "VirtualPortGroup", "VirtualMachine", "VMHost")]
[String]$AssociableTypes = "All"
)
If (-Not $global:DefaultCisServers) { Write-error "No CIS Connection found, please use the Connect-CisServer to connect" } Else {
$tagCatSvc = Get-CisService -Name com.vmware.cis.tagging.category
$tagCatCreateHelper = $tagCatSvc.Help.create.create_spec.Create()
$tagCatCreateHelper.name = $Name
if ($PSBoundParameters.ContainsKey("Description")) {
$tagCatCreateHelper.description = $Description
} else {$tagCatCreateHelper.description = ""}
$tagCatCreateHelper.cardinality = $Cardinality
$tagCatCreateAssocTypeHelper = $tagCatSvc.help.create.create_spec.associable_types.create()
$tagCatCreateAssocTypeHelper.Add($AssociableTypes)
$tagCatCreateHelper.associable_types = $tagCatCreateAssocTypeHelper
$tagCatNewId = $tagCatSvc.create($tagCatCreateHelper)
Get-CISTagCategory -Id $tagCatNewId
}
}
function Remove-CISTagCategory {
<#
.SYNOPSIS
Removes tag category information from the CIS REST API endpoint
.DESCRIPTION
Will remove a tag category
.NOTES
Author: Kyle Ruddy, @kmruddy
.PARAMETER Name
Tag category name which should be removed
.PARAMETER Id
Tag category ID which should be removed
.EXAMPLE
Remove-CISTagCategory -Name tagCategoryName
Removes the tag category information based on the specified name
#>
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'High')]
param(
[Parameter(Mandatory=$false,Position=0,ValueFromPipelineByPropertyName=$true)]
[String]$Name,
[Parameter(Mandatory=$false,Position=2,ValueFromPipelineByPropertyName=$true)]
[String]$Id
)
If (-Not $global:DefaultCisServers) { Write-error "No CIS Connection found, please use the Connect-CisServer to connect" } Else {
$tagCatSvc = Get-CisService -Name com.vmware.cis.tagging.category
if ($PSBoundParameters.ContainsKey("Id")) {
$tagCatSvc.delete($Id)
} elseif ($PSBoundParameters.ContainsKey("Name")) {
$tagCatId = Get-CISTagCategory -Name $Name | Select-Object -ExpandProperty Id
$tagCatSvc.delete($tagCatId)
} else {Write-Warning "No tag category found."}
}
}
function Get-CISTagAssignment {
<#
.SYNOPSIS
Displays a list of the tag assignments from the CIS REST API endpoint
.DESCRIPTION
Will provide a list of the tag assignments
.NOTES
Author: Kyle Ruddy, @kmruddy
.PARAMETER Category
Tag category name which should be referenced
.PARAMETER Entity
Object name which should be retreived
.PARAMETER ObjectId
Object ID which should be retreived
.EXAMPLE
Get-CISTagAssignment
Retreives all tag assignment information
.EXAMPLE
Get-CISTagAssignment -Entity VMName
Retreives all tag assignments for the VM name
.EXAMPLE
Get-CISTagAssignment -ObjectId 'vm-11'
Retreives all tag assignments for the VM object
#>
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'Low')]
param(
[Parameter(Mandatory=$false,Position=0)]
[String]$Category,
[Parameter(Mandatory=$false,Position=1)]
[String]$Entity,
[Parameter(Mandatory=$false,Position=2,ValueFromPipelineByPropertyName=$true)]
[String]$ObjectId
)
If (-Not $global:DefaultCisServers) { Write-error "No CIS Connection found, please use the Connect-CisServer to connect" } Else {
$tagOutput = @()
[Boolean]$vCenterConn = $false
$tagAssocSvc = Get-CisService -Name com.vmware.cis.tagging.tag_association
if ($PSBoundParameters.ContainsKey("ObjectId")) {
if ($ObjectId.split('-')[0] -eq 'vm') {
$objType = "VirtualMachine"
} elseif ($ObjectId.Split('-')[0] -eq 'datastore') {
$objType = 'Datastore'
} else {Write-Warning 'Only VirtualMachine and Datastore types currently supported.'; break}
$objObject = $tagAssocSvc.help.list_attached_tags.object_id.create()
$objObject.id = $ObjectId
$objObject.type = $objType
$tagIdOutput = $tagAssocSvc.list_attached_tags($objObject)
} elseif ($PSBoundParameters.ContainsKey("Entity")) {
if ($global:DefaultVIServer -and $global:DefaultVIServer.Name -eq $global:DefaultCisServers.Name) {
[Boolean]$vCenterConn = $true
$viObject = (Get-Inventory -Name $Entity).ExtensionData.MoRef
$objObject = $tagAssocSvc.help.list_attached_tags.object_id.create()
$objObject.id = $viObject.Value
$objObject.type = $viObject.type
} else {
$vmSvc = Get-CisService -Name com.vmware.vcenter.vm
$filterVmNameObj = $vmsvc.help.list.filter.create()
$filterVmNameObj.names.add($Entity) | Out-Null
$objId = $vmSvc.list($filterVmNameObj) | Select-Object -ExpandProperty vm
if ($objId) {$objType = "VirtualMachine"}
else {
$dsSvc = Get-CisService com.vmware.vcenter.datastore
$filterDsNameObj = $dsSvc.Help.list.filter.Create()
$filterDsNameObj.names.add($Entity) | Out-Null
$objId = $dsSvc.list($filterDsNameObj) | Select-Object -ExpandProperty datastore
if ($objId) {$objType = "Datastore"}
else {Write-Warning "No entities found."; break}
}
$objObject = $tagAssocSvc.help.list_attached_tags.object_id.create()
$objObject.id = $objId
$objObject.type = $objType
}
$tagIdOutput = $tagAssocSvc.list_attached_tags($objObject)
} else {
$tagSvc = Get-CisService -Name com.vmware.cis.tagging.tag
$tagIdOutput = @()
$tagCategories = Get-CISTagCategory | Sort-Object -Property Name
if ($Category) {
$tagCatId = $tagCategories | Where-Object {$_.Name -eq $Category} | Select-Object -ExpandProperty Id
$tagIdOutput += $tagSvc.list_tags_for_category($tagCatId)
} else {
foreach ($tagCat in $tagCategories) {
$tagIdOutput += $tagSvc.list_tags_for_category($tagCat.id)
}
}
}
$tagReference = Get-CISTag
if ($Entity -or $ObjectId) {
foreach ($tagId in $tagIdOutput) {
$tagAttObj = @()
if ($Entity) {
$tagAttObj += $tagAssocSvc.list_attached_objects($tagId) | Where-Object {$_.type -eq $viObject.type -and $_.id -eq $viObject.Value}
} else {
$tagAttObj += $tagAssocSvc.list_attached_objects($tagId) | Where-Object {$_.id -eq $ObjectId}
}
foreach ($obj in $tagAttObj) {
if ($obj.type -eq "VirtualMachine") {
if (-Not $vmSvc) {$vmSvc = Get-CisService -Name com.vmware.vcenter.vm}
$filterVmObj = $vmsvc.help.list.filter.create()
$filterVmObj.vms.add($obj.Id) | Out-Null
$objName = $vmSvc.list($filterVmObj) | Select-Object -ExpandProperty Name
} elseif ($obj.type -eq "Datastore") {
if (-Not $dsSvc) {$dsSvc = Get-CisService -Name com.vmware.vcenter.datastore}
$filterDsObj = $dsSvc.help.list.filter.create()
$filterDsObj.datastores.add($obj.Id) | Out-Null
$objName = $dsSvc.list($filterDsObj) | Select-Object -ExpandProperty Name
} else {$objName = 'Object Not Found'}
$tempObject = "" | Select-Object Tag, Entity
$tempObject.Tag = $tagReference | Where-Object {$_.id -eq $tagId} | Select-Object -ExpandProperty Name
$tempObject.Entity = $objName
$tagOutput += $tempObject
}
}
} else {
foreach ($tagId in $tagIdOutput) {
$tagAttObj = @()
$tagAttObj += $tagAssocSvc.list_attached_objects($tagId)
if ($global:DefaultVIServer -and $global:DefaultVIServer.Name -eq $global:DefaultCisServers.Name) {
[Boolean]$vCenterConn = $true
} elseif ($tagAttObj.Type -contains "VirtualMachine") {
if (-Not $vmSvc) {$vmSvc = Get-CisService -Name com.vmware.vcenter.vm}
} elseif ($tagAttObj.Type -contains "Datastore") {
if (-Not $dsSvc) {$dsSvc = Get-CisService -Name com.vmware.vcenter.datastore}
}
foreach ($obj in $tagAttObj) {
if ($vCenterConn) {
$newViObj = New-Object -TypeName VMware.Vim.ManagedObjectReference
$newViObj.Type = $obj.type
$newViObj.Value = $obj.id
$objName = Get-View -Id $newViObj -Property Name | Select-Object -ExpandProperty Name
} elseif ($obj.type -eq "VirtualMachine") {
$filterVmObj = $vmsvc.help.list.filter.create()
$filterVmObj.vms.add($obj.Id) | Out-Null
$objName = $vmSvc.list($filterVmObj) | Select-Object -ExpandProperty Name
} elseif ($obj.type -eq "Datastore") {
$filterDsObj = $dsSvc.help.list.filter.create()
$filterDsObj.datastores.add($obj.Id) | Out-Null
$objName = $dsSvc.list($filterDsObj) | Select-Object -ExpandProperty Name
} else {$objName = 'Object Not Found'}
$tempObject = "" | Select-Object Tag, Entity
$tempObject.Tag = $tagReference | Where-Object {$_.id -eq $tagId} | Select-Object -ExpandProperty Name
$tempObject.Entity = $objName
$tagOutput += $tempObject
}
}
}
return $tagOutput
}
}
function New-CISTagAssignment {
<#
.SYNOPSIS
Creates new tag assignments from the CIS REST API endpoint
.DESCRIPTION
Will create new tag assignments
.NOTES
Author: Kyle Ruddy, @kmruddy
.PARAMETER Tag
Tag name which should be referenced
.PARAMETER Entity
Object name which should be retreived
.PARAMETER TagId
Tag ID/s which should be referenced
.PARAMETER ObjectId
Object ID which/s should be retreived
.EXAMPLE
New-CISTagAssignment -Tag TagName -Entity VMName
Creates a tag assignment between the Tag name and the VM name
.EXAMPLE
New-CISTagAssignment -TagId $tagId -ObjectId 'vm-11'
Creates a tag assignment between the Tag ID and the Object ID
#>
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'Medium')]
param(
[Parameter(Mandatory=$false,Position=0)]
$Tag,
[Parameter(Mandatory=$false,Position=1)]
$Entity,
[Parameter(Mandatory=$false,Position=2)]
$TagId,
[Parameter(Mandatory=$false,Position=3)]
$ObjectId
)
If (-Not $global:DefaultCisServers) { Write-error "No CIS Connection found, please use the Connect-CisServer to connect" } Else {
$tagAssocSvc = Get-CisService -Name com.vmware.cis.tagging.tag_association
if ($PSBoundParameters.ContainsKey("Tag") -and $PSBoundParameters.ContainsKey("Entity")) {
if ($Tag -is [array] -and $Entity -isnot [array]) {
$tagIdList = $tagAssocSvc.help.attach_multiple_tags_to_object.tag_ids.create()
foreach ($t in $Tag) {
$tempId = Get-CISTag -Name $t | Select-Object -ExpandProperty Id
$tagIdList.add($tempId) | Out-Null
}
if ($global:DefaultVIServer -and $global:DefaultVIServer.Name -eq $global:DefaultCisServers.Name) {
$viObject = (Get-Inventory -Name $Entity).ExtensionData.MoRef
$objObject = $tagAssocSvc.help.list_attached_tags.object_id.create()
$objObject.id = $viObject.Value
$objObject.type = $viObject.type
} else {
if (-Not $vmSvc) {$vmSvc = Get-CisService -Name com.vmware.vcenter.vm}
$filterVmNameObj = $vmsvc.help.list.filter.create()
$filterVmNameObj.names.add($Entity) | Out-Null
$objId = $vmSvc.list($filterVmNameObj) | Select-Object -ExpandProperty vm
if ($objId) {$objType = "VirtualMachine"}
else {
if (-Not $dsSvc) {$dsSvc = Get-CisService -Name com.vmware.vcenter.datastore}
$filterDsNameObj = $dsSvc.Help.list.filter.Create()
$filterDsNameObj.names.add($Entity) | Out-Null
$objId = $dsSvc.list($filterDsNameObj) | Select-Object -ExpandProperty datastore
if ($objId) {$objType = "Datastore"}
else {Write-Warning "No entities found."; break}
}
$objObject = $tagAssocSvc.help.list_attached_tags.object_id.create()
$objObject.id = $objId
$objObject.type = $objType
}
$tagAssocSvc.attach_multiple_tags_to_object($objObject,$tagIdList) | Out-Null
} elseif ($Tag -isnot [array] -and $Entity -is [array]) {
$tagId = Get-CISTag -Name $Tag | Select-Object -ExpandProperty Id
$objList = $tagAssocSvc.help.attach_tag_to_multiple_objects.object_ids.create()
foreach ($e in $Entity) {
if ($global:DefaultVIServer -and $global:DefaultVIServer.Name -eq $global:DefaultCisServers.Name) {
$viObject = (Get-Inventory -Name $e).ExtensionData.MoRef
$objObject = $tagAssocSvc.help.list_attached_tags.object_id.create()
$objObject.id = $viObject.Value
$objObject.type = $viObject.type
} else {
if (-Not $vmSvc) {$vmSvc = Get-CisService -Name com.vmware.vcenter.vm}
$filterVmNameObj = $vmsvc.help.list.filter.create()
$filterVmNameObj.names.add($Entity) | Out-Null
$objId = $vmSvc.list($filterVmNameObj) | Select-Object -ExpandProperty vm
if ($objId) {$objType = "VirtualMachine"}
else {
if (-Not $dsSvc) {$dsSvc = Get-CisService -Name com.vmware.vcenter.datastore}
$filterDsObj = $dsSvc.help.list.filter.create()
$filterDsObj.datastores.add($obj.Id) | Out-Null
$objId = $dsSvc.list($filterDsObj) | Select-Object -ExpandProperty Datastore
if ($objId) {$objType = "Datastore"}
else {Write-Warning "No entities found."; break}
}
$objObject = $tagAssocSvc.help.list_attached_tags.object_id.create()
$objObject.id = $objId
$objObject.type = $objType
}
$objList.add($objObject) | Out-Null
}
$tagAssocSvc.attach_tag_to_multiple_objects($TagId,$objList) | Out-Null
} elseif ($Tag -isnot [array] -and $Entity -isnot [array]) {
$tagId = Get-CISTag -Name $Tag | Select-Object -ExpandProperty Id
if ($global:DefaultVIServer -and $global:DefaultVIServer.Name -eq $global:DefaultCisServers.Name) {
$viObject = (Get-Inventory -Name $Entity).ExtensionData.MoRef
$objObject = $tagAssocSvc.help.list_attached_tags.object_id.create()
$objObject.id = $viObject.Value
$objObject.type = $viObject.type
} else {
if (-Not $vmSvc) {$vmSvc = Get-CisService -Name com.vmware.vcenter.vm}
$filterVmNameObj = $vmsvc.help.list.filter.create()
$filterVmNameObj.names.add($Entity) | Out-Null
$objId = $vmSvc.list($filterVmNameObj) | Select-Object -ExpandProperty vm
if ($objId) {$objType = "VirtualMachine"}
else {
if (-Not $dsSvc) {$dsSvc = Get-CisService -Name com.vmware.vcenter.datastore}
$filterDsNameObj = $dsSvc.Help.list.filter.Create()
$filterDsNameObj.names.add($Entity) | Out-Null
$objId = $dsSvc.list($filterDsNameObj) | Select-Object -ExpandProperty datastore
if ($objId) {$objType = "Datastore"}
else {Write-Warning "No entities found."; break}
}
$objObject = $tagAssocSvc.help.list_attached_tags.object_id.create()
$objObject.id = $objId
$objObject.type = $objType
}
$tagAssocSvc.attach($TagId,$objObject) | Out-Null
}
} elseif ($PSBoundParameters.ContainsKey("TagId") -and $PSBoundParameters.ContainsKey("ObjectId")) {
if ($ObjectId.split('-')[0] -eq 'vm') {
$objType = "VirtualMachine"
} elseif ($ObjectId.Split('-')[0] -eq 'datastore') {
$objType = 'Datastore'
} else {Write-Warning 'Only VirtualMachine and Datastore types currently supported.'; break}
if ($TagId -is [array] -and $ObjectId -isnot [array]) {
$objObject = $tagAssocSvc.help.attach_multiple_tags_to_object.object_id.create()
$objObject.id = $ObjectId
$objObject.type = $objType
$tagIdList = $tagAssocSvc.help.attach_multiple_tags_to_object.tag_ids.create()
foreach ($tId in $TagId) {
$tagIdList.add($tId) | Out-Null
}
$tagAssocSvc.attach_multiple_tags_to_object($objObject,$tagIdList) | Out-Null
} elseif ($TagId -isnot [array] -and $ObjectId -is [array]) {
$objList = $tagAssocSvc.help.attach_tag_to_multiple_objects.object_ids.create()
foreach ($obj in $ObjectId) {
$objObject = $tagAssocSvc.help.attach_tag_to_multiple_objects.object_ids.element.create()
$objObject.id = $obj
$objObject.type = $objType
$objList.add($objObject) | Out-Null
}
$tagAssocSvc.attach_tag_to_multiple_objects($TagId,$objList) | Out-Null
} elseif ($TagId -isnot [array] -and $ObjectId -isnot [array]) {
$objObject = $tagAssocSvc.help.attach.object_id.create()
$objObject.id = $ObjectId
$objObject.type = $objType
$tagAssocSvc.attach($TagId,$objObject) | Out-Null
}
} else {Write-Output "Multiple tags with multiple objects are not a supported call."}
}
}
function Remove-CISTagAssignment {
<#
.SYNOPSIS
Removes a tag assignment from the CIS REST API endpoint
.DESCRIPTION
Will remove provided tag assignments
.NOTES
Author: Kyle Ruddy, @kmruddy
.PARAMETER Tag
Tag name which should be removed
.PARAMETER Entity
Object name which should be removed
.PARAMETER TagId
Tag ID/s which should be removed
.PARAMETER ObjectId
Object ID which/s should be removed
.EXAMPLE
Remove-CISTagAssignment -TagId $tagId -ObjectId 'vm-11'
Removes the tag assignment between the Tag ID and the Object ID
.EXAMPLE
Remove-CISTagAssignment -Tag TagName -Entity VMName
Removes the tag assignment between the Tag name and the Entity name
#>
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'High')]
param(
[Parameter(Mandatory=$false,Position=0,ValueFromPipelineByPropertyName=$true)]
$Tag,
[Parameter(Mandatory=$false,Position=1,ValueFromPipelineByPropertyName=$true)]
$Entity,
[Parameter(Mandatory=$false,Position=2)]
$TagId,
[Parameter(Mandatory=$false,Position=3)]
$ObjectId
)
If (-Not $global:DefaultCisServers) { Write-error "No CIS Connection found, please use the Connect-CisServer to connect" } Else {
$tagAssocSvc = Get-CisService -Name com.vmware.cis.tagging.tag_association
if ($PSBoundParameters.ContainsKey("Tag") -and $PSBoundParameters.ContainsKey("Entity")) {
if ($Tag -is [array] -and $Entity -isnot [array]) {
$tagIdList = $tagAssocSvc.help.detach_multiple_tags_from_object.tag_ids.create()
foreach ($t in $Tag) {
$tempId = Get-CISTag -Name $t | Select-Object -ExpandProperty Id
$tagIdList.add($tempId) | Out-Null
}
if ($global:DefaultVIServer -and $global:DefaultVIServer.Name -eq $global:DefaultCisServers.Name) {
$viObject = (Get-Inventory -Name $Entity).ExtensionData.MoRef
$objObject = $tagAssocSvc.help.detach_multiple_tags_from_object.object_id.create()
$objObject.id = $viObject.Value
$objObject.type = $viObject.type
} else {
$vmSvc = Get-CisService -Name com.vmware.vcenter.vm
$filterVmNameObj = $vmsvc.help.list.filter.create()
$filterVmNameObj.names.add($Entity) | Out-Null
$objId = $vmSvc.list($filterVmNameObj) | Select-Object -ExpandProperty vm
if ($objId) {$objType = "VirtualMachine"}
else {
if (-Not $dsSvc) {$dsSvc = Get-CisService -Name com.vmware.vcenter.datastore}
$filterDsNameObj = $dsSvc.Help.list.filter.Create()
$filterDsNameObj.names.add($Entity) | Out-Null
$objId = $dsSvc.list($filterDsNameObj) | Select-Object -ExpandProperty datastore
if ($objId) {$objType = "Datastore"}
else {Write-Warning "No entities found."; break}
}
$objObject = $tagAssocSvc.help.detach_multiple_tags_from_object.object_id.create()
$objObject.id = $objId
$objObject.type = $objType
}
$tagAssocSvc.detach_multiple_tags_from_object($objObject,$tagIdList) | Out-Null
} elseif ($Tag -isnot [array] -and $Entity -is [array]) {
$tagId = Get-CISTag -Name $Tag | Select-Object -ExpandProperty Id
$objList = $tagAssocSvc.help.detach_tag_from_multiple_objects.object_ids.create()
foreach ($e in $Entity) {
if ($global:DefaultVIServer -and $global:DefaultVIServer.Name -eq $global:DefaultCisServers.Name) {
$viObject = (Get-Inventory -Name $e).ExtensionData.MoRef
$objObject = $tagAssocSvc.help.detach_tag_from_multiple_objects.object_ids.element.create()
$objObject.id = $viObject.Value
$objObject.type = $viObject.type
} else {
$vmSvc = Get-CisService -Name com.vmware.vcenter.vm
$filterVmNameObj = $vmsvc.help.list.filter.create()
$filterVmNameObj.names.add($Entity) | Out-Null
$objId = $vmSvc.list($filterVmNameObj) | Select-Object -ExpandProperty vm
if ($objId) {$objType = "VirtualMachine"}
else {
if (-Not $dsSvc) {$dsSvc = Get-CisService -Name com.vmware.vcenter.datastore}
$filterDsNameObj = $dsSvc.Help.list.filter.Create()
$filterDsNameObj.names.add($Entity) | Out-Null
$objId = $dsSvc.list($filterDsNameObj) | Select-Object -ExpandProperty datastore
if ($objId) {$objType = "Datastore"}
else {Write-Warning "No entities found."; break}
}
$objObject = $tagAssocSvc.help.detach_tag_from_multiple_objects.object_ids.element.create()
$objObject.id = $objId
$objObject.type = $objType
}
$objList.add($objObject) | Out-Null
}
$tagAssocSvc.detach_tag_from_multiple_objects($TagId,$objList) | Out-Null
} elseif ($Tag -isnot [array] -and $Entity -isnot [array]) {
$tagId = Get-CISTag -Name $Tag | Select-Object -ExpandProperty Id
if ($global:DefaultVIServer -and $global:DefaultVIServer.Name -eq $global:DefaultCisServers.Name) {
$viObject = (Get-Inventory -Name $Entity).ExtensionData.MoRef
$objObject = $tagAssocSvc.help.detach.object_id.create()
$objObject.id = $viObject.Value
$objObject.type = $viObject.type
} else {
$vmSvc = Get-CisService -Name com.vmware.vcenter.vm
$filterVmNameObj = $vmsvc.help.list.filter.create()
$filterVmNameObj.names.add($Entity) | Out-Null
$objId = $vmSvc.list($filterVmNameObj) | Select-Object -ExpandProperty vm
if ($objId) {$objType = "VirtualMachine"}
else {
if (-Not $dsSvc) {$dsSvc = Get-CisService -Name com.vmware.vcenter.datastore}
$filterDsNameObj = $dsSvc.Help.list.filter.Create()
$filterDsNameObj.names.add($Entity) | Out-Null
$objId = $dsSvc.list($filterDsNameObj) | Select-Object -ExpandProperty datastore
if ($objId) {$objType = "Datastore"}
else {Write-Warning "No entities found."; break}
}
$objObject = $tagAssocSvc.help.detach.object_id.create()
$objObject.id = $objId
$objObject.type = $objType
}
$tagAssocSvc.detach($TagId,$objObject) | Out-Null
}
} elseif ($PSBoundParameters.ContainsKey("TagId") -and $PSBoundParameters.ContainsKey("ObjectId")) {
if ($ObjectId.split('-')[0] -eq 'vm') {
$objType = "VirtualMachine"
} elseif ($ObjectId.Split('-')[0] -eq 'datastore') {
$objType = 'Datastore'
}else {Write-Warning 'Only VirtualMachine types currently supported.'; break}
if ($TagId -is [array] -and $ObjectId -isnot [array]) {
$objObject = $tagAssocSvc.help.detach_multiple_tags_from_object.object_id.create()
$objObject.id = $ObjectId
$objObject.type = $objType
$tagIdList = $tagAssocSvc.help.detach_multiple_tags_from_object.tag_ids.create()
foreach ($tId in $TagId) {
$tagIdList.add($tId) | Out-Null
}
$tagAssocSvc.detach_multiple_tags_from_object($objObject,$tagIdList) | Out-Null
} elseif ($TagId -isnot [array] -and $ObjectId -is [array]) {
$objList = $tagAssocSvc.help.detach_tag_from_multiple_objects.object_ids.create()
foreach ($obj in $ObjectId) {
$objObject = $tagAssocSvc.help.detach_tag_from_multiple_objects.object_ids.element.create()
$objObject.id = $obj
$objObject.type = $objType
$objList.add($objObject) | Out-Null
}
$tagAssocSvc.detach_tag_from_multiple_objects($TagId,$objList) | Out-Null
} elseif ($TagId -isnot [array] -and $ObjectId -isnot [array]) {
$objObject = $tagAssocSvc.help.detach.object_id.create()
$objObject.id = $ObjectId
$objObject.type = $objType
$tagAssocSvc.detach($TagId,$objObject) | Out-Null
}
} else {Write-Output "Multiple tags with multiple objects are not a supported call."}
}
}

Binary file not shown.

View File

@@ -0,0 +1,256 @@
Function Connect-DRaas {
<#
.NOTES
===========================================================================
Created by: William Lam
Date: 05/23/2019
Organization: VMware
Blog: http://www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.SYNOPSIS
This cmdlet creates $global:draasConnection object containing the DRaaS URL along with CSP Token Header
.DESCRIPTION
This cmdlet creates $global:draasConnection object containing the DRaaS URL along with CSP Token Header
.EXAMPLE
Connect-DRaaS -RefreshToken $RefreshToken -OrgName $OrgName -SDDCName $SDDCName
.NOTES
You must be logged into VMC using Connect-VmcServer cmdlet
#>
Param (
[Parameter(Mandatory=$true)][String]$RefreshToken,
[Parameter(Mandatory=$true)][String]$OrgName,
[Parameter(Mandatory=$true)][String]$SDDCName
)
If (-Not $global:DefaultVMCServers.IsConnected) { Write-error "No valid VMC Connection found, please use the Connect-VMC to connect"; break } Else {
$sddcService = Get-VmcService "com.vmware.vmc.orgs.sddcs"
$orgId = (Get-VMCOrg -Name $OrgName).Id
$sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id
$sddc = $sddcService.get($orgId,$sddcId)
}
$results = Invoke-WebRequest -Uri "https://console.cloud.vmware.com/csp/gateway/am/api/auth/api-tokens/authorize?refresh_token=$RefreshToken" -Method POST -ContentType "application/json" -UseBasicParsing -Headers @{"csp-auth-token"="$RefreshToken"}
if($results.StatusCode -ne 200) {
Write-Host -ForegroundColor Red "Failed to retrieve Access Token, please ensure your VMC Refresh Token is valid and try again"
break
}
$accessToken = ($results | ConvertFrom-Json).access_token
$headers = @{
"csp-auth-token"="$accessToken"
"Content-Type"="application/json"
"Accept"="application/json"
}
$global:draasConnection = new-object PSObject -Property @{
'Server' = "https://vmc.vmware.com/vmc/draas/api/orgs/$orgId/sddcs/$sddcId/site-recovery"
'headers' = $headers
}
$global:draasConnection
}
Function Get-DRaas {
<#
.NOTES
===========================================================================
Created by: William Lam
Date: 05/23/2019
Organization: VMware
Blog: http://www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.SYNOPSIS
Returns information about DRaaS configuration for a given SDDC
.DESCRIPTION
This cmdlet returns information about DRaaS configuration for a given SDDC. Can be used to monitor both activate and deactivate operations.
.EXAMPLE
Get-DRaas
#>
Param (
[Switch]$Troubleshoot
)
If (-Not $global:draasConnection) { Write-error "No DRaaS Connection found, please use Connect-DRaaS" } Else {
$method = "GET"
$draasUrl = $global:draasConnection.Server
$draasVersionUrl = $global:draasConnection.Server + "/versions"
if($Troubleshoot) {
Write-Host -ForegroundColor cyan "`n[DEBUG] - $METHOD`n$draasUrl`n"
}
try {
if($PSVersionTable.PSEdition -eq "Core") {
$requests = Invoke-WebRequest -Uri $draasUrl -Method $method -Headers $global:draasConnection.headers -SkipCertificateCheck
} else {
$requests = Invoke-WebRequest -Uri $draasUrl -Method $method -Headers $global:draasConnection.headers
}
} catch {
if($_.Exception.Response.StatusCode -eq "Unauthorized") {
Write-Host -ForegroundColor Red "`nThe CSP session is no longer valid, please re-run the Connect-DRaaS cmdlet to retrieve a new token`n"
break
} else {
Write-Error "Error in retrieving DRaaS Information"
Write-Error "`n($_.Exception.Message)`n"
break
}
}
if($requests.StatusCode -eq 200) {
$json = ($requests.Content | ConvertFrom-Json)
$draasId = $json.id;
$draasState = $json.site_recovery_state;
$srmNode = $json.srm_node.ip_address;
$srmNodeState = $json.site_recovery_state;
$vrNode = $json.vr_node.ip_address;
$vrNodeState = $json.vr_node.state;
$draasUrl = $json.draas_h5_url;
if($srmNodeState -eq "ACTIVATED") {
if($Troubleshoot) {
Write-Host -ForegroundColor cyan "`n[DEBUG] - $METHOD`n$draasVersionUrl`n"
}
try {
if($PSVersionTable.PSEdition -eq "Core") {
$requests = Invoke-WebRequest -Uri $draasVersionUrl -Method $method -Headers $global:draasConnection.headers -SkipCertificateCheck
} else {
$requests = Invoke-WebRequest -Uri $draasVersionUrl -Method $method -Headers $global:draasConnection.headers
}
} catch {
if($_.Exception.Response.StatusCode -eq "Unauthorized") {
Write-Host -ForegroundColor Red "`nThe CSP session is no longer valid, please re-run the Connect-DRaaS cmdlet to retrieve a new token`n"
break
} else {
Write-Error "Error in retrieving DRaaS Information"
Write-Error "`n($_.Exception.Message)`n"
break
}
}
if($requests.StatusCode -eq 200) {
$json = ($requests.Content | ConvertFrom-Json).node_versions
$srmVersion,$srmDescription = ($json | where {$_.node_ip -eq $srmNode}).full_version.split("`n")
$vrVersion,$vrDescription = ($json | where {$_.node_ip -eq $vrNode}).full_version.split("`n")
$results = [pscustomobject] @{
ID = $draasId;
DRaaSState = $draasState;
SRMNode = $srmNode;
SRMVersion = $srmVersion;
SRMNodeState = $srmNodeState;
VRNode = $vrNode;
VRVersion = $vrVersion;
VRNodeState = $vrNodeState;
DRaaSURL = $draasUrl;
}
$results
}
} elseif ($srmNodeState -eq "ACTIVATING" -or $srmNodeState -eq "DEACTIVATING") {
$results = [pscustomobject] @{
ID = $draasId;
DRaaSState = $draasState;
SRMNode = $srmNode;
SRMNodeState = $srmNodeState;
VRNode = $vrNode;
VRNodeState = $vrNodeState;
DRaaSURL = $draasUrl;
}
$results
} else {
Write-Host "`nDRaaS is currently deactivated, please run Set-DRaas -Activate`n"
}
} else {
Write-Host "`nDRaaS has not been activated before, please run Set-DRaas -Activate`n"
}
}
}
Function Set-DRaas {
<#
.NOTES
===========================================================================
Created by: William Lam
Date: 05/23/2019
Organization: VMware
Blog: http://www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.SYNOPSIS
Activate or deactivate DRaaS for a given SDDC
.DESCRIPTION
This cmdlet activates or deactivates DRaaS for a given SDDC
.EXAMPLE
Get-DRaas
#>
Param (
[Switch]$Activate,
[Switch]$Deactivate,
[Switch]$Troubleshoot
)
If (-Not $global:draasConnection) { Write-error "No DRaaS Connection found, please use Connect-DRaaS" } Else {
$draasUrl = $global:draasConnection.server
if($Activate) {
$method = "POST"
if($Troubleshoot) {
Write-Host -ForegroundColor cyan "`n[DEBUG] - $METHOD`n$draasUrl`n"
}
try {
if($PSVersionTable.PSEdition -eq "Core") {
$requests = Invoke-WebRequest -Uri $draasUrl -Method $method -Headers $global:draasConnection.headers -SkipCertificateCheck
} else {
$requests = Invoke-WebRequest -Uri $draasUrl -Method $method -Headers $global:draasConnection.headers
}
} catch {
if($_.Exception.Response.StatusCode -eq "Unauthorized") {
Write-Host -ForegroundColor Red "`nThe CSP session is no longer valid, please re-run the Connect-DRaaS cmdlet to retrieve a new token`n"
break
} else {
Write-Error "Error in activating DRaaS"
Write-Error "`n($_.Exception.Message)`n"
break
}
}
Write-Host "`nActivating DRaaS, this will take some time and you can monitor the progress using Get-DRaaS or using the VMC Console UI`n"
} elseif ($Deactivate) {
$method = "DELETE"
if($Troubleshoot) {
Write-Host -ForegroundColor cyan "`n[DEBUG] - $METHOD`n$draasUrl`n"
}
try {
if($PSVersionTable.PSEdition -eq "Core") {
$requests = Invoke-WebRequest -Uri $draasUrl -Method $method -Headers $global:draasConnection.headers -SkipCertificateCheck
} else {
$requests = Invoke-WebRequest -Uri $draasUrl -Method $method -Headers $global:draasConnection.headers
}
} catch {
if($_.Exception.Response.StatusCode -eq "Unauthorized") {
Write-Host -ForegroundColor Red "`nThe CSP session is no longer valid, please re-run the Connect-DRaaS cmdlet to retrieve a new token`n"
break
} else {
Write-Error "Error in deactivating DRaaS"
Write-Error "`n($_.Exception.Message)`n"
break
}
}
Write-Host "`nDeactivating DRaaS, this will take some time and you can monitor the progress using Get-DRaaS or the VMC Console UI`n"
} else {
Write-Error "Invalid Operation"
}
}
}

View File

@@ -36,7 +36,12 @@ Description = 'PowerShell Module for Managing Hybrid Cloud Extension (HCX) on VM
PowerShellVersion = '6.0'
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
FunctionsToExport = 'Connect-HcxServer', 'Get-HcxCloudConfig', 'Get-HcxEndpoint', 'New-HcxMigration', 'Get-HcxMigration', 'Connect-HcxVAMI', 'Get-HcxVCConfig', 'Set-HcxLicense', 'Set-HcxVCConfig', 'Get-HcxNSXConfig', 'Set-HcxNSXConfig', 'Get-HcxCity', 'Get-HcxLocation', 'Set-HcxLocation', 'Get-HcxRoleMapping', 'Set-HcxRoleMapping', 'Get-HcxProxy', 'Set-HcxProxy', 'Remove-HcxProxy'
FunctionsToExport = 'Connect-HcxServer', 'Get-HcxCloudConfig', 'Get-HcxEndpoint', 'New-HcxMigration', 'Get-HcxMigration', 'Connect-HcxVAMI',
'Get-HcxVCConfig', 'Set-HcxLicense', 'Set-HcxVCConfig', 'Get-HcxNSXConfig', 'Set-HcxNSXConfig', 'Get-HcxCity', 'Get-HcxLocation', 'Set-HcxLocation',
'Get-HcxRoleMapping', 'Set-HcxRoleMapping', 'Get-HcxProxy', 'Set-HcxProxy', 'Remove-HcxProxy', 'Connect-HcxCloudServer', 'Get-HCXCloudActivationKey',
'Get-HCXCloudSubscription', 'New-HCXCloudActivationKey', 'Get-HCXCloud', 'Set-HCXCloud'
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
CmdletsToExport = @()

View File

@@ -453,12 +453,23 @@ Function Get-HcxMigration {
Get-HcxMigration -MigrationId <MigrationID>
#>
Param (
[Parameter(Mandatory=$false)][String]$MigrationId,
[Parameter(Mandatory=$false)][String[]]$MigrationId,
[Switch]$RunningMigrations
)
If (-Not $global:hcxConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxManager " } Else {
$spec = @{}
If($PSBoundParameters.ContainsKey("MigrationId")){
$spec = @{
filter = @{
migrationId = $MigrationId
}
paging =@{
pageSize = $MigrationId.Count
}
}
} Else {
$spec = @{}
}
$body = $spec | ConvertTo-Json
$hcxQueryUrl = $global:hcxConnection.Server + "/migrations?action=query"
@@ -468,10 +479,10 @@ Function Get-HcxMigration {
$requests = Invoke-WebRequest -Uri $hcxQueryUrl -Method POST -Headers $global:hcxConnection.headers -UseBasicParsing
}
$migrations = ($requests.content | ConvertFrom-Json).rows
if($PSBoundParameters.ContainsKey("MigrationId")){
$migrations = $migrations | where { $_.migrationId -eq $MigrationId }
$migrations = ($requests.content | ConvertFrom-Json).items
} else {
$migrations = ($requests.content | ConvertFrom-Json).rows
}
if($RunningMigrations){
@@ -559,16 +570,22 @@ Function Get-HcxVCConfig {
#>
If (-Not $global:hcxVAMIConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxVAMI " } Else {
$vcConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/vcenter"
$pscConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/lookupservice"
if($PSVersionTable.PSEdition -eq "Core") {
$vcRequests = Invoke-WebRequest -Uri $vcConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck
$ssoRequests = Invoke-WebRequest -Uri $pscConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck
} else {
$vcRequests = Invoke-WebRequest -Uri $vcConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing
$ssoRequests = Invoke-WebRequest -Uri $pscConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing
}
$vcData = ($vcRequests.content | ConvertFrom-Json).data.items
$ssoData = ($ssoRequests.content | ConvertFrom-Json).data.items
$tmp = [pscustomobject] @{
Name = $vcData.config.name;
UserName = $vcData.Config.userName
LookupServiceUrl = $ssoData.config.lookupServiceUrl
Version = $vcData.config.version;
Build = $vcData.config.buildNumber;
UUID = $vcData.config.vcuuid;
@@ -578,6 +595,38 @@ Function Get-HcxVCConfig {
}
}
Function Get-HcxLicense {
<#
.NOTES
===========================================================================
Created by: Mark McGilly
Date: 4/29/2019
Organization: Liberty Mutual Insurance
===========================================================================
.SYNOPSIS
Returns the license key that is registered with HCX Manager
.DESCRIPTION
This cmdlet returns the license key registered with HCX Manager
.EXAMPLE
Get-HcxLicense
#>
If (-Not $global:hcxVAMIConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxVAMI " } Else {
$hcxConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/hcx"
if($PSVersionTable.PSEdition -eq "Core") {
$licenseRequests = Invoke-WebRequest -Uri $hcxConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck
} else {
$licenseRequests = Invoke-WebRequest -Uri $hcxConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing
}
$license = ($licenseRequests.content | ConvertFrom-Json).data.items
if($licenseRequests) {
$license.config.activationKey
}
}
}
Function Set-HcxLicense {
<#
.NOTES
@@ -789,6 +838,7 @@ Function Get-HcxNSXConfig {
$tmp = [pscustomobject] @{
Name = $nsxData.config.url;
UserName = $nsxData.config.userName
Version = $nsxData.config.version;
HCXUUID = $nsxData.config.uuid;
}
@@ -1200,6 +1250,7 @@ Function Set-HcxProxy {
[Parameter(Mandatory=$True)]$ProxyPort,
[Parameter(Mandatory=$False)]$ProxyUser,
[Parameter(Mandatory=$False)]$ProxyPassword,
[Parameter(Mandatory=$False)]$ProxyExclusions,
[Switch]$Troubleshoot
)
@@ -1214,7 +1265,7 @@ Function Set-HcxProxy {
config = @{
proxyHost = "$ProxyServer";
proxyPort = "$ProxyPort";
nonProxyHosts = "";
nonProxyHosts = "$ProxyExclusions";
userName = "$ProxyUser";
password = "$ProxyPassword";
}
@@ -1306,4 +1357,346 @@ Function Remove-HcxProxy {
Write-Warning "No proxy settings were configured"
}
}
}
Function Connect-HcxCloudServer {
<#
.NOTES
===========================================================================
Created by: William Lam
Date: 06/19/2019
Organization: VMware
Blog: http://www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.SYNOPSIS
Connect to the HCX Cloud Service
.DESCRIPTION
This cmdlet connects to the HCX Cloud Service
.EXAMPLE
Connect-HcxCloudServer -RefreshToken
#>
Param (
[Parameter(Mandatory=$true)][String]$RefreshToken,
[Switch]$Troubleshoot
)
$results = Invoke-WebRequest -Uri "https://console.cloud.vmware.com/csp/gateway/am/api/auth/api-tokens/authorize?refresh_token=$RefreshToken" -Method POST -ContentType "application/json" -UseBasicParsing -Headers @{"csp-auth-token"="$RefreshToken"}
if($results.StatusCode -ne 200) {
Write-Host -ForegroundColor Red "Failed to retrieve Access Token, please ensure your VMC Refresh Token is valid and try again"
break
}
$accessToken = ($results | ConvertFrom-Json).access_token
$payload = @{
token = $accessToken;
}
$body = $payload | ConvertTo-Json
$hcxCloudLoginUrl = "https://connect.hcx.vmware.com/provider/csp/api/sessions"
if($PSVersionTable.PSEdition -eq "Core") {
$results = Invoke-WebRequest -Uri $hcxCloudLoginUrl -Body $body -Method POST -UseBasicParsing -ContentType "application/json" -SkipCertificateCheck
} else {
$results = Invoke-WebRequest -Uri $hcxCloudLoginUrl -Body $body -Method POST -UseBasicParsing -ContentType "application/json"
}
if($results.StatusCode -eq 200) {
$hcxAuthToken = $results.Headers.'x-hm-authorization'
$headers = @{
"x-hm-authorization"="$hcxAuthToken"
"Content-Type"="application/json"
"Accept"="application/json"
}
$global:hcxCloudConnection = new-object PSObject -Property @{
'Server' = "https://connect.hcx.vmware.com/provider/csp/consumer/api";
'headers' = $headers
}
$global:hcxCloudConnection
} else {
Write-Error "Failed to connect to HCX Cloud Service, please verify your CSP Refresh Token is valid"
}
}
Function Get-HCXCloudActivationKey {
<#
.NOTES
===========================================================================
Created by: William Lam
Date: 06/19/2019
Organization: VMware
Blog: http://www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.SYNOPSIS
Returns the activation keys from HCX Cloud
.DESCRIPTION
This cmdlet returns the activation keys from HCX Cloud
.EXAMPLE
Get-HCXCloudActivationKeys
.EXAMPLE
Get-HCXCloudActivationKeys -Type [AVAILABLE|CONSUMED|DEACTIVATED|DELETED]
#>
Param (
[Parameter(Mandatory=$false)][ValidateSet("AVAILABLE","CONSUMED","DEACTIVATED","DELETED")][String]$Type,
[Switch]$Troubleshoot
)
If (-Not $global:hcxCloudConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxVAMI " } Else {
$method = "GET"
$hcxLicenseUrl = $global:hcxCloudConnection.Server + "/activationKeys"
if($Troubleshoot) {
Write-Host -ForegroundColor cyan "`n[DEBUG] - $METHOD`n$hcxLicenseUrl`n"
}
if($PSVersionTable.PSEdition -eq "Core") {
$results = Invoke-WebRequest -Uri $hcxLicenseUrl -Method $method -Headers $global:hcxCloudConnection.headers -UseBasicParsing -SkipCertificateCheck
} else {
$results = Invoke-WebRequest -Uri $hcxLicenseUrl -Method $method -Headers $global:hcxCloudConnection.headers -UseBasicParsing
}
if($Type) {
($results.content | ConvertFrom-Json).result.activationKeys | where { $_.status -eq $Type}
} else {
($results.content | ConvertFrom-Json).result.activationKeys
}
}
}
Function Get-HCXCloudSubscription {
<#
.NOTES
===========================================================================
Created by: William Lam
Date: 06/19/2019
Organization: VMware
Blog: http://www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.SYNOPSIS
Returns the subscription information for HCX CLoud Service
.DESCRIPTION
This cmdlet returns the subscription information for HCX Cloud Service
.EXAMPLE
Get-HCXCloudSubscription
#>
Param (
[Switch]$Troubleshoot
)
If (-Not $global:hcxCloudConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxVAMI " } Else {
$method = "GET"
$hcxSubscriptionUrl = $global:hcxCloudConnection.Server + "/subscriptions"
if($Troubleshoot) {
Write-Host -ForegroundColor cyan "`n[DEBUG] - $METHOD`n$hcxSubscriptionUrl`n"
}
if($PSVersionTable.PSEdition -eq "Core") {
$results = Invoke-WebRequest -Uri $hcxSubscriptionUrl -Method $method -Headers $global:hcxCloudConnection.headers -UseBasicParsing -SkipCertificateCheck
} else {
$results = Invoke-WebRequest -Uri $hcxSubscriptionUrl -Method $method -Headers $global:hcxCloudConnection.headers -UseBasicParsing
}
($results.content | ConvertFrom-Json).subscriptions | select @{Name = "SID"; Expression = {$_.sid}},@{Name = "STATUS"; Expression = {$_.status}},@{Name = 'OfferName'; Expression = {$_.subscriptionComponents.offerName}}
}
}
Function New-HCXCloudActivationKey {
<#
.NOTES
===========================================================================
Created by: William Lam
Date: 06/19/2019
Organization: VMware
Blog: http://www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.SYNOPSIS
Requests new HCX Activation License Key
.DESCRIPTION
This cmdlet requests new HCX Activation License Key
.EXAMPLE
Get-HCXCloudActivationKey -SID <SID> -SystemType [HCX-CLOUD|HCX-ENTERPRISE]
#>
Param (
[Parameter(Mandatory=$true)][String]$SID,
[Parameter(Mandatory=$true)][ValidateSet("HCX-CLOUD","HCX-ENTERPRISE")][String]$SystemType,
[Switch]$Troubleshoot
)
If (-Not $global:hcxCloudConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxVAMI " } Else {
$method = "POST"
$hcxLicenseUrl = $global:hcxCloudConnection.Server + "/activationKeys"
$payload = @{
numberOfKeys = "1";
sid = $SID;
systemType = ($SystemType).toLower();
}
$body = $payload | ConvertTo-Json
if($Troubleshoot) {
Write-Host -ForegroundColor cyan "`n[DEBUG] - $METHOD`n$hcxSubscriptionUrl`n"
Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n"
}
try {
if($PSVersionTable.PSEdition -eq "Core") {
$requests = Invoke-WebRequest -Uri $hcxLicenseUrl -Method $method -Body $body -Headers $global:hcxCloudConnection.headers -UseBasicParsing -SkipCertificateCheck
} else {
$requests = Invoke-WebRequest -Uri $hcxLicenseUrl -Method $method -Body $body -Headers $global:hcxCloudConnection.headers -UseBasicParsing
}
} catch {
if($_.Exception.Response.StatusCode -eq "Unauthorized") {
Write-Host -ForegroundColor Red "`nThe HCX Cloud session is no longer valid, please re-run the Connect-HCXCloudServer cmdlet to retrieve a new token`n"
break
} else {
Write-Error "Error in requesting new HCX license key"
Write-Error "`n($_.Exception.Message)`n"
break
}
}
if($requests.StatusCode -eq 200) {
Write-Host "Successfully requestd new $SystemType License Key"
($requests.content | ConvertFrom-Json).activationKeys
}
}
}
Function Get-HCXCloud {
<#
.NOTES
===========================================================================
Created by: William Lam
Date: 06/19/2019
Organization: VMware
Blog: http://www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.SYNOPSIS
Returns HCX deployment information for all SDDCs
.DESCRIPTION
This cmdlet returns HCX deployment information for all SDDCs
.EXAMPLE
Get-HCXCloud
#>
Param (
[Switch]$Troubleshoot
)
If (-Not $global:hcxCloudConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxVAMI " } Else {
$method = "GET"
$hcxCloudSDDCUrl = $global:hcxCloudConnection.Server + "/sddcs"
if($Troubleshoot) {
Write-Host -ForegroundColor cyan "`n[DEBUG] - $METHOD`n$hcxSubscriptionUrl`n"
}
if($PSVersionTable.PSEdition -eq "Core") {
$results = Invoke-WebRequest -Uri $hcxCloudSDDCUrl -Method $method -Headers $global:hcxCloudConnection.headers -UseBasicParsing -SkipCertificateCheck
} else {
$results = Invoke-WebRequest -Uri $hcxCloudSDDCUrl -Method $method -Headers $global:hcxCloudConnection.headers -UseBasicParsing
}
($results.content | ConvertFrom-Json).sddcs | Sort-Object -Property Name | select @{Name = "SDDCName"; Expression = {$_.name}}, @{Name = "SDDCID"; Expression = {$_.id}}, @{Name = "HCXStatus"; Expression = {$_.activationStatus}}, @{Name = "Region"; Expression = {$_.region}}
}
}
Function Set-HCXCloud {
<#
.NOTES
===========================================================================
Created by: William Lam
Date: 06/19/2019
Organization: VMware
Blog: http://www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.SYNOPSIS
Activate or Deactivate HCX for given VMC SDDC
.DESCRIPTION
This cmdlet activates or deactivates HCX for given VMC SDDC
.EXAMPLE
Set-HCXCloud -Activate -SDDCID $SDDCID
.EXAMPLE
Set-HCXCloud -Deactivate -SDDCID $SDDCID
#>
Param (
[Parameter(Mandatory=$true)][String]$SDDCID,
[Switch]$Activate,
[Switch]$Deactivate,
[Switch]$Troubleshoot
)
If (-Not $global:hcxCloudConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxVAMI " } Else {
$method = "POST"
if($Activate) {
$HcxSid = (Get-HCXCloudSubscription | where {$_.STATUS -eq "ACTIVE"}).SID
# Check to see if there is an available HCX-Cloud Key
$HcxKey = ((Get-HCXCloudActivationKey -Type AVAILABLE | where {$_.systemType -eq 'hcx-cloud'}) | select -First 1).activationKey
if($HcxKey -eq $null) {
$HcxKey = New-HCXCloudActivationKey -SID $HcxSid -SystemType HCX-CLOUD
}
if($HCXKey -eq $null -or $HcxSid -eq $null) {
Write-Error "Failed to retrieve HCX Subscription ID or request HCX Cloud License Key"
break
}
$hcxSDDCUrl = $global:hcxCloudConnection.Server + "/sddcs/$($SDDCID)?action=activate"
$payload = @{
activationKey = $HcxKey;
}
} else {
$payload = ""
$hcxSDDCUrl = $global:hcxCloudConnection.Server + "/sddcs/$($SDDCID)?action=deactivate"
}
$body = $payload | ConvertTo-Json
if($Troubleshoot) {
Write-Host -ForegroundColor cyan "`n[DEBUG] - $METHOD`n$hcxSDDCUrl`n"
Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n"
}
try {
if($PSVersionTable.PSEdition -eq "Core") {
$requests = Invoke-WebRequest -Uri $hcxSDDCUrl -Method $method -Body $body -Headers $global:hcxCloudConnection.headers -UseBasicParsing -SkipCertificateCheck
} else {
$requests = Invoke-WebRequest -Uri $hcxSDDCUrl -Method $method -Body $body -Headers $global:hcxCloudConnection.headers -UseBasicParsing
}
} catch {
if($_.Exception.Response.StatusCode -eq "Unauthorized") {
Write-Host -ForegroundColor Red "`nThe HCX Cloud session is no longer valid, please re-run the Connect-HCXCloudServer cmdlet to retrieve a new token`n"
break
} else {
Write-Error "Error in attempting to activate or deactivate HCX"
Write-Error "`n($_.Exception.Message)`n"
break
}
}
if($requests.StatusCode -eq 200) {
if($Activate) {
Write-Host "Activating HCX for SDDC: $SDDCID, starting deployment. You can monitor the status using the HCX Cloud Console"
} else {
Write-Host "Deactivating HCX for SDDC: $SDDCID, starting un-deploymentt. You can monitor the status using the HCX Cloud Console"
}
($requests.content | ConvertFrom-Json)
}
}
}

View File

@@ -0,0 +1,97 @@
{
"Type": "AUTOMATED",
"Data": {
"Name": "LCFarmJson",
"DisplayName": "FarmJsonTest",
"AccessGroup": "Root",
"Description": "created LC Farm from PS via JSON with NVIDIA GRID VGPU",
"Enabled": null,
"Deleting": false,
"Settings": {
"DisconnectedSessionTimeoutPolicy": "NEVER",
"DisconnectedSessionTimeoutMinutes": 1,
"EmptySessionTimeoutPolicy": "AFTER",
"EmptySessionTimeoutMinutes": 1,
"LogoffAfterTimeout": false
},
"Desktop": null,
"DisplayProtocolSettings": {
"DefaultDisplayProtocol": "PCOIP",
"AllowDisplayProtocolOverride": false,
"EnableHTMLAccess": false,
"EnableCollaboration": false,
"EnableGRIDvGPUs": true,
"VGPUGridProfile": "grid_m10-8a"
},
"ServerErrorThreshold": null,
"MirageConfigurationOverrides": {
"OverrideGlobalSetting": false,
"Enabled": false,
"Url": null
}
},
"AutomatedFarmSpec": {
"ProvisioningType": "VIEW_COMPOSER",
"VirtualCenter": null,
"RdsServerNamingSpec": {
"NamingMethod": "PATTERN",
"PatternNamingSettings": {
"NamingPattern": "LCFarmVMPS",
"MaxNumberOfRDSServers": 1
}
},
"VirtualCenterProvisioningSettings": {
"EnableProvisioning": true,
"StopProvisioningOnError": true,
"MinReadyVMsOnVComposerMaintenance": 0,
"VirtualCenterProvisioningData": {
"ParentVm": "RDSServer",
"Snapshot": "RDS_SNAP1",
"Datacenter": null,
"VmFolder": "Praveen",
"HostOrCluster": "CS-1",
"ResourcePool": "CS-1"
},
"VirtualCenterStorageSettings": {
"Datastores": [
{
"Datastore": "Datastore1",
"StorageOvercommit": "UNBOUNDED"
}
],
"UseVSan": false,
"ViewComposerStorageSettings": {
"UseSeparateDatastoresReplicaAndOSDisks": false,
"ReplicaDiskDatastore": null,
"UseNativeSnapshots": false,
"SpaceReclamationSettings": {
"ReclaimVmDiskSpace": false,
"ReclamationThresholdGB": null,
"BlackoutTimes": null
}
}
},
"VirtualCenterNetworkingSettings": {
"Nics": null
}
},
"VirtualCenterManagedCommonSettings": {
"TransparentPageSharingScope": "VM"
},
"CustomizationSettings": {
"CustomizationType": "SYS_PREP",
"DomainAdministrator": null,
"AdContainer": "CN=Computers",
"ReusePreExistingAccounts": false,
"SysprepCustomizationSettings": {
"CustomizationSpec": "PraveenCust"
}
},
"RdsServerMaxSessionsData": {
"MaxSessionsType": "UNLIMITED",
"MaxSessions": null
}
},
"ManualFarmSpec": null,
"NetBiosName": "adviewdev"
}

View File

@@ -12,7 +12,7 @@
# RootModule = ''
# Version number of this module.
ModuleVersion = '1.1'
ModuleVersion = '1.3.1'
# ID used to uniquely identify this module
GUID = '6d3f7fb5-4e52-43d8-91e1-f65f72532a1d'

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,310 @@
<#
Copyright 2018 VMware, Inc. All rights reserved.
#>
# Class to manage Host resources
Class HostResource {
[VMware.VimAutomation.Types.VMHost] $vmhost
[string] $vcname
[string] $clustername
[string] $dcname
[string] $hostname
[string] $apitype
[string] $powerstatus
[string] $productname
[string] $version
[string] $fullname
[string] $connectionstatus
[string] $checkRelease
[int] $port
[Array] $ComponentResource = @()
[Array] $JsonProperties = @('__type__', 'dcname', 'vcname','clustername','hostname', 'apitype',
'powerstatus', 'productname', 'version', 'fullname', 'connectionstatus','checkRelease')
HostResource(
[VMware.VimAutomation.Types.VMHost] $vmhost) {
$this.vmhost = $vmhost
$view =$vmhost|Get-View
$vCenter_IP = $view.Summary.ManagementServerIp
if($vCenter_IP){
$this.vcname =$vCenter_IP
$this.dcname = (Get-Datacenter -VMHost $vmhost).Name
$this.clustername = (Get-Cluster -VMHost $vmhost).Name
}else{
$this.vcname =$this.vmhost.Name
}
$this.hostname = $this.vmhost.Name
$summary = $this.vmhost.ExtensionData.Summary
$this.powerstatus = $summary.runtime.powerState
$this.connectionstatus = $summary.runtime.connectionState
$this.apitype = $summary.Config.Product.apiType
$this.fullname = $summary.Config.Product.FullName
$this.version = $summary.Config.Product.version
$this.productname = $summary.Config.Product.licenseProductName
$this.port = 443
}
[Array] query_components() {
if ($this.ComponentResource.Count -eq 0) {
# Get server info
for($count_retry=0;$count_retry -lt 3;$count_retry ++){
try{
$svrResoure = [ServerResource]::new()
$svrResoure.set_data($this.vmhost)
$this.ComponentResource += $svrResoure
break
}catch{
error('query components server for '+$this.vmhost.Name +' error, retry it ' +($count_retry+1) +' times')
}
}
# Get PCI devices
for($count_retry=0;$count_retry -lt 3;$count_retry ++){
try{
$this.query_pcidevices()
break
}catch{
error('query components pcidevice for '+$this.vmhost.Name +' error, retry it ' +($count_retry+1) +' times')
if($count_retry -eq 2){
error('query components pcidevice for '+$this.vmhost.Name +' faild')
}
}
}
}
return $this.ComponentResource
}
[void] query_pcidevices() {
$EsxCliV2 = Get-EsxCli -V2 -VMHost $this.vmhost
$AllPciDevice = $EsxCliV2.hardware.pci.list.invoke()
foreach ($Pci in $AllPciDevice) {
# Ignore USB controllers, iLO/iDRAC devices
if ($Pci.DeviceName -like "*USB*" -or $Pci.DeviceName -like "*iLO*" -or $Pci.DeviceName -like "*iDRAC*") {
continue
}
# Get the NICs and storage adapters.
# We found NIC and storage adapters usually have module ID other than 0 or 1
$pciDevice = [IoDeviceResource]::new()
if ($Pci.ModuleID -ne 0 -and $Pci.ModuleID -ne -1) {
if (!$this.is_pcidevice_exist($Pci)) {
$pciDevice.set_data($Pci, $EsxCliV2)
$this.ComponentResource += $pciDevice
}
}
}
}
[boolean] is_pcidevice_exist($device) {
foreach ($pci in $this.ComponentResource) {
if ($pci.psobject.TypeNames[0] -eq "IoDeviceResource") {
$vid = [String]::Format("{0:x4}", [int]$device.VendorID)
$did = [String]::Format("{0:x4}", [int]$device.DeviceID)
$svid = [String]::Format("{0:x4}", [int]$device.SubVendorID)
$ssid = [String]::Format("{0:x4}", [int]$device.SubDeviceID)
if ($pci.vid -eq $vid -and $pci.did -eq $did -and
$pci.svid -eq $svid -and $pci.ssid -eq $ssid) {
return $true
}
}
}
return $false
}
[object] to_jsonobj() {
$Json = $this | Select-Object -Property $this.JsonProperties
$ComponentChildren = @()
$this.ComponentResource | ForEach-Object {$ComponentChildren += $_.to_jsonobj()}
$Json | Add-Member -Name "ComponentResource" -Value $ComponentChildren -MemberType NoteProperty
return $Json
}
[string] get_host_status() {
if ($this.powerstatus -and $this.powerstatus -ne 'unknown') {
return $this.powerstatus
}
if ($this.connectionstatus) {
return ("Server " + $this.connectionstatus)
}
else {
return "Server status is unknown"
}
}
[string] get_prompt_name() {
if ($this.apitype) {
$start = $this.apitype
}
else {
$start = "Host"
}
return $start + " " + $this.hostname
}
}
# Class to manage server resources
Class ServerResource {
[string] $type
[string] $model
[string] $vendor
[string] $biosversion
[string] $cpumodel
[string] $cpufeatureid
[string] $uuid
[string] $status
[array] $matchResult
[array] $warnings
[string] $vcgLink
[array] $updateRelease
[VMware.VimAutomation.Types.VMHost] $vmhost
[Array] $JsonProperties = @('__type__','type', 'model', 'vendor', 'biosversion',
'cpumodel', 'cpufeatureid', 'uuid','status','matchResult','warnings','vcgLink','updateRelease')
[void] set_data(
[VMware.VimAutomation.Types.VMHost] $vmhost) {
$this.vmhost = $vmhost
$this.type = "Server"
$this.model = $this.vmhost.Model
$this.vendor = $this.vmhost.Manufacturer
$this.biosversion = $this.vmhost.ExtensionData.Hardware.BiosInfo.BiosVersion
$this.cpumodel = $this.vmhost.ProcessorType
$cpuFeature = $this.vmhost.ExtensionData.Hardware.CpuFeature
if ($cpuFeature -and $cpuFeature.Count -gt 2) {
$this.cpufeatureid = $this.vmhost.ExtensionData.Hardware.CpuFeature[1].Eax
}
$this.uuid = $this.vmhost.ExtensionData.Hardware.systeminfo.uuid
}
[object] to_jsonobj() {
return $this | Select-Object -Property $this.JsonProperties
}
}
# Class to manage each IO device
Class IoDeviceResource {
[string] $type
[string] $model
[string] $deviceid
[string] $device
[string] $comptype
[string] $vid
[string] $did
[string] $svid
[string] $ssid
[string] $pciid
[string] $vendor
[string] $driver
[string] $driverversion
[string] $firmware
[string] $status
[array] $matchResult
[array] $warnings
[string] $vcgLink
[array] $updateRelease
[Array] $JsonProperties = @('__type__','type', 'model', 'deviceid', 'device',
'comptype', 'vid', 'did', 'svid', 'ssid', 'pciid',
'vendor', 'driver', 'driverversion', 'firmware','status','matchResult','warnings','vcgLink','updateRelease')
[void] set_data(
[object] $pci,
[object] $EsxCli) {
$this.type = "IO Device"
$this.model = $Pci.DeviceName
$this.deviceid = $pci.Address
$this.device = $pci.VMKernelName
$this.vid = [String]::Format("{0:x4}", [int]$Pci.VendorID)
$this.did = [String]::Format("{0:x4}", [int]$Pci.DeviceID)
$this.svid = [String]::Format("{0:x4}", [int]$Pci.SubVendorID)
$this.ssid = [String]::Format("{0:x4}", [int]$Pci.SubDeviceID)
$this.pciid = $this.vid + ":" + $this.did + ":" + $this.svid + ":" + $this.ssid
$this.vendor = $pci.VendorName
$this.driver = $Pci.ModuleName
$this.driverversion = "N/A"
$this.firmware = "N/A"
# Set component type and driverversion, firmware
if ($this.device -match 'nic') {
$arg = @{}
$arg['nicname'] = $this.device
$nic = $EsxCli.network.nic.get.invoke($arg)
$this.comptype = "Physical NIC"
$this.driverversion = $nic.driverinfo.Version
$this.firmware = $nic.driverinfo.FirmwareVersion
}
elseif ($this.device -match 'hba') {
$arg = @{}
$arg['module'] = $this.driver
$module = $EsxCli.system.module.get.invoke($arg)
$this.comptype = "Storage Adapter"
$this.driverversion = $module.Version
}
}
[object] to_jsonobj() {
return $this | Select-Object -Property $this.JsonProperties
}
[string] get_id_detail() {
return $this.driver + " (PCIId:" + $this.pciid + ")"
}
}
# Class to manage IO device group
Class IoDeviceResourceGroup {
[Array] $iodevices = @()
[Array] $nics = @()
[Array] $adapters = @()
[void] append_nic([IODeviceResource] $nic) {
$this.iodevices += $nic
$this.nics += $nic
}
[void] append_storage_adapter([IODeviceResource] $adapter) {
$this.iodevices += $adapter
$this.adapters += $adapter
}
[boolean] has_nics() {
return $this.nics.Count > 0
}
[boolean] has_storage_adapters() {
return $this.adapters.Count > 0
}
}
#
# Collect hardware inventory data from all the hosts
#
Function Get-VCGHWInfo {
Param(
[Parameter(Mandatory=$true)] $vmHosts
)
# Collect the hardware data
$Data = @()
foreach($vmHost in $vmHosts) {
$vm = [HostResource]::new($vmHost)
try {
info ("Collecting hardware data from " + $vm.hostname)
$null = $vm.query_components()
if($vm.powerstatus -eq 'poweredOn' -and $vm.connectionstatus -eq 'connected'){
$Data += $vm
info ("Collecting hardware data from " + $vm.hostname +' success')
}
}
catch {
error ("Failed to collect hardware data from " + $vm.hostname)
}
}
return $Data
}

View File

@@ -0,0 +1,168 @@
$Uuid = [guid]::NewGuid()
$Headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$Headers.add("x-request-id", $Uuid)
$Headers.add("x-api-toolid", "180209100001")
$Headers.add("x-api-key", "SJyb8QjK2L")
$Url_Perfix = 'https://apigw.vmware.com/m4/compatibility/v1'
$Url = $Url_Perfix + "/compatible/servers/search?"
$UrlPci = $Url_Perfix + "/compatible/iodevices/search?"
$apiQurryDict=@{}
#
# Ping remote api server.
#
Function PingApiServer(){
$apiServerIp='apigw.vmware.com'
$results =Test-Connection $apiServerIp -Quiet
if($results -ne $true){
error ("Failed to access VMware Compatibility API,
Unable to use comparison function, only view basic hardware information;
you can use 'Get-VCGHWInfo -g <fileName>' create hardware json,
then use 'Check-VCGStatus -f <fileName>' load hardware json file to comapre when connect an available network")
Exit(1)
}
}
#
# Get the web request.
#
Function Get-WebRequest($VCGurl) {
try {
$req = Invoke-WebRequest -Headers $Headers -Uri $VCGUrl -ErrorVariable $err -UseBasicParsing
}
catch {
if ($err[0].errorrecord.exception.response) {
error ("WebReponse code:" + $err[0].errorrecord.exception.response.statuscode.value__)
error ($exitScript)
Exit(1)
}
else {
error ("Failed to check " + $type + " data for " + $HostResource.hostname)
error ("Failed to access VMware Compatibility API, please check your Internet connection or contact VMware Compatibility API administrator")
error ("Exit the script")
Exit(1)
}
}
return $req
}
Function Get-RemoteApiTitleString([object]$device,$EsxiVersion){
if ($device.type -eq 'Server') {
$Title = $device.model + $device.vendor + $device.cpufeatureid + $device.biosversion +$EsxiVersion
}
else{
$Title = $device.vid + $device.did + $device.Svid + $device.Ssid + $EsxiVersion
}
return $Title
}
Function Get-ResponseFromApi([object]$device,$EsxiVersion){
if ($device.type -eq 'Server') {
$VCGUrl = $Url + "model=" + $device.model + "&releaseversion=" + $EsxiVersion `
+ "&vendor=" + $device.vendor + "&cpuFeatureId=" + $device.cpufeatureid `
+ "&bios=" + $device.biosversion
debug ("Model:" + $device.model)
debug ("VCG Url:" + $VCGUrl)
$Headers.GetEnumerator() | ForEach-Object {debug ("Req Header:" + $_.key + ":" + $_.value)}
$request = Get-WebRequest $VCGUrl
$Response = ConvertFrom-Json -InputObject $request -Erroraction 'silentlycontinue'
}
elseif ($device.type -eq 'IO Device') {
$VCGUrl = $UrlPci + "vid=0X" + $device.vid + "&did=0X" + $device.did + "&svid=0X" + $device.Svid `
+ "&ssid=0X" + $device.Ssid + "&releaseversion=" + $EsxiVersion `
+ "&driver=" + $device.Driver + "&driverversion=" + $device.driverversion + "&firmware=N/A"
debug ("Model:" + $device.model)
debug ("VCG Url:" + $VCGUrl)
$Headers.GetEnumerator() | ForEach-Object {debug ("Req Header:" + $_.key + ":" + $_.value)}
$request = Get-WebRequest $VCGUrl
$Response = ConvertFrom-Json -InputObject $request -Erroraction 'silentlycontinue'
}
return $Response
}
#
# Get the data from api
#
Function Get-VCGData($HostResource) {
foreach ($device in $HostResource.ComponentResource) {
if ($HostResource.checkRelease) {
$EsxiVersion = $HostResource.checkRelease
}
else {
$EsxiVersion = $HostResource.version
}
$temp=0
$title=Get-RemoteApiTitleString $device $EsxiVersion
if($apiQurryDict.Count -eq 0){
$Response= Get-ResponseFromApi $device $EsxiVersion
$apiQurryDict.Add($title,$Response)
}else{
foreach($onetitle in $apiQurryDict.keys){
if($onetitle -eq $title){
$Response= $apiQurryDict[$onetitle]
$temp=1
break
}
}
if($temp -eq 0){
$Response= Get-ResponseFromApi $device $EsxiVersion
$apiQurryDict.Add($title,$Response)
}
}
if ($Response.matches) {
foreach ($match in $Response.matches) {
$device.vcgLink += [string]$match.vcgLink
}
}
else {
foreach ($potentialMatche in $Response.potentialMatches) {
$device.vcgLink += [string]$potentialMatche.vcgLink
}
}
$device.status = [string]$Response.searchResult.status
$device.matchResult = [string]$Response.searchResult.matchResult
$device.warnings = $Response.searchResult.warnings
$device.updateRelease = [string]$Response.searchOption.foundRelease
}
}
#
# Send the hardware data to VCG API and handle returned result
#
Function Get-DataFromRemoteApi([object]$servers) {
info ("Checking hardware compatibility result with VMware Compatibility Guide API...")
info ("This may take a few minutes depending on your network.")
for ($idx = 0; $idx -lt $servers.Count; $idx++) {
$server = $servers[$idx]
$i = $idx + 1
info ([string]$i + "/" + [string]$servers.Count + " - Checking hardware compatibility results for " + $server.hostname)
if (!$server -or $server.ComponentResource.Count -eq 0) {
error('Failed to get the hardware info.')
Exit(1)
}
Get-VCGData $server
}
return $servers
}
Function Get-VCGStatus{
Param(
[Parameter(Mandatory=$true)] $Data,
[Parameter(Mandatory=$false)] $Version
)
$checkRelease = $Version
PingApiServer
foreach ($vmHost in $Data) {
# $vmHost|add-member -Name "checkRelease" -value $checkRelease -MemberType NoteProperty -Force
$vmHost.checkRelease=$checkRelease
}
$results = Get-DataFromRemoteApi($Data)
if ($results.Count -eq 0) {
error ("Failed to get compatibility results. No report will be generated")
error ("Exit the script")
Exit(1)
}
return $results
}

View File

@@ -0,0 +1,41 @@
# About
This module is designed to ease the work of collecting hardware inventory data and compare it with VMware's official VCG data. Before deploying vSphere, it is required to validate your physical machines with VCG to make sure all the devices in your physical machines are compatible with the vSphere version you want to install. It is a time-consuming and painful experience to collect hardware/driver/firmware data from all of the machines, especially when you have a huge number of machines in your data center.
# How It Works
By using this module, it will automate the data collection and comparison work.
When running the module, it will connect to the target vCenter or ESXi to read the hardware data. It is a read-only operation and nothing on the target hosts will be changed. There is almost no impact on the machine's performance as the read operation takes just few seconds.
The module will then send your hardware inventory data to VMware's offical website to conduct a compatibility check. The result will be 'Compatible', 'May not be compatible' or 'Not compatible'.
* Compatible: the hardware is compatible with the given vSphere release. Link to that VCG page will be provided.
* May not be compatible: manual check is required to confirm the compatibility status of this hardware. A few potential matching VCG records will be provided.
* Not compatible: the hardware is not compatible with the given vSphere release.
After the checking is completed, the module will generate reports in different formats for your review and future use. A summary view in html will give you an overview of your machines compatibility status; an html file with device details to view each device/driver/firmware you have, their compatibility with vSphere version you specified and links to the corresponding VCG documents online; a csv file with device details to allow customization on report in Excel or by your own tool.
# Usage
Considering many data center may have control on internet access, we create 3 cmdlets to meet various situations.
* Get-VCGHWInfo: cmdlet to collect hardware info
* Get-VCGStatus: cmdlet to check hardware compatibility by query VCG website
* Export-VCGReport: cmdlet to export the summary/html/csv reports
1. You need to first import this module after you import PowerCLI module
PS> Import-Module &lt;path_to_VMware.VCGChecker.psd1>
2. Connect to the target vSphere hosts using Connect-VIServer and get VMHosts
PS> Connect-VIServer -Server &lt;server> -User &lt;username> -Password &lt;password>
PS> $vmhosts = Get-VMHost
3. Collect the hardware data
PS> $hwdata = Get-VCGHWInfo -vmHosts $vmhosts
Note: if you don't have internet access, you need to connect your client to internet before proceeding to the next step.
4. Specify the target vSphere release you want to check and submit the hardware data to VMware website
PS> $vcgdata= Get-VCGStatus -Data $hwdata -Version '&lt;release>'
5. Save the compatibility reports
PS> Export-VCGReport -Data $vcgdata -Dir &lt;dir>
# Known Limitation
* The module is not able to get the firmware version for HBA devices.
* The module is not able to get the HDD/SSD data.

View File

@@ -0,0 +1,17 @@
Function Save-VCGJsonFile{
Param(
[Parameter(Mandatory=$true)] $FileName,
[Parameter(Mandatory=$true)] $Data,
[Parameter(Mandatory=$true)] $Dir
)
$json = @()
$Data | ForEach-Object { $json += $_.to_jsonobj()}
if (!(Test-Path $Dir)) {
New-Item -Type directory -Confirm:$false -Path $Dir -Force |Out-Null
}
$Path= $Dir + '\' + $FileName + '.json'
info ("Saving data to " + $Path)
ConvertTo-Json -Depth 10 -Compress $json | Out-File -encoding 'UTF8' -FilePath $Path
}

View File

@@ -0,0 +1,90 @@
#
# Module manifest for module 'VMware.VCGChecker'
#
# Generated by: fdai@vmware.com, zhangta@vmware.com, linweij@vmware.com
#
# Generated on: 11/15/18
#
@{
# Script module or binary module file associated with this manifest.
# RootModule = 'VMware.VCGChecker.psm1'
# Version number of this module.
ModuleVersion = '1.0.0'
# Supported PSEditions
# CompatiblePSEditions = @()
# ID used to uniquely identify this module
# GUID = ''
# Author of this module
Author = 'Frank Dai, Tao Zhang, Linwei Jiang'
# Company or vendor of this module
CompanyName = 'VMware'
# Copyright statement for this module
Copyright = '(c) 2018 VMware. All rights reserved.'
# Description of the functionality provided by this module
Description = 'PowerShell Module for Checking Hardware Compatibility Status'
RequiredModules = @('VMware.VimAutomation.Core')
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
NestedModules = 'Get-VCGHWInfo.ps1','Get-VCGStatus.ps1','Export-VCGReport.ps1', 'Save-VCGJsonFile.ps1', 'logger.ps1'
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
FunctionsToExport = 'Get-VCGHWInfo', 'Get-VCGStatus', 'Export-VCGReport', 'Save-VCGJsonFile'
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
CmdletsToExport = @()
# Variables to export from this module
VariablesToExport = '*'
# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
AliasesToExport = @()
# DSC resources to export from this module
# DscResourcesToExport = @()
# List of all modules packaged with this module
# ModuleList = @()
# List of all files packaged with this module
# FileList = @()
# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
PrivateData = @{
PSData = @{
# Tags applied to this module. These help with module discovery in online galleries.
# Tags = @()
# A URL to the license for this module.
# LicenseUri = ''
# A URL to the main website for this project.
# ProjectUri = ''
# A URL to an icon representing this module.
# IconUri = ''
# ReleaseNotes of this module
# ReleaseNotes = ''
} # End of PSData hashtable
} # End of PrivateData hashtable
# HelpInfo URI of this module
# HelpInfoURI = ''
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
# DefaultCommandPrefix = ''
}

View File

@@ -0,0 +1,112 @@
<#
Copyright 2018 VMware, Inc. All rights reserved.
#>
# Messages
$HEADER_OK = "[OK] "
$HEADER_INFO = "[INFO] "
$HEADER_WARNING = "[WARNING] "
$HEADER_ERR = "[ERROR] "
Class DebugLog
{
# Static variables of the logger class
static [string] $CAFILE_PATH = "./.certs/"
[boolean] $debug
[string] $logfile
DebugLog()
{
$this.debug = $false
$this.logfile = $null
if (!(Test-Path $this::CAFILE_PATH))
{
New-Item -Type directory -Confirm:$false -Path $this::CAFILE_PATH
}
}
[void] SetDebug(
[boolean] $debug,
[string] $hostname
){
if (!$hostname) {$hostname = ''}
$this.debug = $debug
if ($this.debug)
{
$this.logfile = $this::CAFILE_PATH + $hostname + [DateTime]::Now.ToString("_yyyy-MM-dd_HH-mm") + ".log"
}else{
$this.logfile = $null
}
}
[void] log_vars(
[string] $message,
[object] $var
){
$this.log($message + $var)
}
[void] log(
[string] $message
){
if (!$this.debug -or !$this.logfile) {return}
try
{
$message | Out-File $this.logfile -Append
}catch {
Out-Host -InputObject ("[Exception] Failed to write to a logfile: " + $this.logfile)
Out-Host -InputObject $_
}
}
}
Function debug_vars(
[string] $message,
[object] $var)
{
$logger.log_vars($message, $var)
}
Function debug(
[string] $message)
{
$logger.log($message)
}
Function vcglog(
[string] $message,
[string] $header="")
{
$msg = $header + $message
$logger.log($msg)
Out-Host -InputObject $msg
}
Function ok(
[string] $message)
{
vcglog $message $HEADER_OK
}
Function warning(
[string] $message)
{
vcglog $message $HEADER_WARNING
}
Function info(
[string] $message)
{
vcglog $message $HEADER_INFO
}
Function error(
[string] $message)
{
vcglog $message $HEADER_ERR
}
$logger = [DebugLog]::new()
$logger.SetDebug($true, "vcc-debug")

View File

@@ -36,7 +36,14 @@ Description = 'PowerShell Module for Managing NSX-T on VMware Cloud on AWS'
PowerShellVersion = '6.0'
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
FunctionsToExport = 'Connect-NSXTProxy', 'Get-NSXTSegment', 'New-NSXTSegment', 'Remove-NSXTSegment', 'Get-NSXTGroup', 'New-NSXTGroup', 'Remove-NSXTGroup', 'Get-NSXTService', 'New-NSXTService', 'Get-NSXTFirewall', 'New-NSXTFirewall', 'Remove-NSXTFirewall'
FunctionsToExport = 'Connect-NSXTProxy', 'Get-NSXTSegment', 'New-NSXTSegment', 'Remove-NSXTSegment', `
'Get-NSXTGroup', 'New-NSXTGroup', 'Remove-NSXTGroup', 'Get-NSXTServiceDefinition', 'New-NSXTServiceDefinition', `
'Get-NSXTFirewall', 'New-NSXTFirewall', 'Remove-NSXTFirewall', 'Get-NSXTDistFirewallSection', `
'Get-NSXTDistFirewall', 'New-NSXTDistFirewall', 'Remove-NSXTDistFirewall', 'Get-NSXTRouteTable', `
'Get-NSXTOverviewInfo', 'Get-NSXTInfraScope', 'Get-NSXTInfraGroup', 'New-NSXTRouteBasedVPN', `
'Get-NSXTRouteBasedVPN', 'Remove-NSXTRouteBasedVPN', 'Remove-NSXTServiceDefinition', 'New-NSXTDistFirewallSection', 'Get-NSXTDistFirewallSection', `
'New-NSXTPolicyBasedVPN', 'Get-NSXTPolicyBasedVPN', 'Remove-NSXTPolicyBasedVPN', 'Get-NSXTDNS', 'Set-NSXTDNS', 'Get-NSXTPublicIP', 'New-NSXTPublicIP', `
'Get-NSXTNatRule', 'New-NSXTNatRule', 'Remove-NSXTNatRule'
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
CmdletsToExport = @()

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -49,7 +49,7 @@ Copyright = 'Copyright (c) 2016 VMware, Inc. All rights reserved.'
# Modules that must be imported into the global environment prior to importing this module
RequiredModules = @(
@{"ModuleName"="VMware.VimAutomation.Core";"ModuleVersion"="10.1.0.8346946"}
@{"ModuleName"="VMware.VimAutomation.Core";"ModuleVersion"="10.1.0.8344055"}
)
# Assemblies that must be loaded prior to importing this module

View File

@@ -0,0 +1,7 @@
Prerequisites/Steps to use this module:
1. This module only works for vSphere products that support vSAN Encryption. E.g. vSAN 6.6 and later with a vSAN Enterprise license
2. All the functions in this module only work for KMIP Servers.
3. Install the latest version of Powershell and PowerCLI(11).
4. Import this module by running: Import-Module -Name "location of this module"
5. Get-Command -Module "This module Name" to list all available functions.

View File

@@ -0,0 +1,341 @@
# Script Module : VMware.VsanEncryption
# Version : 1.0
# Author : Jase McCarty, VMware Storage & Availability Business Unit
# Copyright © 2018 VMware, Inc. All Rights Reserved.
# 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.
Function Invoke-VsanEncryptionRekey {
<#
.SYNOPSIS
This function will initiate a ReKey of a vSAN Cluster. Shallow ReKeying (KEK Only) or Deep ReKeying (DEK Also) are supported, as well as Reduced Redundancy if necessary.
.DESCRIPTION
This function will initiate a ReKey of a vSAN Cluster. Shallow ReKeying (KEK Only) or Deep ReKeying (DEK Also) are supported, as well as Reduced Redundancy if necessary.
.PARAMETER Cluster
Specifies the Cluster to perform the rekey process on
.PARAMETER DeepRekey
Use to invoke a Deep Rekey ($true) or a Shallow ($false or omit)
.PARAMETER ReducedRedundancy
For clusters that have 4 or more hosts, this will allow for reduced redundancy.
For clusters that have 2 or 3 hosts, this does not need to be set (can be).
.EXAMPLE
C:\PS>Invoke-VsanEncryptionRekey -Cluster "ClusterName" -DeepRekey $true/$false -ReducedRedundancy $true/$false
#>
# Set our Parameters
[CmdletBinding()]Param(
[Parameter(Mandatory = $True)][String]$Cluster,
[Parameter(Mandatory = $False)][Boolean]$DeepRekey,
[Parameter(Mandatory = $False)][Boolean]$ReducedRedundancy
)
# Get the Cluster
$VsanCluster = Get-Cluster -Name $Cluster
# Get the vSAN Cluster Configuration View
$VsanVcClusterConfig = Get-VsanView -Id "VsanVcClusterConfigSystem-vsan-cluster-config-system"
# Get Encryption State
$EncryptedVsan = $VsanVcClusterConfig.VsanClusterGetConfig($VsanCluster.ExtensionData.MoRef).DataEncryptionConfig
# If vSAN is enabled and it is Encrypted
If($VsanCluster.vSanEnabled -And $EncryptedVsan.EncryptionEnabled){
# Get a count of hosts to guarantee reduced redundancy for 2 and 3 node clusters
$HostCount = $VsanCluster | Select @{n="count";e={($_ | Get-VMHost).Count}}
# If reduced redundancy is specified, or there are less than 4 hosts, force reduced redundancy
If (($ReducedRedundancy -eq $true) -or ($HostCount.Value -lt 4)) {
}
# Determine Rekey Type for messaging
Switch ($DeepRekey) {
$true { $ReKeyType = "deep"}
default { $ReKeyType = "shallow"}
}
# Determine Reduced Redundancy for messaging
Switch ($ReducedRedundancy) {
$true { $RRMessage = "with reduced redundancy"}
default { $RRMessage = ""}
}
# Echo task being performed
Write-Host "Executing $ReKeyType rekey of vSAN Cluster $VsanCluster $RRMessage"
# Execute the rekeying task
$ReKeyTask = $VsanVcClusterConfig.VsanEncryptedClusterRekey_Task($VsanCluster.ExtensionData.MoRef,$DeepRekey,$ReducedRedundancy)
}
}
Function Set-VsanEncryptionKms {
<#
.SYNOPSIS
This function will set the KMS to be used with vSAN Encryption
.DESCRIPTION
This function will set the KMS to be used with vSAN Encryption
.PARAMETER Cluster
Specifies the Cluster to set the KMS server for
.PARAMETER KmsCluster
Use to set the KMS Cluster to be used with vSAN Encryption
.EXAMPLE
C:\PS>Set-VsanEncryptionKms -Cluster "ClusterName" -KmsCluster "vCenter KMS Cluster Entry"
#>
# Set our Parameters
[CmdletBinding()]Param(
[Parameter(Mandatory = $True)][String]$Cluster,
[Parameter(Mandatory = $False)][String]$KmsCluster
)
# Get the Cluster
$VsanCluster = Get-Cluster -Name $Cluster
# Get the list of KMS Servers that are included
$KmsClusterList = Get-KmsCluster
# Was a KMS Cluster Specified?
# Specified: Is it in the list?
# Is it not in the list?
# Not Specified: Present a list
If ($KmsCluster) {
If ($KmsClusterList.Name.Contains($KmsCluster)) {
Write-Host "$KmsCluster In the list, proceeding" -ForegroundColor Green
$KmsClusterProfile = $KmsClusterList | Where-Object {$_.Name -eq $KmsCluster}
} else {
$Count = 0
Foreach ($KmsClusterItem in $KmsClusterList) {
Write-Host "$Count) $KmsClusterItem "
$Count = $Count + 1
}
$KmsClusterEntry = Read-Host -Prompt "$KmsCluster is not valid, please select one of the existing KMS Clusters to use"
Write-Host $KmsClusterList[$KmsClusterEntry]
$KmsClusterProfile = $KmsClusterList[$KmsClusterEntry]
}
} else {
$Count = 0
Foreach ($KmsClusterItem in $KmsClusterList) {
Write-Host "$Count) $KmsClusterItem "
$Count = $Count + 1
}
$KmsClusterEntry = Read-Host -Prompt "No KMS provided, please select one of the existing KMS Clusters to use"
Write-Host $KmsClusterList[$KmsClusterEntry]
$KmsClusterProfile = $KmsClusterList[$KmsClusterEntry]
}
# Get the vSAN Cluster Configuration View
$VsanVcClusterConfig = Get-VsanView -Id "VsanVcClusterConfigSystem-vsan-cluster-config-system"
# Get Encryption State
$EncryptedVsan = $VsanVcClusterConfig.VsanClusterGetConfig($VsanCluster.ExtensionData.MoRef).DataEncryptionConfig
# If vSAN is enabled and it is Encrypted
If($VsanCluster.vSanEnabled -And $EncryptedVsan.EncryptionEnabled){
If ($EncryptedVsan.KmsProviderId.Id -eq $KmsClusterProfile.Name) {
# If the Specified KMS Profile is the KMS Profile being used, then don't do anything
Write-Host $EncryptedVsan.KmsProviderId.Id "is already the assigned KMS Cluster Profile, exiting"
} else {
Write-Host "Changing the KMS Profile to $KmsClusterProfile on Cluster $VsanCluster"
# Setup the KMS Provider Id Specification
$KmsProviderIdSpec = New-Object VMware.Vim.KeyProviderId
$KmsProviderIdSpec.Id = $KmsClusterProfile.Name
# Setup the Data Encryption Configuration Specification
$DataEncryptionConfigSpec = New-Object VMware.Vsan.Views.VsanDataEncryptionConfig
$DataEncryptionConfigSpec.KmsProviderId = $KmsProviderIdSpec
$DataEncryptionConfigSpec.EncryptionEnabled = $true
# Set the Reconfigure Specification to use the Data Encryption Configuration Spec
$vsanReconfigSpec = New-Object VMware.Vsan.Views.VimVsanReconfigSpec
$vsanReconfigSpec.DataEncryptionConfig = $DataEncryptionConfigSpec
# Execute the task of changing the KMS Cluster Profile Being Used
$ChangeKmsTask = $VsanVcClusterConfig.VsanClusterReconfig($VsanCluster.ExtensionData.MoRef,$vsanReconfigSpec)
}
}
}
Function Get-VsanEncryptionKms {
<#
.SYNOPSIS
This function will set the KMS to be used with vSAN Encryption
.DESCRIPTION
This function will set the KMS to be used with vSAN Encryption
.PARAMETER Cluster
Specifies the Cluster to set the KMS server for
.EXAMPLE
C:\PS>Get-VsanEncryptionKms -Cluster "ClusterName"
#>
# Set our Parameters
[CmdletBinding()]Param([Parameter(Mandatory = $True)][String]$Cluster)
# Get the Cluster
$VsanCluster = Get-Cluster -Name $Cluster
# Get the vSAN Cluster Configuration View
$VsanVcClusterConfig = Get-VsanView -Id "VsanVcClusterConfigSystem-vsan-cluster-config-system"
# Get Encryption State
$EncryptedVsan = $VsanVcClusterConfig.VsanClusterGetConfig($VsanCluster.ExtensionData.MoRef).DataEncryptionConfig
# If vSAN is enabled and it is Encrypted
If($VsanCluster.vSanEnabled -And $EncryptedVsan.EncryptionEnabled){
$EncryptedVsan.KmsProviderId.Id
}
}
Function Set-VsanEncryptionDiskWiping {
<#
.SYNOPSIS
This function will update the Disk Wiping option in vSAN Encryption
.DESCRIPTION
This function will update the Disk Wiping option in vSAN Encryption
.PARAMETER Cluster
Specifies the Cluster set the Disk Wiping Setting on
.PARAMETER DiskWiping
Use to set the Disk Wiping setting for vSAN Encryption
.EXAMPLE
C:\PS>Set-VsanEncryptionDiskWiping -Cluster "ClusterName" -DiskWiping $true
.EXAMPLE
C:\PS>Set-VsanEncryptionDiskWiping -Cluster "ClusterName" -DiskWiping $false
#>
# Set our Parameters
[CmdletBinding()]Param(
[Parameter(Mandatory = $True)][String]$Cluster,
[Parameter(Mandatory = $True)][Boolean]$DiskWiping
)
# Get the Cluster
$VsanCluster = Get-Cluster -Name $Cluster
# Get the vSAN Cluster Configuration View
$VsanVcClusterConfig = Get-VsanView -Id "VsanVcClusterConfigSystem-vsan-cluster-config-system"
# Get Encryption State
$EncryptedVsan = $VsanVcClusterConfig.VsanClusterGetConfig($VsanCluster.ExtensionData.MoRef).DataEncryptionConfig
# If vSAN is enabled and it is Encrypted
If($VsanCluster.vSanEnabled -And $EncryptedVsan.EncryptionEnabled){
# Determine Rekey Type for messaging
Switch ($DiskWiping) {
$true { $DiskWipingSetting = "enabled" }
default { $DiskWipingSetting = "disabled" }
}
# Check to see the current Disk Wiping value
If ($DiskWiping -eq $EncryptedVsan.EraseDisksBeforeUse) {
Write-Host "Disk Wiping is already $DiskWipingSetting" -ForegroundColor "Green"
Write-Host "No action necessary" -ForegroundColor "Green"
} else {
Write-Host "Disk Wiping is not set to $DiskWipingSetting" -ForegroundColor "Yellow"
Write-Host "Changing Disk Wiping setting on Cluster $VsanCluster" -ForegroundColor "Blue"
# Setup the Data Encryption Configuration Specification
$DataEncryptionConfigSpec = New-Object VMware.Vsan.Views.VsanDataEncryptionConfig
$DataEncryptionConfigSpec.EncryptionEnabled = $true
$DataEncryptionConfigSpec.EraseDisksBeforeUse = $DiskWiping
# Set the Reconfigure Specification to use the Data Encryption Configuration Spec
$vsanReconfigSpec = New-Object VMware.Vsan.Views.VimVsanReconfigSpec
$vsanReconfigSpec.DataEncryptionConfig = $DataEncryptionConfigSpec
# Execute the task of changing the KMS Cluster Profile Being Used
$VsanVcClusterConfig.VsanClusterReconfig($VsanCluster.ExtensionData.MoRef,$vsanReconfigSpec)
}
}
}
Function Get-VsanEncryptionDiskWiping {
<#
.SYNOPSIS
This function will retrieve the Disk Wiping option setting in vSAN Encryption
.DESCRIPTION
This function will retrieve the Disk Wiping option setting in vSAN Encryption
.PARAMETER Cluster
Specifies the Cluster set the Disk Wiping Setting on
.EXAMPLE
C:\PS>Get-VsanEncryptionDiskWiping -Cluster "ClusterName"
#>
# Set our Parameters
[CmdletBinding()]Param([Parameter(Mandatory = $True)][String]$Cluster)
# Get the Cluster
$VsanCluster = Get-Cluster -Name $Cluster
# Get the vSAN Cluster Configuration View
$VsanVcClusterConfig = Get-VsanView -Id "VsanVcClusterConfigSystem-vsan-cluster-config-system"
# Get Encryption State
$EncryptedVsan = $VsanVcClusterConfig.VsanClusterGetConfig($VsanCluster.ExtensionData.MoRef).DataEncryptionConfig
# If vSAN is enabled and it is Encrypted
If($VsanCluster.vSanEnabled -And $EncryptedVsan.EncryptionEnabled){
# Change the setting
$EncryptedVsan.EraseDisksBeforeUse
}
}
# Export Function for vSAN Rekeying
Export-ModuleMember -Function Invoke-VsanEncryptionRekey
Export-ModuleMember -Function Set-VsanEncryptionKms
Export-ModuleMember -Function Get-VsanEncryptionKms
Export-ModuleMember -Function Set-VsanEncryptionDiskWiping
Export-ModuleMember -Function Get-VsanEncryptionDiskWiping

View File

@@ -0,0 +1,82 @@
function Validate-ESXiPackages {
<#
.DESCRIPTION
Compares all ESXi Host VIBs within a vSphere with a reference Hosts.
.NOTES
File Name : Validate-ESXiPackages.ps1
Author : Markus Kraus
Version : 1.0
State : Ready
Tested Against Environment:
vSphere Version: 6.0 U2, 6.5 U1
PowerCLI Version: PowerCLI 10.0.0 build 7895300
PowerShell Version: 4.0
OS Version: Windows Server 2012 R2
.LINK
https://mycloudrevolution.com/
.EXAMPLE
Validate-ESXiPackages -Cluster (Get-Cluster) -RefernceHost (Get-VMHost | Select-Object -First 1)
.PARAMETER Cluster
vSphere Cluster to verify
.PARAMETER RefernceHost
The VIB Reference ESXi Host
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$True, ValueFromPipeline=$True, HelpMessage="vSphere Cluster to verify")]
[ValidateNotNullorEmpty()]
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.ComputeResourceImpl] $Cluster,
[Parameter(Mandatory=$True, ValueFromPipeline=$false, HelpMessage="The VIB Reference ESXi Host")]
[ValidateNotNullorEmpty()]
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl] $RefernceHost
)
Process {
#region: Get reference VIBs
$EsxCli2 = Get-ESXCLI -VMHost $RefernceHost -V2
$RefernceVibList = $esxcli2.software.vib.list.invoke()
#endregion
#region: Compare reference VIBs
$MyView = @()
foreach ($VmHost in ($Cluster | Get-VMHost)) {
$EsxCli2 = Get-ESXCLI -VMHost $VmHost -V2
$VibList = $esxcli2.software.vib.list.invoke()
[Array]$VibDiff = Compare-Object -ReferenceObject $RefernceVibList.ID -DifferenceObject $VibList.ID
if($VibDiff.Count -gt 0) {
$VibDiffSideIndicator = @()
foreach ($Item in $VibDiff) {
$VibDiffSideIndicator += $($Item.SideIndicator + " " + $Item.InputObject)
}
}
else {
$VibDiffSideIndicator = $null
}
$Report = [PSCustomObject] @{
Host = $VmHost.Name
Version = $VmHost.Version
Build = $VmHost.Build
VibDiffCount = $VibDiff.Count
VibDiff = $VibDiff.InputObject
VibDiffSideIndicator = $VibDiffSideIndicator
}
$MyView += $Report
}
#region: Compare reference VIBs
$MyView
}
}

View File

@@ -0,0 +1,74 @@
Function Get-VCenterCEIP {
<#
.NOTES
===========================================================================
Created by: William Lam
Date: 01/23/2019
Organization: VMware
Blog: http://www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.SYNOPSIS
Retrieves the the Customer Experience Improvement Program (CEIP) setting for vCenter Server
.DESCRIPTION
This cmdlet retrieves the the CEIP setting for vCenter Server
.EXAMPLE
Get-VCenterCEIP
#>
If (-Not $global:DefaultVIServer.IsConnected) { Write-error "No valid VC Connection found, please use the Connect-VIServer to connect"; break } Else {
$ceipSettings = (Get-AdvancedSetting -Entity $global:DefaultVIServer -Name VirtualCenter.DataCollector.ConsentData).Value.toString() | ConvertFrom-Json
$ceipEnabled = $ceipSettings.consentConfigurations[0].consentAccepted
$tmp = [pscustomobject] @{
VCENTER = $global:DefaultVIServer.Name;
CEIP = $ceipEnabled;
}
$tmp
}
}
Function Set-VCenterCEIP {
<#
.NOTES
===========================================================================
Created by: William Lam
Date: 01/23/2019
Organization: VMware
Blog: http://www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.SYNOPSIS
Enables or Disables the Customer Experience Improvement Program (CEIP) setting for vCenter Server
.DESCRIPTION
This cmdlet enables or disables the CEIP setting for vCenter Server
.EXAMPLE
Set-VCenterCEIP -Enabled
.EXAMPLE
Set-VCenterCEIP -Disabled
#>
Param (
[Switch]$Enabled,
[Switch]$Disabled
)
If (-Not $global:DefaultVIServer.IsConnected) { Write-error "No valid VC Connection found, please use the Connect-VIServer to connect"; break } Else {
$ceipSettings = (Get-AdvancedSetting -Entity $global:DefaultVIServer -Name VirtualCenter.DataCollector.ConsentData).Value.toString() | ConvertFrom-Json
If($Enabled) {
$originalVersion = $ceipSettings.version
$ceipSettings.version = [int]$originalVersion + 1
$ceipSettings.consentConfigurations[0].consentAccepted = $True
$ceipSettings.consentConfigurations[1].consentAccepted = $True
$updatedceipSettings = $ceipSettings | ConvertTo-Json
Write-Host "Enabling Customer Experience Improvement Program (CEIP) ..."
Get-AdvancedSetting -Entity $global:DefaultVIServer -Name VirtualCenter.DataCollector.ConsentData | Set-AdvancedSetting -Value $updatedceipSettings -Confirm:$false
} else {
$originalVersion = $ceipSettings.version
$ceipSettings.version = [int]$originalVersion + 1
$ceipSettings.consentConfigurations[0].consentAccepted = $False
$ceipSettings.consentConfigurations[1].consentAccepted = $False
$updatedceipSettings = $ceipSettings | ConvertTo-Json
Write-Host "Disablng Customer Experience Improvement Program (CEIP) ..."
Get-AdvancedSetting -Entity $global:DefaultVIServer -Name VirtualCenter.DataCollector.ConsentData | Set-AdvancedSetting -Value $updatedceipSettings -Confirm:$false
}
}
}

View File

@@ -20,8 +20,8 @@
* [Security](https://github.com/vmware/PowerCLI-Example-Scripts#security)
* [Resource Maintenance](https://github.com/vmware/PowerCLI-Example-Scripts#resource-maintenance)
* [Maintenance Ownership](https://github.com/vmware/PowerCLI-Example-Scripts#maintenance-ownership)
* [Filing issues](https://github.com/vmware/PowerCLI-Example-Scripts#filing-isssues)
* [Resolving issues](https://github.com/vmware/PowerCLI-Example-Scripts#resolving-issues)
* [Filing Issues](https://github.com/vmware/PowerCLI-Example-Scripts#filing-isssues)
* [Resolving Issues](https://github.com/vmware/PowerCLI-Example-Scripts#resolving-issues)
* [Additional Resources](https://github.com/vmware/PowerCLI-Example-Scripts#additional-resources)
* [Discussions](https://github.com/vmware/PowerCLI-Example-Scripts#discussions)
* [VMware Sample Exchange](https://github.com/vmware/PowerCLI-Example-Scripts#vmware-sample-exchange)

View File

@@ -0,0 +1,128 @@
#
# Provide environment information in the PS Console
#
# History:
# 1.0 - August 4th 2019 - LucD
# Initial version (for session HBI1729BU VMworld US 2019)
# 2.0 - September 9th 2019 - virtualex
# Added PowerShell-Core compatibility
#
# 1) PS prompt
# - current (local) time
# - execution time of the previous command
# - shortened PWD
# 2) Window title
# - User/Admin
# - PS-32/64-Edition-Version
# - PCLI version
# - git repo/branch
# - VC/ESXi:defaultServer-User [# connections]
function prompt
{
# Current time
$date = (Get-Date).ToString('HH:mm:ss')
Write-Host -Object '[' -NoNewLine
Write-Host -Object $date -ForegroundColor Cyan -BackgroundColor DarkBlue -NoNewline
Write-Host -Object ']' -NoNewLine
# Execution time previous command
$history = Get-History -ErrorAction Ignore -Count 1
if ($history)
{
$time = ([DateTime](New-TimeSpan -Start $history.StartExecutionTime -End $history.EndExecutionTime).Ticks).ToString('HH:mm:ss.ffff')
Write-Host -Object '[' -NoNewLine
Write-Host -Object "$time" -ForegroundColor Yellow -BackgroundColor DarkBlue -NoNewLine
Write-Host -Object '] ' -NoNewLine
}
# Shortened PWD
$path = $pwd.Path.Split('\')
if ($path.Count -gt 3)
{
$path = $path[0], '..', $path[-2], $path[-1]
}
Write-Host -Object "$($path -join '\')" -NoNewLine
# Prompt function needs to return something,
# otherwise the default 'PS>' will be added
"> "
# Refresh the window's title
Set-Title
}
function Set-Title
{
# Running as Administrator or a regular user
If (($PSEdition -eq 'Core') -and ($IsWindows -eq 'True') -or ($PSEdition -ine 'Core'))
{
$userInfo = [Security.Principal.WindowsIdentity]::GetCurrent()
if ((New-Object Security.Principal.WindowsPrincipal $userInfo).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator))
{
$role = 'Admin'
}
else
{
$role = 'User'
}
}
# Usertype user@hostname
If (($PSEdition -eq 'Core') -and ($IsWindows -ine 'True')) {
$env:computername = hostname
$user = "$($env:user)@$($env:computername)"
}
Else {
$user = "$role $($userInfo.Name)@$($env:computername)"
}
# PowerShell environment/PS version
$bits = 32
if ([Environment]::Is64BitProcess)
{
$bits = 64
}
$ps = " - PS-$($bits): $PSEdition/$($PSVersionTable.PSVersion.ToString())"
# PowerCLI version (derived from module VMware.PowerCLI)
$pcliModule = Get-Module -Name VMware.PowerCLI -ListAvailable |
Sort-Object -Property Version -Descending |
Select-Object -First 1
$pcli = " - PCLI: $(if($pcliModule){$pcliModule.Version.ToString()}else{'na'})"
# If git is present and if in a git controlled folder, display repositoryname/current_branch
$gitStr = ''
if ((Get-Command -Name 'git' -CommandType Application -ErrorAction SilentlyContinue).Count -gt 0)
{
$gitTopLevel = & { git rev-parse --show-toplevel 2> $null }
if ($gitTopLevel.Length -ne 0)
{
$gitRepo = Split-Path -Path $gitTopLevel -Leaf
$gitBranch = (git branch | Where-Object { $_ -match "\*" }).Trimstart('* ')
$gitStr = " - git: $gitRepo/$gitBranch"
}
}
# If there is an open vSphere Server connection
# display [VC|ESXi] last_connected_server-connected_user [number of open server connections]
if ($global:defaultviserver)
{
$vcObj = (Get-Variable -Scope global -Name 'DefaultVIServer').Value
if ($vcObj.ProductLine -eq 'vpx')
{
$vcSrv = 'VC'
}
else
{
$vcSrv = 'ESXi'
}
$vc = " - $($vcSrv): $($vcObj.Name)-$($vcObj.User) [$($global:DefaultVIServers.Count)]"
}
# Update the Window's title
$host.ui.RawUI.WindowTitle = "$user$ps$pcli$vc$gitStr"
}
# Set title after starting session
Set-Title

View File

@@ -0,0 +1,60 @@
[cmdletbinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')]
param(
# [Parameter(Mandatory = $true)]
[ValidateSet('CurrentUserCurrentHost', 'CurrentUserAllHosts',
'AllUsersCurrentHost', 'AllUsersAllHosts')]
[string]$Scope,
[switch]$NoClobber,
[switch]$Backup,
[string]$NewProfile = '.\NewProfile.ps1'
)
if ($PSCmdlet.ShouldProcess("$($Profile.$Scope)", "Create $Scope profile"))
{
$profilePath = $Profile."$Scope"
Write-Verbose -Message "Target is $profilePath"
$createProfile = $true
if (Test-Path -Path $profilePath)
{
Write-Verbose -Message "Target exists"
if ($NoClobber)
{
Write-Verbose -Message "Cannot overwrite target due to NoClobber"
$createProfile = $false
}
elseif ($Backup)
{
Write-Verbose -Message "Create a backup as $profilePath.bak"
Copy-Item -Path $profilePath -Destination "$profilePath.bak" -Confirm:$false -Force
}
elseif (-not $NoClobber)
{
Write-Verbose -Message "Target will be overwritten"
}
else
{
Write-Verbose -Message "Use -NoClobber:$false or -Backup"
}
}
if ($createProfile)
{
if (-not $NewProfile)
{
$script:MyInvocation.MyCommand | select *
$folder = Split-Path -Parent -Path $script:MyInvocation.MyCommand.Path
$folder = Get-Location
$NewProfile = "$folder\NewProfile.ps1"
}
Write-Verbose -Message "New profile expected at $NewProfile"
if (Test-Path -Path $NewProfile)
{
Write-Verbose -Message "Copy $NewProfile to $profilePath"
Copy-Item -Path $NewProfile -Destination $profilePath -Confirm:$false
}
else
{
Write-Warning -Message "Could not find the new profile file!"
Write-Warning -Message "Use the NewProfile parameter or store a NewProfile.ps1 file in folder $folder."
}
}
}

View File

@@ -5,15 +5,23 @@ function Export-Tag {
[VMware.VimAutomation.ViCore.Types.V1.VIServer]$Server,
[Parameter(Mandatory = $True, Position = 2)]
[string]$Destination
[string]$Destination,
[Parameter(Mandatory = $False, Position = 3)]
[boolean]$ExportAssignments
)
# Retrieve all categories
$categoryList = Get-TagCategory -Server $server
# Retrieve all tags
$tagList = Get-Tag -Server $server
# Store the tags and categories in a list to export them at once
$export = @($categoryList, $tagList)
# Store the tags, categories and assignments (if selected) in a list to export them at once
If ($ExportAssignments) {
$tagAssignments = Get-TagAssignment -Server $server
$export = @($categoryList, $tagList, $tagAssignments)
} else {
$export = @($categoryList, $tagList)
}
# Export the tags and categories to the specified destination
Export-Clixml -InputObject $export -Path $destination
}
@@ -25,7 +33,10 @@ function Import-Tag {
[VMware.VimAutomation.ViCore.Types.V1.VIServer]$Server,
[Parameter(Mandatory = $True, Position = 2)]
[string]$Source
[string]$Source,
[Parameter(Mandatory = $False, Position = 3)]
[boolean]$ImportAssignments
)
# Import the tags and categories from the specified source
@@ -62,4 +73,23 @@ function Import-Tag {
-Server $server `
| Out-Null
}
}
# Restore the assignments if selected
If ($ImportAssignments) {
# Check for assignments in the file
If ($import[2]) {
# If tags were found, assign them
$tagAssignments = $import[2]
ForEach ($assignment in $tagAssignments) {
New-TagAssignment `
-Tag (Get-Tag -Server $server -Name $assignment.Tag.Name -Category $assignment.Tag.Category) `
-Entity (Get-VIObjectByVIView -MORef $assignment.Entity.id) `
-Server $server `
| Out-Null
}
} else {
# If no assignments were found, output warning
Write-Warning "Source file does not contain tag assignments."
}
}
}

View File

@@ -0,0 +1,12 @@
<#
Script name: get-migrations.ps1
Created on: 20/12/2018
Author: Chris Bradshaw @aldershotchris
Description: The purpose of the script is to list the currently running + recently finished VM migrations.
Dependencies: None known
#>
Function Get-Migrations{
Get-Task |
Where-Object{$_.Name -eq "RelocateVM_Task"} |
Select-Object @{Name="VM";Expression={Get-VM -Id $_.ObjectID}}, State, @{Name="% Complete";Expression={$_.PercentComplete}},StartTime
}

View File

@@ -0,0 +1,62 @@
function Get-TriggeredAlarm {
<#
.SYNOPSIS
This function lists the triggered alarms for the specified entity in vCenter
.DESCRIPTION
List the triggered alarms for the given object
.NOTES
Author: Kyle Ruddy, @kmruddy, kmruddy.com
.PARAMETER VM
Specifies the name of the VM
.PARAMETER VMHost
Specifies the name of the VMHost
.PARAMETER Datacenter
Specifies the name of the Datacenter
.PARAMETER Datastore
Specifies the name of the Datastore
.EXAMPLE
Get-TriggeredAlarm -VM VMname
Entity Alarm AlarmStatus AlarmMoRef EntityMoRef
---- ---- ---- ---- ----
VMname Name Yellow Alarm-MoRef Entity-MoRef
#>
[CmdletBinding()]
param(
[string]$VM,
[string]$VMHost,
[string]$Datacenter,
[string]$Datastore
)
BEGIN {
switch ($PSBoundParameters.Keys) {
'VM' {$entity = Get-VM -Name $vm -ErrorAction SilentlyContinue}
'VMHost' {$entity = Get-VMHost -Name $VMHost -ErrorAction SilentlyContinue}
'Datacenter' {$entity = Get-Datacenter -Name $Datacenter -ErrorAction SilentlyContinue}
'Datastore' {$entity = Get-Datastore -Name $Datastore -ErrorAction SilentlyContinue}
default {$entity = $null}
}
if ($null -eq $entity) {
Write-Warning "No vSphere object found."
break
}
}
PROCESS {
if ($entity.ExtensionData.TriggeredAlarmState -ne "") {
$alarmOutput = @()
foreach ($alarm in $entity.ExtensionData.TriggeredAlarmState) {
$tempObj = "" | Select-Object -Property Entity, Alarm, AlarmStatus, AlarmMoRef, EntityMoRef
$tempObj.Entity = Get-View $alarm.Entity | Select-Object -ExpandProperty Name
$tempObj.Alarm = Get-View $alarm.Alarm | Select-Object -ExpandProperty Info | Select-Object -ExpandProperty Name
$tempObj.AlarmStatus = $alarm.OverallStatus
$tempObj.AlarmMoRef = $alarm.Alarm
$tempObj.EntityMoRef = $alarm.Entity
$alarmOutput += $tempObj
}
$alarmOutput | Format-Table -AutoSize
}
}
}

View File

@@ -0,0 +1,34 @@
function Move-DatastoreCluster {
<#
.SYNOPSIS
Moves a datastore cluster to a new location
.DESCRIPTION
Will move a datastore cluster to a new location
.NOTES
Author: Kyle Ruddy, @kmruddy
.PARAMETER DatastoreCluster
Specifies the datastore cluster you want to move.
.PARAMETER Destination
Specifies a destination where you want to place the datastore cluster
.EXAMPLE
Move-DatastoreCluster -DatastoreCluster $DSCluster -Destination $DSClusterFolder
Moves the $DSCluster datastore cluster to the specified $DSClusterFolder folder.
#>
[CmdletBinding(SupportsShouldProcess = $True)]
param(
[Parameter(Mandatory=$false,Position=0,ValueFromPipelineByPropertyName=$true)]
[VMware.VimAutomation.ViCore.Types.V1.DatastoreManagement.DatastoreCluster]$DatastoreCluster,
[Parameter(Mandatory=$false,Position=1,ValueFromPipelineByPropertyName=$true)]
[VMware.VimAutomation.ViCore.Types.V1.Inventory.Folder]$Destination
)
if ($Global:DefaultVIServer.IsConnected -eq $false) {
Write-Warning -Message "No vCenter Server connection found."
break
}
If ($Pscmdlet.ShouldProcess($DatastoreCluster,"Move Datastore Cluster")) {
$Destination.ExtensionData.MoveIntoFolder($DatastoreCluster.ExtensionData.MoRef)
}
}

View File

@@ -1,11 +1,11 @@
<#
.NOTES
===========================================================================
Created by: Alan Renouf
Organization: VMware
Blog: http://virtu-al.net
Twitter: @alanrenouf
===========================================================================
Created by: Alan Renouf
Organization: VMware
Blog: http://virtu-al.net
Twitter: @alanrenouf
===========================================================================
#>
Foreach ($vmhost in Get-VMHost) {
@@ -24,4 +24,4 @@ Foreach ($vmhost in Get-VMHost) {
$esxcli.nvme.device.feature.$feature.get.Invoke($currentfeature)
}
}
}
}

View File

@@ -0,0 +1,104 @@
function Get-VMSnapshotConfigContent {
<#
.SYNOPSIS
Reads <vm name>.vmsd file content
.DESCRIPTION
Build the vmsd file http URI following https://code.vmware.com/apis/358/vsphere#/doc/vim.FileManager.html
and reads its content with the session established by Connect-VIServer
.INPUTS
VirtualMachine
.OUTPUTS
String - the content of the vmsd file
.NOTES
Author: Dimitar Milov
Version: 1.0
.EXAMPLE
Get-VM <MyVM> | Get-VMSnapshotConfigContent
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$true, ValueFromPipeline=$true)]
[ValidateNotNull()]
[VMware.VimAutomation.Types.VirtualMachine]
$VM
)
PROCESS {
# Create web client from current session
$sessionKey = $vm.GetClient().ConnectivityService.CurrentUserSession.SoapSessionKey
$certValidationHandler = $vm.GetClient().ConnectivityService.GetValidationHandlerForCurrentServer()
$webClient = [vmware.vimautomation.common.util10.httpclientUtil]::CreateHttpClientWithSessionReuse($certValidationHandler, $sessionKey, $null)
# Build VMSD file http URI
# https://code.vmware.com/apis/358/vsphere#/doc/vim.FileManager.html
$vmName = $vm.Name
$datastoreName = ($vm | Get-Datastore).Name
$dcName = ($vm | Get-Datacenter).Name
$serverAddress = $vm.GetClient().ConnectivityService.ServerAddress
$vmsdUri = [uri]"https://$serverAddress/folder/$vmName/$vmName.vmsd?dcPath=$dcName&dsName=$datastoreName"
# Get VMSD content as string
$task = $webClient.GetAsync($vmsdUri)
$task.Wait()
$vmsdContent = $task.Result.Content.ReadAsStringAsync().Result
# Dispose web client
$webClient.Dispose()
# Result
$vmsdContent
}
}
function Get-VMSnapshotConfigSetting {
<#
.SYNOPSIS
Gets the value of a specified key from the snapshot config file content
.DESCRIPTION
Reads the VM's snapshot config file and searches for specified key.
If key is found its value is returned as an output
.INPUTS
VirtualMachine and key
.OUTPUTS
String - config value for the specified key
.NOTES
Author: Dimitar Milov
Version: 1.0
.EXAMPLE
Get-VM <MyVM> | Get-VMSnapshotConfigSetting -Key "numSentinels"
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$true, ValueFromPipeline=$true)]
[ValidateNotNull()]
[VMware.VimAutomation.Types.VirtualMachine]
$VM,
[Parameter(Mandatory=$true)]
[ValidateNotNull()]
[string]
$Key
)
PROCESS {
$content = Get-VMSnapshotConfigContent -vm $vm
$keyMatch = $content | Select-String ('{0} = "(?<value>.*)"' -f $key)
if ($keyMatch.Matches -ne $null) {
$keyMatch.Matches[0].Groups["value"].Value
}
}
}

158
Scripts/Save-PowerCLI.ps1 Normal file
View File

@@ -0,0 +1,158 @@
function Save-PowerCLI {
<#
.SYNOPSIS
Advanced function which can be used to easily download specific versions of PowerCLI from an online gallery
.DESCRIPTION
Downloads a specific version of PowerCLI and all the dependencies at the appropriate version
.NOTES
Author: 1.0 - Dimitar Milov
Author: 2.0 - Kyle Ruddy, @kmruddy
Author: 2.1 - Luc Dekens, @LucD22
- fixed issue with downloading the correct versions
- added a working cleanup of unwanted versions
.PARAMETER RequiredVersion
Dynamic parameter used to specify the PowerCLI version
.PARAMETER Path
Directory path where the modules should be downloaded
.PARAMETER Repository
Repository to access the PowerCLI modules
.PARAMETER Simple
Switch used to specify the nested version folders should be removed (therefore adding PowerShell 3/4 compatibility)
.EXAMPLE
Save-PowerCLI -RequiredVersion '10.0.0.7895300' -Path .\Downloads\
Downloads PowerCLI 10.0.0 to the Downloads folder
.EXAMPLE
Save-PowerCLI -RequiredVersion '6.5.2.6268016' -Path .\Downloads\ -Simple
Downloads PowerCLI 6.5.2 to the Downloads folder and removes the nested version folders
#>
[CmdletBinding(SupportsShouldProcess = $True)]
param(
[Parameter(Mandatory = $true, Position = 1)]
[ValidateScript( { Test-Path $_} )]
$Path,
[Parameter(Mandatory = $false, Position = 2)]
[string]$Repository = 'PSGallery',
[Parameter(Mandatory = $false, Position = 3)]
[Switch]$Simple
)
DynamicParam
{
# Set the dynamic parameters name
$ParameterName = 'RequiredVersion'
# Create the dictionary
$RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
# Create the collection of attributes
$AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
# Create and set the parameters' attributes
$ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute
$ParameterAttribute.ValueFromPipeline = $true
$ParameterAttribute.ValueFromPipelineByPropertyName = $true
$ParameterAttribute.Mandatory = $true
$ParameterAttribute.Position = 0
# Add the attributes to the attributes collection
$AttributeCollection.Add($ParameterAttribute)
# Generate and set the ValidateSet
$pcliVersions = Find-Module -Name 'VMware.PowerCLI' -AllVersions
$arrSet = $pcliVersions | select-Object -ExpandProperty Version
$ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($arrSet)
# Add the ValidateSet to the attributes collection
$AttributeCollection.Add($ValidateSetAttribute)
# Create and return the dynamic parameter
$RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [String], $AttributeCollection)
$RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter)
return $RuntimeParameterDictionary
}
begin {
$powercliModuleName = 'VMware.PowerCLI'
$desiredPowerCLIModule = Find-Module -Name $powercliModuleName -RequiredVersion $PSBoundParameters.RequiredVersion -Repository $Repository
$depsOrder = 'VMware.VimAutomation.Sdk', 'VMware.VimAutomation.Common', 'VMware.Vim', 'VMware.VimAutomation.Cis.Core', 'VMware.VimAutomation.Core', 'VMware.VimAutomation.Nsxt', 'VMware.VimAutomation.Vmc', 'VMware.VimAutomation.Vds', 'VMware.VimAutomation.Srm', 'VMware.ImageBuilder', 'VMware.VimAutomation.Storage', 'VMware.VimAutomation.StorageUtility', 'VMware.VimAutomation.License', 'VMware.VumAutomation', 'VMware.VimAutomation.HorizonView', 'VMware.DeployAutomation', 'VMware.VimAutomation.vROps', 'VMware.VimAutomation.PCloud'
$orderedDependencies = @()
foreach ($depModuleName in $depsOrder) {
$orderedDependencies += $desiredPowerCLIModule.Dependencies | Where-Object {$_.Name -eq $depModuleName}
}
foreach ($remainingDep in $desiredPowerCLIModule.Dependencies) {
if ($orderedDependencies.Name -notcontains $remainingDep.Name) {
$orderedDependencies += $remainingDep
}
}
}
process {
# Save PowerCLI Module Version
$desiredPowerCLIModule | Save-Module -Path $Path
# Working with the depenent modules
foreach ($dependency in $orderedDependencies) {
if (Get-ChildItem -Path (Join-Path $path $dependency.Name) | Where-Object {$_.Name -ne $dependency.MinimumVersion}) {
# Save dependencies with minimum version
Find-Module $dependency.Name -RequiredVersion $dependency.MinimumVersion | Save-Module -Path $Path
}
}
}
end {
Get-Item -Path "$($Path)\*" -PipelineVariable dir |
ForEach-Object -Process {
$children = Get-ChildItem -Path $dir.FullName -Directory
if($children.Count -gt 1){
$tgtVersion = $orderedDependencies.GetEnumerator() | where {$_.Name -eq $dir.Name}
$children | where{$_.Name -ne $tgtVersion.MinimumVersion} |
ForEach-Object -Process {
Remove-Item -Path $_.FullName -Recurse -Force -Confirm:$false
}
}
}
if ($Simple) {
function FolderCleanup {
param(
[Parameter(Mandatory = $true, Position = 0)]
[ValidateScript( { Test-Path $_} )]
$ParentFolder,
[Parameter(Mandatory = $true, Position = 1)]
[String]$ModuleName,
[Parameter(Mandatory = $true, Position = 2)]
$Version
)
$topFolder = Get-Item -Path (Join-Path $ParentFolder $ModuleName)
$versionFolder = $topFolder | Get-ChildItem -Directory | Where-Object {$_.Name -eq $Version}
$versionFolder | Get-ChildItem | Copy-Item -Destination $topFolder
# Checking for any nested folders within the PowerCLI module version folder
if ($versionFolder| Get-ChildItem -Directory) {
# Obtaining and storing the child items to a variable, then copying the items to the parent folder's nested folder
$nestFolder = $versionFolder| Get-ChildItem -Directory
foreach ($nestDir in $nestFolder) {
$nestDir | Get-ChildItem | Copy-Item -Destination (Join-Path $topFolder $nestDir.Name)
}
}
# Removing any of the former, no longer needed, directory structure
$versionFolder| Remove-Item -Recurse -Force
}
FolderCleanup -ParentFolder $Path -ModuleName $desiredPowerCLIModule.Name -Version $desiredPowerCLIModule.Version
foreach ($cleanUp in $orderedDependencies) {
FolderCleanup -ParentFolder $Path -ModuleName $cleanUp.Name -Version $cleanUp.MinimumVersion
}
}
}
}

View File

@@ -0,0 +1,63 @@
<#
.NOTES
Script name: Set-ClusterDpm.ps1
Created on: 10/10/2019
Author: Doug Taliaferro, @virtually_doug
Description: Configures Distributed Power Management (DPM) on a cluster.
Dependencies: None known
===Tested Against Environment====
vSphere Version: 6.7
PowerCLI Version: 11.3.0
PowerShell Version: 5.1
OS Version: Windows 7, 10
Keyword: Cluster, DPM
.SYNOPSIS
Configures Distributed Power Management (DPM).
.DESCRIPTION
Enables/disables Distributed Power Management (DPM) for one or more clusters and optionally sets the automation level.
.PARAMETER Clusters
Specifies the name of the cluster(s) you want to configure.
.PARAMETER DpmEnabled
Indicates whether Distributed Power Management (DPM) should be enabled/disabled.
.PARAMETER DpmAutomationLevel
Specifies the Distributed Power Management (DPM) automation level. The valid values are 'automated' and 'manual'.
.EXAMPLE
Set-ClusterDpm -Cluster 'Cluster01' -DpmEnabled:$true
.EXAMPLE
Get-Cluster | Set-ClusterDpm -DpmEnabled:$true -DpmAutomationLevel 'automated'
#>
[CmdletBinding()]
param (
[Parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[Alias('Name')]
[string[]]$Clusters,
[Parameter(Mandatory=$true)]
[bool]$DpmEnabled,
[Parameter(Mandatory = $false)]
[ValidateSet('automated','manual')]
[string]$DpmAutomationLevel
)
Begin {
# Create a configuration spec
$spec = New-Object VMware.Vim.ClusterConfigSpecEx
$spec.dpmConfig = New-Object VMware.Vim.ClusterDpmConfigInfo
$spec.dpmConfig.enabled = $DpmEnabled
if ($DpmAutomationLevel) {
$spec.dpmConfig.defaultDpmBehavior = $DpmAutomationLevel
}
}
Process {
ForEach ($cluster in $Clusters) {
# Configure the cluster
(Get-Cluster $cluster).ExtensionData.ReconfigureComputeResource_Task($spec, $true)
}
}

View File

@@ -0,0 +1,84 @@
<#
.NOTES
Script name: Set-CustomAttributesInGuestinfo.ps1
Created on: 10/04/2018
Author: Doug Taliaferro, @virtually_doug
Description: Gets Custom Attributes assigned to a VM and makes them available to the guest OS.
Dependencies: None known
===Tested Against Environment====
vSphere Version: 6.5
PowerCLI Version: 10.0.0.7893909
PowerShell Version: 5.1.14409.1005
OS Version: Windows 7, 10
Keyword: VM, Attributes, Guestinfo
.SYNOPSIS
Gets Custom Attributes assigned to a VM and makes them available to the guest OS.
.DESCRIPTION
Gets the custom attributes assigned to one or more VMs and sets their values in the
VM's 'guestinfo' advanced settings. This makes the attributes available within the
guest OS using VM tools (vmtoolsd.exe) and allows the attributes to be used as metadata
for applications or management agents that run inside the guest. If the attribute name
contains spaces they are removed in naming the advanced setting.
For example, if a VM has a custom attribute named 'Created On', the advanced setting
becomes:
'guestinfo.CreatedOn' = '08/08/2018 14:24:17'
This can be retrieved in the guest OS by running:
vmtoolsd.exe --cmd "info-get guestinfo.CreatedOn"
.PARAMETER VMs
One or more VMs returned from the Get-VM cmdlet.
.PARAMETER Attributes
The names of the Custom Attributes to get. If the names contain spaces they must be
enclosed in quotes. The spaces will be removed to name the advanced setting.
.PARAMETER vCenter
The vCenter server to connect to. Optional if you are already connected.
.EXAMPLE
.\Set-CustomAttributesInGuestInfo.ps1 -VM (get-vm testvm01) -Attributes 'Created On', 'Created By'
Gets the custom attributes 'Created On' and 'Created By' for 'testvm01' and sets their
values in 'guestinfo.CreatedOn' and 'guestinfo.CreatedBy'.
.EXAMPLE
.\Set-CustomAttributesInGuestInfo.ps1-VM (get-cluster Dev-01 | get-vm) -Attributes 'Created On'
Gets the custom attribute 'Created On' for all VMs in the Dev-01 cluster and sets 'guestinfo.CreatedOn'
on each VM.
#>
#Requires -modules VMware.VimAutomation.Core
[CmdletBinding()]
param (
[Parameter(Mandatory=$true,Position=0)]
$VMs,
[Parameter(Mandatory=$true,Position=1)]
[string[]]$Attributes,
[string]$vCenter
)
if ($vCenter) {
Connect-VIServer $vCenter
}
ForEach ($vm in $VMs) {
ForEach ($attributeName in $Attributes) {
# Get the custom attribute with a matcing key name
$customField = $vm.CustomFields | Where-Object Key -eq $attributeName
if ($customField) {
# Remove white space from the attribute name because the advanced
# setting name cannot contain spaces
$attributeNameNoSpaces = $customField.Key -replace '\s',''
$guestinfoName = "guestinfo.$attributeNameNoSpaces"
$guestinfoValue = $customField.Value
Write-Host "$($vm): setting '$guestinfoName' = '$guestinfoValue'"
New-AdvancedSetting -Entity $vm -Name $guestinfoName -Value $guestinfoValue -Confirm:$false -Force | Out-Null
} else {
Write-Host "$($vm): custom attribute '$attributeName' not set on this VM"
}
}
}

View File

@@ -0,0 +1,50 @@
function Set-NetworkAdapterOpaqueNetwork {
param(
[Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 1)]
[VMware.VimAutomation.Types.NetworkAdapter]
$NetworkAdapter,
[Parameter(Mandatory = $true, Position = 2)]
[string]
$OpaqueNetworkName,
[Parameter()]
[switch]
$Connected,
[Parameter()]
[switch]
$StartConnected
)
process {
$opaqueNetwork = Get-View -ViewType OpaqueNetwork | ? {$_.Name -eq $OpaqueNetworkName}
if (-not $opaqueNetwork) {
throw "'$OpaqueNetworkName' network not found."
}
$opaqueNetworkBacking = New-Object VMware.Vim.VirtualEthernetCardOpaqueNetworkBackingInfo
$opaqueNetworkBacking.OpaqueNetworkId = $opaqueNetwork.Summary.OpaqueNetworkId
$opaqueNetworkBacking.OpaqueNetworkType = $opaqueNetwork.Summary.OpaqueNetworkType
$device = $NetworkAdapter.ExtensionData
$device.Backing = $opaqueNetworkBacking
if ($StartConnected) {
$device.Connectable.StartConnected = $true
}
if ($Connected) {
$device.Connectable.Connected = $true
}
$spec = New-Object VMware.Vim.VirtualDeviceConfigSpec
$spec.Operation = [VMware.Vim.VirtualDeviceConfigSpecOperation]::edit
$spec.Device = $device
$configSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
$configSpec.DeviceChange = @($spec)
$NetworkAdapter.Parent.ExtensionData.ReconfigVM($configSpec)
# Output
Get-NetworkAdapter -Id $NetworkAdapter.Id
}
}

View File

@@ -0,0 +1,98 @@
<#
.NOTES
Script name: Set-TagsInGuestinfo.ps1
Created on: 10/02/2018
Author: Doug Taliaferro, @virtually_doug
Description: Gets the vSphere Tags assigned to a VM and makes them available to the guest OS.
Dependencies: None known
===Tested Against Environment====
vSphere Version: 6.5
PowerCLI Version: 10.0.0.7893909
PowerShell Version: 5.1.14409.1005
OS Version: Windows 7, 10
Keyword: VM, Tags, Guestinfo
.SYNOPSIS
Gets the vSphere Tags assigned to a VM and makes them available to the guest OS.
.DESCRIPTION
Gets the tags assigned to one or more VMs from one or more categories and sets the tag values
in the VM's 'guestinfo' advanced settings. This makes the tags available within the guest OS
using VM tools (vmtoolsd.exe) and allows the tags to be used as metadata for applications or
management agents that run inside the guest.
For example, if a VM has a tag named 'Accounting' from the
category 'Departments', the advanced setting becomes:
guestinfo.Departments = Accounting
This can be retrieved in the guest OS by running:
vmtoolsd.exe --cmd "info-get guestinfo.Departments"
If multiple tags are assigned from the same category, they are joined using the specified
delimter (a semicolon by default):
guestinfo.Departments = Accounting;Sales
.PARAMETER VMs
One or more VMs returned from the Get-VM cmdlet.
.PARAMETER Categories
The names of tag categories that should be set in the advanced settings.
.PARAMETER Delimiter
The delimiting character used for multiple tags of the same category. Defaults to a
semicolon.
.PARAMETER vCenter
The vCenter server to connect to. Optional if you are already connected.
.EXAMPLE
.\Set-TagsInGuestInfo.ps1 -VM (get-vm testvm01) -Categories Departments, Environment
Gets tags assigned to 'testvm01' in the Departments and Environment categories and
sets their values in 'guestinfo.Departments' and 'guestinfo.Environment'.
.EXAMPLE
.\Set-TagsInGuestInfo.ps1 -VM (get-cluster Dev-01 | get-vm) -Categories Departments
Gets tags assigned to all VMs in the Dev-01 cluster and sets 'guestinfo.Departments'
on each VM.
#>
#Requires -modules VMware.VimAutomation.Core
[CmdletBinding()]
param (
[Parameter(Mandatory=$true,Position=0)]
$VMs,
[Parameter(Mandatory=$true,Position=1)]
[string[]]$Categories,
[string]$Delimiter = ';',
[string]$vCenter
)
if ($vCenter) {
Connect-VIServer $vCenter
}
ForEach ($categoryName in $Categories) {
$category = Get-TagCategory -Name $categoryName
if ($category) {
$guestinfoName = "guestinfo.$category"
# Get Tag assignments for the VMs
$tags = Get-TagAssignment -Entity $VMs -Category $category
# Group the tags by VM (in this case the Entity property of Group-Object)
$groups = $tags | Group-Object -Property Entity
# Get each VM and set the guestinfo
ForEach ($item in $groups) {
$vm = get-vm $item.Name
# Multiple tags of the same category are joined
$guestinfoValue = $item.Group.Tag.Name -join $Delimiter
Write-Host "$($vm): setting '$guestinfoName' = '$guestinfoValue'"
New-AdvancedSetting -Entity $vm -Name $guestinfoName -Value $guestinfoValue -Confirm:$false -Force | Out-Null
}
} else {
Write-Host "Category '$categoryName' was not found."
}
}

View File

@@ -7,9 +7,10 @@
# Set details for SDDC
$oauthToken = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx"
$sddcName = "PowerCLI-1Node-SDDC"
$sddcName = "PowerCLI-1Host-SDDC"
$hostCount = "1"
$awsRegion = "US_WEST_2"
$useAwsAccount = $false
# --- Deployment code ---
# Connect to VMware Cloud Service
@@ -18,19 +19,25 @@ Connect-Vmc -RefreshToken $oauthToken | Out-Null
# Get ORG ID
$orgSvc = Get-VmcService -Name com.vmware.vmc.orgs
$org = $orgSvc.List()
Write-Host "Org:"$org.display_name" ID:"$org.id
Write-Output -InputObject "Org: $($org.display_name) ID: $($org.id)"
# Get Linked Account ID
$connAcctSvc = Get-VmcService -Name com.vmware.vmc.orgs.account_link.connected_accounts
$connAcctId = $connAcctSvc.get($org.id) | Select-Object -ExpandProperty id
Write-Host "Account ID: $connAcctId"
# Check to use the already existing AWS account connection
if ($useAwsAccount -eq $true) {
# Get Linked Account ID
$connAcctSvc = Get-VmcService -Name com.vmware.vmc.orgs.account_link.connected_accounts
$connAcctId = $connAcctSvc.get($org.id) | Select-Object -ExpandProperty id
Write-Output -InputObject "Account ID: $connAcctId"
# Get Subnet ID
$compSubnetSvc = Get-VmcService -Name com.vmware.vmc.orgs.account_link.compatible_subnets
$vpcMap = $compSubnetSvc.Get($org.id, $connAcctId, $region) | Select-Object -ExpandProperty vpc_map
$compSubnets = $vpcMap | Select-Object -ExpandProperty Values | Select-Object -ExpandProperty subnets
$compSubnet = $compSubnets | where {$_.name -ne $null} | Select-Object -first 1
Write-Host "Subnet CIDR"$compSubnet.subnet_cidr_block"ID:"$compSubnet.subnet_id
# Get Subnet ID
$compSubnetSvc = Get-VmcService -Name com.vmware.vmc.orgs.account_link.compatible_subnets
$vpcMap = $compSubnetSvc.Get($org.id, $connAcctId, $region) | Select-Object -ExpandProperty vpc_map
$compSubnets = $vpcMap | Select-Object -ExpandProperty Values | Select-Object -ExpandProperty subnets
$compSubnet = $compSubnets | where {$_.name -ne $null} | Select-Object -first 1
Write-Output -InputObject "Subnet CIDR $($compSubnet.subnet_cidr_block) ID: $($compSubnet.subnet_id)"
}
elseif ($useAwsAccount -eq $false) {
Write-Output -InputObject "AWS Account Not Configured - you must connect to an AWS account within 14 days of creating this SDDC"
}
# Deploy the SDDC
$sddcSvc = Get-VmcService com.vmware.vmc.orgs.sddcs
@@ -40,12 +47,20 @@ $sddcCreateSpec.Name = $sddcName
$sddcCreateSpec.num_hosts = $hostCount
if ($org.properties.values.sddcTypes) {$sddcCreateSpec.sddc_type = "1NODE"}
$sddcCreateSpec.Provider = "AWS"
$accountLinkSpec = $sddcSvc.Help.create.sddc_config.account_link_sddc_config.Element.Create()
$accountLinkSpec.connected_account_id = $connAcctId
$custSubId0 = $sddcSvc.Help.create.sddc_config.account_link_sddc_config.Element.customer_subnet_ids.Element.Create()
$custSubId0 = $compSubnet.subnet_id
$accountLinkSpec.customer_subnet_ids.Add($custSubId0) | Out-Null
$sddcCreateSpec.account_link_sddc_config.Add($accountLinkSpec) | Out-Null
$sddcCreateSpec
if ($useAwsAccount -eq $true) {
$accountLinkSpec = $sddcSvc.Help.create.sddc_config.account_link_sddc_config.Element.Create()
$accountLinkSpec.connected_account_id = $connAcctId
$custSubId0 = $sddcSvc.Help.create.sddc_config.account_link_sddc_config.Element.customer_subnet_ids.Element.Create()
$custSubId0 = $compSubnet.subnet_id
$accountLinkSpec.customer_subnet_ids.Add($custSubId0) | Out-Null
$sddcCreateSpec.account_link_sddc_config.Add($accountLinkSpec) | Out-Null
}
elseif ($useAwsAccount -eq $false) {
$accountLinkDelaySpec = $sddcSvc.Help.create.sddc_config.account_link_config.delay_account_link.Create()
$accountLinkDelaySpec = $true
$sddcCreateSpec.account_link_config.delay_account_link = $accountLinkDelaySpec
}
$newSddc = $sddcSvc.create($org.Id, $sddcCreateSpec)
$newSddc
$newSddc | Select-Object resource_id,status,task_type,start_time,task_id

View File

@@ -0,0 +1,209 @@
# Author: Kyle Ruddy
# Product: VMware Cloud on AWS
# Description: VMware Cloud on AWS Firewall Rule Accelerator for PowerCLI
# Requirements:
# - PowerShell 3.x or newer
# - PowerCLI 6.5.4 or newer
# - Use Default IP Addresses
# - Use NSX-V on VMware Cloud on AWS
#---------- USER VARIABLES ----------------------------------------
$oauthToken = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx"
$orgId = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx'
$sddcId = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx'
# ---------- DO NOT MODIFY BELOW THIS ------------------------------
Connect-Vmc -RefreshToken $oauthToken | Out-Null
$orgSvc = Get-VmcService -Name com.vmware.vmc.orgs
if ($orgId) {
$org = $orgSvc.List() | where {$_.id -eq $orgId}
}
else {$org = $orgSvc.List()}
if ($org -eq $null) {Write-Output "No Org Found. Exiting."; break}
$sddcSvc = Get-VmcService -Name com.vmware.vmc.orgs.sddcs
if ($sddcId) {
$sddc = $sddcSvc.Get($org.id, $sddcId)
}
else {$sddc = $sddcSvc.List($org.id)}
if ($sddc -eq $null) {Write-Output "No SDDC Found. Exiting."; break}
elseif ($sddc -is [array]) {Write-Output "Multiple SDDCs Found. Please Specify an SDDC ID. Exiting."; break}
$edgeSvc = Get-VmcService com.vmware.vmc.orgs.sddcs.networks.edges
$mgwEdge = ($edgeSvc.Get($org.id,$sddcId,'gatewayServices') | Select-Object -ExpandProperty edge_page).data | where {$_.id -eq 'edge-1'}
$ipsecSvc = Get-VmcService com.vmware.vmc.orgs.sddcs.networks.edges.ipsec.config
$ipsecVPN = $ipsecSvc.Get($org.id, $sddcId, $mgwEdge.id)
$localSubnet = $ipsecVPN.sites.sites.local_subnets.subnets
$vpnSubnet = $ipsecVPN.sites.sites.peer_subnets.subnets
$vcMgmtIP = $sddc.resource_config.vc_management_ip
$vcPublicIP = $sddc.resource_config.vc_public_ip
$esxSubnet = $sddc.resource_config.esx_host_subnet
$ipsecVPNname = $ipsecVPN.sites.sites.name
function Add-VMCFirewallRule {
<#
.NOTES
===========================================================================
Created by: Kyle Ruddy
Date: 08/22/2018
Organization: VMware
Blog: https://www.kmruddy.com
Twitter: @kmruddy
===========================================================================
.SYNOPSIS
Creates a Firewall Rule for a given SDDC
.DESCRIPTION
Creates a Firewall Rule for a given SDDC
.EXAMPLE
Add-VMCFirewallRule -OrgId <org id> -sddcId <sddc id> -FwRuleName <firewall rule name> -SourceIpAddress <source ip address> -DestIpAddress <destination ip address> -Service <service>
#>
param(
[Parameter(Mandatory=$true)]
[String]$OrgId,
[Parameter(Mandatory=$true)]
[String]$SddcId,
[Parameter(Mandatory=$false)]
[ValidateSet('Management Gateway','Compute Gateway')]
[String]$Edge = 'Management Gateway',
[Parameter(Mandatory=$true)]
[String]$FwRuleName,
[Parameter(Mandatory=$false)]
$SourceIpAddress,
[Parameter(Mandatory=$false)]
$DestIpAddress,
[Parameter(Mandatory=$true)]
[ValidateSet('HTTPS','ICMP','SSO','Provisioning','Any','Remote Console')]
[String]$Service,
[Parameter(Mandatory=$false)]
[ValidateSet('accept')]
$FwAction = 'accept'
)
if ($edge -eq 'Management Gateway') {$EdgeId = 'edge-1'}
elseif ($edge -eq 'Compute Gateway') {$EdgeId = 'edge-2'}
else {Write-Output "No Valid Edge Input Found."}
$fwRuleSvc = Get-VmcService com.vmware.vmc.orgs.sddcs.networks.edges.firewall.config.rules
$ruleElementSpec = $fwRuleSvc.Help.add.firewall_rules.firewall_rules.Element.Create()
$fwRules = $fwRuleSvc.Help.add.firewall_rules.Create()
$ruleSpec = $fwRuleSvc.Help.add.firewall_rules.firewall_rules.Create()
# AppSpec
$appSpec = $fwRuleSvc.Help.add.firewall_rules.firewall_rules.Element.application.Create()
# ServiceSpec
$serviceSpec = $fwRuleSvc.Help.add.firewall_rules.firewall_rules.Element.application.service.Element.Create()
if ($Service -eq 'HTTPS') {
$protocol = 'TCP'
$port = @("443")
}
elseif ($Service -eq 'ICMP') {
$protocol = 'ICMP'
$icmpType = 'any'
}
elseif ($Service -eq 'SSO') {
$protocol = 'TCP'
$port = @("7444")
}
elseif ($Service -eq 'Provisioning') {
$protocol = 'TCP'
$port = @("902")
}
elseif ($Service -eq 'Any') {
$protocol = 'Any'
$port = $null
}
elseif ($Service -eq 'Remote Console') {
$protocol = 'TCP'
$port = @("903")
}
else {Write-Output "No Protocol Found."; break}
$serviceSpec.protocol = $protocol
# Process ICMP Type from JSON
$icmpType = $null
if($protocol -eq 'ICMP') {
$icmpType = 'any'
}
if ($icmpType) {
$serviceSpec.icmp_type = $icmpType}
if ($port) {
$serviceSpec.port = $port
$serviceSpec.source_port = @("any")
}
$addSpec = $ruleElementSpec.application.service.Add($serviceSpec)
# Create Source Spec
if($SourceIpAddress) {
$srcSpec = $fwRuleSvc.Help.add.firewall_rules.firewall_rules.Element.source.Create()
$srcSpec.exclude = $false
$srcSpec.ip_address = @($SourceIpAddress)
$ruleElementSpec.source = $srcSpec
}
# Create Destination Spec
if($DestIpAddress) {
$destSpec = $fwRuleSvc.Help.add.firewall_rules.firewall_rules.Element.destination.Create()
$destSpec.exclude = $false
$destSpec.ip_address = @($DestIpAddress)
$ruleElementSpec.destination = $destSpec
}
$ruleElementSpec.rule_type = "user"
$ruleElementSpec.enabled = $true
$ruleElementSpec.logging_enabled = $false
$ruleElementSpec.action = $FwAction
$ruleElementSpec.name = $FwRuleName
# Add the individual FW rule spec into our overall firewall rules array
Write-Output "Creating VMC Firewall Rule: $FwRuleName"
$ruleSpecAdd = $ruleSpec.Add($ruleElementSpec)
$fwRules.firewall_rules = $ruleSpec
$fwRuleAdd = $fwRuleSvc.add($orgId,$sddcId,$EdgeId,$fwRules)
}
# vCenter (ANY) to VPN
Add-VMCFirewallRule -OrgId $org.Id -sddcId $sddc.id -FwRuleName "vCenter (ANY) to $ipsecVPNname" -SourceIpAddress $vcMgmtIP -DestIpAddress $vpnSubnet -Service 'Any'
# ESXi (ANY) to VPN
Add-VMCFirewallRule -OrgId $org.Id -sddcId $sddc.id -FwRuleName "ESXi (ANY) to $ipsecVPNname" -SourceIpAddress $esxSubnet,'10.2.16.0/20' -DestIpAddress $vpnSubnet -Service 'Any'
# VPN to vCenter (HTTPS)
Add-VMCFirewallRule -OrgId $org.Id -sddcId $sddc.id -FwRuleName "$ipsecVPNname to vCenter (HTTPS)" -SourceIpAddress $vpnSubnet -DestIpAddress $vcMgmtIP -Service 'HTTPS'
# VPN to vCenter (ICMP)
Add-VMCFirewallRule -OrgId $org.Id -sddcId $sddc.id -FwRuleName "$ipsecVPNname to vCenter (ICMP)" -SourceIpAddress $vpnSubnet -DestIpAddress $vcMgmtIP -Service 'ICMP'
# VPN to ESXi (Provisioning)
Add-VMCFirewallRule -OrgId $org.Id -sddcId $sddc.id -FwRuleName "$ipsecVPNname to ESXi (Provisioning)" -SourceIpAddress $vpnSubnet -DestIpAddress $esxSubnet,'10.2.16.0/20' -Service 'Provisioning'
# VPN to ESXi (Remove Console)
Add-VMCFirewallRule -OrgId $org.Id -sddcId $sddc.id -FwRuleName "$ipsecVPNname to ESXi (Remote Console)" -SourceIpAddress $vpnSubnet -DestIpAddress $esxSubnet,'10.2.16.0/20' -Service 'Remote Console'
# VPN to ESXi (ICMP)
Add-VMCFirewallRule -OrgId $org.Id -sddcId $sddc.id -FwRuleName "$ipsecVPNname to ESXi (ICMP)" -SourceIpAddress $vpnSubnet -DestIpAddress $esxSubnet,'10.2.16.0/20' -Service 'ICMP'

View File

@@ -0,0 +1,114 @@
<#
.SYNOPSIS
Takes email address input in order to create VMware Cloud on AWS invites for the desired Organization
.DESCRIPTION
Script which can be used to automate the process of adding new users to a specified VMware Cloud on AWS Organization
.NOTES
Author: Kyle Ruddy, @kmruddy, kmruddy.com
.PARAMETER newUserEmail
Plain text email address or array of email addresses
.PARAMETER roleName
Desired role name of the new users, default is Organization Member
.EXAMPLE
PS > ./VMWonAWS_InviteUsers.ps1 -newUserEmail 'testuser@vmware.com'
.EXAMPLE
PS > ./VMWonAWS_InviteUsers.ps1 -newUserEmail $arrayOfEmailAddresses
#>
[CmdletBinding(SupportsShouldProcess=$True)]
param (
[Parameter (Mandatory = $True, Position=0)]
$newUserEmail,
[Parameter (Mandatory = $False, Position=1)]
[ValidateSet("Organization Member","Organization Owner","Support User")]
[string]$roleName = "Organization Member"
)
# Set Static Variables for your environment
$oauthToken = 'xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
$orgID = 'xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
### DO NOT MODIFY CODE BELOW THIS LINE ###
$inviteReport = @()
$userEmail = @()
# Email Validation Testing
if ($newUserEmail -is [array]) {
foreach ($email in $newUserEmail) {
try {
$userEmail += [mailAddress]$email | select-object -ExpandProperty Address
}
catch {
Write-Warning "$email is not a valid email address"
}
}
}
else {
try {
$userEmail += [mailAddress]$newUserEmail | select-object -ExpandProperty Address
}
catch {
Write-Warning "$newUserEmail is not a valid email address"
}
}
if ($userEmail.Count -eq 0) {
Write-Warning "No valid email addresses found."
Break
}
# Validation and translation of the role name to the role ID
if ($roleName -eq 'Organization Member') {
$orgRoleNames = @("org_member")
}
elseif ($roleName -eq 'Organization Owner') {
$orgRoleNames = @("org_owner")
}
elseif ($roleName -eq 'Support User') {
$orgRoleNames = @("support_user")
}
# Creating custom objects to start building out the body input
$bodyObj = new-object -TypeName System.Object
$SvcRoleNames = @("vmc-user:full")
$SvcDefinitionLink = '/csp/gateway/slc/api/definitions/external/ybUdoTC05kYFC9ZG560kpsn0I8M_'
$bodyObj | Add-Member -Name 'orgRoleNames' -MemberType Noteproperty -Value $orgRoleNames
$serviceRolesDtos = New-Object -TypeName System.Object
$serviceRolesDtos | Add-Member -Name 'serviceDefinitionLink' -MemberType Noteproperty -Value $SvcDefinitionLink
$serviceRolesDtos | Add-Member -Name 'serviceRoleNames' -MemberType Noteproperty -Value $SvcRoleNames
$bodyObj | Add-Member -Name 'serviceRolesDtos' -MemberType Noteproperty -Value @($serviceRolesDtos)
$bodyObj | Add-Member -Name 'usernames' -MemberType Noteproperty -Value $userEmail
$body = $bodyObj | ConvertTo-Json -Depth 100
# Connecting to the REST API service for authentication and then to perform the POST method
$connection = Invoke-WebRequest -Uri "https://console.cloud.vmware.com/csp/gateway/am/api/auth/api-tokens/authorize?refresh_token=$oauthToken" -Method Post
$accesskey = ($connection.content | Convertfrom-json).access_token
$inviteUsers = Invoke-WebRequest -Uri "https://console.cloud.vmware.com/csp/gateway/am/api/orgs/$orgID/invitations" -headers @{"csp-auth-token"="$accesskey"} -Method Post -Body $body -ContentType "application/json"
# Outputting the successful invite which was just created
$orgInviteRefResponse = Invoke-WebRequest -Uri "https://console.cloud.vmware.com/csp/gateway/am/api/orgs/$orgid/invitations" -headers @{"csp-auth-token"="$accessKey"} -Method Get
if ($orgInviteRefResponse) {
$orgInviteRefObject = $orgInviteRefResponse | ConvertFrom-Json
foreach ($inviteRef in $orgInviteRefObject) {
$link = $inviteRef.refLink
$orgInviteResponse = Invoke-WebRequest -Uri "https://console.cloud.vmware.com$link" -headers @{"csp-auth-token"="$accessKey"} -Method Get
$orgInviteObject = $orgInviteResponse.content | ConvertFrom-Json
foreach ($emailInput in $userEmail) {
if ($orgInviteObject.username -eq $emailInput) {
$i = New-Object System.Object
$i | Add-Member -Type NoteProperty -Name InviteID -Value $orgInviteObject.refLink.Substring($orgInviteObject.refLink.Length - 36)
$i | Add-Member -Type NoteProperty -Name Username -Value $orgInviteObject.username
$i | Add-Member -Type NoteProperty -Name Status -Value $orgInviteObject.status
$i | Add-Member -Type NoteProperty -Name OrgRoles -Value ($orgInviteObject.OrgRoleNames -join ", ")
$i | Add-Member -Type NoteProperty -Name Requester -Value $orgInviteObject.generatedBy
$inviteReport += $i
}
}
}
}
return $inviteReport

View File

@@ -0,0 +1,37 @@
$refreshToken = 'your-refresh-token'
$reportPath = '.\VMC-services.xlsx'
Connect-Vmc -RefreshToken $refreshToken > $null
$columns = @{}
$services = Get-VmcService | Sort-Object -Property Name
$services | ForEach-Object -Process {
$_.Help | Get-Member -MemberType NoteProperty | where{'Constants','Documentation' -notcontains $_.Name} |
ForEach-Object -Process {
if(-not $columns.ContainsKey($_.Name)){
$columns.Add($_.Name,'')
}
}
}
$columns = $columns.Keys | Sort-Object
$report = @()
foreach($service in $services){
$obj = [ordered]@{
Name = $service.Name
}
$columns | ForEach-Object -Process {
$obj.Add($_,'')
}
$service.Help | Get-Member -MemberType NoteProperty | where{'Constants','Documentation' -notcontains $_.Name} |
ForEach-Object -Process {
# $obj.Item($_.Name) = "$($service.Help.$($_.Name).Documentation)"
$obj.Item($_.Name) = "X"
}
$report += New-Object PSObject -Property $obj
}
$report | Export-Excel -Path $reportPath -WorksheetName 'Services' -FreezeTopRow -BoldTopRow -AutoSize -Show
Disconnect-Vmc -Confirm:$false

View File

@@ -0,0 +1,22 @@
<#
Script name: backup-esxi-host-configuration.ps1
Created on: 09/10/2018
Author: Gerasimos Alexiou, @jerrak0s
Description: The purpose of the script is to backup esxi host configuration for restore purposes.
Dependencies: None known
===Tested Against Environment====
vSphere Version: 6.5 U2
PowerCLI Version: PowerCLI 10.1.1
PowerShell Version: 5.1
OS Version: Windows 10
Keyword: Backup Configuration ESXi Host
#>
$serverIp = Read-Host 'What is the server ip address:'
$path = Read-Host 'Give path where backup configuration will be stored:'
$serverPass = Read-Host 'What is the server root password:' -AsSecureString
Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false
Connect-VIServer serverip -user "root" -password $serverPass
Get-VMHostFirmware -vmhost serverip -BackupConfiguration -DestinationPath $path