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 credential into a encrypted file .DESCRIPTION Sometime you need to save credential 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 Credential Full credential of the user .EXAMPLE Save-Credential -Username myuser .EXAMPLE $cred = Get-Credential Save-Credential -Credential $cred .EXAMPLE $cred = Get-Credential $cred | Save-Credential .NOTES General notes #> function Save-Credential { [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 credential 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 = 'CREDENTIAL')][System.Management.Automation.PSCredential]$Credential, [Parameter(Mandatory = $false)][string]$Path = $Script:PROFILEDIR ) Begin { Write-EnterFunction } Process { switch ($PSCmdlet.ParameterSetName) { 'USERNAME' { # if ($Username -match "(?<domain>.*)\\(?<username>.*)") { # $DOMAIN = $Matches.domain # $Username = $Matches.username # } if ($USERNAME.Contains("\")) { $Domain, $Username = $USERNAME.Split("\") } if ($Domain) { $Credential = new-object -typename System.Management.Automation.PSCredential -argumentlist "$Domain\$Username",$Password } else { $Credential = new-object -typename System.Management.Automation.PSCredential -argumentlist "$Username",$Password } } 'CREDENTIAL' { } } $Filename = "$Path/" if ($Domain) { $Filename += "$Domain_" } if ($TargetHost) { $Filename += "$TargetHost_" } $Filename += "$UserName.pwd" $Credential.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 credential from a encrypted file .DESCRIPTION This function can load credential previously saved by Save-Credential .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-Credential -Username myuser .EXAMPLE Load-Credential -Filename c:\path\to\user.pwd .NOTES General notes #> function Load-Credential { [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 credential 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) { $Credential = new-object -typename System.Management.Automation.PSCredential -argumentlist "$Domain\$Username",$Password } else { $Credential = new-object -typename System.Management.Automation.PSCredential -argumentlist "$Username",$Password } return $Credential } End { Write-LeaveFunction } } <# .SYNOPSIS Display credential in plain text .DESCRIPTION Sometime you need to see credential 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 Credential Full credential of a user .PARAMETER Filename Path to the credential file if not in standard path. .EXAMPLE Show-Credential -Username myuser .EXAMPLE $cred = Get-Credential Show-Credential -Credential $cred .NOTES General notes #> function Show-Credential { [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 = 'CREDENTIAL')][PSCredential]$Credential, [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" $Credential = Load-Credential -Domain $Domain -TargetHost $TargetHost -Username $Username -Path $Path } 'FILENAME' { $Credential = Load-Credential -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 # } } 'CREDENTIAL' { } } $Username = $Credential.UserName $Password = $Credential.Password $Ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($Password) $result = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($Ptr) [System.Runtime.InteropServices.Marshal]::ZeroFreeCoTaskMemUnicode($Ptr) $output = "" | Select-Object TargetHost, Domain, Username, Password $output.TargetHost = $TargetHost $output.Domain = $Domain $output.Username = $Username $output.Password = $result return $output } End { Write-LeaveFunction } } |