SOLVED

Get-AzAccessToken "Method not found: Void..."

Iron Contributor

When running the script below, I get the following error:

Get-AzAccessToken : Method not found: 'Void Azure.Identity.BrokeredAuthentication.SharedTokenCacheCredentialBrokerOptio ns..ctor(Azure.Identity.TokenCachePersistenceOptions)'. 

 

Import-Module Microsoft.Graph.Authentication
Import-Module Az.Accounts

function Connect-MgGraphViaCred {
      [CmdletBinding()]
      param (
          [Parameter(Mandatory = $true)]
          [System.Management.Automation.PSCredential] $credential,

          [string] $tenant = "customersbank.com"
      )

      # connect to Azure using credentials
      $param = @{
          Credential = $credential
          Force      = $true
      }
      if ($tenant) { $param.tenant = $tenant }
      Connect-AzAccount 

      # retrieve token for MSGraph
      $token = (Get-AzAccessToken -ResourceTypeName MSGraph -ErrorAction Stop).token

      # convert token string to securestring if new version of Connect-MgGraph is used
      if ((Get-Help Connect-MgGraph -Parameter accesstoken).type.name -eq "securestring") {
          $token = ConvertTo-SecureString $token -AsPlainText -Force
      }
      # use token for connecting to Microsoft Graph
      $null = Connect-MgGraph -AccessToken $token -ErrorAction Stop
  }

$User = "##username##"
$PWord = ConvertTo-SecureString -String "##password##" -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $PWord

Connect-MgGraphViaCred -credential $Credential

 

 

 

I am running the script inside a Power Automate Desktop flow.  When I run it on my Win10 machine, it runs fine, but it needs to run on a Windows Server 2019 OS, which is where it fails.  I am assuming that it has something to do with the version of the Connect-AZAccount or Get-AZAccessToken commands.

 

P.A.D. only supports PowerShell 5, so I am forced to use that version.  The server's version of PowerShell is slightly older but, from what I understand, the only way to update it is via Windows Update and that says there are no new updates.  Is it possible that this just won't run on Windows Server?

 

Major  Minor  Build  Revision
-----  -----  -----  --------
5      1      19041  3031 - Win 10 Laptop
5      1      17763  4720 - Server 2019
 
Module NameWin10 VersionServer 2019 Version
Az9.7.110.2.0
Az.Accounts2.12.22.12.5

 

6 Replies
best response confirmed by Steve Wright (Iron Contributor)
Solution

@Steve Wright 

 

Hi, Steve.

 

I can't offer any advice on what's causing that issue as I've not seen it before, but I can offer some commentary around the environment and your questions towards the end.

 

Firstly, on the environment, I only use Windows PowerShell (aka 5.1) as it's the only option out-of-the-box, and is therefore the only option available in practically every customer engagement I've been in. And in most cases, this is on Windows Server 2019, too.

 

This dovetails into your question of "is it possible that this just won't run on Windows Server?", for which the answer is it most certainly does run on Windows Server under Windows PowerShell.

 

That said, while I have a few solutions doing as you're doing - which is using Az.Accounts to procure a token for including in subsequent Microsoft.Graph calls (amongst others), there is a point of difference in that I'm using certificate-based authentication rather than old-school username-and-password credentials. Still, that one point aside, the approach you're taking definitely works.

 

With respect to the error, "method not found" is typically thrown for one of "two" reasons (technically, it's one reason but it's useful to split it):

 

  1. The method or constructor really does not exist;
  2. The method or constructor does exist, but not with a definition that matches the parameters passed in.

 

One possibility is that different versions of a library are required by different PowerShell modules. And it's noteworthy that the class (contained in Azure.Identity.BrokeredAuthentication.dll) from your error message is used by both the Az.Accounts and Microsoft.Graph.Authentication modules. So, there's a possibility that they are in conflict.

 

There's a lot of different troubleshooting steps you can pursue here, but in the interest of keeping things simple, I'd wipe out all module versions (using Uninstall-Module) matching the following specifications and re-install those that you need:

 

  • Az.*
  • Microsoft.Graph.*

 

There's a reasonable chance that ensuring that both the Az modules and Microsoft.Graph modules are current that the underpinning SharedTokenCacheCredentialBrokerOptions class issue will also be resolved.

 

