update New-LDAPSIdentitySource cmdlet (#103)

* update New-LDAPSIdentitySource to automatically download certs from domain controllers

* fix bugs

* fix bugs

* fix bugs

* add more error messages

* refactor the codes

* add the original error message

* fix console messages

* fix console messages

* fix error messages

Co-authored-by: Jian Cao <caojian@microsoft.com>
This commit is contained in:
Jiancao164 2023-01-24 13:28:02 -08:00 коммит произвёл GitHub
Родитель 2a34280f46
Коммит f58727ddd5
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 87 добавлений и 9 удалений

1
.gitignore поставляемый
Просмотреть файл

@ -348,3 +348,4 @@ MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
/.idea/

Просмотреть файл

@ -271,6 +271,48 @@ function New-LDAPIdentitySource {
}
}
<#
.Synopsis
Download the certificate from a domain controller
#>
function Get-CertificateFromDomainController {
param (
[Parameter(
Mandatory = $true)]
[ValidateNotNull()]
[System.Uri]
$ParsedUrl,
[Parameter(
Mandatory = $true)]
[ValidateNotNull()]
[string]
$computerUrl
)
try {
$Command = 'nslookup ' + $ParsedUrl.Host + ' -type=soa'
$SSHRes = Invoke-SSHCommand -Command $Command -SSHSession $SSH_Sessions['VC']
if ($SSHRes.ExitStatus -ne 0) {
throw "The FQDN $($ParsedUrl.Host) cannot be resolved to an IP address. Make sure DNS is configured."
}
$Command = 'nc -vz ' + $ParsedUrl.Host + ' ' + $ParsedUrl.Port
$SSHRes = Invoke-SSHCommand -Command $Command -SSHSession $SSH_Sessions['VC']
if ($SSHRes.ExitStatus -ne 0) {
throw "The connection cannot be established. Please check the address, routing and/or firewall and make sure port $($ParsedUrl.Port) is open."
}
Write-Host ("Starting to Download Cert from " + $computerUrl)
$Command = 'echo "1" | openssl s_client -connect ' + $ParsedUrl.Host + ':' + $ParsedUrl.Port + ' -showcerts'
$SSHRes = Invoke-SSHCommand -Command $Command -SSHSession $SSH_Sessions['VC']
$SSHOutput = $SSHRes.Output | out-string
} catch {
throw "Failure to download the certificate from $computerUrl. $_"
}
return $SSHOutput
}
<#
.Synopsis
Recommended: Add a secure external identity source (Active Directory over LDAPS) for use with vCenter Server Single Sign-On.
@ -369,8 +411,8 @@ function New-LDAPSIdentitySource {
$Credential,
[Parameter(
Mandatory = $true,
HelpMessage = 'A comma-delimited list of SAS path URI to Certificates for authentication. Ensure permissions to read included. To generate, place the certificates in any storage account blob and then right click the cert and generate SAS')]
Mandatory = $false,
HelpMessage = 'Optional: The certs will be installed from domain controllers if not specified. A comma-delimited list of SAS path URI to Certificates for authentication. Ensure permissions to read included. To generate, place the certificates in any storage account blob and then right click the cert and generate SAS')]
[System.Security.SecureString]
$SSLCertificatesSasUrl,
@ -379,6 +421,7 @@ function New-LDAPSIdentitySource {
HelpMessage = 'A group in the external identity source to give CloudAdmins access')]
[string]
$GroupName
)
if (-not ($PrimaryUrl -match '^(ldaps:).+((:389)|(:636)|(:3268)|(:3269))$')) {
Write-Error "PrimaryUrl $PrimaryUrl is invalid. Ensure the port number is 389, 636, 3268, or 3269 and that the url begins with ldaps: and not ldap:" -ErrorAction Stop
@ -408,19 +451,53 @@ function New-LDAPSIdentitySource {
else {
Write-Host "No existing external identity sources found."
}
$Password = $Credential.GetNetworkCredential().Password
$DestinationFileArray = Get-Certificates -SSLCertificatesSasUrl $SSLCertificatesSasUrl -ErrorAction Stop
$DestinationFileArray = @()
if ($PSBoundParameters.ContainsKey('SSLCertificatesSasUrl')) {
$DestinationFileArray = Get-Certificates -SSLCertificatesSasUrl $SSLCertificatesSasUrl -ErrorAction Stop
} else {
$exportFolder = "$home/"
$remoteComputers = ,$PrimaryUrl
if ($PSBoundParameters.ContainsKey('SecondaryUrl')) {
$remoteComputers += $SecondaryUrl
}
foreach ($computerUrl in $remoteComputers) {
try {
if (![uri]::IsWellFormedUriString($computerUrl, 'Absolute')) { throw }
$ParsedUrl = [System.Uri]$computerUrl
}
catch {
throw "Incorrect Url format entered from: $computerUrl"
}
if ($ParsedUrl.Host -match "^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$" -and [bool]($ParsedUrl.Host -as [ipaddress])) {
throw "Incorrect Url format. $computerUrl is an IP address. Consider using hostname exactly as specified on the issued certificate."
}
$SSHOutput = Get-CertificateFromDomainController -ParsedUrl $ParsedUrl -computerUrl $computerUrl
if ($SSHOutput -notmatch '(?s)(?<cert>-----BEGIN CERTIFICATE-----.*?-----END CERTIFICATE-----)') {
throw "The certificate from $computerUrl has an incorrect format"
} else {
$certs = select-string -inputobject $SSHOutput -pattern "(?s)(?<cert>-----BEGIN CERTIFICATE-----.*?-----END CERTIFICATE-----)" -allmatches
$cert = $certs.matches[0]
$exportPath = $exportFolder+($ParsedUrl.Host.split(".")[0])+".cer"
$cert.Value | Out-File $exportPath -Encoding ascii
$DestinationFileArray += $exportPath
}
}
}
[System.Array]$Certificates =
foreach ($CertFile in $DestinationFileArray) {
foreach($CertFile in $DestinationFileArray) {
try {
[System.Security.Cryptography.X509Certificates.X509Certificate2]::CreateFromCertFile($certfile)
}
catch {
} catch {
Write-Error "Failure to convert file $certfile to a certificate $($PSItem.Exception.Message)"
throw "File to certificate conversion failed. See error message for more details"
}
}
Write-Host "Adding the LDAPS Identity Source..."
Add-LDAPIdentitySource `
-Name $Name `
@ -688,9 +765,9 @@ function Add-GroupToCloudAdmins {
Write-Error "Internal Error fetching CloudAdmins group. Contact support" -ErrorAction Stop
}
$GroupToAddTuple = [System.Tuple]::Create($($GroupToAdd.Name), $($GroupToAdd.Domain))
$GroupToAddTuple = [System.Tuple]::Create("$($GroupToAdd.Name)","$($GroupToAdd.Domain)")
$CloudAdminMembers = @()
foreach ($a in $(Get-SsoGroup -Group $CloudAdmins)) { $tuple = [System.Tuple]::Create($($a.Name), $($a.Domain)); $CloudAdminMembers += $tuple }
foreach ($a in $(Get-SsoGroup -Group $CloudAdmins)) { $tuple = [System.Tuple]::Create("$($a.Name)","$($a.Domain)"); $CloudAdminMembers += $tuple }
if ($GroupToAddTuple -in $CloudAdminMembers) {
Write-Host "Group $($GroupToAddTuple.Item1)@$($($GroupToAddTuple.Item2)) has already been added to CloudAdmins."
return