Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix update connect vraserver function #235

Merged
merged 6 commits into from Aug 19, 2020
Merged
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
252 changes: 137 additions & 115 deletions src/Functions/Public/Connect-vRAServer.ps1
Expand Up @@ -12,6 +12,7 @@
.PARAMETER Username
Username to connect with
For domain accounts ensure to specify the Username in the format username@domain, not Domain\Username
Note: UPN's are valid login Usernames as well and may also be in the format username@domain
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Note: UPN's are valid login Usernames as well and may also be in the format username@domain
Note: UPNs are valid login Usernames as well and may also be in the format username@domain

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just submitted the fix for this typo in latest commit to this pull request.


.PARAMETER Password
Password to connect with
Expand All @@ -20,6 +21,11 @@
Credential object to connect with
For domain accounts ensure to specify the Username in the format username@domain, not Domain\Username

.PARAMETER UserAttribute
The AD/LDAP Attribute configured in VMware Identity Manager as the Username
Default is SAMAccountName (SAM)
Accepted values: sAMAccountName, SAM, userPrincipalName, UPN

.PARAMETER APIToken
API Token to connect with

Expand All @@ -45,7 +51,11 @@

.EXAMPLE
$SecurePassword = ConvertTo-SecureString “P@ssword” -AsPlainText -Force
Connect-vRAServer -Server vraappliance01.domain.local -Username TenantAdmin01 -Password $SecurePassword -IgnoreCertRequirements
Connect-vRAServer -Server vraappliance01.domain.local -Username TenantAdmin01@domain.com -Password $SecurePassword -IgnoreCertRequirements -UserAttribute UPN

.EXAMPLE
$SecurePassword = ConvertTo-SecureString “P@ssword” -AsPlainText -Force
Connect-vRAServer -Server vraappliance01.domain.local -Username TenantAdmin01 -Password $SecurePassword -Domain My.Local -IgnoreCertRequirements

.EXAMPLE
Connect-vRAServer -Server api.mgmt.cloud.vmware.com -APIToken 'CuIKrjQgI6htiyRgIyd0ZtQM91fqg6AQyQhwPFJYgzBsaIKxKcWHLAGk81kknulQ'
Expand Down Expand Up @@ -77,6 +87,10 @@
[ValidateNotNullOrEmpty()]
[String]$APIToken,

[parameter(Mandatory=$false)]
[ValidateSet('sAMAccountName', 'SAM', 'userPrincipalName', 'UPN')]
[String]$UserAttribute = 'SAM',

[parameter(Mandatory=$false)]
[Switch]$IgnoreCertRequirements,

Expand All @@ -85,162 +99,170 @@
[String]$SslProtocol
)

# --- Handle untrusted certificates if necessary
$SignedCertificates = $true
Process {
# --- Handle untrusted certificates if necessary
$SignedCertificates = $true

if ($IgnoreCertRequirements.IsPresent){
if ($IgnoreCertRequirements.IsPresent){

if (!$IsCoreCLR) {
if (!$IsCoreCLR) {

if ( -not ("TrustAllCertsPolicy" -as [type])) {
if ( -not ("TrustAllCertsPolicy" -as [type])) {

Add-Type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
Add-Type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
}
"@
}
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
}
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy

}
}

$SignedCertificates = $false
$SignedCertificates = $false

}
}

# --- Security Protocol
$SslProtocolResult = 'Default'
# --- Security Protocol
$SslProtocolResult = 'Default'

