我有一份计算机名称列表,我需要一份关于它们的 OU、mangedby 属性和名称的报告。我已经创建了一个堆栈,其中包含我想要的每个设置,但它们没有对齐。对于 650 台计算机,managedby 和 OU 堆栈的计数属性都是 650,但是当我将数据输出到 txt 文件时,我只从 ManagedBy 中获取 603 行。如果数据在组合时对齐,则没有问题,但是当我将空白数据添加到 txt 文件时,它似乎不会改变堆栈。我的代码如下。生成堆栈后,我将它们导出到 txt 文件,其中有一个宏可以为我截断数据。任何帮助都将不胜感激。
$stackDN = New-Object System.Collections.Stack
$stackMB = New-Object System.Collections.Stack
$stackNE = New-Object System.Collections.Stack
foreach($computer in $computers){
try{
Get-ADComputer -Identity $computer -Server $domain -Properties * -ErrorAction Stop
$object = Get-ADComputer -Identity $computer -Server $domain -Properties *
$stackDN.Push($object.DistinguishedName)
$mb = $object.ManagedBy
$stackMB.Push($object.ManagedBy)
$stackMB.push('MB not listed')
}
catch{
$stackNE.Push($computer)
}
}
$stackDN | Out-File -FilePath H:\dn.txt
$stackMB | out-file -FilePath H:\mb.txt
$stackNE | out-file -FilePath H:\ne.txt'
答案1
您现有的代码中有很多...非常规...Powershell。我认为您让事情变得比原本应该的更困难。特别是,使用 .NET Stack 对象是不必要的,并且尝试将每个列表存储在自己的堆栈中并不是组织的最佳选择,正如您所发现的那样。
您的代码似乎表明您已经有一个$computers
包含计算机名称列表的变量。那么让我们从那里开始吧。您对迭代集合的想法是正确的,但让我们切换到使用 ForEach-Object cmdlet 而不是 ForEach 语句。最好将结果通过管道传递给其他命令。
$adComputers = $computers | ForEach-Object {
Get-ADComputer $_ -Properties managedBy
}
上面的代码中发生了一些事情。这$_
是您在 ForEach-Object 循环中引用“当前项目”的方式。我们还明确要求 AD 提供该managedBy
属性,因为它不包含在返回的默认属性中。我们没有指定Name
或DistingiushedName
因为那些是在默认输出中。但添加它们也没什么坏处(有些人认为这样更易于阅读)。
现在,我们已经将计算机对象放在自己的集合中,让我们用它们制作一份报告。对于这种主要由行和列组成的数据,通常可以使用 CSV 输出。我们只需从每个对象中选择所需的特定属性,然后调用Export-Csv
。
$adComputers | Select Name,ManagedBy,DistinguishedName |
Export-Csv .\report.csv -NoTypeInformation
您可以省略 Export-Csv 调用来预览 CSV 中的内容。但除非您使用非常宽的窗口,否则 DN 字段可能会被截断。我还包含了它,-NoTypeInformation
因为它省略了大多数查看报告的人不会关心的标题行。
从技术上讲,您甚至不需要拆分这些命令。它们可以是像这样的一行大命令。
$computers | %{ Get-ADComputer $_ -Prop managedBy } |
Select Name,ManagedBy,DistinguishedName |
Export-Csv .\report.csv -NoTypeInformation
请注意,我将 切换ForEach-Object
为它的简写别名%
,这样在命令行上输入起来会更快。我还将其缩短-Properties
为-Prop
,这样 Powershell 就不会产生歧义,从而知道您的意思。