Вызов функции Powershell, изменяющий переданную строку на int

Итак, я использую какую-то глючную студию Sapien powershell для создания приложения с графическим интерфейсом на основе PowerShell, и я пытаюсь выполнить запрос ADSI.

$ nameOfDeviceInput - это System.Windows.Forms.TextBox

В одной форме у меня есть следующая функция:

$buttonPerformAction_Click={
    if (FindInAD($nameOfDeviceInput.Text).Count -gt 0)
    {
        $buttonPerformAction.BackColor = 'Red'
        $buttonPerformAction.Text = "System already exists in AD with that name. Try another name"
        return
    }
.....
}

В основной форме у меня есть функция FindInAD

function FindInAd($nameOfSystem)
{
    Write-Host "seeking system" $nameOfSystem
    ([adsisearcher]"(CN=$nameOfSystem)").FindAll()
}

FindInAd () не работает, потому что по какой-то причине $ nameOfSystem установлено в 1, и если я явно не приведу его как строку, он будет неявно преобразован в Int32 (очевидно)

Я пробовал следующее:

Полная квалификация ввода текстового поля, указав форму, которой он принадлежит ($ adObjectModifier)

 $buttonPerformAction_Click={
        if (FindInAD($adObjectModifier.$nameOfDeviceInput.Text).Count -gt 0)
        {
            $buttonPerformAction.BackColor = 'Red'
            $buttonPerformAction.Text = "System already exists in AD with that name. Try another name"
            return
        }
    .....
    }

Явное приведение параметра $ nameOfSystem как типа [строка]

function FindInAd([string]$nameOfSystem)
{
    Write-Host "seeking system" $nameOfSystem
    ([adsisearcher]"(CN=$nameOfSystem)").FindAll()
}

Передача необработанной строки в FindInAD из формы AdObjectModifier.

.... 

if (FindInAD("Test").Count -gt 0)

....

В данный момент на конвейере вывода больше ничего (по крайней мере, не от меня) между вызовами метода. Это EventHandler ›Вызов функции со строковым параметром

Почему строки, которые я передаю, меняются на цифры ???

РЕДАКТИРОВАТЬ: Я думаю, что мой переданный параметр каким-то образом автоматически заменяется полученным логическим значением, но для меня это не имеет никакого смысла ....


person ReticnT    schedule 08.12.2020    source источник


Ответы (1)


У вас проблема с синтаксисом:

FindInAD($nameOfDeviceInput.Text).Count # WRONG

Примечание. Неправильно в этом контексте означает: синтаксис формально действителен, но не делает того, что вы ожидаете - см. внизу раздел.

Должен быть:

(FindInAD $nameOfDeviceInput.Text).Count

PowerShell команды - функции, командлеты, сценарии и внешние программы - вызываются как команды оболочки - foo arg1 arg2 - и нет как методы C # - foo('arg1', 'arg2').

То есть:

  • Не помещайте (...) в список аргументов.

    • However, you do need (...) around the call as a whole if you want a command call to participate in an expression, as shown above with the access to property .Count - see this answer for more information.
  • Разделяйте аргументы пробелом (хотя бы одним пробелом) как друг от друга, так и от имени команды - не используйте ,

    • , between arguments functions differently: It constructs an array that is passed as a single argument - see below.
  • Вы можете передавать простые строки (те, которые не содержат ни пробелов, ни метасимволов PowerShell, таких как ; или &) как пустые слова; то есть цитирование их необязательно; например, вместо foo 'bar' вы можете вызвать foo bar - см. этот ответ, чтобы узнать, как PowerShell анализирует аргументы команд без кавычек.

  • Кроме того, если целевая функция или сценарий имеет явно объявленные параметры (которые всегда выполняются с помощью двоичных командлетов), например -bar и -baz, вы можете передавать свои значения как named аргументы, т. е. добавляя к ним имя целевого параметра; это хорошая практика в скриптах: foo -bar arg1 -baz arg2

Напротив, при вызове методов объектов используется синтаксис, знакомый по обычным языкам программирования, например C # ($obj.foo('arg1', 'arg2')).

Это различие связывает два двух основных режимов синтаксического анализа PowerShell, подробно объясненный в этом ответе:

  • Команды анализируются в режиме аргументов - как в оболочках.

  • Вызов методов и выражения на основе операторов анализируются в режиме выражения - как в обычных языках программирования.

Эти режимы необходимы, чтобы позволить PowerShell выполнять двойную функцию: как оболочку с одной стороны, и как язык сценариев (программирования) с другой.


PowerShell может помочь вам избежать этой синтаксической проблемы:

Обратите внимание, что проблема не в том, что использование синтаксиса method для вызова команды является недопустимым синтаксисом, а в том, что он не работает как задумано, что может быть трудно диагностировать.

Вкратце: Когда вы вызываете command foo как foo('foo', 'bar'), ('foo', 'bar') является двухэлементным массивом, который затем передается в foo как один аргумент .

Чтобы предотвратить проблему, вы можете установить От Set-StrictMode до -Version 2 или выше, что заставляет PowerShell сообщать об ошибке, если вы случайно используете синтаксис метода при вызове команды:

# Turn on the check for accidental method syntax.
# Note: This also turns on ADDITIONAL checks - see below.
Set-StrictMode -Version 2

# This call now produces an ERROR, because the proper syntax would be:
#    foo 'a' 'b'
foo('a', 'b')

Предостережения:

  • Set-StrictMode -Version 2 включает дополнительные проверки строгости, которым вы также должны соответствовать, в частности:

    • You must not reference non-existent variables.
    • Вы не должны ссылаться на несуществующие свойства; см. выпуск GitHub № 2798, чтобы узнать о связанной ловушке, связанной с унифицированной обработкой скаляров PowerShell и коллекции.
  • Об ошибке сообщается только при вызове псевдометода с несколькими аргументами (например,
    foo('bar', 'baz')), а не только с одним; например, foo('bar') принимается, потому что случай с одним аргументом обычно все еще (случайно) работает.

  • Ошибки, сообщаемые для нарушений строгости, являются ошибками, завершающими оператор: то есть они только завершают текущий оператор, но по умолчанию скрипт продолжается; чтобы гарантировать, что выполнение в целом прерывается - при любом типе ошибки - вам необходимо установить
    $ErrorActionPreference = 'Stop' в начале вашего кода. Дополнительную информацию см. В этом ответе.


Что касается того, что вы пробовали:

FindInAD($nameOfDeviceInput.Text).Count

такой же как:

FindInAD ($nameOfDeviceInput.Text).Count

То есть результат выражения ($nameOfDeviceInput.Text).Count передается в качестве аргумента функции FindInAD.

person mklement0    schedule 08.12.2020