function New-SftpPasswordHash { <# .SYNOPSIS Generates a password hash for use by SFTP functions. .PARAMETER Password [string] The password to hash. .EXAMPLE New-SftpPasswordHash -Password "Example" #> [CmdletBinding()] [OutputType([string])] param( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$Password ) $logLead = Get-LogLeadName $scriptBlock = { $modulePath = $args[0] $password = $args[1] Import-Module $modulePath return (New-PasswordHash $password) } # Primary directory for DLL based on installed module paths. $dllPath = [IO.Path]::Combine( "$PSScriptRoot", 'Resources', 'EncryptPassword.dll' ) if ( $false -eq ( Test-Path $dllPath ) ) { # Fallback directory for local testing of this function. $dllPath = [IO.Path]::Combine( "$PSScriptRoot", '..', 'Resources', 'EncryptPassword.dll' ) } if ( $false -eq ( Test-Path $dllPath ) ) { Write-Error "$logLead : Unable to find EncryptPassword.dll! Check your module path and retry." return $null } # Wrap the call in a PSSession to prevent the DLL from being loaded into our general context. # If we load the DLL in a new session, the DLL is unloaded when we destroy the session. # # Note that wrapping this functionality in an Invoke-Command does not yield a string; it only yields # an object that behaves like a string unless it is unwrapped by 'ConvertTo-Json'. # # To see this for yourself, run the following command: # ConvertTo-Json ( Invoke-Command -ComputerName localhost -ScriptBlock { return 'Test' }) # # To avoid this behavior, we cast the result to a string which appears to trim off those extra properties. # # To see this for yourself, run the following command: # ConvertTo-Json ([string](Invoke-Command -ComputerName localhost -ScriptBlock { return 'Test' })) $tempSession = New-PSSession [string]$result = Invoke-Command -Session $tempSession -ScriptBlock $scriptBlock -ArgumentList @( $dllPath, $Password ) Remove-PSSession -Session $tempSession return $result }