您的症状的唯一解释是变量$certcn的值:
-
或者:是 空字符串 ('') 因为'someString'.Contains('') 为任何返回$true em> 输入字符串。
-
或:被隐式转换为空字符串,尽管这在实践中不会经常发生;以下是一些示例(请参阅GitHub issue # 了解下面提到的[pscustomobject] 字符串化错误):
# An empty array stringifies to ''
'someString'.Contains(@()) # -> $true
# A single-element array containing $null stringifies to ''
'someString'.Contains(@($null)) # -> $true
# Due to a longstanding bug, [pscustomobject] instances, when
# stringified via .ToString(), convert to the empty string.
# This makes the command equivalent to `.Contains(@(''))`, which is again
# the same as `.Contains('')`
'someString'.Contains(@([pscustomobject] @{ foo=1 })) # -> $true
$args[0] 不是字符串
automatic $args variable 是一个数组,其中包含所有未绑定到声明的参数(如果有)的位置参数。
$args 可以包含任何数据类型的元素,而该类型是由调用者单独确定。
但是,如果你正式声明一个参数,你可以键入它,这意味着如果调用者传递一个不同的参数数据类型,尝试将参数转换为参数的类型(这可能会失败,但至少失败会“响亮”,原因很明显)。
为您的脚本提供强大的解决方案:
param(
[Parameter(Mandatory)] # Ensure that the caller passes a value.
[string] $CertCN # Type-constrain to a string.
# , ... declare other parameters as needed
)
# $CertCN is now guaranteed to be a *string* that is *non-empty*.
$crt =
(Get-ChildItem -Path Cert:\LocalMachine\WebHosting |
Where-Object { $_.Subject.Contains($CertCN) }).thumbprint
注意:
-
参数声明块中的use of the [Parameter()] attribute (param(...)) 使您的脚本成为advanced one,这意味着不支持$args,需要所有 参数显式绑定声明的参数;但是,如果需要,您可以使用 [Parameter(ValueFromRemaningArguments)] 定义一个包罗万象的参数。 (使脚本或函数成为高级脚本或函数的另一件事是在整个 param(...) 块上方使用 [CmdletBinding()] 属性。)
-
[Parameter(Mandatory)],除了确保调用者传递参数的值外,还隐式地阻止传递 empty 字符串(或 $null) - 尽管您可以使用 @ 显式允许它987654345@
-
此外,高级脚本和函数会自动阻止将 数组 传递给 [string] 类型的参数,这是可取的。 (相比之下,simple 函数和脚本只是 stringify 数组,就像在可扩展字符串(字符串插值)中发生的那样;例如,& { param([string] $foo) $foo } 1, 2 绑定 '1 2',这也是"$(1, 2)" 会得到什么)
警告:
将值传递给[string] 类型的参数时,PowerShell接受任何类型的标量(非集合),并且任何非字符串类型都通过.ToString()自动转换为字符串。这通常是可取和方便的,但会导致无用的字符串化;例如:
& { param([string] $str) $str } @{} # -> 'System.Collections.Hashtable'
hashtables (@{ ... }) 的实例将其字符串化为它们的类型名称,这是没有帮助的,并且这种行为是任何没有显式实现有意义的字符串表示的类型的默认行为通过覆盖.ToString() 方法。
如果这是一个问题,您可以修改您的脚本以确保传递的参数值已经是一个字符串,使用[ValidateScript()] 属性。 p>
param(
[Parameter(Mandatory)]
# Ensure that the argument value is a [string] to begin with.
# Note: The `ErrorMessage` property requires PowerShell (Core) 7+
[ValidateScript({ $_ -is [string] }, ErrorMessage='Please pass a *string* argument.')]
$CertCN # Do not type-constrain, so that the original type can be inspected.
# , ... declare other parameters as needed
)
# ...
不幸的是,正如代码 cmets 中所述,在需要 PowerShell (Core) 7+ 中使用 ErrorMessage 属性。在 Windows PowerShell 中总是会显示标准错误消息,这根本不是用户友好的。