As a side note, you might also want to ensure you're running .NET 4.7.2 or above, as both Az and Graph modules are tagged to this as the minimum version:

 

 

Cheers,

Lain

@LainRobertson Thank you, Lain, for a detailed and thoughtful response!

 

I did not understand that both the Az.Accounts and Microsoft.Graph.Authentication modules utilized the same DLL that was mentioned in the error.  Once I understood that, I realized that the largest gap in versions was for Graph.Authentication:

Name

Win10 Laptop Version

RPA Server 2019 Version

Az.Accounts

2.12.2

2.12.5

Microsoft.Graph.Authentication

1.27.0

2.3.0

 

I then uninstalled all the Graph modules and reinstalled using the "-requiredversion 1.27" switch.  My script now executes successfully on the 2019 server! :stareyes:

 

Oh, and after checking the registry, both machines running .NET 4.8.

 

Some follow-up questions:

  • For future reference, how could I determine if a DLL that's mentioned in an error is used by other commands than the one that failed?
  • Are the Microsoft Graph v2 commands considered preview?  I am hoping that at some point in the future they will include all of the functionality of the v1 commands.  I am just concerned that a future PowerShell script will require v2 commands while this script must stay at v1.  I am not sure how to handle that scenario other than spinning up an entirely separate server.

Thanks again for your assistance!  I opened a Microsoft ticket for this issue but it's still being routed to the correct support group. :unamused:

@LainRobertson It doesn't appear that the DLL mentioned in the error, Azure.Identity.BrokeredAuthentication.dll, is used by both Az.Accounts and Microsoft.Graph.Authentication.  I used Process Explorer to do a little testing and the DLL is only loaded with Az.Accounts:

SteveWright_0-1693947721249.pngSteveWright_1-1693947728585.png

Though dropping the version of Microsoft.Graph.Authentication back from v2 to v1 is what fixed the error.

 

The really strange thing is a colleague reminded me that they were unable to get the script to run on their laptop with PowerShell 5.1 and they have almost the same versions of those modules as the server.  The only difference is Microsoft.Graph.Authentication is at 1.28 instead of 1.27.  This is so confusing.



@Steve Wright 

 

Hey, Steve.

 

Speaking to your two earlier questions (which covers your last post):

 

Q: How could I determine if a DLL that's mentioned in an error is used by other commands than the one that failed?

First, you need to know which DLL you're looking for, as DLLs themselves have dependencies, and there's more than one way to load a DLL which can obscure locating them in memory.

 

Let's use your error message as the example to consider, where looking at it gives us two important clues:

 

  • There's no DLL reference but there is a class reference: [Azure.Identity.BrokeredAuthentication.SharedTokenCacheCredentialBrokerOptions];
  • We can tell that it's failing on the constructor by the ".ctor" keyword.

 

So, while there's no mention of a DLL, we do have a class name to work with.

 

Next, we check the class to see from which module it was loaded. In my example below, I'm killing two birds with one stone as this is actually taken from having loaded Microsoft.Graph.Authentication (second screenshot, showing the progression of events leading to the class being loaded) where you can see it does indeed use Azure.Identity.BrokeredAuthentication.dll:

 

LainRobertson_0-1693958062834.png

 

LainRobertson_1-1693958209832.png

 

Now that we know the actual DLL name the class is defined in (as distinct from the process owner that imported it), it's a basic case of looking for the file - which in my example I've scoped to the x64 Windows PowerShell directory, but you could just as easily scan the whole drive for:

 

LainRobertson_2-1693958522793.png

 

