PSCredential.psm1

[CmdletBinding()]
param()
$baseName = [System.IO.Path]::GetFileNameWithoutExtension($PSCommandPath)
$script:PSModuleInfo = Test-ModuleManifest -Path "$PSScriptRoot\$baseName.psd1"
$script:PSModuleInfo | Format-List | Out-String -Stream | ForEach-Object { Write-Debug $_ }
$scriptName = $script:PSModuleInfo.Name
Write-Debug "[$scriptName] - Importing module"
#region [functions] - [public]
Write-Debug "[$scriptName] - [functions] - [public] - Processing folder"
#region [functions] - [public] - [New-PSCredential]
Write-Debug "[$scriptName] - [functions] - [public] - [New-PSCredential] - Importing"
function New-PSCredential {
    <#
        .SYNOPSIS
        Creates a new PSCredential object.

        .DESCRIPTION
        This function generates a PSCredential object using a specified username and password.
        The password can be provided as a secure string or a plain text string, which will be
        converted into a SecureString automatically.

        .EXAMPLE
        New-PSCredential

        Prompts the user for a username and password and returns a PSCredential object.

        .EXAMPLE
        New-PSCredential -Username 'admin' -Password (ConvertTo-SecureString 'P@ssw0rd!' -AsPlainText -Force)

        Creates a PSCredential object for the specified username and password.

        .LINK
        https://psmodule.io/PSCredential/Functions/New-PSCredential/
    #>


    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSUseShouldProcessForStateChangingFunctions', '',
        Justification = 'Does not change state, just holding a credential in memory'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSAvoidUsingUsernameAndPasswordParams', '',
        Justification = 'The function is for creating a PSCredential'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSAvoidUsingConvertToSecureStringWithPlainText', '',
        Justification = 'The function is for creating a PSCredential'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSAvoidUsingPlainTextForPassword', '',
        Justification = 'The function is for creating a PSCredential'
    )]
    [OutputType([System.Management.Automation.PSCredential])]
    [CmdletBinding()]
    param(
        # Specifies the username for the PSCredential object.
        [Parameter()]
        [string] $Username = (Read-Host -Prompt 'Enter a username'),

        # Specifies the password for the PSCredential object. Accepts a secure string or plain text.
        [Parameter()]
        [object] $Password = (Read-Host -Prompt 'Enter Password' -AsSecureString)
    )

    if ($Password -is [String]) {
        $Password = ConvertTo-SecureString -String $Password -AsPlainText -Force
    }

    New-Object -TypeName System.Management.Automation.PSCredential($Username, $Password)
}
Write-Debug "[$scriptName] - [functions] - [public] - [New-PSCredential] - Done"
#endregion [functions] - [public] - [New-PSCredential]
#region [functions] - [public] - [Restore-PSCredential]
Write-Debug "[$scriptName] - [functions] - [public] - [Restore-PSCredential] - Importing"
function Restore-PSCredential {
    <#
        .SYNOPSIS
        Restores a PSCredential object from a file.

        .DESCRIPTION
        The Restore-PSCredential function retrieves a PSCredential object that was previously saved using `Save-PSCredential`.
        It reads the file from the specified path and ensures the content is a valid PSCredential object before returning it.

        .EXAMPLE
        Restore-PSCredential -Path 'C:\secure\mycredential.cred'

        Restores the PSCredential object from the file located at `C:\secure\mycredential.cred`.

        .EXAMPLE
        'C:\secure\mycredential.cred' | Restore-PSCredential

        Uses pipeline input to restore the PSCredential object from the specified file path.

        .LINK
        https://psmodule.io/PSCredential/Functions/Restore-PSCredential/
    #>


    [OutputType([System.Management.Automation.PSCredential])]
    [Alias('Import-PSCredential')]
    [CmdletBinding()]
    param(
        # Specifies the path to the credential file to restore.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [System.IO.FileInfo] $Path
    )

    process {
        Write-Verbose "Restoring PSCredential from [$Path]"
        if (Test-Path $Path) {
            $credential = Import-Clixml -Path $Path
        } else {
            throw "Unable to locate a credential file for [$Path]"
        }

        if ($credential -isnot [System.Management.Automation.PSCredential]) {
            throw "Unable to restore a PSCredential object from [$Path]"
        }

        $credential
    }
}
Write-Debug "[$scriptName] - [functions] - [public] - [Restore-PSCredential] - Done"
#endregion [functions] - [public] - [Restore-PSCredential]
#region [functions] - [public] - [Save-PSCredential]
Write-Debug "[$scriptName] - [functions] - [public] - [Save-PSCredential] - Importing"
function Save-PSCredential {
    <#
        .SYNOPSIS
        Saves a PSCredential object to a file.

        .DESCRIPTION
        This function takes a PSCredential object and exports it to a file.
        If the specified file path does not exist, it creates the necessary directory structure before saving the credential.

        .EXAMPLE
        $credential = Get-Credential
        Save-PSCredential -Credential $credential -Path 'C:\secure\credential.cred'

        Prompts for a username and password, then saves the credential securely to `C:\secure\credential.cred`.

        .EXAMPLE
        $password = ConvertTo-SecureString 'MyPassword' -AsPlainText -Force
        $credential = New-PSCredential -Username 'UserName' -Password $password
        Save-PSCredential -Credential $credential -Path 'C:\secure\mycreds.cred'

        Saves the predefined credential securely to `C:\secure\mycreds.cred`.

        .LINK
        https://psmodule.io/PSCredential/Functions/Save-PSCredential/
    #>


    [OutputType([void])]
    [CmdletBinding()]
    param(
        # The PSCredential object to be saved.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [System.Management.Automation.PSCredential] $Credential,

        # The file path to save the PSCredential to.
        [Parameter(Mandatory)]
        [string] $Path
    )

    process {
        Write-Verbose "Saving PSCredential to [$Path]"
        $pathExists = Test-Path $Path
        if (-not $pathExists) {
            # Create the folder structure to the file if they don't exist, including an empty file.
            $null = New-Item -ItemType File -Path $Path -ErrorAction Stop -Force
        }
        $Credential | Export-Clixml -Path $Path
    }
}
Write-Debug "[$scriptName] - [functions] - [public] - [Save-PSCredential] - Done"
#endregion [functions] - [public] - [Save-PSCredential]
Write-Debug "[$scriptName] - [functions] - [public] - Done"
#endregion [functions] - [public]

#region Member exporter
$exports = @{
    Alias    = '*'
    Cmdlet   = ''
    Function = @(
        'New-PSCredential'
        'Restore-PSCredential'
        'Save-PSCredential'
    )
}
Export-ModuleMember @exports
#endregion Member exporter