<# .SYNOPSIS PowerShell helper script to temporarily download a SSH Key stored in Bitwarden to make a SSH connection. .DESCRIPTION PowerShell helper script to temporarily download a SSH Key stored in Bitwarden to make a SSH connection. .PARAMETER SSHUser Username used for the SSH Connection. Defaults to the current username. .PARAMETER SSHDevice Device to connect via SSH .PARAMETER SSHCommand Extra parameters to be used in the SSH command to allow additional options such as alternate ports, port forwards, etc... See OpenSSH docs for possible options. .PARAMETER SearchString The name of the item/attachment in Bitwarden for the SSH key. .NOTES Version: 1.0 Author: Tyler Hale Creation Date: 2021.09.11 #> [CmdletBinding()] param ( [Parameter(Mandatory = $false)] [string] $SSHUser = [Environment]::UserName, [Parameter(Mandatory = $true)] [string] $SSHDevice, [Parameter(Mandatory = $false)] [string] $SSHCommand, [Parameter(Mandatory = $true)] [string] $SearchString ) begin { Write-Verbose "Generate a temp path for storing files" $TempPath = ([System.IO.Path]::GetTempPath()) + ([System.Guid]::NewGuid()) Write-Verbose "TempPath: $TempPath" # Setup default variables $TempArchive = ($TempPath + '.zip') $BwPath = ($TempPath + "\bw.exe") $Uri = "https://vault.bitwarden.com/download/?app=cli&platform=windows" # Showing progress for iwr causes severe performance issues (28 sec download vs 2.5 sec) $InitialProgress = $ProgressPreference $ProgressPreference = 'SilentlyContinue' } process { Write-Verbose "Downloading Bitwarden CLI" Invoke-WebRequest -Uri $Uri -OutFile $TempArchive Write-Verbose "Expanding archive to temp path" Expand-Archive -Path $TempArchive -DestinationPath $TempPath Try { Write-Verbose "Login to Bitwarden" $SessionKey = & $BwPath login --raw Write-Verbose "Check Bitwarden login status" $Status = & $BwPath status | ConvertFrom-Json if ($Status.status -ne "unauthenticated") { Write-Verbose "Find the specified SSH Key" $SearchResults = & $BwPath list items --search "$SearchString" --session $SessionKey | ConvertFrom-Json # Grab the file name of the attachment $FileName = $SearchResults.attachments.filename # Setup the keypath based on the file name $KeyPath = ($TempPath + "\$FileName.key") Write-Verbose "Created an encrypted placeholder for the key" (New-Item -Path "$KeyPath" -ItemType File).Encrypt() Write-Verbose "Setup ACL for the key" $NewAcl = Get-Acl -Path "$KeyPath" $NewAcl.SetAccessRuleProtection($True, $False) $fileSystemAccessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList (([System.Security.Principal.WindowsIdentity]::GetCurrent().Name), "FullControl", "Allow") $NewAcl.SetAccessRule($fileSystemAccessRule) Set-Acl -Path "$KeyPath" -AclObject $NewAcl Write-Verbose "Download the key" & $BwPath get attachment "$FileName" --output "$KeyPath" --itemid "$($SearchResults.id)" --quiet --session $SessionKey Write-Verbose "Connect to specified ssh location" if ($null -eq $SSHCommand) { Write-Verbose "SSH command: ssh.exe -i $KeyPath `"$SSHUser@$SSHDevice`"" Start-Process -FilePath ssh.exe -ArgumentList "-i $KeyPath `"$SSHUser@$SSHDevice`"" -NoNewWindow -Wait } else { Write-Verbose "SSH command: ssh.exe -i $KeyPath $SSHCommand `"$SSHUser@$SSHDevice`"" Start-Process -FilePath ssh.exe -ArgumentList "-i $KeyPath $SSHCommand `"$SSHUser@$SSHDevice`"" -NoNewWindow -Wait } } } Finally { Write-Verbose "Logging out of Bitwarden" Start-Process -FilePath $BwPath -NoNewWindow -Wait -ArgumentList "logout" Write-Verbose "Cleaning up files" if (Test-Path -Path $TempPath -ErrorAction SilentlyContinue) {Remove-Item -Path $TempPath -Recurse -Force} if (Test-Path -Path $TempArchive -ErrorAction SilentlyContinue) {Remove-Item -Path $TempArchive -Recurse -Force} Write-Verbose "Resetting ProgressPreference" $ProgressPreference = $InitialProgress Write-Verbose "Checking that private key was removed" if ($null -ne $KeyPath) { if (Test-Path -Path $KeyPath -ErrorAction SilentlyContinue) { Write-Host "Warning Private Key was not removed at: $KeyPath" -ForegroundColor Red pause } } } }