【问题标题】:Passing a Array of information to a separate script in powershell将信息数组传递给powershell中的单独脚本
【发布时间】:2021-10-22 06:01:52
【问题描述】:

我有一个从 SQL 中获取一系列信息的脚本。然后它解析信息并将其传递给一系列数组。然后我想将每个数组传递给一个单独的脚本。

我已经看到 Start-job 应该能够做到这一点,但从我的测试来看,它似乎不起作用。这是我尝试过的。每个脚本单独工作,我目前只是使用 CVS 来传递信息。

一旦信息在脚本中,我需要能够调用每个对象的特定属性。我确实得到它只是将数组打印为字符串,但我不能调用任何特定的东西。

Invoke-Sqlcmd -Query $Q1 -ServerInstance $I -Database $DB | Export-Csv "$Files\Employees.csv"

$emps = Import-Csv "$Files\Employees.csv"
$newaccounts = @()
$deacaccounts = @()
$changedusers = @()
if(Test-Path -Path "$Files\Employees.csv"){
    foreach ($emp in $emps) {
        if ($emp.emp_num.trim() -ne $emp.EmpNum) {
           $newaccounts += $emp 
        }
        if ($emp.emp_num.trim() -eq $emp.EmpNum) {
            if ($emp.fname -ne $emp.GivenName -and $emp.lname -ne $emp.SurName) {
                $deacaccounts += $emp
                $newaccounts += $emp
            }
            else ($emp.dept -ne $emp.DepartmentNumber -or $emp.job_title -ne $emp.JobTitle) {
                $changedusers += $emp
            }
        }
    }
}

Start-job -path "script" -argumentlist (,$deacaccounts)
Start-job -path "script" -argumentlist (,$changedusers)
Start-job -path "script" -argumentlist (,$newaccounts )

编辑: 传递给脚本的信息将是多行员工数据。我需要能够在“子”脚本中获取该信息并根据它们执行操作。

前: 失职=

fname Lname empnum
ted kaz 1234
sam cart 245

【问题讨论】:

  • 后台工作对我来说并不重要。 “父”脚本将自动运行,所以它都在后台。我只需要能够传递信息。如果不同的命令会更好地工作,那很好。

标签: powershell automation


【解决方案1】:

如果你真的需要background jobs - 事实证明你不需要 - 注意Start-Job 没有-Path 参数;你应该改用-ScriptBlock { & "$script" }

要简单地在前台调用脚本,请按顺序使用以下内容(script 代表您的 .ps1 文件路径):

& "script" $deacaccounts
& "script" $changedusers
& "script" $newaccounts

注意:&call operator,仅在脚本/可执行路径被引用和/或包含变量引用(或子表达式);例如,路径为c:\foo\bar.ps1 的脚本可以在没有 & 的情况下调用;例如
c:\foo\bar.ps1 $deacaccounts

请注意,您的脚本将收到一个单个参数,其中包含一个数组值。

如果您想将数组元素作为单独的(位置)参数传递,则必须使用 splatting,在此您使用 sigil @ 而不是 $传递您的变量(例如,
& "script" @deaccounts)。

如果您需要枚举数组并单独传递每个对象作为参数,请使用以下内容:

foreach ($obj in $deaccounts)   { & "script" $obj }
foreach ($obj in $changedusers) { & "script" $obj }
foreach ($obj in $newaccounts)  { & "script" $obj }

如果每个对象都应该根据其属性值按位置进行喷溅

foreach ($obj in $deaccounts) { 
  $vals = $obj.psobject.Properties.Value
  & "script" @vals 
}
# ... ditto for $changeduser and $newaccounts

如果每个对象都应该按属性名称进行分割,则基于属性名称和值,您需要首先将每个对象转换为哈希表

foreach ($obj in $deaccounts) { 
  $params = @{}
  foreach ($prop in $obj.psobject.Properties) {
    $params[$prop.Name] = $prop.Value
  } 
  & "script" @params
}
# ... ditto for $changeduser and $newaccounts

顺便说一句:在循环中使用+= 增量扩展数组效率低下,因为必须在每次迭代中在后台创建一个数组,因为数组是固定大小的。

一般来说,更有效的方法是使用foreach 循环作为表达式,并让PowerShell 自己将输出收集到一个数组中:[array] $outputs = foreach (...) { ... } - 请参阅this answer

如果您需要手动创建数组,例如创建 多个 数组,例如在您的情况下,请使用可有效扩展的列表类型,例如 [System.Collections.Generic.List[object]] - 请参阅 this answer

【讨论】:

  • 要么我很难完全理解所提出的概念,要么存在误解,因为它似乎不像我认为的那样工作。这些脚本的目标是创建、更新和停用帐户。所以他们每个人都会得到一行数据,其中包含多个值(名字、姓氏、标题、数字等),可能还有多行。我希望能够收集每个信息的所有信息,然后运行执行所需操作的脚本,而不需要多次运行脚本,或者每次都创建一个 CSV。我在主要问题中编辑了更多信息。
  • @AndeCase,恐怕您的评论和编辑都不会让我更清楚您的意图。也许如果您显示脚本的参数声明和使用文字数据的示例调用,它会变得更加清晰。同时,这个答案提供了一些关于参数传递和喷溅的一般指示。
  • @AndeCase,我添加了更多关于泼溅的信息;也许这有帮助。
猜你喜欢
  • 2013-10-15
  • 2023-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-05
  • 2012-07-06
  • 2013-04-27
  • 1970-01-01
相关资源
最近更新 更多