And presto! We now know which modules (and which versions of those modules) contain the potentially-conflicting DLL. Conveniently, this also confirms both Az.Accounts and Microsoft.Graph.Authentication leverage Azure.Identity.BrokeredAuthentication.dll (unsurprising given they're both aimed at authentication).

 

Q: Are the Microsoft Graph v2 commands considered preview?

No, they're not preview.

 

Sometimes things disappear from current module when compared to old ones because they forgot to include them (which even happens at the Graph API level, too), or because of a regression (aka bug), or just because they're not doing something the same way anymore - which is the most common reason.

 

In this brave, new "agile" world, you can't count on backwards compatibility the way you could in the past, so constant script fiddling is something we all just have to live with.

 

Checking out constructor definitions

Because the ".ctor" reference tells us we're dealing with the constructor, we can see what constructor definitions exist by simply including "::new" (without the parentheses at the end):

 

LainRobertson_3-1693959177970.png

Constructor definitions taken from the Microsoft.Graph.Authentication 2.3.0 module.

 

I don't have an older version of Az.Accounts to compare, but I'd wager a comparison between ne Graph and old Az would result in different overloaded definitions being seen.

 

Summary

Your error message is a clear one to understand (the "what") - in the context of what it's telling you, but do find out the "why", you have to dig deeper as we've done above.

 

Depending on how a DLL is being loaded, you can find conflicts between older and newer versions of the same DLL, which in turn impacts the downstream DLLs/applications that have been coded to expect an overload that no longer exists in the explicit form it is aligned to, resulting in the error message you're seeing.

 

I would also quickly add (perhaps all too obviously) that while we're talking about Az.Accounts and Microsoft.Graph.Authentication in this specific case, given the nature of PowerShell modules, a given DLL could be spread out across many more, which is why it pays to keep them all on the current branch (or near to it) when possible to do so.

 

This isn't solving your problem, of course, but hopefully it helps you better understand it.

 

Cheers,

Lain

@LainRobertson Thank you again for your insightful and detailed response!  I am not completely sure I would be able to duplicate your detective work if this type of an issue comes up again, but at least I understand the reasons for an error like this and what direction to proceed when troubleshooting.

 

A few follow-up questions regarding DLLs:

  • Is the DLL only loaded after a command executes that calls it?  That's what it looks like from your screenshots.
  • I assume the version of the DLL that's loaded has to do with when it is first used, meaning the command that calls is first.  Is that correct? In my example, I'm assuming that the Get-AzAccessToken command was using the version of the DLL loaded by Microsoft.Graph.Authentication.
  • When are DLLs "unloaded"?  If I close the PowerShell window, does that unload them?  Meaning if I need to test possible DLL conflicts, can I just close PowerShell, re-open and then experiment with a different order of commands?

One question not related to DLLs:

I am using the workaround of logging into Azure first, then getting a token to use in MgGraph commands because I'm unable to assign the needed permissions to an app registration and connect that way.  That, or the command I need to execute does not support running as an app.  This unfortunately necessitates logging in with a name and password, which I have to try to obfuscate the best that I can.  You had mentioned that you sometimes need to do the same workaround, but you use a certificate, which is preferable.   Is there a way to do this yet still use administrator roles instead of app permissions?  (I apologize for not using all of the correct terms - hopefully you know what I'm getting at.)

Thanks again.
BTW, Microsoft still has not been able to respond to my ticket.

 

@Steve Wright 

 

Here's some matching answers in short-form:

 

  1. When loading a new PowerShell module, DLLs can be loaded at any point, so the answer it "it depends" on a per module basis. i.e. the module could load DLLs as part of its own initialisation, or it could be deferred until later where a particular command triggers the loading;
  2. Yes, this is correct - as a general rule. Whichever version is loaded first usually "wins". There are exceptions to this but they're not worth going into in depth as it's just not common enough to talk about. But in this particular scenario, it doesn't matter which module wins since fundamentally, each PowerShell module (Az and Graph) have different expectations from the constructor;
  3. Generally when the PowerShell module is closed. In much the same spirit as point 2 above, there are exceptions, however, they're not common enough to warrant talking about. It is worth calling though that Remove-Module does not unload DLLs from memory (I've come across that misunderstanding before so figured it was worth a shout-out.)

 

On the final question, I haven't come across the need to use a normal user account as everything I've done works just fine with a servicePrincipal (aka app registration), and I've only seen certificate-based authentication for the latter - though I've also had no reason to look into if it's possible for a regular user (of type "member" as distinct from "guest") account.

 

If I can muster up some time, I'll have a look and let you know - or maybe someone else already knows. But for now, from me, the answer for CBA on user accounts is "I don't know" (or in Australian, we simply say "dunno"!).

 

Cheers,

Lain