Inconsistent property behaviour in Apps

Inconsistent property behaviour in Apps

avatar

I've got the following code (stripped down to mostly just logic), which gets AD user details.

Sometimes I get all properties back, but rarely. More often than not (95% of the time), the MemberOf value is missing. Very frequently Canononical Name, Last Logon Timestamp, Mail, and TargetAddress will also be missing. I always get back Name, SamAccountName, UPN, DN and SID. The properties names exist in the object, just not their corresponding values.

At first I thought it might be something with the session scope, but that doesn't seem to be the case (I've tested with toast messages outputting the object assigned to a temp variable before handing it off to the session). I don't get this issue if I test in the terminal, nor do I get it running scripts - so the service account is fine. It's only using the app.

Note: The code does a couple of 'sync-udelement' hops because there are other items being pulled back elsewhere in the full version.

$session:UserID = $null
$session:User = $null

$cache:UserProperties = @(
    "Name",
    "SamAccountName",
    "UserPrincipalName",
    "Enabled",
    "CanonicalName",
    "DistinguishedName",
    "LastLogonTimestamp",
    "SID",
    "Mail",
    "TargetAddress",
    "MemberOf",
    "ShowInAddressBook"
)

New-UDApp -Title "User Overview" -Content {
    New-UDForm -Content {
        New-UDTextbox -Id 'txtSearchQuery' -Label 'Enter User ID'
    } -OnSubmit {
        $session:UserID = $EventData.txtSearchQuery
        Sync-UDElement -Id 'LoadUser'
    }

    New-UDDynamic -Id 'LoadUser' -Content {
        if (-not [string]::IsNullOrWhiteSpace($session:UserID)) {

            # Issue appears to be right at the 'get-aduser' call - property values are missing here
            $session:User = Get-ADUser -Identity $session:UserID -Property $cache:UserProperties

            Sync-UDElement -Id 'UserDetails'
        }
    }

    New-UDDynamic -Id 'UserDetails' -LoadingComponent {
        New-UDProgress -Circular
    } -Content {
        if ($session:User) {

            # Splits the object into a name/value list
            $Data = ($session:User | Select-Object -Property $cache:UserProperties).psobject.Properties.foreach({ [pscustomobject]@{Property=$_.Name; Value=$_.Value} })

            $Columns = @(
                New-UDTableColumn -Property Property -Title Property
                New-UDTableColumn -Property Value -Title Value
            )
            New-UDTable -Data $Data -Columns $Columns
        }
    }
}

All Comments (7)

avatar

Ok, to make matters more confusing, I've tested in a script and I see the same behaviour - but still the terminal window is absolutely fine. Testing on an old v3.4.6 install, properties are returned no issue.

Forgot to mention: we're running the latest 2026.3.2.

avatar

Hi Lloyd,

Thank you for the code and for the follow-up with the script and v3.4.6 results.

We ran your code on PowerShell Universal 2026.3.2 against our test domain. We left out TargetAddress, which our test domain does not have, and added one line that records what Get-ADUser returned.

In a script, we found one place where the values go missing. When a script returns the Get-ADUser object, the job's Pipeline Output tab keeps only the object's built-in properties, such as Name, SamAccountName, UserPrincipalName, DistinguishedName and SID. MemberOf, CanonicalName, LastLogonTimestamp and Mail appear only as names in the PropertyNames list, with no values. The Log tab of the same job shows their values. We saw this in the Integrated, PowerShell 7 and Windows PowerShell 5.1 environments. Inside the script itself, MemberOf, CanonicalName, LastLogonTimestamp and Mail had their values in all 36 runs.

In the app, we could not reproduce it. With your app code in the Integrated and PowerShell 7 environments (6 runs, 3 in each), those four properties had their values, both right after the Get-ADUser call and after the $session: hop.

Could you tell us:

