120 lines
4.5 KiB
PowerShell
120 lines
4.5 KiB
PowerShell
function Get-SSHConfigEntries {
|
|
<#
|
|
.SYNOPSIS
|
|
This function is used to get the specified user's SSH config entries as a hashtable for ease of parsing
|
|
|
|
.PARAMETER Username
|
|
[string] The user to get the ssh config for
|
|
|
|
.PARAMETER Path
|
|
[string] The path to the config file to read in
|
|
#>
|
|
[CmdletBinding(DefaultParameterSetName = 'Username')]
|
|
[OutputType([object[]])]
|
|
param (
|
|
[Parameter(ParameterSetName = 'Username')]
|
|
[string]$Username = (Get-CurrentUsername),
|
|
|
|
[Parameter(ParameterSetName = 'Path', Mandatory = $true)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string]$Path
|
|
)
|
|
|
|
$logLead = (Get-LogLeadName)
|
|
|
|
if ($PSCmdlet.ParameterSetName -eq 'Username') {
|
|
$magicPathRoot = '~\.ssh'
|
|
$magicPath = (Join-Path -Path $magicPathRoot -ChildPath 'config')
|
|
|
|
if (!(Test-Path -Path $magicPathRoot) -or !(Test-Path -Path $magicPath)) {
|
|
Write-Warning "$logLead : No SSH config file found for current user"
|
|
return $null
|
|
} else {
|
|
$Path = $magicPath
|
|
}
|
|
}
|
|
|
|
if (!(Test-Path -Path $Path)) {
|
|
Write-Warning "$logLead : No SSH config file found at [$Path]"
|
|
return $null
|
|
}
|
|
|
|
$lines = (Get-Content -Path $Path)
|
|
|
|
<#
|
|
Format of SSH client config file ssh_config
|
|
The ssh_config client configuration file has the following format. Both the global /etc/ssh/ssh_config and per-user ~/ssh/config have the same format.
|
|
|
|
Empty lines and lines starting with '#' are comments.
|
|
|
|
Each line begins with a keyword, followed by argument(s).
|
|
|
|
Configuration options may be separated by whitespace or optional whitespace and exactly one =.
|
|
|
|
Arguments may be enclosed in double quotes (") in order to specify arguments that contain spaces.
|
|
#>
|
|
|
|
$currentObject = @{ Comments = @(); }
|
|
$return = @()
|
|
foreach ($line in $lines) {
|
|
$rawLine = $line
|
|
$line = $line.Trim()
|
|
if ([string]::IsNullOrWhiteSpace($line)) {
|
|
if (($currentObject.Comments.Count -gt 0) -or ($null -ne $currentObject.Host)) {
|
|
# We have either an object or a random block of comments.
|
|
# Assume it's a "previous record" and put it on the $return, then gen up a new object and keep going
|
|
$return += $currentObject
|
|
$currentObject = @{ Comments = @(); }
|
|
}
|
|
continue
|
|
}
|
|
|
|
$value = ''
|
|
|
|
$commentStartingIndex = $line.IndexOf('#')
|
|
$comment = ''
|
|
if ($commentStartingIndex -gt -1) {
|
|
$comment = $line.Substring($commentStartingIndex + 1).Trim()
|
|
$line = $line.Substring(0, $commentStartingIndex).Trim()
|
|
}
|
|
|
|
if ([string]::IsNullOrWhiteSpace($line)) {
|
|
$currentObject.Comments += $comment
|
|
|
|
continue
|
|
}
|
|
|
|
$quotedIdentifierStartingIndex = $line.IndexOf('"')
|
|
$quotedIdentifierEndingIndex = $line.LastIndexOf('"')
|
|
if (($quotedIdentifierStartingIndex -gt -1) -and ($quotedIdentifierEndingIndex -gt $quotedIdentifierStartingIndex)) {
|
|
# There is a value on the line that starts and ends with a quote mark, so we should escape that into a variable for now
|
|
$value = $line.Substring($quotedIdentifierStartingIndex + 1, $quotedIdentifierEndingIndex - $quotedIdentifierStartingIndex - 1)
|
|
$line = $line.Substring(0, $quotedIdentifierStartingIndex).Trim()
|
|
}
|
|
|
|
if ([string]::IsNullOrWhiteSpace($value)) {
|
|
$firstSpaceIndex = $line.Trim().IndexOf(' ')
|
|
if ($firstSpaceIndex -gt -1) {
|
|
$value = $line.Trim().Substring($firstSpaceIndex + 1)
|
|
$line = $line.Trim().Substring(0, $firstSpaceIndex)
|
|
}
|
|
}
|
|
|
|
if ([string]::IsNullOrWhiteSpace($line)) {
|
|
Write-Host "$logLead : Somehow we have ended up with an empty key name for [$rawLine] with a value [$value] and potential comment [$comment]"
|
|
} else {
|
|
Write-Verbose "$logLead : We have ended up with a key name for [$line] with a value [$value] and potential comment [$comment]"
|
|
$currentObject.$line = $value
|
|
if (![string]::IsNullOrWhiteSpace($comment)) {
|
|
$currentObject.$line | Add-Member -NotePropertyName 'Comment' -NotePropertyValue $comment
|
|
}
|
|
}
|
|
}
|
|
|
|
if (($currentObject.Comments.Count -gt 0) -or ($null -ne $currentObject.Host)) {
|
|
# We ended with something that hasn't been appended to the return value yet.
|
|
$return += $currentObject
|
|
}
|
|
|
|
return $return
|
|
} |