pnp / powershell

PnP PowerShell
https://pnp.github.io/powershell
MIT License
621 stars 331 forks source link

[BUG]Object reference not set to an instance of an object. Calling Update-PnPTeamsUser -Team $TeamID -User $UserUPN -Role 'Member' -force #4056

Open MarkF26 opened 5 days ago

MarkF26 commented 5 days ago

Reporting an Issue

when executing the command below on certain Team objects the error message above is returned. The command is used to change an owner to a member (there is more than 1 owner on this object). Only certain teams for this user is failing. I haven't been able to find a common factor among the teams that fail with this command.

Update-PnPTeamsUser -Team $TeamID -User $UserUPN -Role 'Member' -force

Expected behavior

The user's membership should be changed to Member.

Actual behavior

It fails with the message below: Object reference not set to an instance of an object

Steps to reproduce behavior

$UserUPN ='JDoe@mycompany.com' $TeamID = "xxxxxxxx-yyyy-zzzz-aaaa-bbbbbbbbbbbb" Update-PnPTeamsUser -Team $TeamID -User $UserUPN -Role 'Member' -force

What is the version of the Cmdlet module you are running?

2.5.0

Which operating system/environment are you running PnP PowerShell on?

jackpoz commented 5 days ago

Could you please run these commands ?

Update-PnPTeamsUser -Team $TeamID -User $UserUPN -Role 'Member' -force -ErrorAction:Stop
(Get-PnPException).Exception | select *

and post the output. It should show the stacktrace with the file and line where the exception happened, which will help to understand the issue.

MarkF26 commented 5 days ago

Could you please run these commands ?

Update-PnPTeamsUser -Team $TeamID -User $UserUPN -Role 'Member' -force -ErrorAction:Stop
(Get-PnPException).Exception | select *

and post the output. It should show the stacktrace with the file and line where the exception happened, which will help to understand the issue.

ErrorRecord    : Object reference not set to an instance of an object.
TargetSite     : Void ProcessRecord()
Message        : Object reference not set to an instance of an object.
Data           : {}
InnerException : 
HelpLink       : 
Source         : PnP.PowerShell
HResult        : -2146233079
StackTrace     :    at PnP.PowerShell.Commands.Base.PnPConnectedCmdlet.ProcessRecord() in
                 c:\build\src\Commands\Base\PnPConnectedCmdlet.cs:line 101
                    at System.Management.Automation.CommandProcessor.ProcessRecord()
jackpoz commented 5 days ago

Is that with the -ErrorAction:Stop parameter passed to Update-PnPTeamsUser ?

MarkF26 commented 5 days ago

Is that with the -ErrorAction:Stop parameter passed to Update-PnPTeamsUser ?

I used a Try / Catch block that does the same thing.

jackpoz commented 4 days ago

But you need to pass -ErrorAction:Stop to the command, otherwise the callstack will not be useful as it will not show where the exception happened but only where it was rethrown.

MarkF26 commented 4 days ago

But you need to pass -ErrorAction:Stop to the command, otherwise the callstack will not be useful as it will not show where the exception happened but only where it was rethrown.

Sorry for the confusion. Here it is after following your instructions:

TargetSite     : Void ExecuteCmdlet()
Message        : Object reference not set to an instance of an object.
Data           : {[CorrelationId, ], [TimeStampUtc, 7/3/2024 4:40:50 PM]}
InnerException : 
HelpLink       : 
Source         : PnP.PowerShell
HResult        : -2147467261
StackTrace     :    at PnP.PowerShell.Commands.Teams.UpdateTeamsUser.ExecuteCmdlet() in
                 c:\build\src\Commands\Teams\UpdateTeamsUser.cs:line 46
                    at PnP.PowerShell.Commands.Base.PnPConnectedCmdlet.ProcessRecord() in
                 c:\build\src\Commands\Base\PnPConnectedCmdlet.cs:line 53
jackpoz commented 4 days ago

By the look of that part of the code, that happens when a Owner is only Owner and not Owner+Member. I will try to reproduce the issue that way to see if I get the same error.

jackpoz commented 4 days ago

I was able to reproduce the issue by removing a member from Teams client and then running Update-PnPTeamsUser right away. The user was found in the M365 group but not in the Team, as that takes a few seconds. See in the screenshot below how specifiedUser != null is false (so the user is in the M365 group) but then teamUserWithDisplayName is empty:

image

Running the same command a few seconds later returns correctly Update-PnPTeamsUser: User not found in the team .

I will open a PR with a better error message than Object reference not set to an instance of an object for this case.

MarkF26 commented 4 days ago

I was able to reproduce the issue by removing a member from Teams client and then running Update-PnPTeamsUser right away. The user was found in the M365 group but not in the Team, as that takes a few seconds. See in the screenshot below how specifiedUser != null is false (so the user is in the M365 group) but then teamUserWithDisplayName is empty:

image

Running the same command a few seconds later returns correctly Update-PnPTeamsUser: User not found in the team .

I will open a PR with a better error message than Object reference not set to an instance of an object for this case.

Thanks for the update. I am just wondering how much sleep time does the script need before attempting the update call. Are you suggesting that there is an inconsistency between the M365 groups and Teams ?, if this is the case, how do I correct it. The script's purpose is to refresh a user's membership in Teams by going through each user's Teams and flip a user's membership from member to owner and back. The reason we are doing it is because after some users are migrated from one on-premise domain to another they lose some of their membership in Teams they belonged before the domain migration. The manual way we learned this was fixable was to go to the Sharepoint Admin site and flip a user's membership back and forth. I wanted to do the same using PnP.PowerShell but I ran into this issue.

jackpoz commented 3 days ago

That's sounds like a strange issue 😮

I haven't really used Update-PnPTeamsUser before so not sure what its behavior is when flipping back and forth between Member and Owner. I used mostly cmdlets like Remove-PnPMicrosoft365GroupMember and Add-PnPMicrosoft365GroupMember which work at M365 group level instead of Teams team.

As for how much time to sleep, a retry pattern is usually the best, where you throw the exception only after enough failed retries. M365 Groups and Teams seem to take a few seconds to sync, so not that long.

Hope you find a reliable way to deal with your user migration issue 😃