1. In your script test, where did you see the values missing: inside the script itself, in the job's Log tab, or in its Pipeline Output tab?
2. Which environment and which Run As credential, if any, your app uses, and which ones your terminal uses (a terminal has its own: https://docs.devolutions.net/powershell-universal/automation/terminals/#configure-a-terminal)?
3. The exact line you used for the toast message, so we can repeat the same check here?

Best regards,

Michel

Michel Audi

avatar

Thanks for your time Michel.

This has taken a few twists. I managed to isolate it to the node in a single site - so fingers were pointed at AD (replication/permissions/etc) as it was working consistently outside of that site.

BUT!

If I change the environment from Integrated to PowerShell 7, it works consistently, every time. If I switch it back, it breaks.

So, I have a single node that fails to return these attributes every time I use Integrated. Otherwise I have the same: Code, Version, Service Account, and DCs.

avatar

Hi Lloyd,

Thank you, isolating it to one node and to Integrated narrows this down a lot. You can keep the app on PowerShell 7 while we look into it. The line below replaces my earlier request for your toast line.

One difference is where the app runs. In Integrated, an app runs inside the PowerShell Universal server process itself, and a Run As credential is not used. In PowerShell 7, it runs in its own process, started with the app's or the environment's Run As credential, if set. Is a Run As credential set on this app or on the PowerShell 7 environment?

We tested one way to get your result. In our lab on 2026.3.2, we removed the ActiveDirectory module's type adapters from an app's session. The table then showed Name, SamAccountName, UserPrincipalName, Enabled, DistinguishedName and SID with values, and MemberOf, CanonicalName, LastLogonTimestamp and Mail empty. We have not confirmed that this is what happens on your node, so could you check it with this line? Add it right after the Get-ADUser line in LoadUser:

Show-UDToast -Duration 60000 -Message ("PowerShell {0} | ActiveDirectory {1} | {2} | adapters {3}" -f $PSVersionTable.PSVersion, (Get-Module ActiveDirectory).Version, [Microsoft.ActiveDirectory.Management.ADEntity].Assembly.Location, @(Get-TypeData Microsoft.ActiveDirectory.Management.* | Where-Object TypeAdapter).Count)

Please run it on that node once in Integrated and once in PowerShell 7, and send us both toasts. In our lab, both environments show "adapters 38" with the same ActiveDirectory version and DLL path; with the adapters removed, "adapters 0". A toast from a working node would help too. Restarting the service starts a new server process, so please capture the toasts before any restart on that node.

Separately, we have reported the Pipeline Output issue from my last message to our developers. If your script test still shows the values missing, where do you see them missing: inside the script itself, in the job's Log tab, or only in its Pipeline Output tab?

Best regards,

Michel

Michel Audi

avatar

We haven't set any Run As parameters for PowerShell 7 vs Integrated - it's all as normal. I've also double-checked the properties for the Environments, and no RunAs properties have been set there, either.

I've been testing in a script, so I've pushed the string to Write-Host instead.

Here's integrated:
PowerShell 7.6.5
ActiveDirectory 1.0.1.0
C:\Windows\Microsoft.NET\assembly\GAC_64\Microsoft.ActiveDirectory.Management\v4.0_10.0.0.0__31bf3856ad364e35\Microsoft.ActiveDirectory.Management.dll
adapters 38

And here's PowerShell 7:
PowerShell 7.6.5
ActiveDirectory 1.0.1.0
C:\Windows\Microsoft.NET\assembly\GAC_64\Microsoft.ActiveDirectory.Management\v4.0_10.0.0.0__31bf3856ad364e35\Microsoft.ActiveDirectory.Management.dll
adapters 38

To my eyes, they appear identical.

avatar

And just for full transparency, here's the updated script:

Param(
    [string]$Identity
)

try {
    Get-ADUser -Identity $Identity -Server "user.domain" -Property MemberOf,ShowInAddressbook

    Write-Host ("PowerShell {0} | ActiveDirectory {1} | {2} | adapters {3}" -f $PSVersionTable.PSVersion, (Get-Module ActiveDirectory).Version, [Microsoft.ActiveDirectory.Management.ADEntity].Assembly.Location, @(Get-TypeData Microsoft.ActiveDirectory.Management.* | Where-Object TypeAdapter).Count)
}
catch {
    Write-Error "Unable to fetch user details`n$_"
}
avatar

And just to spam the posts:

I'm not ruling out authentication/permissions just yet in our environment. At this stage it looks like the way the Integrated environment is treated by Kerberos in some fashion is different to the PS7 method. I'll speak to our AD team and attempt to find anything, but if you could give me some kind of indication what to look for on their end, that would be great.