powershellactive-directoryuser-profileterminal-services

How do I get the "Terminal Services Profile Path"/CtxWFProfilePath from PowerShell?


I am trying to get the profile path from the Remote Desktop Services Profile tab in AD.
I picked a few users to test with and each user has a path in that tab. (picture below)

Each time I try and get this field through PowerShell I am disappointed to get nothing.

Does anyone know what could be preventing me from getting the info I so desire?

Thank you

With Quest:

Get-QADuser $user | select TsProfilePath

This returns an empty string

With ADSI:

$user = "JBiggs"
$ADUser = Get-qADUser $user | select -ExpandProperty DN
$ADUser = [ADSI]”LDAP://$ADUser”
$ADUser.psbase.InvokeGet(“terminalservicesprofilepath”)

This errors out

Exception calling "InvokeGet" with "1" argument(s): "Unknown name. (Exception from HRESULT: 0x80020006 (DISP_E_UNKNOWNNAME))"
At line:4 char:25
+ $ADUser.psbase.InvokeGet <<<< (“terminalservicesprofilepath”)
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

Picture with the field

Found what I need but cannot decode

As it turns out the old way of storing this information is through the UserParameters value. It is stored as a base64 blob. The old way remains in use as you upgrade through newer versions of windows server, so mine has been around for a long time. When this happens the new fields remain blank which is what I am seeing with some of my examples above.

$id = "JXD122"
$User = New-Object DirectoryServices.DirectoryEntry(Get-qADUser $id | select -ExpandProperty Path)
$w.userParameters

So I am able to see sort of what I need in this. Within it is the text CtxWFProfilePath followed by what appear to be Chinese symbols. So now my last step is to decode what I am seeing. Anyone know how?


Solution

  • As it turns out Legacy DCs that have been upgraded keep storing this information in the UserParameters object. And this object is stupidly encoded for some reason.

    It took me some time but I was able to decode it using the following website as reference: http://daduke.org/linux/userparameters.html

    Here is my quick and dirty PowerShell function to return the TS Profile Path. Works every time for me.

    Note: Requires Quest. This script uses the get-qADUser command. For this you need to install the Quest ActiveDirectory cmdlets.

    function get-TSPP($id) {
        $enc = [system.Text.Encoding]::UTF8
        $User = New-Object DirectoryServices.DirectoryEntry(Get-qADUser $id | select -ExpandProperty Path)
        $coded = $user.userParameters.tostring().split("")[-1].replace("〰","").replace("CtxWFProfilePath","").ToCharArray()
        $result = @()
        foreach ($c in $coded) {
            $bytes = $enc.GetBytes($c)
            $d = @()
            foreach ($byte in $bytes) {
                $d += [Convert]::ToString($byte, 2) 
            }
            $d = -join $d
            $control_Y = -join $d[4..9]
            $yyyy = -join $d[10..13]
            $control_X = -join $d[14..19]
            $xxxx = -join $d[20..23]
    
            if ($control_X -eq "011010") {
                $xxxx = [Convert]::ToString([Convert]::ToInt32($xxxx,2) + 9,2)
            }
            if ($control_Y -eq "011010") {
                $yyyy = [Convert]::ToString([Convert]::ToInt32($yyyy,2) + 9,2)
            }
    
            $binary = @($xxxx, $yyyy)
    
            $result += [char][Convert]::ToInt32((-join $binary), 2) 
        }
    
        return -join $result
    }