Pode icon indicating copy to clipboard operation
Pode copied to clipboard

Possible threading issue

Open Chris--A opened this issue 2 years ago • 3 comments

Describe the Bug

I'm not sure if this is Pode related, however, I have not been able to reproduce the issue in other tests outside of Pode using runspaces or such.

When using Pode in a multi threaded scenario (threads > 1) using a Powershell cmdlets that return a CimInstance/[] I have noticed that some fields are empty, whereas subsequent/previous calls contain data.

I have reproduced the issue in the small excerpt below, and this is not specific to the Get-NetAdapter, and have observed this behavior with other cmdlets.

Steps To Reproduce

Import-Module pode

Start-PodeServer -Threads 2 -Browse -ScriptBlock {
    Add-PodeEndpoint -Address localhost -Port 8081 -Protocol Http

    Add-PodeRoute -Path '/' -Method Get -ScriptBlock {
        $text = Get-NetAdapter | Select @(
            @{n="Name";e={$_.Name}}
            @{n="Description";e={$_.InterfaceDescription}}
            @{n="Status";e={$_.Status}}
            @{n="MAC";e={$_.MacAddress}}
            @{n="Speed";e={$_.LinkSpeed}}
        ) | Sort Name | ConvertTo-Html

        Write-PodeHtmlResponse -Value (-join $text) -StatusCode 200
    }
}

Expected Behavior

Name Description Status MAC Speed
Bluetooth Network Connection Bluetooth Device (Personal Area Network) Disconnected 38-D5-XX-XX-XX-XX 3 Mbps
Ethernet Realtek Gaming 2.5GbE Family Controller Disconnected 04-7C-XX-XX-XX-XX 0 bps
Ethernet 2 VirtualBox Host-Only Ethernet Adapter Up 0A-00-XX-XX-XX-XX 1 Gbps
Wi-Fi RZ608 Wi-Fi 6E 80MHz Up 38-D5-XX-XX-XX-XX 866.7 Mbps

Observed Behavior

Upon refreshing the page, this is displayed instead. Sometimes it is every 2nd run, or multiple in a row.

Name Description Status MAC Speed
Bluetooth Network Connection Bluetooth Device (Personal Area Network)
Ethernet Realtek Gaming 2.5GbE Family Controller
Ethernet 2 VirtualBox Host-Only Ethernet Adapter
Wi-Fi RZ608 Wi-Fi 6E 80MHz

Platform

  • OS: Windows 10
  • Browser: Chrome, Edge, FireFox
  • Versions:
    • Pode: 2.8.0
    • PowerShell: 5.1 & 7.3.6.0

Additional Context

This issue is not specific to the custom fields I have created, it can be observed when simply using Get-NetAdapter | ConvertTo-Html. This produces a far larger output, but data is clearly missing on subsequent calls. It is also not related to ConvertTo-Html as I'm only using it for this example.

Chris--A avatar Aug 25 '23 08:08 Chris--A

I tried your code I was not able to find any issue. Only one note I added the -rootpath property. By default Pode set the rootpath to c:/windows/system32/public

I'm using Windows 11 and PWSH 7.3.7

mdaneri avatar Sep 24 '23 18:09 mdaneri

I tried your code I was not able to find any issue. Only one note I added the -rootpath property. By default Pode set the rootpath to c:/windows/system32/public

I'm using Windows 11 and PWSH 7.3.7

Hi, cheers for testing, the root path shouldn't matter as no files are loaded in my example. However, I have just confirmed this issue again on two additional computers. Both are Windows 10, using PS 5.1 & 7.4.0. Just to clarify, did you refresh the page multiple times?

Chris--A avatar Sep 28 '23 01:09 Chris--A

Yes, I tried multiple refreshes. The only difference I can see is that I'm using windows 11. No antivirus and security other than the standard ones provided by Microsoft for a standalone win 11 professional . I'm using the GitHub code not the PowerShell gallery one

mdaneri avatar Sep 28 '23 02:09 mdaneri

I have a very similar issue. When using the cmdlet get-SMBShareAccess , e.g. $shareperms = Get-SMBShareAccess -Name $ShareName | Where-Object {$_.AccountName -Like "*$($UserName)"} | Select AccessRight The first thread gives "Read" and "Change" (I don't use the other "FullAccess" and subsequent threads give me numerical index 2 and 1 respectively.

I work around this by using a function:

function get-users-file-share-permissions {
	[CmdletBinding()]
	param (
		[Parameter(Mandatory)]
		# Share to check permissions of
		[string] $ShareName,
		# name to check for permissions
		[string] $UserName
	)
	#Log-Message "Checking permissions of $UserName to share $ShareName"
	$shareperms = Get-SMBShareAccess -Name $ShareName | Where-Object {$_.AccountName -Like "*$($UserName)"} | Select AccessRight
	$sharepermsfull = Get-SMBShareAccess -Name $ShareName | Where-Object {$_.AccountName -Like "*$($UserName)"}
	$shareaccessperms = $shareperms.AccessRight
	If($shareaccessperms -eq "1") {$shareaccessperms = "Change"}
	If($shareaccessperms -eq "2") {$shareaccessperms = "Read"}
	return $shareaccessperms
}

I wonder if some internal index is locked by the first thread? Best, Millsey

millsey45 avatar May 23 '24 15:05 millsey45

When it comes to functions which deal with and return CimInstance objects, these usually come from internal modules which are auto-imported when the function is used.

In these cases, the auto-importing which PowerShell itself does doesn't always 100% work inside runspaces - ActiveDirectory notably suffers from this, where unless the module is explicitly imported then certain functions in one thread return all expected values but then in other don't. Importing the ActiveDirectory module before Start-PodeServer and have Pode's auto-import feature enabled (this is by default) tends to resolve the issue.

For the NetAdapter for the @Chris--A, and SMB for yourself @millsey45, if you try importing the relevant modules beforehand at the top of your scripts, does this resolve the issue?

Import-Module NetAdapter
# or
Import-Module SmbShare

Start-PodeServer { ... }

Pode's auto-importing for modules is on by default, if you need to re-enable or explicitly export the module for Pode see here: https://badgerati.github.io/Pode/Tutorials/Scoping/#modules

Badgerati avatar May 23 '24 20:05 Badgerati

Good morning,

Thank you very much for such a detailed and clear explanation, it is very much appreciated. I had suspected that any modules would have to be loaded inside the Pode Route, so this is going to be very helpful. Given my script also uses the activedirectory and invoke-sqlcmd2 modules, I will import those before Start-Pode.

Have a great day! Regards

millsey45 avatar May 24 '24 07:05 millsey45

Jus to confirm this DOES fix the return values from Get-SMBShareAccess, and also to note that importing the modules (SMB, activedirectory, Invoke-SQLcmd2) before Start-Pode also makes each REST call faster, was taking five seconds now takes three. Cheers!

millsey45 avatar May 24 '24 09:05 millsey45