将参数作为数组传递给PowerShell函数 不应可写但实际上是的自动变量列表:

我试图弄清楚如何将多个字符串作为数组传递给Powershell函数。

function ArrayCount([string[]] $args) {
    Write-Host $args.Count
}

ArrayCount "1" "2" "3"
ArrayCount "1","2","3"
ArrayCount @("1","3")

打印

2
0
0

如何将具有3个值的数组传递给ArrayCount函数? 为什么某些调用的计数为零?

wjqact 回答:将参数作为数组传递给PowerShell函数 不应可写但实际上是的自动变量列表:

在PowerShell中, $ args 是一个自动变量,它引用未命名参数。只需更改您的参数名称:

function ArrayCount([string[]] $myParam) {
    Write-Host $myParam.Count
}

您将获得预期的输出

1
3
3
,

撰写者:PowerShell Core 7.0.0-preview.5 / Windows PowerShell v5.1

Martin Brandl's helpful,to-the-point answer补充一些背景信息:

$argsautomatic variable 的实例,表示其 值由PowerShell本身控制的特殊变量

因此,即使需要工作(请参阅下文),您也应 避免自定义使用自动变量。>

理想情况下,PowerShell本身会一致地阻止此类自定义使用 (仅针对 some 自动变量这样做),并且存在{{ 3}}关于执行该操作,但出于向后兼容的原因,最终决定不执行该操作。

相反,计划是通过安装debate on GitHub发出有关在Visual Studio Code 中自动变量赋值的设计时警告。 {3}}。

从PowerShell扩展版本2019.11.0 (基于捆绑的PSScriptAnalyzer版本)开始,部分已实现:尽管有一个可用的PSAvoidAssignmentToAutomaticVariable规则,但是它仅警告分配给 deacto 只读的自动变量(例如$Host),而不警告那些不是只读的,但应该是(例如$args);此外,必须手动激活规则,然后激活PowerShell extension
参见PSScriptAnalyzer

不幸的是,您通常不能推断变量名是否从其中引用了自动变量,并且也没有程序化 >发现它们的方式-阅读帮助主题是唯一的选择;请参阅下一节。


不应可写但实际上是的自动变量列表:

注意:

  • 此列表是使用以下命令生成的,从 Windows PowerShell v5.1开始-在PowerShell Core 中,该列表较短,因为某些过时的变量已被删除。

    • 该命令依赖于相关帮助主题字符串解析;这种方法比较脆弱,但是由于没有基于 reflection 的方法,因此这是发现自动变量的唯一方法。

    • isn't persisted建议实现程序发现性,并讨论为自动变量引入单独的,保留的命名空间的可能性。

  • 随着时间的推移,可能会引入新的自动变量。希望它们的只读状态(如果适用)将在引入时强制实施。

    • 由于自动变量与用户变量共享命名空间,因此引入任何新的自动变量都可能会破坏现有代码。
  • 选择少数个自动变量是合法可写的:

    • $OFS-对数组进行字符串化时使用的分隔符。
    • $null-特殊变量,它不仅在 read 读取时代表空值,而且还旨在允许为其分配任何值以丢弃(不将其写入(成功的)输出流中。)
    • $LASTEXITCODE,格式为$global:LASTEXITCODE,用于设置要使用的进程退出代码(尽管最好用exit <n>完成)。
  • 下面列出的自动变量 not (例如$PID)已经有效为只读(应为只读)。未列出的(如下所列)分为以下几类:

    • 总是安静地丢弃分配值(例如$Input$MyInvocation$PSCmdlet)的那些人

    • 那些接受自定义值,但会在自动分配值的上下文中覆盖(阴影)(例如,$args,每当新脚本块被自动设置为局部变量({函数/脚本);您作为局部 parameter 变量的使用已被有效忽略)。

    • 在混合情况下,尤其是$_ / $PSItem,在其中自动为$_分配了值的任何上下文之外,分配的值都被安静地丢弃,但是在这样的上下文中, 可以(但不应)分配一个新值(例如'in' | ForEach-Object { $_ = $_ + '!'; $_ }输出in!

Name                          Predefined
----                          ----------
_                                  False
AllNodes                           False
Args                                True
Event                              False
EventArgs                          False
EventSubscriber                    False
ForEach                             True
Input                               True
Matches                             True
MyInvocation                        True
NestedPromptLevel                   True
Profile                             True
PSBoundParameters                   True
PsCmdlet                           False
PSCommandPath                       True
PSDebugContext                     False
PSItem                             False
PSScriptRoot                        True
PSSenderInfo                       False
Pwd                                 True
ReportErrorShowExceptionClass      False
ReportErrorShowInnerException      False
ReportErrorShowSource              False
ReportErrorShowStackTrace          False
Sender                             False
StackTrace                          True
This                               False

“预定义”是指默认情况下它们是否存在于全局范围中。

以下代码用于检测它们-您可以预先设置$VerbosePreference = 'Continue'(并在之后重置)以查看已经是只读的变量:

$autoVarNames = ((get-help about_automatic_variables) -split [environment]::newline -match '^\s*\$\w+\s*$').Trim().Trim('$') | Sort-Object -Unique

foreach ($varName in $autoVarNames) {
  $var = Get-Variable $varName -ErrorAction 'SilentlyContinue'
  $exists = $?
  if ($exists -and $var.Options -match 'readonly|constant') {
    Write-Verbose "$varName`: read-only or constant"
  } elseif ($varName -in 'NULL','OFS','LastExitCode') { # exceptions
    Write-Verbose "$varName`: writable by design"
  } else {
    Set-Variable -Name $varName -Value $null -ErrorAction SilentlyContinue
    if ($?) {
      [pscustomobject] @{ Name = $varName; Predefined = $exists }
    }
  }
}

请注意,该代码具有硬编码的例外列表,以免报告确实确实可写的自动变量,例如$OFS$LastExitCode,或可分配为安静的no- op,例如$null

本文链接:https://www.f2er.com/3117645.html

大家都在问