Completions/ssh.ps1

function Get-SshConfigHosts {
    $configfile = "$HOME/.ssh/config"
    if (Get-Item $configfile -ErrorAction SilentlyContinue) {
        $config = Get-Content $configfile
        $m = $config | Select-String "Host\s+(?<name>.*$)"
        $m.Matches | ForEach-Object { $_.Groups["name"].Value }
    }
}
function Get-SshKnownHosts {
    $knownhostsfile = "$HOME/.ssh/known_hosts"
    if (Get-Item $knownhostsfile -ErrorAction SilentlyContinue) {
        $knownhosts = Import-Csv $knownhostsfile -Delimiter " " -Header "H"
        foreach ($h in $knownhosts.H) {
            $h -split ','
        }
    }
}


$sshScriptBlock = {
    param($wordToComplete, $commandAst, $cursorPosition)

    $options = "-4", "-6", "-A", "-a", "-C", "-f", "-G", "-g", "-K", "-k", "-M", "-N", "-n", "-q", "-s", "-T", "-t", "-V", "-v", "-X", "-x", "-Y", "-y", "-B", "-b", "-c", "-D", "-E", "-e", "-F", "-I", "-i", "-J", "-L", "-l", "-m", "-O", "-o", "-p", "-Q", "-R", "-S", "-W", "-w"
    $prev = Get-PrevAst $commandAst $cursorPosition

    switch -CaseSensitive ($prev) {
        "-b" {
            Get-NetIPAddress | ForEach-Object { $_.IPAddress } | Where-Object { $_.IPAddress -like "$wordToComplete*" }
        }
        "-c" {
            ssh -Q cipher | Where-Object { $_ -like "$wordToComplete*" }
        }
        "-l" {
            Get-LocalUser | ForEach-Object { $_.Name } | Where-Object { $_ -like "$wordToComplete*" }
        }
        "-m" {
            ssh -Q mac | Where-Object { $_ -like "$wordToComplete*" }
        }
        "-O" {
            "check" , "forward" , "cancel", "exit" , "stop" | Where-Object { $_ -like "$wordToComplete*" }
        }
        "-w" {
            Get-NetIPInterface | ForEach-Object { $_.InterfaceAlias } | Where-Object { $_ -like "$wordToComplete*" }
        }
        Default {

        }
    }

    if ($wordToComplete -eq "-") {
        $options
    }
    else {
        $c = Get-SshConfigHosts
        $k = Get-SshKnownHosts

        $all = $c + $k

        $atIndex = $wordToComplete.IndexOf('@')
        if ($atIndex -ne -1) {
            $prefix = $wordToComplete.SubString(0, $atIndex + 1)
            $all = $all | ForEach-Object { "$prefix$_" }
        } 
        $all | Where-Object { $_ -like "$($wordToComplete)*" }
    }
}

$scpScriptBlock = {
    param($wordToComplete, $commandAst, $cursorPosition)
    if ($wordToComplete -eq "-") {
        
    }
    else {
        $c = Get-SshConfigHosts
        $k = Get-SshKnownHosts
        $c + $k | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { "${_}:" }
    }
}

Register-ArgumentCompleter -CommandName ssh -Native -ScriptBlock $sshScriptBlock
Register-ArgumentCompleter -CommandName scp -Native -ScriptBlock $scpScriptBlock