Scripts/Get-CMSSecret.ps1

function Get-CMSSecret
{
  <#
      .Synopsis
      Gets encrypted settings stored in the registry
      .Description
      Gets encrypted settings stored in the registry
      .Example
      Get-CMSSecret
 
      The above example gets all encrypted MCS secrets currently stored in the current user's registry.
      .Example
      PS C:\> Get-CMSSecret -Name my-AzureCredential
 
      Name Type EncryptedData
      ---- ---- -------------
      my-AzureCredential System.Management.Automation.PSCredential -----BEGIN CMS-----...
      .Example
      PS C:\> Get-CMSSecret -Name my-AzureCredential -Decrypted
 
      Name Type DecryptedData
      ---- ---- -------------
      my-AzureCredential System.Management.Automation.PSCredential System.Management.Automation.PSCredential
      .Example
      PS C:\> Get-CMSSecret -Name my-AzureCredential -ValueOnly
 
      UserName Password
      -------- --------
      ad\adUsername System.Security.SecureString
      .Link
      Add-CMSSecret
      .Link
      Remove-CMSSecret
  #>
    
  [Alias('cms')]
  [OutputType('PSObj.CMSData')]
  param(
    # The name of the secure setting
    [Parameter(Position=0,ValueFromPipelineByPropertyName=$true)]
    [String]
    $Name,
    
    # The type of the secure setting
    [Validateset('String','Object','PSCredential','Hashtable')]
    [Parameter(Position=1,ValueFromPipelineByPropertyName=$true)]
    [String]
    $Type,
    
    # If set, will decrypt the setting value
    [Parameter(ValueFromPipelineByPropertyName=$true)]
    [Switch]
    $Decrypted,
    
    # If set, will decrypt the setting value and return the data
    [Parameter(ValueFromPipelineByPropertyName=$true)]
    [switch]
    $ValueOnly,

    # Parameter help description
    [Parameter()]
    [string]
    $cmsFolderName = 'CMSData'            
  )
    
  begin 
  {

    # region Create Registry Location If It Doesn't Exist
    # If we dont do this when we run get-cmssecret the first time we get an error about missing reg key
    $registryPath = "HKCU:\Software\$cmsFolderName\"
    $fullRegistryPath = "$registryPath\$($psCmdlet.ParameterSetName)"
    if (-not (Test-Path $fullRegistryPath)) 
    {
      $null = New-Item $fullRegistryPath  -Force
    }         
        
                
    $getSecureSetting = {
      $Obj = $_
      $typeName = $_.pschildName
      foreach ($propName in ($obj.psobject.properties | Select-Object -ExpandProperty Name)) 
      {
        if ('PSPath', 'PSParentPath', 'PSChildName', 'PSProvider' -contains $propName) 
        {
          $obj.psobject.properties.Remove($propname)
        }
      }
      $Obj.psobject.properties | 
      ForEach-Object {
        $secureSetting = New-Object PSObject 
        $null = $secureSetting.pstypenames.insert(0,'PSObj.CMSData')
        $secureSetting | 
        Add-Member NoteProperty Name $_.Name -PassThru |
        Add-Member NoteProperty Type ($typename -as [Type]) -PassThru |
        Add-Member NoteProperty EncryptedData $_.Value -PassThru 

      }
    }
  }
   
  process 
  {
                   
    Get-ChildItem $registryPath | Get-ItemProperty | ForEach-Object $getSecureSetting |
    Where-Object {
      if ($psBoundParameters.Name -and $_.Name -ne $name){return}
      if ($psBoundParameters.Type -and $_.Type -ne ($Type -as [type])) { return } 
      $true
    } |
    ForEach-Object -Begin {
      $TempCredTable = @{}
    } -Process {
      if (-not ($decrypted -or $ValueOnly)) { return $_ }
                
      #region Decrypt and Convert Output
      $inputObject = $_
      if ([Hashtable], [string] -contains $_.Type) 
      {
                        
        $decryptedValue= $_.EncryptedData | Unprotect-CmsMessage 
                    
        if ($_.Type -eq [Hashtable]) 
        {

          $decryptedValue = . ([ScriptBlock]::Create($decryptedValue))
        }

      } 
      elseif($_.Type -eq [Object])
      {
        $decryptedValue = $_.EncryptedData | Unprotect-CmsMessage | ConvertFrom-Json
            
      }
      elseif($_.Type -eq [Management.Automation.PSCredential])
      {
        $decryptedCredObject = $_.EncryptedData | Unprotect-CmsMessage | ConvertFrom-Json
        $secpasswd = ConvertTo-SecureString $decryptedCredObject.Password -AsPlainText -Force
        $decryptedValue = New-Object Management.Automation.PSCredential ($decryptedCredObject.UserName,$secpasswd)
                            
      }            
      $null = $inputObject.psobject.properties.Remove('EncryptedData')
      $inputObject | Add-Member NoteProperty DecryptedData $decryptedValue -PassThru | ForEach-Object {
          if ($ValueOnly) 
          {
            $_.DecryptedData
          } 
          else 
          {
            $_
          }
                  
      }# Foreach inputobject

    }
                    
  }

}