Powershell 函数调用将传递的字符串更改为 int

Powershell function call changing passed string into int

所以我正在使用那种有问题的 Sapien powershell studio 制作一个 powershell 驱动的 GUI 应用程序,并且我正在尝试执行 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 参数显式转换为 [string] 类型

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

将原始字符串从 AdObjectModifier 表单传递到 FindInAD。

.... 

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

....

在方法调用之间,当时输出管道上没有其他东西(至少我没有)。它是 EventHandler > 带字符串参数的函数调用

为什么我传递的字符串变成了数字???

编辑:我认为我传递的参数会以某种方式自动替换为生成的布尔值,但这对我来说没有任何意义....

你有一个语法问题:

FindInAD($nameOfDeviceInput.Text).Count # WRONG

注意:错误在此上下文中的意思是:语法正式有效,但不符合您的预期 - 请参阅底部。

应该是:

(FindInAD $nameOfDeviceInput.Text).Count

PowerShell 命令 - 函数、cmdlet、脚本和外部程序 - 像 shell 命令一样被调用 - foo arg1 arg2 - 并且 不像 C# 方法那样 - foo('arg1', 'arg2').

即:

  • 不要(...)放在参数列表周围.

    • 但是,如果您希望命令调用参与 ,您确实需要 (...) 整个调用 ]expression,如上所示访问 属性 .Count - 请参阅 了解更多信息。
  • whitespace分隔参数(至少一个space),彼此和命令名称 - 不要使用 ,

    • , 之间的参数功能不同:它构造一个 array 作为 single 参数传递 - 见下文。
  • 您可以将简单的字符串(既不包含 space 也不包含 PowerShell 元字符,例如 ;& 的字符串)作为 裸词;也就是说,引用它们是可选的;例如,您可以调用 foo bar 而不是 foo 'bar' - 请参阅 了解 PowerShell 如何解析不带引号的命令参数。

  • 此外,如果目标函数或脚本具有 explicitly declared parametersbinary cmdlet 总是这样做),例如 -bar-baz,您可以将您的值作为 named 参数传递,即在它们前面加上目标参数名称;这样做是脚本中的好习惯:foo -bar arg1 -baz arg2

相比之下,调用对象方法使用语法熟悉常规编程语言,例如 C# ($obj.foo('arg1', 'arg2'))

这个差异涉及两个 PowerShell's two fundamental parsing modes, explained in detail in :

  • 命令参数模式中被解析——如shells.

  • 方法调用 和基于运算符的表达式在表达式模式 中解析 - 与常规编程语言一样。

这些模式是为了允许 PowerShell 服务 双重职责:一方面作为 shell,另一方面,作为 脚本(编程)语言


PowerShell 可以帮助您避免这个语法问题:

请注意,问题不在于使用 method 语法调用 command invalid 语法,但它 没有按预期工作,这可能很难诊断。

简而言之:当你调用command foo作为foo('foo', 'bar')时,('foo', 'bar')是一个2 元素数组,然后作为单个参数传递给 foo .

为了防止出现问题,您可以Set-StrictMode 设置为 -Version 2 或更高 ,这会使 PowerShell 报告 error 如果调用命令时不小心使用了方法语法:

# 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 包含 额外的 严格检查,您还必须遵守这些检查,特别是:

    • 您不得引用不存在的变量
    • 您不得引用不存在的属性;有关与 PowerShell 统一处理标量和集合相关的陷阱,请参阅 GitHub issue #2798
  • 仅针对具有 多个 参数的伪方法调用报告错误(例如,
    foo('bar', 'baz')), 而不是只有 one;例如,foo('bar') 被接受,因为单参数情况通常仍然(意外地)有效。

  • 报告的违反严格性的错误是语句-终止错误:也就是说,它们只终止手头的语句,但默认情况下脚本继续;确保整体执行中止 - 在 任何 类型的错误 - 你必须设置
    $ErrorActionPreference = 'Stop' 在代码的开头。有关详细信息,请参阅 this answer


至于你试过的

FindInAD($nameOfDeviceInput.Text).Count

等同于:

FindInAD ($nameOfDeviceInput.Text).Count

表达式($nameOfDeviceInput.Text).Count的结果作为参数传递给函数FindInAD.