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
Get-QADuser $user | select TsProfilePath
This returns an empty string
$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
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?
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
}
You can use this to make an export to c:\temp\tspath.csv
Get-ADUser -Filter {enabled -eq "true"} | ForEach-Object {
$User = [ADSI]"LDAP://$($_.DistinguishedName)"
$User.psbase.InvokeGet(“terminalservicesprofilepath”)
} |Out-File C:\temp\tspath.csv
In your ADSI example, OU=Users,OU=123,OU=place,OU=state,DC=dc1,DC=NET
is an OU, whose underlying ADSI object does not implement the IADsTSUserEx interface.
If you pass the DN of a user, it should work.
User contributions licensed under CC BY-SA 3.0