【问题标题】:In a CSV file I have a list of machines, if inactive in AD remove it from the file在 CSV 文件中,我有一个机器列表,如果在 AD 中不活动,则将其从文件中删除
【发布时间】:2019-01-21 19:08:42
【问题描述】:

我有一个 CSV 文件,其中包含 2 个字段,1. ComputerName 2. ErrorCode。它是从安全应用程序创建的。

我需要将 ComputerName 列表与 AD 进行比较。如果它处于活动状态,我需要将其导出到另一个 CSV 文件。

听起来很简单,但我不知道如何将错误消息也写入同一个文件。如果我可以读取 AD 并简单地删除不存在的行,那也很好,但我已经拥有了我需要的大部分内容。

我可以将列表分为存在于 AD 中的机器和不存在的机器,但它不会复制错误消息。

编辑以获得更多说明

database-1.csv:

计算机名,错误 4140lw7,系统分区太小

当我运行脚本时,输出如下所示,并且不会删除不活动的机器;

4140lw7,系统分区太小

我使用的脚本会将 AD 中的活动与非活动区分开来,但前提是错误列不存在,即database-1.csv w/o Error 列:

计算机名 2sd8cfngw98 23987hgivuw

这将创建以下内容:

exist.csv(活跃于 AD):

2sd8cfngw98

nonexist.csv(在 AD 中无效):

23987hgivuw

但如果错误代码在文​​件中,它将不起作用。我需要与机器名称关联的文件中的错误代码。

foreach ($computer in (Get-Content C:\apps\database-1.csv)) {
    try {
        $test = Get-ADComputer -Identity $computer -ErrorAction Stop
        if ($test) {
            Write-Output "$computer" | Out-File C:\apps\exist.csv -Append
        }
    } catch {
        Write-Output "$computer" | Out-File C:\apps\Nonexist.csv -Append
    }
}

【问题讨论】:

  • 所以 database-1.csv 是一个包含两列的 csv。您使用 Get-Content 阅读它,每一行都是一个计算机名称。我认为您需要使用 Import-CSV 而不是 Get-Content。请提供database-1.csv的内容样本
  • 什么错误信息?请为现有和缺少的计算机提供示例输入以及所需输出的示例。
  • 也可以用2>filename.txt写错误或者查看write-error
  • 格特,是的,是的。但它目前只使用机器名称。我只是不知道如何确保也导出错误代码。示例内容如说明 A 列有机器名称列表,B 列有和错误代码,即“系统分区太小”。
  • 引用您的问题:“但我不知道如何将错误消息也写入同一个文件” 那么,再次,什么错误消息?另外,请再次edit您的问题并提供我要求您提供的 3 个样本。

标签: powershell csv


【解决方案1】:

首先,您希望将输入文件读取为 CSV (Import-Csv),而不是纯文本文件 (Get-Content),因为后者会给您整行(包括错误消息)而前者会让您分别访问这两个字段。

一个简单的解决方案是这样的:

foreach ($computer in (Import-Csv 'C:\input.csv')) {
    if (Get-ADComputer -Filter "Name -eq '$($_.ComputerName)'") {
        $_ | Export-Csv 'C:\exist.csv' -NoType -Append
    } else {
        $_ | Export-Csv 'C:\nonexist.csv' -NoType -Append
    }
}

但是,根据 AD 中的计算机数量和输入 CSV 中的记录数量,这不会很好地扩展,因为 AD 查询成本很高。仅当您的 CSV 中的条目数量与 AD 中的计算机总数相比非常少时,才使用此方法。

通常更好的方法是从您的 AD 计算机构建哈希表:

$computers = @{}
Get-ADComputer -Filter * | ForEach-Object { $computers[$_.Name] = $true }

允许您廉价地查找计算机名称。

foreach ($computer in (Import-Csv 'C:\input.csv')) {
    if ($computers.ContainsKey($_.ComputerName)) {
        $_ | Export-Csv 'C:\exist.csv' -NoType -Append
    } else {
        $_ | Export-Csv 'C:\nonexist.csv' -NoType -Append
    }
}

与仅查询一台计算机相比,从 AD 查询所有计算机所需的时间相对较长,但其执行时间或多或少是恒定的,而对于单个查询,执行时间与查询数量成正比。像这样:

^ 吨 | | ,' | ,´ 个人查询 | ,' | ,' | ,' |-----,´---------- | ,´ 查询所有 | ,' |,' +--------------------> n

在上面的粗略图中,t 是脚本执行时间,n 是输入 CSV 中的条目数。

【讨论】:

  • 谢谢,很有帮助!
  • @MitchellWalker 不客气。如果您发现它解决了您的问题,请考虑accepting the answer
【解决方案2】:

你有没有想过比较输出文件:

Compare-Object -DifferenceObject (Get-Content file1.txt ) -ReferenceObject (Get-Content file2.txt ) -PassThru |
    Out-File file3.txt 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-17
    • 1970-01-01
    • 2015-01-01
    • 1970-01-01
    • 2019-03-10
    • 2015-10-13
    • 1970-01-01
    相关资源
    最近更新 更多