CPolydorou.PuTTY.psm1
#region Download-Putty function Download-Putty { #region Parameters [cmdletBinding()] Param ( [Parameter()] $Path ) #endregion #region Destination Path # Set the path to download the file to if($Path) { if( (Test-Path -Path $Path) -ne $true) { Write-Error "Could not find directory $Path" return } else { $filePath = $Path + '\' + 'putty.exe' } } else { $filePath = (Get-Location).Path + '\' + 'putty.exe' } #endregion #region Download Write-Verbose "Downloading PuTTY.exe." try { Invoke-WebRequest -Uri 'http://the.earth.li/~sgtatham/putty/latest/x86/putty.exe' -OutFile $filePath -ErrorAction Stop Write-Verbose "PuTTY.exe has been successfully downloaded to $filePath" } catch { Write-Error "Failed to download the file. $($_.Exception.Message)" } #endregion } #endregion #region Download-PuttyGen function Download-PuttyGen { #region Parameters [cmdletBinding()] Param ( [Parameter()] $Path ) #endregion #region Destination Path # Set the path to download the file to if($Path) { if( (Test-Path -Path $Path) -ne $true) { Write-Error "Could not find directory $Path" return } else { $filePath = $Path + '\' + 'puttygen.exe' } } else { $filePath = (Get-Location).Path + '\' + 'puttygen.exe' } #endregion #region Download Write-Verbose "Downloading PuTTYGen.exe." try { Invoke-WebRequest -Uri 'http://the.earth.li/~sgtatham/putty/latest/x86/puttygen.exe' -OutFile $filePath -ErrorAction Stop Write-Verbose "PuTTYGen.exe has been successfully downloaded to $filePath" } catch { Write-Error "Failed to download the file. $($_.Exception.Message)" } #endregion } #endregion #region Get-PuttySesssion Function Get-PuttySession { #region Parameters [cmdletBinding()] Param ( [Parameter()] [string] $Name ) #endregion # Set the registry base path $registryPath = "HKCU:\SOFTWARE\SimonTatham\PuTTY\Sessions\" # Get the session keys Write-Verbose "Getting sessions from registry." try { $sessions = Get-ChildItem $registryPath -ErrorAction Stop } catch { Write-Error "Failed to read the registry. $($_.Exception.Message)" } # Process each session Write-Verbose "Getting session details." foreach( $s in $sessions) { # Get the properties of the sessions $hostname = Get-ItemProperty -Path ("HKCU:\Software\SimonTatham\PuTTY\Sessions\" + $s.PSChildName) -Name Hostname $obj = New-Object PSObject $obj | Add-Member -MemberType NoteProperty -Name "Name" -Value $s.PSChildName $obj | Add-Member -MemberType NoteProperty -Name "Hostname" -Value $hostname.hostname # Check if a specific session was requested if($Name) { if($Name -eq $obj.Name) { $obj } } else { $obj } } } #endregion #region Export-PuttySession Function Export-PuttySession { #region Parameters [CmdletBinding()] Param ( [Parameter(Mandatory = $false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] [string] $Name, [Parameter(Mandatory = $false)] [string] $Path = (Get-Location).Path ) #endregion #region Begin Begin { # Test if path exists $sessionsDirectory = $Path + '\' if((Test-Path($sessionsDirectory)) -eq $false) { Write-Error "Target directory does not exist." return } # Get sessions from registry $registryPath = "HKCU:\SOFTWARE\SimonTatham\PuTTY\Sessions\" try { $sessions = Get-ChildItem $registryPath -ErrorAction Stop } catch { Throw "Failed to read the registry. $($_.Exception.Message)" } } #endregion #region Process Process { # Export sessions foreach( $s in $sessions) { # If a specific session is to be exported, skip the others if($Name) { if($s.PSChildName -ne $Name) { continue } } # Create a directory for the session Write-Verbose "Creating a directory for the session files." if( (Test-Path -Path ($sessionsDirectory + $s.PSChildName)) -ne $true) { try { New-Item -ItemType Directory -Path $sessionsDirectory -Name $s.PSChildName -ErrorAction Stop | Out-Null } catch { Write-Error "Failed to create directory to save the session. $($_.Exception.Message)" return } } # Export the session options Write-Verbose "Exporting the session." # Create the process start information $pinfo = New-Object System.Diagnostics.ProcessStartInfo $pinfo.FileName = $env:SystemRoot + "\System32\reg.exe" $pinfo.CreateNoWindow = $true $pinfo.UseShellExecute = $false $pinfo.WorkingDirectory = (Get-Location).Path $pinfo.Arguments = @("export", $s.Name, ($sessionsDirectory + $s.PSChildName + '\' + $s.PSChildName + ".reg")) # Create the process $p = New-Object System.Diagnostics.Process $p.StartInfo = $pinfo $p.Start() | Out-Null $p.WaitForExit() # Copy the private key $key = Get-ItemProperty -Path ("HKCU:\Software\SimonTatham\PuTTY\Sessions\" + $s.PSChildName) -Name PublicKeyFile if( $key.PublicKeyFile.Length -gt 0 ) { Write-Verbose "Exporting the private key." try { # Get the name of the file $keyFileName = $key.PublicKeyFile.Substring($key.PublicKeyFile.LastIndexOf('\') + 1) # Copy the file Copy-Item -Path $key.PublicKeyFile -Destination ((resolve-path($sessionsDirectory)).Path + '\' + $s.PSChildName + '\' + $keyFileName) -ErrorAction Stop } catch { Write-Error "Failed to copy the private key file. $($_.Exception.Message)" continue } } } } #endregion #region End End{} #endregion } #endregion #region Import-PuttySession Function Import-PuttySession { #region Parameters [CmdletBinding()] Param ( [Parameter(Mandatory = $true)] [string] $Path, [Parameter(Mandatory = $false)] [string] $KeyFileDirectory ) #endregion #region Begin Begin {} #endregion #region Process Process { # Test if path exists $sessionsDirectory = $Path if((Test-Path($sessionsDirectory)) -eq $false) { Write-Error "Source directory does not exist." return } # Find the reg file $sessionFile = @(Get-ChildItem -Path $sessionsDirectory | Where-Object {$_.Name.ToLower().EndsWith(".reg")}) if($sessionFile.Count -ne 1) { Write-Error "No/Multiple session files found." return } # Find the key file $keyFile = @(Get-ChildItem -Path $sessionsDirectory | Where-Object {$_.Name.ToLower().EndsWith(".ppk")}) # Set the session name $sessionName = $sessionFile.BaseName # Create the registry keys CreateRegistryKeys -SessionName $sessionName # Import the session Write-Verbose "Importing session $sessionName from file $($sessionFile.Fullname)." # Create the process start information $pinfo = New-Object System.Diagnostics.ProcessStartInfo $pinfo.FileName = $env:SystemRoot + "\System32\reg.exe" $pinfo.CreateNoWindow = $true $pinfo.UseShellExecute = $false $pinfo.WorkingDirectory = (Get-Location).Path $pinfo.Arguments = @("import", ('"' + $sessionFile.FullName +'"')) $pinfo.RedirectStandardError = $true $pinfo.RedirectStandardOutput = $true # Create the process $p = New-Object System.Diagnostics.Process $p.StartInfo = $pinfo $p.Start() | Out-Null $p.WaitForExit() # Write the output from the import $stdOut = $p.StandardOutput.ReadToEnd() if( -not ([System.String]::IsNullOrEmpty($stdOut))) { Write-Verbose $stdOut } $stdErr = $p.StandardError.ReadToEnd() if($p.ExitCode -ne 0) { Write-Error $stdErr return } # Copy the key file $key = Get-ItemProperty -Path ("HKCU:\Software\SimonTatham\PuTTY\Sessions\" + $sessionName) -Name PublicKeyFile -ErrorAction Stop if( $key.PublicKeyFile.Length -gt 0 ) { # Check if a directory has been provided for the key file if($KeyFileDirectory) { if( (Test-Path -Path $KeyFileDirectory) -ne $true) { Write-Error "Failed to access the directory for the key file." } else { $targetKeyFileDirectory = $KeyFileDirectory } } else { Write-Verbose "A directory to store the session key has not been provided, using profile directory." # Check if a directory exists for the key files if( (Test-Path -Path ($home+ '\PuTTYSessionKeys')) -ne $true) { try { New-Item -ItemType Directory -Path $home -Name "PuTTYSessionKeys" -Force -ErrorAction Stop | Out-Null $targetKeyFileDirectory = $home +'\' + "PuTTYSessionKeys\" } catch { Write-Error "Failed to create directory to save the key file." return } } else { $targetKeyFileDirectory = $home + "\PuTTYSessionKeys" } } # Create a subdirectory for the session try { Write-Verbose "Creating a directory for the key." New-Item -ItemType Directory -Path $targetKeyFileDirectory -Name $sessionName -Force -ErrorAction Stop | Out-Null $subDirectory = $targetKeyFileDirectory + '\' + $sessionName } catch { Write-Error "Failed to create a directory for the session key. $($_.Exception.Message)" return } # Copy the key file try { Write-Verbose "Copying key file." Copy-Item -Path $keyFile.FullName -Destination $subDirectory -Force -ErrorAction Stop } catch { Write-Error "Failed to copy key file to $($key.PublicKeyFile). $_.Exception.Message" return } # Update the session with the new key try { Write-Verbose "Updating session with new key file path." Set-ItemProperty -Path ("HKCU:\Software\SimonTatham\PuTTY\Sessions\" + $sessionName) -Name PublicKeyFile -Value ($subDirectory + '\' + $keyFile.Name) -ErrorAction Stop } catch { Write-Error "Failed to update the session with the new key file path." return } Write-Verbose "The sesssion was successfully imported." } #> } #endregion #region End End {} #endregion } #endregion #region Remove-PuttySession Function Remove-PuttySession { #region Parameters [cmdletBinding(SupportsShouldProcess=$true, ConfirmImpact = 'Medium')] Param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [String[]] $Name ) #endregion #region Begin Begin{} #endregion Process { # Process each session name foreach( $n in $Name) { # Check if a session exists Write-Verbose "Checking if a session named $n exists." if( Test-Path ("HKCU:\SOFTWARE\SimonTatham\PuTTY\Sessions\" + $n)) { if ($pscmdlet.ShouldProcess($n, "Remove-PuTTYSession")) { # Remove the session Write-Verbose "Removing session $n." try { Remove-Item -Path ("HKCU:\SOFTWARE\SimonTatham\PuTTY\Sessions\" + $n) -Recurse -Force -ErrorAction Stop Write-Verbose "The session $n has been removed." } catch { Write-Error "Failed to remove session $n. $($_.Exception.Message)" continue } } } else { Write-Warning "Could not find a session named $n." } } } #region End End {} #endregion } #endregion #region Helper Functions function CreateRegistryKeys { param ( [string]$SessionName ) if(-not (Test-Path -Path 'HKCU:\Software\SimonTatham')) { New-Item 'HKCU:\Software\SimonTatham' | Out-Null } if(-not (Test-Path -Path 'HKCU:\Software\SimonTatham\PuTTY')) { New-Item 'HKCU:\Software\SimonTatham\PuTTY' | Out-Null } if(-not (Test-Path -Path 'HKCU:\Software\SimonTatham\PuTTY\Sessions')) { New-Item 'HKCU:\Software\SimonTatham\PuTTY\Sessions' | Out-Null } $sessionPath = 'HKCU:\Software\SimonTatham\PuTTY\Sessions\' + $SessionName if(-not (Test-Path -Path $sessionPath)) { New-Item $sessionPath | Out-Null } } #endregion |