PowerSSH.psm1
$Commands = @{ 'PowerSsh' = @('ssh', 'ssh-agent', 'ssh-add', 'scp', 'sftp', 'rsync'); 'Bash' = @('ssh-keygen', 'ssh-copy-id', 'ssh-keyscan'); } Function Set-PowerSshModule { ForEach ($Type in $Commands.GetEnumerator()) { ForEach ($Command in $Type.Value) { Invoke-Expression -Command "Add-$($Type.Key)Command -Command $Command" } } } Function Invoke-PowerSshCommand { If ([System.Environment]::GetEnvironmentVariable('PowerSshChecked', 'Process')) { $AgentPid = [System.Environment]::GetEnvironmentVariable('PowerSshAgentPid', 'User') $AgentSocket = [System.Environment]::GetEnvironmentVariable('PowerSshAgentSocket', 'User') } Else { # Bash If (` (-Not ($ProcessBashId = [System.Environment]::GetEnvironmentVariable('PowerSshId', 'User')))` -Or (-Not ($ProcessBash = Get-Process -Id $ProcessBashId -ErrorAction Ignore))` -Or ($ProcessBash.StartTime.GetHashCode() -NotLike [System.Environment]::GetEnvironmentVariable('PowerSshHash', 'User'))` ) { $ProcessBash = Start-Process PowerShell -PassThru -ArgumentList '-WindowStyle Hidden -Command Bash' [System.Environment]::SetEnvironmentVariable('PowerSshId', $ProcessBash.Id, 'User') [System.Environment]::SetEnvironmentVariable('PowerSshHash', $ProcessBash.StartTime.GetHashCode(), 'User') } # Agent If (` (-Not ($AgentPid = [System.Environment]::GetEnvironmentVariable('PowerSshAgentPid', 'User')))` -Or (-Not ($AgentSocket = [System.Environment]::GetEnvironmentVariable('PowerSshAgentSocket', 'User')))` -Or (-Not (Bash -c "ps $AgentPid | grep ssh-agent")) ) { If ($MyInvocation.InvocationName -eq 'ssh-agent') { $AgentOutput = Bash -c "ssh-agent $Args" | Select-String -Pattern '(SSH_[A-Z_]+)=([^;]*)' -AllMatches } Else { $AgentOutput = Bash -c 'ssh-agent' | Select-String -Pattern '(SSH_[A-Z_]+)=([^;]*)' -AllMatches } $AgentPid = $AgentOutput.Matches[1].Groups[2].Value $AgentSocket = $AgentOutput.Matches[0].Groups[2].Value [System.Environment]::SetEnvironmentVariable('PowerSshAgentPid', $AgentPid, 'User') [System.Environment]::SetEnvironmentVariable('PowerSshAgentSocket', $AgentSocket, 'User') If (Bash -c "grep ~/.bashrc -e 'export SSH_AGENT_PID'") { Bash -c "sed -i 's/export SSH_AGENT_PID=.*/export SSH_AGENT_PID=$AgentPid/g' ~/.bashrc" Bash -c "sed -i 's/export SSH_AUTH_SOCK=.*/export SSH_AUTH_SOCK=$($AgentSocket -replace '/', '\/')/g' ~/.bashrc" } Else { Bash -c "printf 'export SSH_AGENT_PID=$AgentPid\nexport SSH_AUTH_SOCK=$AgentSocket' >> ~/.bashrc" } } # Key If ($MyInvocation.InvocationName -eq 'ssh-add') { Bash -c "export SSH_AGENT_PID=$AgentPid && export SSH_AUTH_SOCK=$AgentSocket && ssh-add $Args" } Else { If (-Not (Bash -c "export SSH_AGENT_PID=$AgentPid && export SSH_AUTH_SOCK=$AgentSocket && ssh-add -l 2> /dev/null | grep .ssh")) { Bash -c "export SSH_AGENT_PID=$AgentPid && export SSH_AUTH_SOCK=$AgentSocket && ssh-add" } } If (Bash -c "export SSH_AGENT_PID=$AgentPid && export SSH_AUTH_SOCK=$AgentSocket && ssh-add -l 2> /dev/null | grep .ssh") { [System.Environment]::SetEnvironmentVariable('PowerSshChecked', $true, 'Process') } } Bash -c "export SSH_AGENT_PID=$AgentPid && export SSH_AUTH_SOCK=$AgentSocket && $($MyInvocation.InvocationName) $Args" } Function Add-PowerSshCommand { Param( [Parameter( Mandatory = $True )] [String] $Command ) Set-Alias -Name $Command -Value Invoke-PowerSshCommand -Scope Global -ErrorAction Stop If (-Not (Test-Path -PathType Leaf -Path $Profile)) { New-Item -ItemType File -Path $Profile } $Expression = "Set-Alias -Name $Command -Value Invoke-PowerSshCommand" If (-Not (Get-Content -Path $Profile | Select-String -SimpleMatch $Expression)) { Add-Content -Path $Profile -Value $Expression } } Function Remove-PowerSshCommand { Param( [Parameter( Mandatory = $True )] [String] $Command ) Remove-Item Alias:$Command If (Test-Path -PathType Leaf -Path $Profile) { $Content = Get-Content -Path $Profile | Select-String -NotMatch -Pattern "Set-Alias -Name $Command -Value Invoke-PowerSshCommand" Set-Content -Path $Profile -Value $Content } } Function Get-PowerSshCommand { Param( [String] $Command ) If ($Command) { If (Get-Content -Path $Profile | Select-String -Pattern "Set-Alias -Name $Command -Value Invoke-PowerSshCommand") { Write-Output $Command } } Else { $MatchesCommands = Get-Content -Path $Profile | Select-String -Pattern "Set-Alias -Name (\w+) -Value Invoke-PowerSshCommand" ForEach ($Match in $MatchesCommands.Matches) { Write-Output $Match.Groups[1].Value } } } Function Set-SshKeys { Param( [String] $Comment = (Get-Culture).TextInfo.ToTitleCase($env:COMPUTERNAME.ToLower()) ) Bash -c "ssh-keygen -t rsa -b 4096 -C '$Comment'" } Function Get-SshPublicKey { Bash -c "cat ~/.ssh/id_rsa.pub" } |