【问题标题】:How to Pull Data Value from Array and Input as a Variable如何从数组中提取数据值并作为变量输入
【发布时间】:2019-04-11 12:24:18
【问题描述】:

我想为每个服务器加载一个包含服务器和 ID 的 csv。第 1 列是服务器名称,第 2 列是 ID 字符串。将有 40 个服务器,每个服务器都有一个特定的 ID 字符串。在我的脚本中,我想提取主机名,然后在我的数组中搜索它。一旦找到,我想将与服务器名称对应的ID输出到变量中。我对powershell很陌生,所以请记住这一点。我最好用例子来解决问题。

$Server = @()
$ID = @()

Import-Csv C:\SecuredFiles\ID.csv | ForEach-Object {$Server += $_.Server ; 
$ID += $_.ID}

$ServerName = Invoke-Command -ScriptBlock {hostname}

if ($Server -contains $ServerName)
  {
    $Where = [array]::IndexOf($Server, $ServerName)
    $InputID = $ID[$Where]
  }

Start-Process -FilePath 'C:\MyFolder\App.exe' "-id $InputID -d C:\MyFolder"

我已经研究了几个小时,我知道我的工作比需要的更努力,但我很固执,喜欢自己寻找答案,但我迷路了,偏头痛,哈哈,也许我做错了。

我尝试了各种格式,但得到了不同的错误,例如“在语句块或类型定义中缺少关闭 '}'”,即使它显然存在。我当前的错误是“if”语句开头的“if(条件)之后缺少语句块”。非常感谢任何帮助。

【问题讨论】:

  • 为什么要把它拉出阵列?就地使用它,你不需要管理额外的变量。
  • 系统如何知道使用哪个 Id 作为参数列表?我不需要它来搜索和匹配,然后提取关联的 ID 吗?
  • 如果您知道该项目在数组中的位置,您可以通过$Collection[$Index].Parameter 简单地引用它。您的方法有效,但似乎是不需要的额外步骤。但是,请使用最适合您对问题的思考方式的方法!你是必须维护它的人... [grin]

标签: powershell csv variables


【解决方案1】:

这是从导入的 CSV 文件中获取系统 ID 的一种方法...

# fake reading in a CSV file
#    in real life, use Import-CSV
$InStuff = @"
Name, ID
Srv001, 1001
Srv002, 2002
Srv003, 3003
Srv004, 4004
Srv005, 5005
$env:COMPUTERNAME, 6006
Srv007, 7007
"@ | ConvertFrom-Csv

($InStuff -match $env:COMPUTERNAME).ID

输出=6006

【讨论】:

    【解决方案2】:

    导入 CSV 然后使用它返回的自定义对象实例更容易、更高效:

    # Import into an array of custom objects ([pscustomobject]) that have
    # both a .Server and an .ID property.
    $serversAndTheirIds = Import-Csv C:\SecuredFiles\ID.csv
    

    具体来说,使用+= 迭代构建输出数组非常有效,因为数组是不可变 数据结构,“添加”到它们意味着 数组每次都必须在幕后分配。


    无需使用Invoke-Command 来同步调用控制台应用程序 - 只需直接调用应用程序

    $ServerName = hostname # invoke hostname.exe and capture its output
    

    使用Where-Object cmdlet 或 PSv4+ .Where() 方法 过滤集合:

    $inputId = $serversAndTheirIds | Where-Object { $_.Server -eq $ServerName } | 
      Select-Object -ExpandProperty ID
    

    更高效的 PSv4+ 替代方案:

    $inputId = $serversAndTheirIds.Where({ $_.Server -eq $ServerName }, 'First' }).ID
    

    再次,同步调用另一个控制台应用程序,直接调用它:

    C:\MyFolder\App.exe -id $InputID -d C:\MyFolder
    

    注意:如果可执行路径被引用,您需要在前面加上& , the call operator

    仅将Start-Process 用于调用GUI 应用程序,或异步隐藏 运行程序。


    至于你的语法问题

    在撰写本文时您的问题中发布的代码在语法上是正确的,不会导致您引用的错误消息。

    这是导致他们的原因:

    Missing closing '}' in statement block or type definiton

    没有关闭 } 的脚本块 ({...}) 将触发此错误;例如,如果您的脚本包含以下内容:

     { 'foo'   # no closing '}'
    

    Missing statement block after if ( condition )

    if 语句后面没有脚本块会触发此错误;例如,如果您的脚本包含以下内容:

     if ($true) # no script block ({ ... }) to follow the conditional
    

    【讨论】:

    • 感谢您提供给我的大量信息,尽管我没有完全理解其中的一些信息,但我仍然非常感谢。我正在与我的导师一起帮助我查看建议,以进一步解释您给我的内容的来龙去脉,以便我了解我输入特定代码的内容和原因。至于错误,我使用的是 Visual Studio Code,这可能会导致这些错误吗?我可能会打开一个工作区以便您看到它,但这些是我遇到的错误,还是与我使用 PS5.1 有关?
    • 我很高兴听到这个消息,@Kameron。不,无论是使用 Visual Studio Code 还是使用 v5.1 都无法解释这些错误。
    猜你喜欢
    • 2022-01-04
    • 2022-12-08
    • 1970-01-01
    • 2016-05-29
    • 2016-05-04
    • 2020-12-16
    • 1970-01-01
    • 1970-01-01
    • 2015-04-30
    相关资源
    最近更新 更多