0

I have an Azure Automation Runbook that needs to Connect-AzAccount to export a CSV from the Automation Account to a Blob Storage Account. My Service Principal has an ApplicationID and a Secret. per the documentation for Connect-AzAccount -Credential can accept this.

However when I attempt to feed it in via:

$Credential = New-Object -TypeName System.Management.Automation.PSCredential($ApplicationID, $AppSecret)
Connect-AzAccount -ServicePrincipal -TenantId $TenantId -Credential $Credential

I get the following error:

Cannot bind argument to parameter 'Credential' because it is null

Would anyone be able to point me to where I am messing up?

Daniel Mann
  • 57,011
  • 13
  • 100
  • 120
BPengu
  • 92
  • 8
  • 2
    In your code, the only scenario in which this error would occur is if `$Credential` is indeed `$null`, which in turn would only occur if the `New-Object` call failed silently (which it wouldn't by default). – mklement0 Feb 17 '23 at 18:28
  • 1
    After running it again there is more to the error. ```Cannot find overload for "PSCredential" and the argument count: "2". ``` – BPengu Feb 17 '23 at 18:35
  • 2
    `$AppSecret` must be a `[securestring]` instance for the `System.Management.Automation.PSCredential` constructor call to succeed. – mklement0 Feb 17 '23 at 18:45

1 Answers1

2

tl;dr

Since the root cause turned out to be the following error:

Cannot find overload for "PSCredential" and the argument count: "2".

the implication is that the $AppSecret argument in your New-Object -TypeName PSCredential call was not of type [securestring], which is what the relevant [pscredential] constructor overload requires.

Making it a [securestring] instance solved your problem.


A [securestring] instance can be constructed or obtained in several ways:

Alternatively, you could obtain the entire [pscredential] instance differently:

  • Interactively, via Get-Credential:

    # Prompts for the app secret (password) and returns a [pscredential] instance.
    $Credential = Get-Credential $ApplicationID
    
  • On Windows only, import a [pscredential] instance that was previously persisted to a file with Export-Clixml with Import-Clixml - see this answer.

A general caveat: [securestring] offers limited security on Windows, and virtually none on Unix-like platforms, where encryption isn't even employed - see this answer.


As for what you tried and the error message you saw:

New-Object -TypeName System.Management.Automation.PSCredential($ApplicationID, $AppSecret)

This command can be simplified to:

New-Object pscredential $ApplicationID, $AppSecret
# Short for:
#  New-Object -TypeName pscredential -ArgumentList $ApplicationID, $AppSecret

Note:

New-Object calls translate into .NET constructor calls, and in PowerShell 5 and above there's now a a more direct way to call constructors, using the static ::new() method exposed by PowerShell on types. Therefore, the equivalent of the command above is:

# PSv5+ equivalent of the above.
# Note that this syntax *does* require method-call syntax.
[pscredential]::new($ApplicationID, $AppSecret)

The advantage of this approach is that you can easily inspect the constructor overloads (variants with different parameters), simply by accessing ::new without the (...) part:

# Print constructor overloads
[pscredential]::new

Output:

OverloadDefinitions
-------------------
pscredential new(string userName, securestring password)
pscredential new(psobject pso)

The first overload - the only one to accept two arguments - also reveals the parameter types, and indeed shows that the second parameter requires a [securestring] instance as its argument.

Unfortunately, the error message you get when the count of arguments is correct but the type isn't is somewhat misleading:

Cannot find overload for "PSCredential" and the argument count: "2".

Clearly, you did pass 2 arguments, but it was the fact that the 2nd argument had the wrong type that triggered the error, whereas the message makes it sound like you passed the wrong number of arguments.

Improving this error message has been green-lit in GitHub issue #3658, but so far no one has stepped up to implement it.

mklement0
  • 382,024
  • 64
  • 607
  • 775