powershell - 将项目动态添加到集合数组中
问题描述
好的。这就是我想要做的。我基本上是想通过从 AD 和 SQL 数据库导入东西来在 powershell 中创建一个二维数组。我将在脚本后面使用数组来写入、更新和删除数据库中的行。我遇到的问题是将所有内容都放入一个变量中。
当我运行我的代码时,它会一遍又一遍地将同一个用户添加到所需的数组中。$Table 变量中创建的最后一项被写入 $ToWrite 中的每个实例。
我尝试在将所有变量输入 $Table 后暂停,将 $Table 写入控制台,然后将 $ToWrite 写入控制台。$Table 在每个循环中都会正确更改,但同样,一旦它写入 $ToWrite,它就会覆盖每个实例。我尝试了多种方法,如 .add()、PsCustomObject[] 等。我现在只是卡住了。
这是我的半功能代码:
$AllPOCs = Get-ADGroupMember 'ALL POC'
$POCs = @()
$Counter = 0
$AllPOCs | ForEach-Object {
$Name = $AllPOCs[$Counter].SamAccountName
$TestPOC = Invoke-Sqlcmd -Query "SELECT * FROM TABLE WHERE CLIENT = '$Name'" -ServerInstance "SERVER\INSTANCE"
if ($TestPOC -eq $null) {
$POCs += Get-ADUser $Name -Properties * |
select -Property SamAccountName, GivenName, Surname, SID, EmailAddress
}
$Counter += 1
}
$ToWrite = @()
$Counter = 0
$SEQUENCE = Invoke-Sqlcmd -Query "Select TABLEFIELD FROM DATABASE WHERE NAME = 'FIELDID'" -ServerInstance "SERVER\INSTANCE"
$SEQUENCE = $SEQUENCE.RECNUM + 1
$Table = "" | select SEQUENCE, LASTUSER, GROUP, CLIENT, FNAME, NAME, EMAILID, USEDEPT, USELOCATION, CREATEDFROMSSD, DISPLAYCLIENTCOMMENTS, _INACTIVE_, WINUSERID, SELFSERVICEACCESS, SELFSERVICELICENSE, WIAENABLED, SID
#everything works correctly up to here
$POCs | ForEach-Object {
$Table.SEQUENCE = $SEQUENCE
$Table.LASTUSER = 'SYSTEMACCOUNT'
$Table.GROUP = 1
$Table.CLIENT = $POCs[$Counter].SamAccountName.ToUpper()
$Table.FNAME = $POCs[$Counter].GivenName.ToString()
$Table.Name = $POCs[$Counter].surname.ToString()
$Table.EmailID = 'SMTP:{' + $POCs[$Counter].EmailAddress.ToString() + '}' +
$POCs[$Counter].EmailAddress.ToString()
$Table.USEDEPT = 0
$Table.USELOCATION = 0
$Table.CREATEDFROMSSD = 0
$Table.DISPLAYCLIENTCOMMENTS = 0
$Table._INACTIVE_ = 0
$Table.WINUSERID = '\DOMAIN' + $POCs[$Counter].SamAccountName.ToString()
$Table.SELFSERVICEACCESS = 'TYPE'
$Table.SELFSERVICELICENSE = 1
$Table.WIAENABLED = 1
$Table.SID = $POCs[$Counter].SID.ToString()
$ToWrite += $Table #THIS DOESN'T WORK PROPERLY.
$SEQUENCE += 1
$Counter += 1
}
输出示例:
序号:1206 上一个用户:系统帐户 组 : 1 客户:用户名 FNAME : 名字 姓名:姓氏 EMAILID : SMTP:{EMAIL}EMAIL 使用日期:0 使用位置:0 创建自SSD:0 显示客户评论:0 _不活跃_:0 WINUSERID:域\用户名 自助服务访问:类型 自助服务许可证:1 支持:1 SID:S-1-Z-XX-CCCCCCCCCC-YYYYYYYYY-VVVVVVVVVV-125121 序号:1206 上一个用户:系统帐户 组 : 1 客户:用户名 FNAME : 名字 姓名:姓氏 EMAILID : SMTP:{EMAIL}EMAIL 使用日期:0 使用位置:0 创建自SSD:0 显示客户评论:0 _不活跃_:0 WINUSERID:域\用户名 自助服务访问:类型 自助服务许可证:1 支持:1 SID:S-1-Z-XX-CCCCCCCCCC-YYYYYYYYY-VVVVVVVVVV-125121 序号:1206 上一个用户:系统帐户 组 : 1 客户:用户名 FNAME : 名字 姓名:姓氏 EMAILID : SMTP:{EMAIL}EMAIL 使用日期:0 使用位置:0 创建自SSD:0 显示客户评论:0 _不活跃_:0 WINUSERID:域\用户名 自助服务访问:类型 自助服务许可证:1 支持:1 SID:S-1-Z-XX-CCCCCCCCCC-YYYYYYYYY-VVVVVVVVVV-125121
有任何想法吗?
解决方案
问题是您$Table
一遍又一遍地更新同一个对象,并将对同一对象的引用添加到输出数组$ToWrite
中,因此其所有元素最终都指向唯一$Table
的对象,其属性值为该点包含在最后一次迭代中分配的点。
此答案中详细解释了该问题,该答案显示了使用自定义类的可能解决方案,可在 PowerShell v5 及更高版本中使用。
没有自定义类的解决方案要求您在每次迭代中克隆自定义$Table
对象:
# Create a new instance with the same properties:
$Table = $Table.psobject.Copy()
注意:此克隆技术仅适用于自定义对象,即 的实例[System.Management.Automation.PSCustomObject]
,例如由Select-Object
cmdlet 和文字语法创建的实例[pscustomobject] @{ ... }
也就是说,由于您在循环中分配了自定义对象的所有属性,因此预先创建模板对象没有任何好处- 相反,只需在循环中使用文字自定义对象创建语法[pscustomobject] @{ ... }
(PSv3+),这隐含在每次迭代中创建一个新实例。
此外,您的解决方案可以得到简化,因为让 PowerShell 为您创建数组既简单又高效,只需收集在一个变量中输出多个对象的命令的输出即可。
这是一个将所有内容放在一起的简化示例:
# Loop over the input and instantiate a new custom object
# in each iteration, then let PowerShell collect the results
# in array variable $ToWrite
[array] $ToWrite = 1..3 | ForEach-Object {
# Instantiate and output a new custom object in each iteration.
[pscustomobject] @{
PropA = "ValueA-$_"
PropB = "ValueB-$_"
}
}
# Output the resulting array
$ToWrite
注意:只有在需要确保它始终是数组[array]
时才需要类型约束;没有它,如果碰巧只有一个循环迭代并因此输出对象,将按原样存储该输出对象,而不是包装在数组中(此行为是 PowerShell 管道的基础)。$ToWrite
$ToWrite
以上产生以下结果,表明创建了不同的对象:
PropA PropB
----- -----
ValueA-1 ValueB-1
ValueA-2 ValueB-2
ValueA-3 ValueB-3
推荐阅读
- java - 计算非二叉树的元素个数
- javascript - JavaScript - 设置超时功能,然后获取 innerHTML 并设置 sessionStorage
- numpy - numpy.rfftn 的多元多项式数组表示
- swift - 如何在完成处理程序中使用完成处理程序
- python - 通过查询集访问的对象没有 Django 中的属性
- vb.net - VB.net 使用验证执行插入语句时出现语法错误
- html - 放大镜和图像对齐
- git - .gitattributes 语言学家语言声明
- javascript - 遍历数组并加入 Google Apps 脚本
- python - AttributeError:“TensorSliceDataset”对象没有属性“get_shape”