A positional parameter cannot be found that accept

2020-06-30 04:55发布

问题:

I am trying to understand what this error actually means. So far a search of similar help requests for this error range from missing parameters, missing pipes, use of single or multi lines and also concatenation issues but none of the answers seem to give a definitive reason. So I assume the issue is code format (which makes it a lot harder to track down).

This is my script which I am writing to rename active directory users per target OU from whatever format they are now into a firstname.surname format.

I have created a test OU in AD with some users which will trigger errors and some that will not. However the users that should not give me an error are giving me the "a positional parameter cannot be found that accepts arguement "firstname.surname"

I cannot see what is wrong with the script but hopefully someone can give me some pointers.

Import-Module ActiveDirectory

$users = $null

$users = Get-ADUser -SearchBase "ou=Testing,ou=Users,dc=my,dc=domain" -Filter * -Properties *
foreach ($user in $users) {
    Write-Host "Processing... $($user)"
    $newname = $null

    # Check first/last name is set
    if (!$user.givenName -or !$user.Surname) {
        Write-Host "$($user) does not have first name or last name set. Please correct, skipping user."
        continue
    } else {
        $newname = ("$($user.givenName).$($user.Surname)")

        #Check if new username already exists
        if (dsquery user -samid $newname) {
            Write-Host "$($user) requires altered username with initial."

            if (!$user.Initials) {
                Write-Host "$($user) does not have any initials set. Please correct, skipping user."
                continue
            }

            $newname = ("$($user.givenName)$($user.Initials).$($user.Surname)")

            #Check if altered new username already exists
            if (dsquery user -samid $newname) {
                Write-Host "$($user) requires manual change. Please correct, skipping user."
                continue
            }
        }

        try {
            #Change UPN
            Set-ADUser $user -userPrincipalName = $newname
            #Change DN
            Rename-ADObject -identity $user -Newname $newname
        } catch {
            Write-Host "Error when renaming $($user). Error is: $($_.Exception.Message). User requires manual change. Please correct, skipping user."
            continue
        }
    }
}

回答1:

Cmdlets in powershell accept a bunch of arguments. When these arguments are defined you can define a position for each of them.

This allows you to call a cmdlet without specifying the parameter name. So for the following cmdlet the path attribute is define with a position of 0 allowing you to skip typing -Path when invoking it and as such both the following will work.

Get-Item -Path C:\temp\thing.txt
Get-Item C:\temp\thing.txt

However if you specify more arguments than there are positional parameters defined then you will get the error.

Get-Item C:\temp\thing.txt "*"

As this cmdlet does not know how to accept the second positional parameter you get the error. You can fix this by telling it what the parameter is meant to be.

Get-Item C:\temp\thing.txt -Filter "*"

I assume you are getting the error on the following line of code as it seems to be the only place you are not specifying the parameter names correctly, and maybe it is treating the = as a parameter and $username as another parameter.

Set-ADUser $user -userPrincipalName = $newname

Try specifying the parameter name for $user and removing the =



回答2:

I had this issue after converting my Write-Host cmdlets to Write-Information and I was missing quotes and parens around the parameters. The cmdlet signatures are evidently not the same.

Write-Host this is a good idea $here
Write-Information this is a good idea $here <=BAD

This is the cmdlet signature that corrected after spending 20-30 minutes digging down the function stack...

Write-Information ("this is a good idea $here") <=GOOD



回答3:

In my case it was the difference between (En dash) and -(Hyphen) as in:

Add-Type –Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"

and:

Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"

Dashes, Hyphens, and Minus signs oh my!



回答4:

In my case there was a corrupted character in one of the named params ("-StorageAccountName" for cmdlet "Get-AzureStorageKey") which showed as perfectly normal in my editor (SublimeText) but Windows Powershell couldn't parse it.

To get to the bottom of it, I moved the offending lines from the error message into another .ps1 file, ran that, and the error now showed a botched character at the beginning of my "-StorageAccountName" parameter.

Deleting the character (again which looks normal in the actual editor) and re-typing it fixes this issue.



回答5:

I had to use

powershell.AddCommand("Get-ADPermission");
powershell.AddParameter("Identity", "complete id path with OU in it");

to get past this error



回答6:

I had this problem when trying to change directory, using the character _. The solution was to use a string to change directories.

C:\> cd "my_new_dir"


回答7:

In my case I had tried to make code more readable by putting:

"LONGTEXTSTRING " +
"LONGTEXTSTRING" +
"LONGTEXTSTRING"

Once I changed it to

LONGTEXTSTRING LONGTEXTSTRING LONGTEXTSTRING 

Then it worked