vCDEdgeSSL.psm1
# vCDEdgeSSL.psm1 # # PS Module to allow management of NSX Edge SSL Certificates via the vCloud API # # Requires that you are already connected to the appropriate vCloud Director # site(s) - powervcav will use the $Global:DefaultCIServers context to extract # vCD session keys and use these to authenticate to vCD. VMware PowerCLI is # required for this module to function. # # Copyright 2019 Jon Waite, All Rights Reserved # Released under MIT License - see https://opensource.org/licenses/MIT # Date: 27th December 2019 # Version: 0.1.4 # Internal function to return the correct member of $global:DefaultCIServer if # we are connected to multiple clouds and the -Server parameter has been # provided or the current instance if only connected to one server. Function Get-vCDServerRef{ [cmdletbinding()] Param( [parameter(Mandatory=$false)][String]$Server ) # If not connected generate error and exit if (-Not $Global:DefaultCIServers) { Write-Host -ForegroundColor Red ("Error: Not connected to any vCloud Director endpoints, use Connect-CIServer to connect prior to running commands.") Break } if ($Global:DefaultCIServers.Count -gt 1) { # If connected to multiple clouds if (-not $Server) { # and no -Server parameter provided, generate error and exit Write-Host -ForegroundColor Red ("Error: You are currently connected to more than one vCD API Endpoint, the -Server parameter must be used to specify which one to operate against. Connected vCD endpoints:") foreach ($vcdserver in $global:DefaultCIServers) { Write-Host -ForegroundColor Cyan ($vcdserver.Name) } Break } else { # -Server parameter has been specified ForEach ($ServerCon in $Global:DefaultCIServers) { if ($ServerCon.Name.ToLower() -eq $Server.ToLower()) { # Found a match Write-Host 'Found Match' return $ServerCon } } # No match found Write-Host -ForegroundColor Red ("Error: Could not match an API connection to server '$($Server)'. Connected vCD endpoints:") foreach ($vcdserver in $global:DefaultCIServers) { Write-Host -ForegroundColor Cyan ($vcdserver.Name) } Break } } else { # Only connected to 1 cloud if ($Server) { if ($Global:DefaultCIServers[0].Name.ToLower() -ne $Server.ToLower()) { Write-Host -ForegroundColor Red ("Error: Specified server name '$($Server)' does not match currently connected cloud name '$($Global:DefaultCIServers[0].Name)'.") Break } else { # Name matches return $Global:DefaultCIServers[0] } } return $Global:DefaultCIServers[0] } } # Internal function to return the highest supported vCD API version on the # specified endpoint (or connected endpoint if only 1). Function Get-vCDAPIVersion{ [cmdletbinding()] Param( [parameter(Mandatory=$False)][string]$Server # Which API endpoint to use if connected to multiple ) $serverRef = Get-vcdServerRef -Server $Server $uri = "https://$($serverRef.Name)/api/versions" $headers = @{'Accept'='application/*+xml'} Try { [xml]$r = Invoke-WebRequest -Method Get -Uri $uri -Headers $headers -ErrorAction Stop } Catch { Write-Host -ForegroundColor Red ("Error: $($_.Exception.Message)") Write-Host -ForegroundColor Red ("Item: $($_.Exception.ItemName)") Break } $apivers = (($r.SupportedVersions.VersionInfo | Where-Object { $_.deprecated -eq $False }) ` | Measure-Object -Property Version -Maximum).Maximum.ToString() + ".0" return $apivers } Function Get-EdgeSSLCert{ <# .SYNOPSIS Retrieves SSL Certificates on the specified NSX Edge Gateway for a vCloud Director tenant organization. .DESCRIPTION Get-EdgeSSLCert retrieves all (or optionally a single) object representing the SSL certificates installed on a vCloud Director edge gateway. The Id field in the returned object can be used for other cmdlets in this module (e.g Create-EdgeSSLCert and Update-EdgeSSLCert). Available Edge Gateways can be obtained from the VMware Get-EdgeGateway cmdlet. .PARAMETER Server Optional parameter specifying which vCloud Director API endpoint should be used if currently connected to multiple endpoints. If only connected to a single API endpoint this parameter is not required. .PARAMETER EdgeGW Parameter representing the NSX Edge Gateway to operate against. Either this parameter or the EdgeGWName parameter must be specified. An object returned by the Get-EdgeGateway cmdlet can be piped to Get-EdgeSSLCert. .PARAMETER EdgeGWName The name of the NSX Edge Gateway to operate against. Either this parameter or the EdgeGW parameter must be specified. If the name cannot be matched to an accessible Edge Gateway an error is returned. .PARAMETER CertName An optional parameter that attempts to match the certificate name provided and will only return a certificate whose name matches exactly. .PARAMETER CertId An optional parameter that attempts to match the certificate Id provided and will only return a certificate whose Id matches exactly. .OUTPUTS Any matching SSL Certificates are returned as a PSCustomObject containing the details of the certificate(s). .EXAMPLE Get-EdgeGateway | Get-EdgeSSLCert .EXAMPLE Get-EdgeGateway | Get-EdgeSSLCert -EdgeGWName 'MyEdge' .EXAMPLE Get-EdgeGateway | Get-EdgeSSLCert -CertName 'My Service Certificate' .NOTES Must be already connected to the vCloud Director API (Connect-CIServer) prior to running this command. Must have permissions in vCloud Director to allow access to the Edge Gateway configuration (typically Organization Administrator). #> [cmdletbinding()] Param ( [parameter(Mandatory=$False)][string]$Server, [parameter(ValueFromPipeline=$True,Mandatory=$False)]$EdgeGW, [parameter(Mandatory=$False)][string]$EdgeGWName, [parameter(Mandatory=$False)][string]$CertName, [parameter(Mandatory=$False)][string]$CertId ) Process{ # Check we are connected and obtain environment details: $ServerRef = Get-vcdServerRef -Server $Server $apiVersion = Get-vCDAPIVersion -Server $Server $sessionId = $ServerRef.SessionId $Server = $ServerRef.Name # If EdgeGWName is supplied, attempt to locate an Edge Gateway with that name If ($EdgeGWName) { Try { $EdgeGW = Get-EdgeGateway -Server $Server -Name $EdgeGWName -ErrorAction Stop } Catch { Write-Host -ForegroundColor Yellow ("Could not find Edge Gateway with name: " + $EdgeGWName) break } } else { Try { $EdgeGW = Get-EdgeGateway -Server $Server -ErrorAction Stop } Catch { Write-Host -ForegroundColor Red ("Error: $($_.Exception.Message)") Write-Host -ForegroundColor Red ("Item: $($_.Exception.ItemName)") Break } } # If EdgeGWName is specified # If we have an Edge Gateway object, process it If (!$EdgeGW[0].Id) { Write-Host -ForegroundColor Yellow ("No Edge Gateway Found") break } $certs = @() Foreach ($edge in $EdgeGW) { # Process each edge gateway in turn if more than one $EdgeSvr = $edge.Href.SubString(0,$edge.Href.IndexOf('/api/admin')) $EdgeId = $edge.Id.Substring($edge.Id.LastIndexOf(':') +1) # Get certificates from the Edge GW: $CertURI = "$($EdgeSvr)/network/services/truststore/certificate/scope/$($EdgeId)/" $headers = @{'x-vcloud-authorization'=$sessionId;'Accept'='application/*+xml;version=' + $apiVersion} [xml]$r = Invoke-WebRequest -Uri $CertURI -Headers $headers -Method Get if ($r.certificates.certificate.objectId) { # If certificates found in store ForEach ($cert in $r.Certificates.certificate) { $certfile = $env:TMP + "\cert-data" Set-Content -Path $certfile -Value $cert.pemEncoding $x509cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate $x509cert.Import($certfile) $certObj = [PSCustomObject]@{ 'EdgeGWName' = [string]$edge.Name 'EdgeGWId' = [string]$EdgeId 'CertName' = [string]$cert.name 'CertId' = [string]$cert.objectId 'CertRef' = [string]$cert.objectId.Substring($cert.objectId.LastIndexOf(':') + 1) 'CertSerial' = [string]$x509cert.GetSerialNumberString() 'CertIssuer' = [string]$x509cert.GetIssuerName() 'CertSubject' = [string]$x509cert.Subject 'CertDescription' = [string]$cert.description 'CertNotBefore' = Get-Date($x509cert.GetEffectiveDateString()) 'CertNotAfter' = Get-Date($x509cert.GetExpirationDateString()) 'CertThumbprint' = [String]$x509cert.GetCertHashString() -replace '(..(?!$))','$1:' 'CertDaysToExpiry' = [Int]$cert.daysLeftToExpiry } $certs += $certObj } # For each certificate found } # if certificates found in store } # Each gateway processed if ($CertName -or $CertId) { # If we've asked to match on name or Id, find match and return it ForEach ($cert in $certs) { if ($CertName) { if ($cert.CertName.ToLower() -eq $CertName.ToLower()) { return $cert } } if ($CertId) { if ($cert.CertId.ToLower() -eq $CertId.ToLower()) { return $cert } } } if ($CertName) { Write-Host -ForegroundColor Yellow ("Could not find a matching certificate with name '$($CertName)'.") } if ($CertId) { Write-Host -ForegroundColor Yellow ("Could not find a matching certificate with Id '$($CertId)'.") } break } # Otherwise return collection of all found certificates: if ($certs.Count -gt 0) { return $certs } else { Write-Host -ForegroundColor Yellow ("No SSL certificates found on Edge Gateway '$($EdgeGW.Name)' in OrgVDC '$($EdgeGW.OrgVdc)'.") } } # Process } # Get-SSLEdge Function Function Add-EdgeSSLCert{ <# .SYNOPSIS Add a new SSL Certificate to the specified Edge Gateway .DESCRIPTION This cmdlet will add a new SSL certificate to the specified NSX Edge Gateway from the files specified in CertFile and CertKeyFile. You must specify the Server if currently connected to multiple vCloud Director API endpoints. You must also specify which Edge Gateway to add the certificate to (even if only one exists). Get-EdgeGateway can provide a list of accessible gateways. .PARAMETER Server Optional parameter specifying which vCloud Director API endpoint should be used if currently connected to multiple endpoints. If only connected to a single API endpoint this parameter is not required. .PARAMETER EdgeGW Parameter representing the NSX Edge Gateway to operate against. Either this parameter or the EdgeGWName parameter must be specified. An object returned by the Get-EdgeGateway cmdlet can be piped to Add-EdgeSSLCert. .PARAMETER EdgeGWName The name of the NSX Edge Gateway to operate against. Either this parameter or the EdgeGW parameter must be specified. If the name cannot be matched to an accessible Edge Gateway an error is returned. .PARAMETER CertFile A text file containing the public key (PEM format) of the certificate to be uploaded to the Edge Gateway. .PARAMETER CertKeyFile A text file containing the private key (PEM format) of the certificate to be uploaded to the Edge Gateway, cannot be encrypted or passphrase protected. If not specified the uploaded certificate can only be used as a reference (e.g. Issuer certificate) and not for a service endpoint. .PARAMETER CertDescription An optional description of the certificate which will be visible in the Edge Gateway view in vCloud Director .OUTPUTS An object containing the certificate details is returned on successful upload/creation of a certificate. .EXAMPLE Add-EdgeSSLCert -EdgeGWName 'MyEdge' -CertFile 'issuer.pem' -CertDescription 'Issuer Certificate' .EXAMPLE Add-EdgeSSLCert -EdgeGWName 'MyEdge' -CertFile 'cert.pem' -CertKeyFile 'cert.key' -CertDescription 'My Signed Certificate' .NOTES Must be already connected to the vCloud Director API (Connect-CIServer) prior to running this command. Must have permissions in vCloud Director to allow access to the Edge Gateway configuration (typically Organization Administrator). #> [cmdletbinding()] Param ( [parameter(Mandatory=$False)][string]$Server, [parameter(ValueFromPipeline=$True,Mandatory=$False)][VMware.VimAutomation.Cloud.Types.V1.EdgeGateway]$EdgeGW, [parameter(Mandatory=$False)][string]$EdgeGWName, [parameter(Mandatory=$True)][string]$CertFile, [parameter(Mandatory=$False)][string]$CertKeyFile, [parameter(Mandatory=$False)][string]$CertDescription ) Process{ # Check we are connected and obtain environment details: $ServerRef = Get-vcdServerRef -Server $Server $apiVersion = Get-vCDAPIVersion -Server $Server $sessionId = $ServerRef.SessionId $Server = $ServerRef.Name # If EdgeGWName is supplied, attempt to locate an Edge Gateway with that name If (!$EdgeGWName) { if (!$EdgeGW) { Write-Host -ForegroundColor Yellow ("You must specify an EdgeGW or EdgeGWName to add an SSL Certificate.") break } } else { Try { $EdgeGW = Get-EdgeGateway -Server $Server -Name $EdgeGWName -ErrorAction Stop } Catch { Write-Host -ForegroundColor Yellow ("Could not find Edge Gateway with name '$($EdgeGWName)'.") break } } $EdgeSvr = $EdgeGW.Href.SubString(0,$EdgeGW.Href.IndexOf('/api/admin')) $EdgeId = $EdgeGW.Id.Substring($EdgeGW.Id.LastIndexOf(':') +1) # Make a new XML TrustObject for the Certificate from files: Try { $pemcert = Get-Content $CertFile -Raw -ErrorAction Stop $prvcert = Get-Content $CertKeyFile -Raw -ErrorAction Stop } Catch { Write-Host -ForegroundColor Red ("Error: $($_.Exception.Message)") Write-Host -ForegroundColor Red ("Item: $($_.Exception.ItemName)") Break } # Build XML Body containing the new certificate [xml]$cert = New-Object System.Xml.XmlDocument $cert.AppendChild($cert.CreateXmlDeclaration("1.0","UTF-8",$null)) | Out-Null $root = $cert.CreateElement("trustObject") $cert.AppendChild($root) | Out-Null $pem = $root.AppendChild($cert.CreateElement("pemEncoding")) $pem.AppendChild($cert.CreateTextNode($pemcert)) | Out-Null $prv = $root.AppendChild($cert.CreateElement("privateKey")) $prv.AppendChild($cert.CreateTextNode($prvcert)) | Out-Null $desc = $root.AppendChild($cert.CreateElement("description")) $desc.AppendChild($cert.CreateTextNode($CertDescription)) | Out-Null # Try to upload the cert to vCD $CertURI = "$($EdgeSvr)/network/services/truststore/certificate/$($EdgeId)/" $headers = @{'x-vcloud-authorization'=$sessionId;'Accept'='application/*+xml;version=' + $apiVersion} Try { [xml]$r = Invoke-WebRequest -Uri $CertURI -Headers $headers -Method Post -ContentType 'application/xml' -Body $cert.InnerXml -ErrorAction Stop Write-Host -ForegroundColor Green ("Certificate '$($r.certificates.certificate.name)' added successfully.") } Catch { Write-Host -ForegroundColor Red ("Error: $($_.Exception.Message)") Write-Host -ForegroundColor Red ("Item: $($_.Exception.ItemName)") Break } # Build PSCustomObject of uploaded certificate and return: $NewCert = $r.certificates.certificate $tmpcertfile = $env:TMP + "\cert-data" Set-Content -Path $tmpcertfile -Value $NewCert.pemEncoding $x509cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate $x509cert.Import($tmpcertfile) $certObj = [PSCustomObject]@{ 'EdgeGWName' = [string]$EdgeGW.Name 'EdgeGWId' = [string]$EdgeId 'CertName' = [string]$NewCert.name 'CertId' = [string]$NewCert.objectId 'CertRef' = [string]$NewCert.objectId.Substring($NewCert.objectId.LastIndexOf(':') + 1) 'CertSerial' = [string]$x509cert.GetSerialNumberString() 'CertIssuer' = [string]$x509cert.GetIssuerName() 'CertSubject' = [string]$x509cert.Subject 'CertDescription' = [string]$NewCert.description 'CertNotBefore' = Get-Date($x509cert.GetEffectiveDateString()) 'CertNotAfter' = Get-Date($x509cert.GetExpirationDateString()) 'CertThumbprint' = [String]$x509cert.GetCertHashString() -replace '(..(?!$))','$1:' 'CertDaysToExpiry' = [Int]$NewCert.daysLeftToExpiry } return $certObj } # Process } # Add-EdgeSSLCert Function Function Remove-EdgeSSLCert{ <# .SYNOPSIS Delete an SSL Certificate from the specified Edge Gateway .DESCRIPTION This cmdlet will remove an existing SSL certificate from the specified NSX Edge Gateway. You must specify the Server if currently connected to multiple vCloud Director API endpoints. You must also specify which Edge Gateway to remove the certificate from (even if only one exists). Get-EdgeSSLCert can provide a list of certificates on gateways. .PARAMETER Server Optional parameter specifying which vCloud Director API endpoint should be used if currently connected to multiple endpoints. If only connected to a single API endpoint this parameter is not required. .PARAMETER EdgeGW Parameter representing the NSX Edge Gateway to operate against. Either this parameter or the EdgeGWName parameter must be specified. An object returned by the Get-EdgeGateway cmdlet can be piped to Add-EdgeSSLCert. .PARAMETER EdgeGWName The name of the NSX Edge Gateway to operate against. Either this parameter or the EdgeGW parameter must be specified. If the name cannot be matched to an accessible Edge Gateway an error is returned. .PARAMETER CertId The ID reference of the certificate to be removed from the Edge Gateway. This Id is a combination of the Edge Gateway and Certificate Ids as returned by the Get-EdgeSSLCert cmdlet. .OUTPUTS A message indicating whether the operation was successfully completed or not. .EXAMPLE Remove-EdgeSSLCert -EdgeGWName 'MyEdge' -CertId '610f4180-9316-4d60-9500-527708c9bfc1:certificate-18' .NOTES Must be already connected to the vCloud Director API (Connect-CIServer) prior to running this command. Must have permissions in vCloud Director to allow access to the Edge Gateway configuration (typically Organization Administrator). #> [cmdletbinding()] Param ( [parameter(Mandatory=$False)][string]$Server, [parameter(ValueFromPipeline=$True,Mandatory=$False)][VMware.VimAutomation.Cloud.Types.V1.EdgeGateway]$EdgeGW, [parameter(Mandatory=$False)][string]$EdgeGWName, [parameter(Mandatory=$True)][string]$CertId ) Process{ # Check we are connected and obtain environment details: $ServerRef = Get-vcdServerRef -Server $Server $apiVersion = Get-vCDAPIVersion -Server $Server $sessionId = $ServerRef.SessionId $Server = $ServerRef.Name # If EdgeGWName is supplied, attempt to locate an Edge Gateway with that name If (!$EdgeGWName) { if (!$EdgeGW) { Write-Host -ForegroundColor Yellow ("You must specify an EdgeGW or EdgeGWName to add an SSL Certificate.") break } } else { Try { $EdgeGW = Get-EdgeGateway -Server $Server -Name $EdgeGWName -ErrorAction Stop } Catch { Write-Host -ForegroundColor Yellow ("Could not find Edge Gateway with name '$($EdgeGWName)'.") break } } $EdgeSvr = $EdgeGW.Href.SubString(0,$EdgeGW.Href.IndexOf('/api/admin')) # Try to remove the cert from vCD $CertURI = "$($EdgeSvr)/network/services/truststore/certificate/$($CertId)" $headers = @{'x-vcloud-authorization'=$sessionId;'Accept'='application/*+xml;version=' + $apiVersion} Try { Invoke-WebRequest -Uri $CertURI -Headers $headers -Method Delete -ContentType 'application/xml' -ErrorAction Stop Write-Host -ForegroundColor Green ("Certificate '$($CertId)' removed from Edge Gateway '$($EdgeGW.Name)' successfully.") } Catch { Write-Host -ForegroundColor Red("Error: Error encountered attempting to remove certificate '$($CertId)' from Edge Gateway '$($EdgeGW.Name)'.") Write-Host -ForegroundColor Red ("Error: $($_.Exception.Message)") Write-Host -ForegroundColor Red ("Item: $($_.Exception.ItemName)") Break } } # Process } # Remove-EdgeSSLCert Function Function Get-EdgeAppProfile{ <# .SYNOPSIS Returns all application profiles on the specified Edge gateway. .DESCRIPTION Get-EdgeAppProfile returns a custom PSObject containing details of the application profiles on the specified Edge gateway. If the optional AppProfileName parameter is specified only returns the first application profile which matches this parameter. .PARAMETER Server Optional parameter specifying which vCloud Director API endpoint should be used if currently connected to multiple endpoints. If only connected to a single API endpoint this parameter is not required. .PARAMETER EdgeGW Parameter representing the NSX Edge Gateway to operate against. Either this parameter or the EdgeGWName parameter must be specified. An object returned by the Get-EdgeGateway cmdlet can be piped to Add-EdgeSSLCert. .PARAMETER EdgeGWName The name of the NSX Edge Gateway to operate against. Either this parameter or the EdgeGW parameter must be specified. If the name cannot be matched to an accessible Edge Gateway an error is returned. .PARAMETER AppProfileName An optional parameter to filter the returned results to a single application profile if a matching name is found on the specified edge gateway. .OUTPUTS A custom PSObject containing details of the application profiles on the specified Edge gateway. .EXAMPLE Get-EdgeAppProfile -EdgeGWName 'MyEdge' .NOTES Must be already connected to the vCloud Director API (Connect-CIServer) prior to running this command. Must have permissions in vCloud Director to allow access to the Edge Gateway configuration (typically Organization Administrator). #> [cmdletbinding()] Param ( [parameter(Mandatory=$False)][string]$Server, [parameter(ValueFromPipeline=$True,Mandatory=$False)][VMware.VimAutomation.Cloud.Types.V1.EdgeGateway]$EdgeGW, [parameter(Mandatory=$False)][string]$EdgeGWName, [parameter(Mandatory=$False)][string]$AppProfileName ) Process{ # Check we are connected and obtain environment details: $ServerRef = Get-vcdServerRef -Server $Server $apiVersion = Get-vCDAPIVersion -Server $Server $sessionId = $ServerRef.SessionId $Server = $ServerRef.Name # If EdgeGWName is supplied, attempt to locate an Edge Gateway with that name If (!$EdgeGWName) { if (!$EdgeGW) { Write-Host -ForegroundColor Yellow ("You must specify an EdgeGW or EdgeGWName.") break } } else { Try { $EdgeGW = Get-EdgeGateway -Server $Server -Name $EdgeGWName -ErrorAction Stop } Catch { Write-Host -ForegroundColor Yellow ("Could not find Edge Gateway with name '$($EdgeGWName)'.") break } } $EdgeSvr = $EdgeGW.Href.SubString(0,$EdgeGW.Href.IndexOf('/api/admin')) $EdgeId = $EdgeGW.Id.Substring($EdgeGW.Id.LastIndexOf(':') +1) # Attempt to retrieve a list of application profiles from the Edge Gateway $AppProfURI = "$($EdgeSvr)/network/edges/$($EdgeId)/loadbalancer/config/applicationprofiles" $headers = @{'x-vcloud-authorization'=$sessionId;'Accept'='application/*+xml;version=' + $apiVersion} Try { [xml]$r = Invoke-WebRequest -Uri $AppProfURI -Headers $headers -Method Get -ContentType 'application/xml' -ErrorAction Stop } Catch { Write-Host -ForegroundColor Red("Error: Error encountered attempting to retrieve application profiles from Edge Gateway '$($EdgeGW.Name)'.") Write-Host -ForegroundColor Red ("Error: $($_.Exception.Message)") Write-Host -ForegroundColor Red ("Item: $($_.Exception.ItemName)") Break } if ($r.loadBalancer.applicationProfile.applicationProfileId.Count -gt 0) { # Found 1 or more application profiles $appProfs = @() ForEach ($appProf in $r.loadBalancer.applicationProfile) { if ($appProf.clientSsl.serviceCertificate) { $appProfCertRef = $EdgeId + ":" + $appProf.clientSsl.serviceCertificate } else { $appProfCertRef = $null } $appProfObj = [PSCustomObject]@{ 'Name' = [string]$appProf.name 'ProfileId' = [string]$appProf.applicationProfileId 'CertId' = [string]$appProfCertRef 'SSLEnabled' = [boolean]$appProf.serverSslEnabled } $appProfs += $appProfObj } if ($AppProfileName) { # Match a particular application profile name ForEach ($appProf in $appProfs) { if ($AppProfileName.ToLower() -eq $AppProf.Name.ToLower()) { # Match found return $appProf } } Write-Host -ForegroundColor Yellow ("No application profile matching name $($AppProfileName) found.") Break } else { # No AppProfileName specified - return all profiles: return $appProfs } } else { Write-Host -ForegroundColor Yellow ("Did not find any application profiles on '$($EdgeGW.Name)' Edge Gateway.") } } # Process } # Get-EdgeAppProfiles Function Function Set-EdgeAppProfileCert{ <# .SYNOPSIS Updates the certificate used by the specified application profile on the Edge gateway to the specified certificate. .DESCRIPTION Set-EdgeAppProfileCert updates the application profile on the Edge Gateway to the provided certificate reference. Available certificate Ids can be retrieved using the Get-EdgeSSLCert cmdlet, available application profiles can be retrieved using the Get-EdgeAppProfiles cmdlet. .PARAMETER Server Optional parameter specifying which vCloud Director API endpoint should be used if currently connected to multiple endpoints. If only connected to a single API endpoint this parameter is not required. .PARAMETER EdgeGW Parameter representing the NSX Edge Gateway to operate against. Either this parameter or the EdgeGWName parameter must be specified. An object returned by the Get-EdgeGateway cmdlet can be piped to Add-EdgeSSLCert. .PARAMETER EdgeGWName The name of the NSX Edge Gateway to operate against. Either this parameter or the EdgeGW parameter must be specified. If the name cannot be matched to an accessible Edge Gateway an error is returned. .PARAMETER AppProfileName The name of the application profile whose certificate is to be updated as returned by the Get-EdgeAppProfiles cmdlet. .PARAMETER CertId The certificate Id to be configured for the specified application profile as returned by the Get-EdgeSSLCert. Note that a full certificate Id is required which includes the Edge Gateway Id and the certificate reference e.g. 'b1b92ec7-4263-4d81-af2a-c9ab5bae08ca:certificate-21' .OUTPUTS A message indicating whether the application certificate was successfully updated or not. .EXAMPLE Set-EdgeAppProfileCert -EdgeGWName 'MyEdge' -AppProfileName 'MyWebServer' -CertId 'b1b92ec7-4263-4d81-af2a-c9ab5bae08ca:certificate-21' .NOTES Must be already connected to the vCloud Director API (Connect-CIServer) prior to running this command. Must have permissions in vCloud Director to allow access to the Edge Gateway configuration (typically Organization Administrator). #> [cmdletbinding()] Param ( [parameter(Mandatory=$False)][string]$Server, [parameter(ValueFromPipeline=$True,Mandatory=$False)][VMware.VimAutomation.Cloud.Types.V1.EdgeGateway]$EdgeGW, [parameter(Mandatory=$False)][string]$EdgeGWName, [parameter(Mandatory=$True)][string]$AppProfileName, [parameter(Mandatory=$True)][String]$CertId ) Process{ # Check we are connected and obtain environment details: $ServerRef = Get-vcdServerRef -Server $Server $apiVersion = Get-vCDAPIVersion -Server $Server $sessionId = $ServerRef.SessionId $Server = $ServerRef.Name # If EdgeGWName is supplied, attempt to locate an Edge Gateway with that name If (!$EdgeGWName) { if (!$EdgeGW) { Write-Host -ForegroundColor Yellow ("You must specify an EdgeGW or EdgeGWName.") break } } else { Try { $EdgeGW = Get-EdgeGateway -Server $Server -Name $EdgeGWName -ErrorAction Stop } Catch { Write-Host -ForegroundColor Yellow ("Could not find Edge Gateway with name '$($EdgeGWName)'.") break } } $EdgeSvr = $EdgeGW.Href.SubString(0,$EdgeGW.Href.IndexOf('/api/admin')) $EdgeId = $EdgeGW.Id.Substring($EdgeGW.Id.LastIndexOf(':') +1) # Check both objects exist (the application profile and certificate): $AppProf = Get-EdgeAppProfile -Server $Server -EdgeGW $EdgeGW -AppProfileName $AppProfileName $Cert = Get-EdgeSSLCert -Server $Server -EdgeGW $EdgeGW -CertId $CertId $AppProfURI = "$($EdgeSvr)/network/edges/$($EdgeId)/loadbalancer/config/applicationprofiles/$($AppProf.ProfileId)" $headers = @{'x-vcloud-authorization'=$sessionId;'Accept'='application/*+xml;version=' + $apiVersion} Try { # Get current XML definition of application profile [xml]$r = Invoke-WebRequest -Uri $AppProfURI -Method Get -Headers $Headers -ErrorAction Stop } Catch { Write-Host -ForegroundColor Red("Error: Error encountered attempting to read application profile '$($AppProf.Name)' from Edge Gateway '$($EdgeGW.Name)'.") Write-Host -ForegroundColor Red ("Error: $($_.Exception.Message)") Write-Host -ForegroundColor Red ("Item: $($_.Exception.ItemName)") Break } # Update to new certificate: $r.applicationProfile.clientSsl.serviceCertificate = $cert.CertRef Try { Invoke-WebRequest -Uri $AppProfURI -Method Put -Headers $headers -Body $r.OuterXml -ContentType 'application/xml' -ErrorAction Stop } Catch { Write-Host -ForegroundColor Red("Error: Error encountered attempting to update application profile '$($AppProf.Name)' on Edge Gateway '$($EdgeGW.Name)'.") Write-Host -ForegroundColor Red ("Error: $($_.Exception.Message)") Write-Host -ForegroundColor Red ("Item: $($_.Exception.ItemName)") Break } Write-Host -ForegroundColor Green ("Application profile '$($AppProf.Name)' updated successfully.") } # Process } # Set-EdgeAppProfileCert Function Update-EdgeAppProfileCert{ <# .SYNOPSIS Updates the specified Edge Gateway application profile to use the supplied certificate and (optionally) removes the old/existing certificate from the certificate store. .DESCRIPTION Update-EdgeAppProfileCert allows an 'all in one' replacement of the SSL certificate assigned to a Load Balancer application profile on an Edge Gateway and can also remove the previous certificate if required. .PARAMETER Server Optional parameter specifying which vCloud Director API endpoint should be used if currently connected to multiple endpoints. If only connected to a single API endpoint this parameter is not required. .PARAMETER EdgeGW Parameter representing the NSX Edge Gateway to operate against. Either this parameter or the EdgeGWName parameter must be specified. An object returned by the Get-EdgeGateway cmdlet can be piped to Add-EdgeSSLCert. .PARAMETER EdgeGWName The name of the NSX Edge Gateway to operate against. Either this parameter or the EdgeGW parameter must be specified. If the name cannot be matched to an accessible Edge Gateway an error is returned. .PARAMETER AppProfileName The name of the application profile whose certificate is to be updated as returned by the Get-EdgeAppProfiles cmdlet. .PARAMETER CertFile A text file containing the public key (PEM format) of the certificate to be uploaded to the Edge Gateway. .PARAMETER CertKeyFile A text file containing the private key (PEM format) of the certificate to be uploaded to the Edge Gateway, cannot be encrypted or passphrase protected. .PARAMETER CertDescription An optional description of the certificate which will be visible in the Edge Gateway view in vCloud Director .PARAMETER RemoveOldCert An optional boolean parameter (defaults to 'False') which specifies whether the 'old' certificate previously assigned to the application profile should be removed from the Edge Gateway if the certificate update is successful. .OUTPUTS A message indicating whether the application certificate was successfully updated or not. .EXAMPLE Update-EdgeAppProfileCert -EdgeGWName 'MyEdge' -AppProfileName 'MyWebServer' -CertFile website.cer -CertKeyFile website.key -CertDescription 'My Web Server' -RemoveOldCert $true .NOTES Must be already connected to the vCloud Director API (Connect-CIServer) prior to running this command. Must have permissions in vCloud Director to allow access to the Edge Gateway configuration (typically Organization Administrator). #> [cmdletbinding()] Param ( [parameter(Mandatory=$False)][string]$Server, [parameter(ValueFromPipeline=$True,Mandatory=$False)][VMware.VimAutomation.Cloud.Types.V1.EdgeGateway]$EdgeGW, [parameter(Mandatory=$False)][string]$EdgeGWName, [parameter(Mandatory=$True)][string]$AppProfileName, [parameter(Mandatory=$True)][String]$CertFile, [parameter(Mandatory=$True)][String]$CertKeyFile, [parameter(Mandatory=$False)][String]$CertDescription, [parameter(Mandatory=$False)][Boolean]$RemoveOldCert = $False ) Process{ # Check we are connected and obtain environment details: $ServerRef = Get-vcdServerRef -Server $Server $Server = $ServerRef.Name # If EdgeGWName is supplied, attempt to locate an Edge Gateway with that name If (!$EdgeGWName) { if (!$EdgeGW) { Write-Host -ForegroundColor Yellow ("You must specify an EdgeGW or EdgeGWName.") break } } else { Try { $EdgeGW = Get-EdgeGateway -Server $Server -Name $EdgeGWName -ErrorAction Stop } Catch { Write-Host -ForegroundColor Yellow ("Could not find Edge Gateway with name '$($EdgeGWName)'.") break } } # Check the specified application profile exists and get it's current certificate Id: $AppProf = Get-EdgeAppProfile -Server $Server -EdgeGW $EdgeGW -AppProfileName $AppProfileName $OldCertId = $AppProf.CertId # Upload the new certificate to this Edge GW: $NewCert = Add-EdgeSSLCert -Server $Server -EdgeGW $EdgeGW -CertFile $CertFile -CertKeyFile $CertKeyFile -CertDescription $CertDescription # Change the application profile to use this new certificate: Set-EdgeAppProfileCert -Server $Server -EdgeGW $EdgeGW -AppProfileName $AppProfileName -CertId $NewCert.CertId # Optionally remove the 'old' certificate: if ($RemoveOldCert) { Remove-EdgeSSLCert -Server $Server -EdgeGW $EdgeGW -CertId $OldCertId } } # Process } # Update-EdgeAppProfileCert # Export the public functions from this module to the environment: Export-ModuleMember -Function Get-EdgeSSLCert Export-ModuleMember -Function Add-EdgeSSLCert Export-ModuleMember -Function Remove-EdgeSSLCert Export-ModuleMember -Function Get-EdgeAppProfile Export-ModuleMember -Function Set-EdgeAppProfileCert Export-ModuleMember -Function Update-EdgeAppProfileCert |