Write-Credential.ps1
#----------------------------------------------------[Function synopsis]----------------------------------------------------- Function Write-Credential { <# .SYNOPSIS Saves credentials to disk system as secure string for re-use. Part of CredentialsManager module. .DESCRIPTION Saves credentials to disk system as secure string for re-use. User will be prompted to enter user name and password which will be saved. Username will be re-used exactly as specified, i.e. depending on target use you may want to specify domain\user or user@domain.com Only currently logged in user will be able to decrypt and use saved credentials. Other users even if they will have access to saved files, will not be able to decrypt it. .EXAMPLE Write-Credential Dev User is prompted for credentials (user name and password) which are saved to default location. .EXAMPLE Write-Credential BAcc -Path P:\cred User is prompted for credentials for B account, which are afterwards saved to P: disk. .EXAMPLE Write-Credential Azure -Credential $AzureAdmin Saving credentials from variable $AzureAdmin to file Azure.cred on the disk. .PARAMETER Environment Name of environment for which credentials are saved. It will be used in Get commands, and also as part of file names. If you want to save credentials for multiple users in same environment, use different Environment names, like EnvAdmin and EnvUser. You may specify multiple environments. .PARAMETER Path Optional parameter which defines where credentials will be saved. If not specified, %APPDATA%\CredentialsManager is used. If specified, default value will be updated and re-used on next calls within the same PowerShell session. .PARAMETER PassThru Switch parameter which defines if credentials created by this cmdlet will be passed through the pipeline. Default is false. .PARAMETER Credential By default user will be prompted to enter credentials interactivly. If you already have credentials in variable, then specify this parameter. .OUTPUTS Cmdlet is not returning any value by default. If switch PassThru is specified, it returns Credentials object as Get-Credential, System.Management.Automation.PSCredential. .LINK https://www.powershellgallery.com/packages/CredentialsManager .NOTES NAME: Write-Credential AUTHOR: Igor Iric, IricIgor@Gmail.com CREATEDATE: October, 2015 #> #-------------------------------------------------[Parameters definitions]-------------------------------------------------- [cmdletbinding()] Param( [parameter(Mandatory=$true,ValueFromPipeline=$true)][string[]]$Environment, [parameter(Mandatory=$false,ValueFromPipeline=$false)][string]$Path=$Script:CredentialsPath, [parameter(Mandatory=$false,ValueFromPipeline=$false)][System.Management.Automation.PSCredential]$Credential, [switch]$PassThru ) #end param #-------------------------------------------------[Constant declarations]--------------------------------------------------- #-------------------------------------------------[Function initialization]-------------------------------------------------- BEGIN { # function begin phase # handling Path parameter, if folder not exisiting create it and set hidden if (!$Path) { # if path is not specified, it means also global needs to be initialized $Script:CredentialsPath = Join-Path -Path $env:APPDATA -ChildPath 'CredentialsManager' Write-Verbose -Message "Setting default path to: $Script:CredentialsPath" $Path = $Script:CredentialsPath Write-Verbose -Message "Using default path $Path" } if (!(Test-Path -Path $Path)) { # folder not existing -> create it try { Write-Verbose -Message "Trying to create exports folder $Path" $Folder = New-Item -Path $Path -ErrorAction Stop -ItemType Directory $PathFolderCreated = $true } catch { # folder creation error $PathFolderCreated = $false throw $Error[0] } if ($PathFolderCreated) { Write-Verbose -Message 'Exports folder created.' # set folder to be hidden, if creating it $Folder.Attributes = $Folder.Attributes -bor [io.fileattributes]::Hidden if ($Path -ne $Script:CredentialsPath) { Write-Verbose -Message "Updating default path to $Path." $Script:CredentialsPath = $Path } } } # end of folder creation part } #---------------------------------------------------[Function processing]---------------------------------------------------- PROCESS { foreach ($E in @($Environment)) { # function process phase, executed once for each element in main Parameter # main code Write-Verbose -Message '----------------------' Write-Verbose -Message "Processing environment $E..." $VerboseMessage = "Environment $E processed with issues." # it will be updated at the end, if successfull # prompt user for credentials if (!($Credential)) { $Cred = Get-Credential -Message "Enter your credentials for $E..." } else { $Cred = $Credential } if (!$Cred) { Write-Error -Message 'Credentials not obtained. Ensure you are not clicking on Cancel.' } elseif ($Cred.Password.Length -eq 0) { Write-Error -Message 'Blank passwords not supported.' } else { # if credentials are obtained, proceed Write-Verbose -Message "Credentials for $E obtained." #$FileNameUser = Join-Path -Path $Path -ChildPath ($E + '_UserName.cred') #$FileNamePass = Join-Path -Path $Path -ChildPath ($E + '_Password.cred') $FileName = Join-Path -Path $Path -ChildPath ($E + '.creds') # if file is existing, delete it try { Write-Verbose -Message "Trying to delete existing file(s) for $E..." #if (Test-Path -Path $FileNameUser) {Remove-Item -Path $FileNameUser -ErrorAction Stop} #if (Test-Path -Path $FileNamePass) {Remove-Item -Path $FileNamePass -ErrorAction Stop} if (Test-Path -Path $FileName) {Remove-Item -Path $FileName -ErrorAction Stop} Write-Verbose -Message 'File deleted.' } catch { Write-Error -Message ('Credential file can not be updated. '+($Error[0].Exception)) } # if file is not existing, export values #if ((!(Test-Path -Path $FileNameUser)) -and (!(Test-Path -Path $FileNamePass))) { if (!(Test-Path -Path $FileName)) { # create encrypted values $EncUser = ConvertTo-SecureString -String ($Cred.UserName) -AsPlainText -Force | ConvertFrom-SecureString $EncPass = ConvertFrom-SecureString -SecureString ($Cred.Password) # save them try { #Write-Verbose -Message "Attempting to save credentials to $Path..." Write-Verbose -Message "Attempting to save credentials to $FileName..." #$EncUser | Out-File $FileNameUser #$EncPass | Out-File $FileNamePass $EncUser | Out-File $FileName $EncPass | Out-File $FileName -Append $VerboseMessage = "Environment $E processed successfully." Write-Verbose -Message 'Credentials saved.' } catch { Write-Error -Message ('Credential files can not be updated. '+($Error[0].Exception)) } } } # return values if ($PassThru) { Write-Verbose -Message "Returning credentials for $E to output." Return $Cred } Write-Verbose -Message $VerboseMessage } # end of foreach } # end of function #-----------------------------------------------------[Function closing]----------------------------------------------------- END { # function closing phase Write-Verbose -Message 'Write-Credential finishing.' } } # end of function code #----------------------------------------------------[End of function]------------------------------------------------------ #---------------------------------------------------[Comments section]------------------------------------------------------ |