如何从数组中提取数据值并将输入作为变量

时间:2018-11-08 01:11:55

标签: powershell csv variables

我想用服务器的ID和每个服务器的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(condition)之后缺少语句块”。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分: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

特别地,用+=迭代地构建输出数组非常有效,因为数组是不可变数据结构,并且向它们“添加”意味着 new 每次必须在后台分配数组。


无需使用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

答案 1 :(得分: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

output = 6006