Не удается найти позиционный параметр powershell
Не найден позиционный параметр, который принимает аргумент «xxx».
Я пытаюсь понять, что на самом деле означает эта ошибка. До сих пор поиск похожих запросов на помощь для этой ошибки варьировался от отсутствующих параметров, отсутствующих каналов, использования одной или нескольких строк, а также проблем конкатенации, но ни один из ответов, похоже, не дает окончательной причины. Поэтому я предполагаю, что проблема заключается в формате кода (из-за которого его намного сложнее отследить).
Это мой сценарий, который я пишу для переименования пользователей активного каталога для каждой целевой OU из любого формата, в котором они сейчас находятся, в формат firstname.surname.
Я не вижу, что не так со сценарием, но, надеюсь, кто-нибудь может дать мне несколько советов.
7 ответов
Командлеты в PowerShell принимают множество аргументов. Когда эти аргументы определены, вы можете определить позицию для каждого из них.
Однако, если вы укажете больше аргументов, чем указано позиционных параметров, вы получите ошибку.
Поскольку этот командлет не знает, как принять второй позиционный параметр, вы получите ошибку. Вы можете исправить это, указав, каким должен быть параметр.
В моем случае я попытался сделать код более читабельным, добавив:
Как только я изменил его на
Тогда это сработало
Мне пришлось использовать
Чтобы обойти эту ошибку
В моем случае в одном из названных параметров («-StorageAccountName» для командлета «Get-AzureStorageKey») был поврежденный символ, который в моем редакторе (SublimeText) отображался совершенно нормально, но Windows Powershell не смогла его проанализировать.
Удаление символа (опять же, которое выглядит нормально в реальном редакторе) и его повторный ввод устраняет эту проблему.
Powershell: не удается найти позиционный параметр, который принимает аргумент » xxx»
Я пытаюсь понять, что на самом деле означает эта ошибка. До сих пор поиск подобных запросов справки для этого диапазона ошибок от отсутствующих параметров, отсутствующих труб, использования одиночных или нескольких строк, а также проблем конкатенации, но ни один из ответов, похоже, не дает окончательной причины. Поэтому я предполагаю, что проблема заключается в формате кода (что делает его намного сложнее отследить).
Это мой скрипт, который я пишу, чтобы переименовать пользователей active directory на целевой OU из любого формата сейчас в «имя».формат фамилия.
Я создал тестовый OU в AD с некоторыми пользователями, которые будут вызывать ошибки, а некоторые-нет. Однако пользователи, которые не должны давать мне ошибку, дают мне «позиционный параметр не может быть найден, который принимает аргумент «firstname.фамилия»
Я не вижу, что не так со скриптом, но, надеюсь, кто-то может дать мне несколько указателей.
3 ответов
командлеты в powershell принимают кучу аргументов. Когда эти аргументы определены, вы можете определить позицию для каждого из них.
это позволяет вызывать командлет без указания имени параметра. Таким образом, для следующего командлета атрибут path определяется с позицией 0, позволяющей пропустить путь ввода при его вызове, и как таковой будет работать следующее.
однако, если вы укажете больше аргументов, чем есть позиционные параметры определены, то вы получите ошибку.
поскольку этот командлет не знает, как принять второй позиционный параметр, вы получаете ошибку. Вы можете исправить это, сообщив ему, каким должен быть параметр.
у меня была эта проблема после преобразования Write-Host командлетов Write-Information и мне не хватает кавычки и скобки вокруг параметров. Подписи командлетов, очевидно, не совпадают.
это подпись командлета, которая исправлена после 20-30 минут копания стека функций.
в моем случае был поврежден символ в одном из именованных параметров («- StorageAccountName «для командлета» Get-AzureStorageKey»), который показался совершенно нормальным в моем редакторе (SublimeText), но Windows Powershell не смог его разобрать.
удаление символ (опять же, который выглядит нормально в фактическом редакторе) и повторный ввод исправляет эту проблему.
Python-сообщество
Уведомления
#1 Март 18, 2016 19:29:16
PowerShell, Set-Location: Не удается найти позиционный параметр
Не могу зайти в Python Scripts через PowerShell. Путь к файлу: C:\Users\PC\Documents\Python Scripts. Через cd Documents захожу в C:\Users\PC\Documents, через cd Python Scripts выдает ошибку.
Отредактировано Kurtz (Март 18, 2016 19:31:46)
#2 Март 18, 2016 20:59:36
PowerShell, Set-Location: Не удается найти позиционный параметр
А зачем вы пробел в имени папки сделали? Не делайте пробелов, не надо будет учиться с ними бороться.
p.s.
PowerShell для работы с питоном абсолютно не нужен.
#3 Март 18, 2016 21:26:05
PowerShell, Set-Location: Не удается найти позиционный параметр
Понял, спасибо.
Я понимаю что проблема в пробеле, другое дело что эта папка создана системой, которую сама система не может прочитать. Мне это показалось маловероятным.
По каким-то причинам, использование терминала является обязательным что на Coursera, что в книге Learn Python the Hard Way.
Отредактировано Kurtz (Март 18, 2016 21:32:22)
#4 Март 18, 2016 22:12:49
PowerShell, Set-Location: Не удается найти позиционный параметр
#5 Март 18, 2016 22:17:29
PowerShell, Set-Location: Не удается найти позиционный параметр
Это как так? Какой системой? Как вы такое получили? Питон насколько я знаю такое не создает.
Вы пользуетесь Windows. Давно пора усвоить что эта ОС постоянно создает такие штуки которыми практически нельзя пользоваться. Ее можно использовать, но надо это учитывать.
Отредактировано doza_and (Март 18, 2016 22:18:06)
#6 Март 19, 2016 00:01:13
PowerShell, Set-Location: Не удается найти позиционный параметр
Я имел в виду не папку переименовать
попробуйте в консоли выполнить
CMD
cd c:\Document and settings и ее короткий аналог cd c:\docume
Используем параметры в функциях Powershell с param и Parameter
При создании функции Powershell мы можем передать в нее разные параметры использую атрибут Parameters() и блок param(). Эти параметры могут быть использованы при работе в конвейере, валидации типов данных, определении обязательности их использования, значений по умолчанию и многого другого. В этой статье мы разберем как использовать Powershell Parameters() и param() на примерах.
Навигация по посту
Где и как использовать param и Parameters
Ситуация меняется, например, когда вам нужно пинговать разные хосты. Самым плохим вариантом будет дублирование предыдущего кода:
Для соблюдения принципа DRY есть несколько вариантов.
Переменная args
В Powershell, так же как и во многих других языках, существует переменная ‘args’. Смысл в этой переменной хранить все переданные значения в коллекции (так же называются списки, листы или просто массив).
Эта переменная создается автоматически при вызове команды:
Что бы получать доступ к каждому значение мы должны обращаться к нему по индексу:
Одна из проблем, которая появляется при использовании ‘$args’, неочевидность использования. Спустя время вы, или другой человек, можете не вспомнить про порядок передаваемых значений, их типы данных и т.д. Нужно будет открывать код и читать его что бы разобраться в этом.
Именованные параметры
Использование ключей выглядит так:
Вряд ли у вас возникнут сомнения в том, что должно находится в параметре «ComputerName» или «Hops». Это нельзя гарантировать при использовании «$args».
Что бы реализовать параметры в вашей функции существует 2 подхода.
Первый способ похож на реализацию параметров в большинстве языков, мы просто помещаем их в круглые скобки:
Второй способ реализуется через блок param() в котором мы объявляем параметры:
Блок ‘param’ более предпочтительный способ. Он принят сообществом как стандарт передачи параметров. Кроме этого он позволяет использовать расширенный функционал.
Расширенные функции с CmdletBinding и Parameter
В Powershell есть понятие расширенных функций. Эти функции создаются при наличии одного или двух атрибутов: ‘CmdletBinding ‘ и ‘Parameter’. Благодаря им у вашей команды автоматически появляется следующий список ключей (указан ключ и алиас):
Атрибут ‘Parameter’ используется внутри ‘param’. Он используется для проверки (валидации) определенных параметров. Эти проверки могут быть разными: может ли ключ принимать данные с конвейера, какова его максимальна длина, является ли он обязательным и т.д. Блок ‘Parameter’ можно дублировать.
Пример использования (только для демонстрации синтаксиса):
Так как я сам легко путаюсь в понятии параметр, аргумент и атрибут, ниже скриншот с небольшим объяснением:
Использование param в файлах
Эта статья рассматривает использования ‘param()’ в функциях т.к. это наиболее популярный способ использования. Тем не менее вы можете поместить этот блок в файл:
Далее мы можем вызвать этот файл и передать в него значения:
Если до блока ‘param()’ будет какой-то код (кроме комментариев), произойдет ошибка:
Обязательные Mandatory аргументы
Работая с другими командами Powershell вы замечали, что какие-то параметры являются обязательными к заполнению, а какие-то нет. По умолчанию все параметры опциональны. Что бы сделать их обязательными к заполнению используется аргумент ‘Mandatory’. Обязательность использования параметра указывается в ‘Parameter()’:
Если вы не используете параметр явно, то он у вас будет запрошен. Это правило, в случае выше, касается только одного параметра так как он является обязательным.
Обратите внимание, что объявление ‘Mandatory’ не снимает с вас обязанности проверки на корректность переданных данных. Это дает лишь возможность остановить работу функции еще на первоначальном этапе.
Проверка типов и значение по умолчанию
Эта проверка выполняется до объявления переменной.
У некоторых типов вы можете добавить скобки ‘[]’. Такой прием говорит, что вы ожидаете получить массив определенных типов. В случае строк ‘[string]’ массив строк будет выглядеть ‘[string[]]’ (ниже пример на числах):
Объявить значение по умолчанию мы можем только у аргумента, который не является ‘Mandatory’. Это делается следующим образом:
switch
Аналогичным образом мы можем объявить переменную типа switch. Если параметр будет указан, то такая переменна будет иметь значение ‘True’:
Такой подход уменьшает риск ошибок и сокращает время на написание команды. Использование switch похоже на bool, но у них есть разница. В случае ‘[bool]’ нужно будет указывать значение параметра.
Разделение параметров на группы с ParameterSetName
В ситуациях, когда в функцию нужно передать разный набор обязательных параметров, мы можем использовать атрибут ParameterSetName. Для примера можно посмотреть на описание синтаксиса команды ‘Get-EventLog’:
У нас выводится 2 возможных варианта использования команды. Для каждого из варианта использования команды могут быть определены свои индивидуальные ключи. Именно для этого используется ParameterSetName.
Создадим команду с 2-умя группами. Первая группа ‘Group1’ работает с именами пользователей, а ‘Group2’ только с идентификаторами и требует дополнительно параметра:
Группу, которую вы планируете использовать по умолчанию, можно определить в ‘CmdletBinding’ используя атрибут ‘DefaultParameterSetName’:
Один ключ может находится в нескольких группах. Для этого, группу, нужно указать в разных ‘Parameter()’. Каждый аргумент, указанный в Parameter, будет действовать для определенной группы. Так, в случае ниже, в одной группе «$Message» является обязательным, а в другой опциональным параметром:
Позиционные параметры с Position
При создании команды каждый параметр имеет свою позицию. Эти позиции соответствуют порядку их объявления внутри функции:
Такой подход часто используется в обычных командах Powershell. Параметры типа ‘Name’ или ‘ComputerName’ могут работать позиционно, а остальные нет.
Параметры конвейера
Для использования конвейера можно определить несколько аргументов:
Создадим функцию, которая будет принимать оба параметра:
Единственный момент, который не оговорен в той статье, ‘ValueFromPipeline’ можно использовать несколько раз, но в определенном случае. Если у вы используете группировку (разделяете параметры на группы) и указываете один из параметров явно:
Включаем значения вне параметров с ValueFromRemainingArguments
У вас может быть ситуация, когда вы не можете предусмотреть параметр для конкретного значения. Это так же может быть проблема с ограничением Powershell на 32 параметра. В этом случае вы можете использовать ‘ValueFromRemainingArguments’, который включает все значения не привязанных к каким-то параметрам.
Атрибут ‘ValueFromRemainingArguments’ объявляется следующим образом:
Обратите внимание, что порядок в этом случае не важен.
Атрибуты валидации параметров
Значения у параметров могут проходить разные проверки. Для этих проверок существуют разные атрибуты:
Рассмотрим некоторые из этих атрибутов.
Ошибки при этом могут быть разными:
‘AllowNull()’ работает для типов ‘[array]’ и других типов данных, кроме строк и коллекций. Для них нужно использовать ‘[AllowEmptyString()]’ и ‘[AllowEmptyCollection()]’.
Перед указанием таких атрибутов стоит проверить во что будет преобразован ваш тип данных, например:
Подсчет значений
Проверка по скрипту
Вы можете создать свою проверку параметров с помощью «ValidateScript». Так вы создадите параметр, который запретит указывать прошедшие даты:
Ошибка происходит из-за того, что команда отправляет данные, допустим в 11.1 секунд, а валидация в 11.2. Во втором примере мы добавляем 1 секунду что бы ошибки не было.
Вместо «$PSItem» можно использовать «$_».
Проверка по шаблонам регулярных выражений
Мы можем привязать к параметру проверку на простые регулярные выражения (SupportsWildcards) и расширенные (ValidatePattern). Так мы убедимся, что в параметр передают валидный IP адрес:
Ограничение выбора значений с ValidateSet
В некоторых командах есть возможность выбора значений у параметров. Такой выбор осуществляется через кнопку ‘tab’. Вы можете проверить это нажав ‘tab’ в следующей команде:
У вас будет выполняться переключение между значениями: Continue, Ignore, Inquire и т.д.
Подобный выбор задается в атрибуте ValidateSet:
Если вы укажете значение не прописанное в ‘ValidateSet’, то получите ошибку:
Передача ключей и значений в одной переменной (Splatting)
Обычный вызов команды выглядит следующим образом:
Мы можем взять все ключи и значения из этой команды, поместить в hashtable и передать в команду как набор параметров:
Что бы Powershell понял, что мы передаем не одну переменную, а набор ключей и значений, мы должны ее пометить знаком ‘@’:
Такой подход называется ‘Splatting’ (брызги) и немного повышает читаемость кода.
Если в hashtable будет находиться дополнительный параметр, который не реализован в команде, то выйдет ошибка:
Обычные массивы так тоже можно передавать, но вы должны знать позиции под которыми должны располагаться значения:
Используя splatting, в Powershell 7+, вы можете перезаписывать значения из метода splatting:
Алиасы
К параметрам можно привязать алиасы (короткие имена/псевдонимы). Это делается через атрибут ‘Alias()’. Ограничений в количестве атрибутов нет:
Передача параметров в PowerShell
Иногда создаваемый вами сценарий или функция должна принять какое либо входное значение — имя компьютера, путь к папке, название сервиса и т.п. В PowerShell есть несколько способов передать данные в сценарий из командной строки, сделав их ввод более простым и эффективным.
Этот скрипт должен вывести состояние заданного сервиса\сервисов для одного или нескольких компьютеров. Имя сервиса и компьютера передаются в скрипт в качестве аргументов.
Теперь выполним его, указав в качестве аргументов сервис печати (spooler) и имя компьютера SRV1:
.\service.ps1 spooler SRV1
Более эффективным способом передачи параметров является использование в сценарии блока param. Для примера возьмем наш сценарий и изменим его:
Param (
[string]$service,
[string]$computer
)
Разбивать сценарий на строки необязательно, вполне возможно записать все в одну строку. Если блок param имеется в сценарии или функции, PowerShell сам считывает его и разделяет знаками табуляции. Поскольку имена параметров явно указаны, то их можно вводить в любом порядке, например так:
Чтобы вводить меньше текста, имена параметров можно сократить, например так:
.\service.ps1 spooler SRV1
Есть в PowerShell и более сложный способ передачи параметров, позволяющий задавать параметры как обязательные, указывать для каждого позицию и многое другое. Для примера изменим сценарий следующим образом:
Param (
[Parameter (Mandatory=$true, Position=1)]
[string]$service,
[Parameter (Mandatory=$true, Position=2)]
[string]$computer
)
Здесь оба параметра указаны как обязательные (Mandatory=$true) и для каждого задана своя позиция. Это значит, что оба параметра обязательно должны быть указаны и должны идти строго в определенном порядке. Теперь если не указать один из параметров, то PowerShell автоматически напомнит об этом и предложит ввести недостающую информацию.
Использование расширенного синтаксиса позволяет задавать различные ограничения для вводимых параметров. Еще раз изменим сценарий, указав в нем для имени компьютера ограничение в 3 символа (ValidateLength(1,3):
Param (
[Parameter (Mandatory=$true)]
[string]$service,
[Parameter (Mandatory=$true)]
[ValidateLength(1,3)]
[string]$computer
)
И теперь, если введенные значения не подходят под заданные ограничения, то сценарий не отработает. В нашем случае вот такая команда выдаст ошибку
А такая отработает нормально: