PwSh.Fw.Security.psm1
$Script:PROFILEDIR = $env:USERPROFILE if ($IsLinux) { $Script:PROFILEDIR = $env:HOME } if ($IsMacOS) { $Script:PROFILEDIR = $env:HOME } if ($IsWindows) { $Script:PROFILEDIR = $env:USERPROFILE } <# .SYNOPSIS Save credentials into a encrypted file .DESCRIPTION Sometime you need to save credentials to be used by scripts running unattended (in cron jobs for example). This function lets you save an encrypted version in standard way to be easily re-used. .PARAMETER Domain Domain of the user. Optional .PARAMETER Username Username of the user. .PARAMETER Password Password of the user. .PARAMETER Credentials Full credentials of the user .EXAMPLE Save-Credentials -Username myuser .EXAMPLE $cred = Get-Credentials Save-Credentials -Credentials $cred .EXAMPLE $cred = Get-Credentials $cred | Save-Credentials .NOTES General notes #> function Save-Credentials { [CmdletBinding(DefaultParameterSetName = 'USERNAME')] [OutputType([Boolean])] [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseApprovedVerbs", "", Justification="'Save' is a more intuitive verb for this function because it just... well... save your credentials into a file.")] Param ( [Parameter(Mandatory = $false, ParameterSetName = 'USERNAME')][string]$Domain, [Parameter(Mandatory = $true, ParameterSetName = 'USERNAME')][string]$Username, [Parameter(Mandatory = $true, ParameterSetName = 'USERNAME')][SecureString]$Password, [Parameter(Mandatory = $false)][string]$TargetHost, [Parameter(Mandatory = $true, ParameterSetName = 'CREDENTIALS')][System.Management.Automation.PSCredential]$Credentials, [Parameter(Mandatory = $false)][string]$Path = $Script:PROFILEDIR ) Begin { Write-EnterFunction } Process { switch ($PSCmdlet.ParameterSetName) { 'USERNAME' { if ($Domain) { $Credentials = new-object -typename System.Management.Automation.PSCredential -argumentlist "$Domain\$Username",$Password } else { $Credentials = new-object -typename System.Management.Automation.PSCredential -argumentlist "$Username",$Password } } 'CREDENTIALS' { } } $Filename = "$Path/" if ($Domain) { $Filename += "$Domain_" } if ($TargetHost) { $Filename += "$TargetHost_" } $Filename += "$UserName.pwd" $Credentials.Password | ConvertFrom-SecureString | Out-File $Filename -encoding UTF8 -Force:$force if (Test-Path -PathType Leaf $Filename) { return $true } return $false } End { Write-LeaveFunction } } <# .SYNOPSIS Load credentials from a encrypted file .DESCRIPTION This function can load credentials previously saved by Save-Credentials .PARAMETER Domain Domain of the user. Optional .PARAMETER Username Username of the user. .PARAMETER Filename Path to the credential file if not in standard path. .EXAMPLE Load-Credentials -Username myuser .EXAMPLE Load-Credentials -Filename c:\path\to\user.pwd .NOTES General notes #> function Load-Credentials { [CmdletBinding(DefaultParameterSetName = 'USERNAME')] [OutputType([System.Management.Automation.PSCredential])] [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseApprovedVerbs", "", Justification="'Load' is a more intuitive verb for this function because it just... well... load your credentials from a file.")] Param ( [Parameter(Mandatory = $false, ParameterSetName = 'USERNAME')][string]$Domain, [Parameter(Mandatory = $true, ParameterSetName = 'USERNAME')][string]$Username, [Parameter(Mandatory = $false, ParameterSetName = 'USERNAME')][string]$TargetHost, [Parameter(Mandatory = $true, ParameterSetName = 'FILENAME')][string]$Filename, [Parameter(Mandatory = $false)][string]$Path = $Script:PROFILEDIR ) Begin { Write-EnterFunction } Process { switch ($PSCmdlet.ParameterSetName) { 'USERNAME' { if ($USERNAME.Contains("\")) { $Domain, $Username = $USERNAME.Split("\") } $Filename = "$Path/" if ($Domain) { $Filename += "$Domain_" } if ($TargetHost) { $Filename += "$TargetHost_" } $Filename += "$UserName.pwd" } 'FILENAME' { $Item = Get-Item $Filename -ErrorAction stop if ($Item.Basename -match "_.*_") { $Domain, $TargetHost, $Username = $Item.Basename -split '_' } elseif ($Item.Basename -match "_") { $Domain, $Username = $Item.Basename -split '_' } else { $Username = $Item.Basename } } } if (!($Username)) { return $null } if (!(Test-Path -path $Filename -PathType leaf)) { return $null } $Password = get-content $Filename | ConvertTo-SecureString if ($Domain) { $Credentials = new-object -typename System.Management.Automation.PSCredential -argumentlist "$Domain\$Username",$Password } else { $Credentials = new-object -typename System.Management.Automation.PSCredential -argumentlist "$Username",$Password } return $Credentials } End { Write-LeaveFunction } } <# .SYNOPSIS Display credentials in plain text .DESCRIPTION Sometime you need to see credentials in plain text to be sure it the good one. This function just display it .PARAMETER Domain Domain of the user. Optional .PARAMETER Username Username of a user. .PARAMETER Credentials Full credentials of a user .PARAMETER Filename Path to the credential file if not in standard path. .EXAMPLE Show-Credentials -Username myuser .EXAMPLE $cred = Get-Credentials Show-Credentials -Credentials $cred .NOTES General notes #> function Show-Credentials { [CmdletBinding(DefaultParameterSetName = 'USERNAME')] [OutputType([string])] Param ( [Parameter(Mandatory = $false, ParameterSetName = 'USERNAME')][string]$Domain, [Parameter(Mandatory = $true, ParameterSetName = 'USERNAME')][string]$Username, [Parameter(Mandatory = $false, ParameterSetName = 'USERNAME')][string]$TargetHost, [Parameter(Mandatory = $true, ParameterSetName = 'FILENAME')][string]$Filename, [Parameter(Mandatory = $true, ParameterSetName = 'CREDENTIALS')][PSCredential]$Credentials, [Parameter(Mandatory = $false)][string]$Path = $Script:PROFILEDIR ) Begin { Write-EnterFunction } Process { switch ($PSCmdlet.ParameterSetName) { 'USERNAME' { # $Filename = "$Path/" # if ($Domain) { $Filename = "$Domain_" } # if ($TargetHost) { $Filename = "$TargetHost_" } # $Filename += "$UserName.pwd" $Credentials = Load-Credentials -Domain $Domain -TargetHost $TargetHost -Username $Username -Path $Path } 'FILENAME' { $Credentials = Load-Credentials -Filename $Filename # $Item = Get-Item $Filename -ErrorAction stop # if ($Item.Basename -match "_.*_") { # $Domain, $TargetHost, $Username = $Item.Basename -split '_' # } elseif ($Item.Basename -match "_") { # $Domain, $Username = $Item.Basename -split '_' # } else { # $Username = $Item.Basename # } } 'CREDENTIALS' { } } $Username = $Credentials.UserName $Password = $Credentials.Password $Ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($Password) $result = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($Ptr) [System.Runtime.InteropServices.Marshal]::ZeroFreeCoTaskMemUnicode($Ptr) $Username, $result } End { Write-LeaveFunction } } |