if ($PSBoundParameters.ContainsKey("SslProtocol") ){
if ($PSBoundParameters.ContainsKey("SslProtocol") ){

if (!$IsCoreCLR) {
if (!$IsCoreCLR) {

$CurrentProtocols = ([System.Net.ServicePointManager]::SecurityProtocol).toString() -split ', '
if (!($SslProtocol -in $CurrentProtocols)){
$CurrentProtocols = ([System.Net.ServicePointManager]::SecurityProtocol).toString() -split ', '
if (!($SslProtocol -in $CurrentProtocols)){

[System.Net.ServicePointManager]::SecurityProtocol += [System.Net.SecurityProtocolType]::$($SslProtocol)
[System.Net.ServicePointManager]::SecurityProtocol += [System.Net.SecurityProtocolType]::$($SslProtocol)
}
}
$SslProtocolResult = $SslProtocol
}
$SslProtocolResult = $SslProtocol
}

try {

# --- if a refresh token is supplied, we use iaas login
if ($PSBoundParameters.ContainsKey("APIToken")){
# -- iaas login with refresh token
$URI = "https://$($Server)/iaas/login"

# --- Create Invoke-RestMethod Parameters
$JSON = @{
refreshToken = $APIToken
} | ConvertTo-Json
} else {
# --- Convert Secure Credentials to a format for sending in the JSON payload
if ($PSBoundParameters.ContainsKey("Credential")){

$Username = $Credential.UserName
$JSONPassword = $Credential.GetNetworkCredential().Password
}

if ($PSBoundParameters.ContainsKey("Password")){

$JSONPassword = (New-Object System.Management.Automation.PSCredential("username", $Password)).GetNetworkCredential().Password
}

# --- Test for a '\' in the username, e.g. DOMAIN\Username, not supported by the API
if ($Username -match '\\'){
try {

throw "The Username format DOMAIN\Username is not supported by the vRA REST API. Please use username@domain instead"
}
# --- if a refresh token is supplied, we use iaas login
if ($PSBoundParameters.ContainsKey("APIToken")){
# -- iaas login with refresh token
$URI = "https://$($Server)/iaas/login"

# --- Logging in with a domain
if ($Username -match '@') {
# Log in using the advanced authentication API
$URI = "https://$($Server)/csp/gateway/am/idp/auth/login?access_token"
$User = $Username.split('@')[0]
$Domain = $Username.split('@')[1]
# --- Create Invoke-RestMethod Parameters
$JSON = @{
username = $User
password = $JSONPassword
domain = $Domain
refreshToken = $APIToken
} | ConvertTo-Json
} else {
# -- Login with the basic authentication API
$URI = "https://$($Server)/csp/gateway/am/api/login?access_token"
# --- Convert Secure Credentials to a format for sending in the JSON payload
if ($PSBoundParameters.ContainsKey("Credential")){

# --- Create Invoke-RestMethod Parameters
$JSON = @{
username = $Username
password = $JSONPassword
} | ConvertTo-Json
}
}
$Username = $Credential.UserName
$JSONPassword = $Credential.GetNetworkCredential().Password
}

if ($PSBoundParameters.ContainsKey("Password")){

$JSONPassword = (New-Object System.Management.Automation.PSCredential("username", $Password)).GetNetworkCredential().Password
}

# --- Test for a '\' in the username, e.g. DOMAIN\Username, not supported by the API
if ($Username -match '\\'){

$Params = @{
throw "The Username format DOMAIN\Username is not supported by the vRA REST API. Please use username@domain instead"
}

Method = "POST"
URI = $URI
Headers = @{
"Accept"="application/json";
"Content-Type" = "application/json";
# --- Logging in with a domain
if (@("SAM", "SAMAccountName").Contains($UserAttribute) -and $Username -match '@') {
# Log in using the advanced authentication API
$URI = "https://$($Server)/csp/gateway/am/idp/auth/login?access_token"
$User = $Username.split('@')[0]
$Domain = $Username.split('@')[1]
$JSON = @{
username = $User
password = $JSONPassword
domain = $Domain
} | ConvertTo-Json
} else {
# -- Login with the basic authentication API
$URI = "https://$($Server)/csp/gateway/am/api/login?access_token"

# --- Create Invoke-RestMethod Parameters
$JSON = @{
username = $Username
password = $JSONPassword
} | ConvertTo-Json
}
}
Body = $JSON
}

if ((!$SignedCertificates) -and ($IsCoreCLR)) {
$Params = @{

$Params.Add("SkipCertificateCheck", $true)
Method = "POST"
URI = $URI
Headers = @{
"Accept"="application/json";
"Content-Type" = "application/json";
}
Body = $JSON
}

}
if ((!$SignedCertificates) -and ($IsCoreCLR)) {

if (($SslProtocolResult -ne 'Default') -and ($IsCoreCLR)) {
$Params.Add("SkipCertificateCheck", $true)

$Params.Add("SslProtocol", $SslProtocol)
}

}
if (($SslProtocolResult -ne 'Default') -and ($IsCoreCLR)) {

$Response = Invoke-RestMethod @Params
$Params.Add("SslProtocol", $SslProtocol)

if ('refresh_token' -in $Response.PSobject.Properties.Name) {
$Token = $Response.access_token
$RefreshToken = $Response.refresh_token
}
}

if ('token' -in $Response.PSobject.Properties.Name) {
$Token = $Response.token
$RefreshToken = $APIToken
}
$Response = Invoke-RestMethod @Params

# --- Create Output Object
$Script:vRAConnection = [PSCustomObject] @{
if ('refresh_token' -in $Response.PSobject.Properties.Name) {
$Token = $Response.access_token
$RefreshToken = $Response.refresh_token
}

Server = "https://$($Server)"
Token = $Token
RefreshToken = $RefreshToken
APIVersion = $Null
SignedCertificates = $SignedCertificates
SslProtocol = $SslProtocolResult
}
if ('token' -in $Response.PSobject.Properties.Name) {
$Token = $Response.token
$RefreshToken = $APIToken
}

# --- Create Output Object
$Script:vRAConnection = [PSCustomObject] @{

Server = "https://$($Server)"
Token = $Token
RefreshToken = $RefreshToken
APIVersion = $Null
SignedCertificates = $SignedCertificates
SslProtocol = $SslProtocolResult
}

# --- Update vRAConnection with API version
$Script:vRAConnection.APIVersion = (Get-vRAAPIVersion).APIVersion
# --- Update vRAConnection with API version
$Script:vRAConnection.APIVersion = (Get-vRAAPIVersion).APIVersion

}
catch [Exception]{
}
catch [Exception]{

if ($_.Exception.Response.StatusCode -eq "BadRequest") {
# This could be due to an incorrectly set UserAttribute, so customizing the message.
if ($Username -match "@") {
Write-Error -Exception $_.Exception -Message "Is it possible that your environment has userPrincipalName set as the Username attribute? If so, please make sure to include the parameter UserAttribute and set it to either UPN or userPrincipalName (e.g. -UserAttribute UPN)`n`n$($_)" -ErrorAction Stop
} else {
Write-Error -Exception $_.Exception -Message "It is possible that the Username you provided, $Username, is missing a domain (e.g. $Username@domain.com)?`n`n$($_)" -ErrorAction Stop
}
}

throw
throw

}
}

Write-Output $vRAConnection
Write-Output $vRAConnection
}

}